Commit 09821499 authored by Igor Kravchenko's avatar Igor Kravchenko Committed by Alex Deucher

drm/amd/display: Read VBIOS Golden Settings Tbl

[Why]
For ver.4.4 and higher VBIOS contains default setting table.

{How]
Read Golden Settings Table from VBIOS, apply Aux tuning parameters.
Signed-off-by: default avatarIgor Kravchenko <Igor.Kravchenko@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c06f670f
...@@ -2834,6 +2834,8 @@ static const struct dc_vbios_funcs vbios_funcs = { ...@@ -2834,6 +2834,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
.bios_parser_destroy = bios_parser_destroy, .bios_parser_destroy = bios_parser_destroy,
.get_board_layout_info = bios_get_board_layout_info, .get_board_layout_info = bios_get_board_layout_info,
.get_atom_dc_golden_table = NULL
}; };
static bool bios_parser_construct( static bool bios_parser_construct(
......
...@@ -2079,6 +2079,85 @@ static uint16_t bios_parser_pack_data_tables( ...@@ -2079,6 +2079,85 @@ static uint16_t bios_parser_pack_data_tables(
return 0; return 0;
} }
static struct atom_dc_golden_table_v1 *bios_get_golden_table(
struct bios_parser *bp,
uint32_t rev_major,
uint32_t rev_minor,
uint16_t *dc_golden_table_ver)
{
struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL;
uint32_t dc_golden_offset = 0;
*dc_golden_table_ver = 0;
if (!DATA_TABLES(dce_info))
return NULL;
/* ver.4.4 or higher */
switch (rev_major) {
case 4:
switch (rev_minor) {
case 4:
disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
DATA_TABLES(dce_info));
if (!disp_cntl_tbl_4_4)
return NULL;
dc_golden_offset = disp_cntl_tbl_4_4->dc_golden_table_offset;
*dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver;
break;
}
break;
}
if (!dc_golden_offset)
return NULL;
if (*dc_golden_table_ver != 1)
return NULL;
return GET_IMAGE(struct atom_dc_golden_table_v1,
dc_golden_offset);
}
static enum bp_result bios_get_atom_dc_golden_table(
struct dc_bios *dcb)
{
struct bios_parser *bp = BP_FROM_DCB(dcb);
enum bp_result result = BP_RESULT_OK;
struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL;
struct atom_common_table_header *header;
struct atom_data_revision tbl_revision;
uint16_t dc_golden_table_ver = 0;
header = GET_IMAGE(struct atom_common_table_header,
DATA_TABLES(dce_info));
if (!header)
return BP_RESULT_UNSUPPORTED;
get_atom_data_table_revision(header, &tbl_revision);
atom_dc_golden_table = bios_get_golden_table(bp,
tbl_revision.major,
tbl_revision.minor,
&dc_golden_table_ver);
if (!atom_dc_golden_table)
return BP_RESULT_UNSUPPORTED;
dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver;
dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val;
dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val;
dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val;
dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val;
dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val;
dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val;
dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val;
dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val;
dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val;
return result;
}
static const struct dc_vbios_funcs vbios_funcs = { static const struct dc_vbios_funcs vbios_funcs = {
.get_connectors_number = bios_parser_get_connectors_number, .get_connectors_number = bios_parser_get_connectors_number,
...@@ -2128,6 +2207,8 @@ static const struct dc_vbios_funcs vbios_funcs = { ...@@ -2128,6 +2207,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
.get_board_layout_info = bios_get_board_layout_info, .get_board_layout_info = bios_get_board_layout_info,
.pack_data_tables = bios_parser_pack_data_tables, .pack_data_tables = bios_parser_pack_data_tables,
.get_atom_dc_golden_table = bios_get_atom_dc_golden_table
}; };
static bool bios_parser2_construct( static bool bios_parser2_construct(
......
...@@ -1540,6 +1540,9 @@ static bool dc_link_construct(struct dc_link *link, ...@@ -1540,6 +1540,9 @@ static bool dc_link_construct(struct dc_link *link,
} }
} }
if (bios->funcs->get_atom_dc_golden_table)
bios->funcs->get_atom_dc_golden_table(bios);
/* /*
* TODO check if GPIO programmed correctly * TODO check if GPIO programmed correctly
* *
......
...@@ -133,6 +133,9 @@ struct dc_vbios_funcs { ...@@ -133,6 +133,9 @@ struct dc_vbios_funcs {
uint16_t (*pack_data_tables)( uint16_t (*pack_data_tables)(
struct dc_bios *dcb, struct dc_bios *dcb,
void *dst); void *dst);
enum bp_result (*get_atom_dc_golden_table)(
struct dc_bios *dcb);
}; };
struct bios_registers { struct bios_registers {
...@@ -154,6 +157,7 @@ struct dc_bios { ...@@ -154,6 +157,7 @@ struct dc_bios {
struct dc_firmware_info fw_info; struct dc_firmware_info fw_info;
bool fw_info_valid; bool fw_info_valid;
struct dc_vram_info vram_info; struct dc_vram_info vram_info;
struct dc_golden_table golden_table;
}; };
#endif /* DC_BIOS_TYPES_H */ #endif /* DC_BIOS_TYPES_H */
...@@ -890,6 +890,20 @@ struct dsc_dec_dpcd_caps { ...@@ -890,6 +890,20 @@ struct dsc_dec_dpcd_caps {
uint32_t branch_max_line_width; uint32_t branch_max_line_width;
}; };
struct dc_golden_table {
uint16_t dc_golden_table_ver;
uint32_t aux_dphy_rx_control0_val;
uint32_t aux_dphy_tx_control_val;
uint32_t aux_dphy_rx_control1_val;
uint32_t dc_gpio_aux_ctrl_0_val;
uint32_t dc_gpio_aux_ctrl_1_val;
uint32_t dc_gpio_aux_ctrl_2_val;
uint32_t dc_gpio_aux_ctrl_3_val;
uint32_t dc_gpio_aux_ctrl_4_val;
uint32_t dc_gpio_aux_ctrl_5_val;
};
#if defined(CONFIG_DRM_AMD_DC_DCN3_0) #if defined(CONFIG_DRM_AMD_DC_DCN3_0)
enum dc_gpu_mem_alloc_type { enum dc_gpu_mem_alloc_type {
DC_MEM_ALLOC_TYPE_GART, DC_MEM_ALLOC_TYPE_GART,
......
...@@ -38,7 +38,8 @@ ...@@ -38,7 +38,8 @@
#define AUX_REG_LIST(id)\ #define AUX_REG_LIST(id)\
SRI(AUX_CONTROL, DP_AUX, id), \ SRI(AUX_CONTROL, DP_AUX, id), \
SRI(AUX_DPHY_RX_CONTROL0, DP_AUX, id) SRI(AUX_DPHY_RX_CONTROL0, DP_AUX, id), \
SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id)
#define HPD_REG_LIST(id)\ #define HPD_REG_LIST(id)\
SRI(DC_HPD_CONTROL, HPD, id) SRI(DC_HPD_CONTROL, HPD, id)
...@@ -107,6 +108,7 @@ ...@@ -107,6 +108,7 @@
struct dce110_link_enc_aux_registers { struct dce110_link_enc_aux_registers {
uint32_t AUX_CONTROL; uint32_t AUX_CONTROL;
uint32_t AUX_DPHY_RX_CONTROL0; uint32_t AUX_DPHY_RX_CONTROL0;
uint32_t AUX_DPHY_RX_CONTROL1;
}; };
struct dce110_link_enc_hpd_registers { struct dce110_link_enc_hpd_registers {
......
...@@ -31,10 +31,10 @@ ...@@ -31,10 +31,10 @@
#define TO_DCN10_LINK_ENC(link_encoder)\ #define TO_DCN10_LINK_ENC(link_encoder)\
container_of(link_encoder, struct dcn10_link_encoder, base) container_of(link_encoder, struct dcn10_link_encoder, base)
#define AUX_REG_LIST(id)\ #define AUX_REG_LIST(id)\
SRI(AUX_CONTROL, DP_AUX, id), \ SRI(AUX_CONTROL, DP_AUX, id), \
SRI(AUX_DPHY_RX_CONTROL0, DP_AUX, id) SRI(AUX_DPHY_RX_CONTROL0, DP_AUX, id), \
SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id)
#define HPD_REG_LIST(id)\ #define HPD_REG_LIST(id)\
SRI(DC_HPD_CONTROL, HPD, id) SRI(DC_HPD_CONTROL, HPD, id)
...@@ -73,6 +73,7 @@ struct dcn10_link_enc_aux_registers { ...@@ -73,6 +73,7 @@ struct dcn10_link_enc_aux_registers {
uint32_t AUX_CONTROL; uint32_t AUX_CONTROL;
uint32_t AUX_DPHY_RX_CONTROL0; uint32_t AUX_DPHY_RX_CONTROL0;
uint32_t AUX_DPHY_TX_CONTROL; uint32_t AUX_DPHY_TX_CONTROL;
uint32_t AUX_DPHY_RX_CONTROL1;
}; };
struct dcn10_link_enc_hpd_registers { struct dcn10_link_enc_hpd_registers {
...@@ -443,7 +444,10 @@ struct dcn10_link_enc_registers { ...@@ -443,7 +444,10 @@ struct dcn10_link_enc_registers {
type AUX_TX_PRECHARGE_LEN; \ type AUX_TX_PRECHARGE_LEN; \
type AUX_TX_PRECHARGE_SYMBOLS; \ type AUX_TX_PRECHARGE_SYMBOLS; \
type AUX_MODE_DET_CHECK_DELAY;\ type AUX_MODE_DET_CHECK_DELAY;\
type DPCS_DBG_CBUS_DIS type DPCS_DBG_CBUS_DIS;\
type AUX_RX_PRECHARGE_SKIP;\
type AUX_RX_TIMEOUT_LEN;\
type AUX_RX_TIMEOUT_LEN_MUL
struct dcn10_link_enc_shift { struct dcn10_link_enc_shift {
DCN_LINK_ENCODER_REG_FIELD_LIST(uint8_t); DCN_LINK_ENCODER_REG_FIELD_LIST(uint8_t);
......
...@@ -309,7 +309,6 @@ bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc) ...@@ -309,7 +309,6 @@ bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc)
void enc2_hw_init(struct link_encoder *enc) void enc2_hw_init(struct link_encoder *enc)
{ {
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
/* /*
00 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__1to2 : 1/2 00 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__1to2 : 1/2
01 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__3to4 : 3/4 01 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__3to4 : 3/4
...@@ -333,9 +332,18 @@ void enc2_hw_init(struct link_encoder *enc) ...@@ -333,9 +332,18 @@ void enc2_hw_init(struct link_encoder *enc)
AUX_RX_PHASE_DETECT_LEN, [21,20] = 0x3 default is 3 AUX_RX_PHASE_DETECT_LEN, [21,20] = 0x3 default is 3
AUX_RX_DETECTION_THRESHOLD [30:28] = 1 AUX_RX_DETECTION_THRESHOLD [30:28] = 1
*/ */
AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110); if (enc->ctx->dc_bios->golden_table.dc_golden_table_ver > 0) {
AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, enc->ctx->dc_bios->golden_table.aux_dphy_rx_control0_val);
AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, enc->ctx->dc_bios->golden_table.aux_dphy_tx_control_val);
AUX_REG_WRITE(AUX_DPHY_RX_CONTROL1, enc->ctx->dc_bios->golden_table.aux_dphy_rx_control1_val);
} else {
AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110);
AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c4d);
AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a); }
//AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32; //AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32;
// Set AUX_TX_REF_DIV Divider to generate 2 MHz reference from refclk // Set AUX_TX_REF_DIV Divider to generate 2 MHz reference from refclk
......
...@@ -191,7 +191,10 @@ ...@@ -191,7 +191,10 @@
LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_DETECTION_THRESHOLD, mask_sh), \ LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_DETECTION_THRESHOLD, mask_sh), \
LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_TX_PRECHARGE_LEN, mask_sh),\ LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_TX_PRECHARGE_LEN, mask_sh),\
LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_TX_PRECHARGE_SYMBOLS, mask_sh),\ LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_TX_PRECHARGE_SYMBOLS, mask_sh),\
LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_MODE_DET_CHECK_DELAY, mask_sh) LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_MODE_DET_CHECK_DELAY, mask_sh),\
LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_PRECHARGE_SKIP, mask_sh),\
LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\
LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh)
#define UNIPHY_DCN2_REG_LIST(id) \ #define UNIPHY_DCN2_REG_LIST(id) \
SRI(CLOCK_ENABLE, SYMCLK, id), \ SRI(CLOCK_ENABLE, SYMCLK, id), \
......
...@@ -941,7 +941,6 @@ struct atom_display_controller_info_v4_1 ...@@ -941,7 +941,6 @@ struct atom_display_controller_info_v4_1
uint8_t reserved3[8]; uint8_t reserved3[8];
}; };
struct atom_display_controller_info_v4_2 struct atom_display_controller_info_v4_2
{ {
struct atom_common_table_header table_header; struct atom_common_table_header table_header;
...@@ -976,6 +975,59 @@ struct atom_display_controller_info_v4_2 ...@@ -976,6 +975,59 @@ struct atom_display_controller_info_v4_2
uint8_t reserved3[8]; uint8_t reserved3[8];
}; };
struct atom_display_controller_info_v4_4 {
struct atom_common_table_header table_header;
uint32_t display_caps;
uint32_t bootup_dispclk_10khz;
uint16_t dce_refclk_10khz;
uint16_t i2c_engine_refclk_10khz;
uint16_t dvi_ss_percentage; // in unit of 0.001%
uint16_t dvi_ss_rate_10hz;
uint16_t hdmi_ss_percentage; // in unit of 0.001%
uint16_t hdmi_ss_rate_10hz;
uint16_t dp_ss_percentage; // in unit of 0.001%
uint16_t dp_ss_rate_10hz;
uint8_t dvi_ss_mode; // enum of atom_spread_spectrum_mode
uint8_t hdmi_ss_mode; // enum of atom_spread_spectrum_mode
uint8_t dp_ss_mode; // enum of atom_spread_spectrum_mode
uint8_t ss_reserved;
uint8_t dfp_hardcode_mode_num; // DFP hardcode mode number defined in StandardVESA_TimingTable when EDID is not available
uint8_t dfp_hardcode_refreshrate;// DFP hardcode mode refreshrate defined in StandardVESA_TimingTable when EDID is not available
uint8_t vga_hardcode_mode_num; // VGA hardcode mode number defined in StandardVESA_TimingTable when EDID is not avablable
uint8_t vga_hardcode_refreshrate;// VGA hardcode mode number defined in StandardVESA_TimingTable when EDID is not avablable
uint16_t dpphy_refclk_10khz;
uint16_t hw_chip_id;
uint8_t dcnip_min_ver;
uint8_t dcnip_max_ver;
uint8_t max_disp_pipe_num;
uint8_t max_vbios_active_disp_pipum;
uint8_t max_ppll_num;
uint8_t max_disp_phy_num;
uint8_t max_aux_pairs;
uint8_t remotedisplayconfig;
uint32_t dispclk_pll_vco_freq;
uint32_t dp_ref_clk_freq;
uint32_t max_mclk_chg_lat; // Worst case blackout duration for a memory clock frequency (p-state) change, units of 100s of ns (0.1 us)
uint32_t max_sr_exit_lat; // Worst case memory self refresh exit time, units of 100ns of ns (0.1us)
uint32_t max_sr_enter_exit_lat; // Worst case memory self refresh entry followed by immediate exit time, units of 100ns of ns (0.1us)
uint16_t dc_golden_table_offset; // point of struct of atom_dc_golden_table_vxx
uint16_t dc_golden_table_ver;
uint32_t reserved3[3];
};
struct atom_dc_golden_table_v1
{
uint32_t aux_dphy_rx_control0_val;
uint32_t aux_dphy_tx_control_val;
uint32_t aux_dphy_rx_control1_val;
uint32_t dc_gpio_aux_ctrl_0_val;
uint32_t dc_gpio_aux_ctrl_1_val;
uint32_t dc_gpio_aux_ctrl_2_val;
uint32_t dc_gpio_aux_ctrl_3_val;
uint32_t dc_gpio_aux_ctrl_4_val;
uint32_t dc_gpio_aux_ctrl_5_val;
uint32_t reserved[23];
};
enum dce_info_caps_def enum dce_info_caps_def
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment