modegen: Support for VFP based modes for Galileo

This commit is contained in:
Keith Mikoleit 2023-07-31 16:54:26 -07:00 committed by Joshua Ashton
parent 0dbf62aa6b
commit 68fcc76a55
4 changed files with 108 additions and 18 deletions

View file

@ -85,6 +85,16 @@ static uint32_t steam_deck_display_rates[] =
60,
};
static uint32_t galileo_display_rates[] =
{
45,47,48,49,
50,51,53,55,56,59,
60,62,64,65,66,68,
72,73,76,77,78,
80,81,82,84,85,86,87,88,
90,
};
static uint32_t get_conn_display_info_flags(struct drm_t *drm, struct connector *connector)
{
if (!connector)
@ -813,6 +823,9 @@ void drm_update_patched_edid( drm_t *drm )
create_patched_edid(drm->connector->edid_data.data(), drm->connector->edid_data.size(), drm, drm->connector);
}
#define GALILEO_SDC_PID 0x3003
#define GALILEO_BOE_PID 0x3004
static void parse_edid( drm_t *drm, struct connector *conn)
{
memset(conn->make_pnp, 0, sizeof(conn->make_pnp));
@ -883,8 +896,14 @@ static void parse_edid( drm_t *drm, struct connector *conn)
(strcmp(conn->make_pnp, "VLV") == 0 && strcmp(conn->model, "ANX7530 U") == 0) ||
(strcmp(conn->make_pnp, "VLV") == 0 && strcmp(conn->model, "Jupiter") == 0);
if ( conn->is_steam_deck_display )
conn->valid_display_rates = std::span(steam_deck_display_rates);
if ((vendor_product->product == GALILEO_SDC_PID) || (vendor_product->product == GALILEO_BOE_PID)) {
conn->is_galileo_display = vendor_product->product;
conn->valid_display_rates = std::span(galileo_display_rates);
} else {
conn->is_galileo_display = 0;
if ( conn->is_steam_deck_display )
conn->valid_display_rates = std::span(steam_deck_display_rates);
}
drm_hdr_parse_edid(drm, conn, edid);
@ -3026,7 +3045,7 @@ bool drm_set_refresh( struct drm_t *drm, int refresh )
case DRM_MODE_GENERATE_FIXED:
{
const drmModeModeInfo *preferred_mode = find_mode(connector, 0, 0, 0);
generate_fixed_mode( &mode, preferred_mode, refresh, drm->connector->is_steam_deck_display );
generate_fixed_mode( &mode, preferred_mode, refresh, drm->connector->is_steam_deck_display, drm->connector->is_galileo_display );
break;
}
}

View file

@ -174,6 +174,7 @@ struct connector {
char *model;
bool is_steam_deck_display;
std::span<uint32_t> valid_display_rates{};
uint16_t is_galileo_display;
int target_refresh;
bool vrr_capable;

View file

@ -268,28 +268,98 @@ void generate_cvt_mode(drmModeModeInfo *mode, int hdisplay, int vdisplay,
}
}
void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, int vrefresh, bool use_tuned_clocks)
// galielo SDC rev B ds.10 spec'd rates
// fps 45 48 51 55 60 65 72 80 90
// VFP 1321 1157 993 829 665 501 337 173 9
// galielo BOE spec'd rates
// fps 45 48 51 55 60 65 72 80 90
// VFP 1320 1156 992 828 664 500 336 172 8
// SDC VFP values for 45 Hz to 90 Hz
unsigned int galileo_sdc_vfp[] =
{
1321,1264,1209,1157,1106,1058,993,967,925,883,829,805,768,732,698,
665,632,601,571,542,501,486,459,433,408,383,360,337,314,292,271,250,230,210,191,
173,154,137,119,102,86,70,54,38,23,9
};
// BOE VFP values for 45 Hz to 90 Hz
// BOE Vtotal must be a multiple of 4
unsigned int galileo_boe_vfp[] =
{
1320,1272,1216,1156,1112,1064,992,972,928,888,828,808,772,736,700,
664,636,604,572,544,500,488,460,436,408,384,360,336,316,292,272,252,228,212,192,
172,152,136,120,100,84,68,52,36,20,8
};
#define GALILEO_MIN_REFRESH 45
#define GALILEO_SDC_PID 0x3003
#define GALILEO_SDC_VSYNC 1
#define GALILEO_SDC_VBP 22
#define GALILEO_BOE_PID 0x3004
#define GALILEO_BOE_VSYNC 2
#define GALILEO_BOE_VBP 30
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
unsigned int get_galileo_vfp( int vrefresh, unsigned int * vfp_array, unsigned int num_rates )
{
for ( unsigned int i = 0; i < num_rates; i++ ) {
if ( i+GALILEO_MIN_REFRESH == (unsigned int)vrefresh ) {
return vfp_array[i];
}
}
return 0;
}
void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, int vrefresh,
bool use_tuned_clocks, unsigned int use_vfp )
{
*mode = *base;
if (!vrefresh)
vrefresh = 60;
if ( use_vfp ) {
unsigned int vfp, vsync, vbp = 0;
if (GALILEO_SDC_PID == use_vfp) {
vfp = get_galileo_vfp( vrefresh, galileo_sdc_vfp, ARRAY_SIZE(galileo_sdc_vfp) );
// if we did not find a matching rate then we default to 60 Hz
if ( !vfp ) {
vrefresh = 60;
vfp = 665;
}
vsync = GALILEO_SDC_VSYNC;
vbp = GALILEO_SDC_VBP;
} else { // BOE Panel
vfp = get_galileo_vfp( vrefresh, galileo_boe_vfp, ARRAY_SIZE(galileo_boe_vfp) );
// if we did not find a matching rate then we default to 60 Hz
if ( !vfp ) {
vrefresh = 60;
vfp = 664;
}
vsync = GALILEO_BOE_VSYNC;
vbp = GALILEO_BOE_VBP;
}
mode->vsync_start = mode->vdisplay + vfp;
mode->vsync_end = mode->vsync_start + vsync;
mode->vtotal = mode->vsync_end + vbp;
} else {
if ( use_tuned_clocks )
{
mode->hdisplay = 800;
mode->hsync_start = 840;
mode->hsync_end = 844;
mode->htotal = 884;
if ( use_tuned_clocks )
{
mode->hdisplay = 800;
mode->hsync_start = 840;
mode->hsync_end = 844;
mode->htotal = 884;
mode->vdisplay = 1280;
mode->vsync_start = 1310;
mode->vsync_end = 1314;
mode->vtotal = 1322;
}
mode->vdisplay = 1280;
mode->vsync_start = 1310;
mode->vsync_end = 1314;
mode->vtotal = 1322;
mode->clock = ( ( mode->htotal * mode->vtotal * vrefresh ) + 999 ) / 1000;
}
mode->clock = ( ( mode->htotal * mode->vtotal * vrefresh ) + 999 ) / 1000;
mode->vrefresh = (1000 * mode->clock) / (mode->htotal * mode->vtotal);
snprintf(mode->name, sizeof(mode->name), "%dx%d@%d.00", mode->hdisplay, mode->vdisplay, vrefresh);
}

View file

@ -9,4 +9,4 @@
void generate_cvt_mode(drmModeModeInfo *mode, int hdisplay, int vdisplay,
float vrefresh, bool reduced, bool interlaced);
void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base,
int vrefresh, bool use_tuned_clocks);
int vrefresh, bool use_tuned_clocks, unsigned int use_vfp);