diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index 14fc4ef482f1..ba1b46d3a13e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -601,3 +601,25 @@ void dc_link_get_alpm_support(struct dc_link *link, { link->dc->link_srv->edp_get_alpm_support(link, auxless_support, auxwake_support); } + +void dc_link_set_panel_polarity_enable(struct dc_link *link, bool enable) +{ + if (link->dc->link_srv->edp_set_panel_polarity_enabled) + link->dc->link_srv->edp_set_panel_polarity_enabled(link, enable); +} + +void dc_link_panel_polarity_reset(struct dc_link *link) +{ + if (link->dc->link_srv->edp_panel_polarity_reset) + link->dc->link_srv->edp_panel_polarity_reset(link); +} + +bool dc_link_get_panel_polarity(struct dc_link *link, int32_t *polarity) +{ + bool ret = false; + + if (link->dc->link_srv->edp_get_panel_polarity) + ret = link->dc->link_srv->edp_get_panel_polarity(link, polarity); + + return ret; +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 6e45a484a9ad..34d4ede12e79 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -3897,4 +3897,11 @@ unsigned int dc_override_memory_bandwidth_request( struct dc *dc, unsigned int bw_mbps); +/** + * Panel Polarity Control + */ +void dc_link_set_panel_polarity_enable(struct dc_link *link, bool enable); +void dc_link_panel_polarity_reset(struct dc_link *link); +bool dc_link_get_panel_polarity(struct dc_link *link, int32_t *polarity); + #endif /* DC_INTERFACE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 47fa3d4265e0..b9fd375a3997 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -2475,3 +2475,55 @@ void dc_dmub_srv_get_fams2_debug_meta(struct dc_dmub_srv *dc_dmub_srv) dm_execute_dmub_cmd_list(dc_dmub_srv->ctx, 1, &cmd, DM_DMUB_WAIT_TYPE_WAIT); } + +void dc_dmub_srv_panel_polarity_set_enable(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst, bool enable) +{ + union dmub_rb_cmd cmd; + struct dc_context *ctx = dc_dmub_srv->ctx; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.panel_polarity_enable.header.type = DMUB_CMD__PANEL_POLARITY; + cmd.panel_polarity_enable.header.sub_type = DMUB_CMD__PANEL_POLARITY_ENABLE; + cmd.panel_polarity_enable.header.payload_bytes = sizeof(cmd.panel_polarity_enable.data); + cmd.panel_polarity_enable.data.enable = enable ? 1 : 0; + cmd.panel_polarity_enable.data.otg_inst = panel_inst; + + dc_wake_and_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT); +} + +void dc_dmub_srv_panel_polarity_reset(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst) +{ + union dmub_rb_cmd cmd; + struct dc_context *ctx = dc_dmub_srv->ctx; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.panel_polarity_enable.header.type = DMUB_CMD__PANEL_POLARITY; + cmd.panel_polarity_enable.header.sub_type = DMUB_CMD__PANEL_POLARITY_RESET; + cmd.panel_polarity_enable.header.payload_bytes = sizeof(cmd.panel_polarity_enable.data); + cmd.panel_polarity_enable.data.otg_inst = panel_inst; + + dc_wake_and_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT); +} + +bool dc_dmub_srv_panel_polarity_get_polarity(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst, int32_t *polarity) +{ + bool ret = false; + uint32_t raw_polarity = 0; + uint32_t retry_count = 0; + struct dc_context *ctx = dc_dmub_srv->ctx; + + *polarity = 0; + + do { + /* Send gpint command and wait for ack */ + if (dc_wake_and_execute_gpint(ctx, DMUB_GPINT__PANEL_POLARITY_GET_BIAS, panel_inst, &raw_polarity, + DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) { + *polarity = (int32_t)raw_polarity; + ret = true; + } + } while (++retry_count <= 1000 && ret == false); + + return ret; +} diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h index 6d15ed77c17d..ec5387aedf46 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -424,4 +424,31 @@ bool dc_dmub_srv_ihc_set_dig_hdcp_interrupt_dest( * @dc_dmub_srv - pointer to DMUB service object */ void dc_dmub_srv_get_fams2_debug_meta(struct dc_dmub_srv *dc_dmub_srv); + +/** + * dc_dmub_srv_panel_polarity_set_enable() - Enables or disables panel polarity. + * + * @dc_dmub_srv: DMUB service handle + * @panel_inst: Panel instance + * @enable: true to enable, false to disable + */ +void dc_dmub_srv_panel_polarity_set_enable(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst, bool enable); + +/** + * dc_dmub_srv_panel_polarity_reset() - Resets panel polarity. + * + * @dc_dmub_srv: DMUB service handle + * @panel_inst: Panel instance + */ +void dc_dmub_srv_panel_polarity_reset(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst); + +/** + * dc_dmub_srv_panel_polarity_get_polarity() - Gets the current panel polarity. + * + * @dc_dmub_srv: DMUB service handle + * @panel_inst: Panel instance + * @polarity: Pointer to store the current polarity + */ +bool dc_dmub_srv_panel_polarity_get_polarity(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst, int32_t *polarity); + #endif /* _DMUB_DC_SRV_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_service.h b/drivers/gpu/drm/amd/display/dc/inc/link_service.h index 026d28046eea..f87dfe63227d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_service.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_service.h @@ -315,7 +315,9 @@ struct link_service { bool (*dp_pr_set_general_cmd)(struct dc_link *link, struct dmub_cmd_pr_general_cmd_data *general_cmd_data); bool (*dp_pr_get_state)(const struct dc_link *link, uint64_t *state); void (*edp_set_panel_power)(struct dc_link *link, bool powerOn); - + void (*edp_set_panel_polarity_enabled)(const struct dc_link *link, bool enable); + void (*edp_panel_polarity_reset)(struct dc_link *link); + bool (*edp_get_panel_polarity)(struct dc_link *link, int32_t *polarity); /*************************** HDMI FRL *********************************/ bool (*hdmi_frl_poll_status_flag)(struct dc_link *link); @@ -363,5 +365,6 @@ struct link_service { uint64_t (*dp_trace_get_edp_poweroff_timestamp)(struct dc_link *link); void (*dp_trace_source_sequence)( struct dc_link *link, uint8_t dp_test_mode); + }; #endif /* __DC_LINK_HPD_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 7146f8356233..a83693ea43c0 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -234,6 +234,10 @@ static void construct_link_service_edp_panel_control(struct link_service *link_s link_srv->edp_receiver_ready_T7 = edp_receiver_ready_T7; link_srv->edp_power_alpm_dpcd_enable = edp_power_alpm_dpcd_enable; link_srv->edp_set_panel_power = edp_set_panel_power; + + link_srv->edp_set_panel_polarity_enabled = edp_set_panel_polarity_enabled; + link_srv->edp_panel_polarity_reset = edp_panel_polarity_reset; + link_srv->edp_get_panel_polarity = edp_get_panel_polarity; } /* link dp panel replay implements DP panel replay functionality. diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 16951a9550f2..e3527b14686b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -1301,3 +1301,33 @@ void edp_set_panel_assr(struct dc_link *link, struct pipe_ctx *pipe_ctx, *panel_mode = DP_PANEL_MODE_DEFAULT; } } + +void edp_set_panel_polarity_enabled(const struct dc_link *link, bool enable) +{ + struct dc *dc = link->ctx->dc; + struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv; + + if (dc_dmub_srv) + dc_dmub_srv_panel_polarity_set_enable(dc_dmub_srv, 0, enable); +} + +void edp_panel_polarity_reset(struct dc_link *link) +{ + struct dc *dc = link->ctx->dc; + struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv; + + if (dc_dmub_srv) + dc_dmub_srv_panel_polarity_reset(dc_dmub_srv, 0); +} + +bool edp_get_panel_polarity(struct dc_link *link, int32_t *polarity) +{ + struct dc *dc = link->ctx->dc; + struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv; + bool ret = false; + + if (dc_dmub_srv) + ret = dc_dmub_srv_panel_polarity_get_polarity(dc_dmub_srv, 0, polarity); + + return ret; +} diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h index 8fdb76d9953e..51de13e2387e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h @@ -77,4 +77,8 @@ bool edp_setup_freesync_replay(struct dc_link *link, const struct dc_stream_stat void edp_set_panel_power(struct dc_link *link, bool powerOn); void edp_set_panel_assr(struct dc_link *link, struct pipe_ctx *pipe_ctx, enum dp_panel_mode *panel_mode, bool enable); + +void edp_set_panel_polarity_enabled(const struct dc_link *link, bool enable); +void edp_panel_polarity_reset(struct dc_link *link); +bool edp_get_panel_polarity(struct dc_link *link, int32_t *polarity); #endif /* __DC_LINK_EDP_POWER_CONTROL_H__ */