Skip to content

Commit

Permalink
drm/msm/dp: enable widebus feature for display port
Browse files Browse the repository at this point in the history
Widebus feature will transmit two pixel data per pixel clock to interface.
This feature now is required to be enabled to easy migrant to higher
resolution applications in future. However since some legacy chipsets
does not support this feature, this feature is enabled base on chip's
hardware revision.

changes in v2:
-- remove compression related code from timing
-- remove op_info from  struct msm_drm_private
-- remove unnecessary wide_bus_en variables
-- pass wide_bus_en into timing configuration by struct msm_dp

Changes in v3:
-- split patch into 3 patches
-- enable widebus feature base on chip hardware revision

Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/1644878346-28511-3-git-send-email-quic_khsieh@quicinc.com
  • Loading branch information
Kuogee Hsieh authored and andersson committed Mar 1, 2022
1 parent 6568a0a commit 87ad166
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 11 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
Expand Up @@ -2078,6 +2078,10 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
timer_setup(&dpu_enc->vsync_event_timer,
dpu_encoder_vsync_event_handler,
0);
else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) {
dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]];
dpu_enc->wide_bus_en = msm_dp_wide_bus_enable(dpu_enc->dp);
}

INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
dpu_encoder_off_work);
Expand Down
36 changes: 34 additions & 2 deletions drivers/gpu/drm/msm/dp/dp_catalog.c
Expand Up @@ -482,6 +482,27 @@ int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog,
return 0;
}

/**
* dp_catalog_hw_revision() - retrieve DP hw revision
*
* @dp_catalog: DP catalog structure
*
* return: u32
*
* This function return the DP controller hw revision
*
*/
u32 dp_catalog_hw_revision(struct dp_catalog *dp_catalog)
{
u32 revision;
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);

revision = dp_read_ahb(catalog, REG_DP_HW_VERSION);

return revision;
}

/**
* dp_catalog_ctrl_reset() - reset DP controller
*
Expand Down Expand Up @@ -739,10 +760,11 @@ u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog *dp_catalog)
}

/* panel related catalog functions */
int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog)
int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog, bool wide_bus_en)
{
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);
u32 reg;

dp_write_link(catalog, REG_DP_TOTAL_HOR_VER,
dp_catalog->total);
Expand All @@ -751,7 +773,17 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog)
dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY,
dp_catalog->width_blanking);
dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active);
dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0);

reg = dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);

if (wide_bus_en)
reg |= BIT(4); /* DATABUS_WIDEN */
else
reg &= ~BIT(4);

DRM_DEBUG_DP("wide_bus_en=%d reg=%x\n", wide_bus_en, reg);

dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
return 0;
}

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/msm/dp/dp_catalog.h
Expand Up @@ -95,6 +95,7 @@ void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 cc, u32 tb);
void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate,
u32 stream_rate_khz, bool fixed_nvid);
int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, u32 pattern);
u32 dp_catalog_hw_revision(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog);
bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
Expand All @@ -115,7 +116,7 @@ void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog *dp_catalog,
u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog *dp_catalog);

/* DP Panel APIs */
int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog);
int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog, bool wide_bus_en);
void dp_catalog_dump_regs(struct dp_catalog *dp_catalog);
void dp_catalog_panel_tpg_enable(struct dp_catalog *dp_catalog,
struct drm_display_mode *drm_mode);
Expand Down
13 changes: 9 additions & 4 deletions drivers/gpu/drm/msm/dp/dp_ctrl.c
Expand Up @@ -154,7 +154,7 @@ static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl)
dp_catalog_ctrl_config_ctrl(ctrl->catalog, config);
}

static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl)
static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl, bool wide_bus_en)
{
u32 cc, tb;

Expand All @@ -167,7 +167,7 @@ static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl)
ctrl->panel->dp_mode.bpp);
cc = dp_link_get_colorimetry_config(ctrl->link);
dp_catalog_ctrl_config_misc(ctrl->catalog, cc, tb);
dp_panel_timing_cfg(ctrl->panel);
dp_panel_timing_cfg(ctrl->panel, wide_bus_en);
}

/*
Expand Down Expand Up @@ -1802,6 +1802,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
int ret = 0;
bool mainlink_ready = false;
struct dp_ctrl_private *ctrl;
u32 pixel_rate_orig;

if (!dp_ctrl)
return -EINVAL;
Expand All @@ -1810,6 +1811,10 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)

ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;

pixel_rate_orig = ctrl->dp_ctrl.pixel_rate;
if (dp_ctrl->wide_bus_en)
ctrl->dp_ctrl.pixel_rate >>= 1;

DRM_DEBUG_DP("rate=%d, num_lanes=%d, pixel_rate=%d\n",
ctrl->link->link_params.rate,
ctrl->link->link_params.num_lanes, ctrl->dp_ctrl.pixel_rate);
Expand Down Expand Up @@ -1845,11 +1850,11 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
*/
reinit_completion(&ctrl->video_comp);

dp_ctrl_configure_source_params(ctrl);
dp_ctrl_configure_source_params(ctrl, dp_ctrl->wide_bus_en);

dp_catalog_ctrl_config_msa(ctrl->catalog,
ctrl->link->link_params.rate,
ctrl->dp_ctrl.pixel_rate, dp_ctrl_use_fixed_nvid(ctrl));
pixel_rate_orig, dp_ctrl_use_fixed_nvid(ctrl));

dp_ctrl_setup_tr_unit(ctrl);

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/msm/dp/dp_ctrl.h
Expand Up @@ -17,6 +17,7 @@ struct dp_ctrl {
bool orientation;
atomic_t aborted;
u32 pixel_rate;
bool wide_bus_en;
};

int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl);
Expand Down
32 changes: 31 additions & 1 deletion drivers/gpu/drm/msm/dp/dp_display.c
Expand Up @@ -116,6 +116,8 @@ struct dp_display_private {
struct dp_event event_list[DP_EVENT_Q_MAX];
spinlock_t event_lock;

bool wide_bus_en;

struct dp_audio *audio;
};

Expand Down Expand Up @@ -885,6 +887,8 @@ static int dp_display_enable(struct dp_display_private *dp, u32 data)
return 0;
}

dp->ctrl->wide_bus_en = dp->wide_bus_en;

rc = dp_ctrl_on_stream(dp->ctrl);
if (!rc)
dp_display->power_on = true;
Expand Down Expand Up @@ -1016,6 +1020,7 @@ int dp_display_get_modes(struct msm_dp *dp,
dp->connector, dp_mode);
if (dp_mode->drm_mode.clock)
dp->max_pclk_khz = dp_mode->drm_mode.clock;

return ret;
}

Expand Down Expand Up @@ -1488,6 +1493,28 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
}

bool msm_dp_wide_bus_enable(struct msm_dp *dp_display)
{
struct dp_display_private *dp;
u32 revision, major, minor;

dp = container_of(dp_display, struct dp_display_private, dp_display);

/* for the time being widebus only support on DP */
if (dp_display->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
revision = dp_catalog_hw_revision(dp->catalog);
major = ((revision >> 28) & 0x0ff);
minor = ((revision >> 16) & 0x0fff);

DRM_DEBUG_DP("id=%d major=%d minor=%d\n", dp->id, major, minor);

if (major >= 1 && minor >= 2)
return true;
}

return false;
}

void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
{
struct dp_display_private *dp;
Expand All @@ -1510,8 +1537,8 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
struct drm_encoder *encoder)
{
struct msm_drm_private *priv;
struct dp_display_private *dp_priv;
struct msm_drm_private *priv;
int ret;

if (WARN_ON(!encoder) || WARN_ON(!dp_display) || WARN_ON(!dev))
Expand Down Expand Up @@ -1543,6 +1570,9 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,

priv->connectors[priv->num_connectors++] = dp_display->connector;

dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
dp_priv->wide_bus_en = msm_dp_wide_bus_enable(dp_display);

dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
if (IS_ERR(dp_display->bridge)) {
ret = PTR_ERR(dp_display->bridge);
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/msm/dp/dp_display.h
Expand Up @@ -24,6 +24,8 @@ struct msm_dp {

hdmi_codec_plugged_cb plugged_cb;

bool wide_bus_en;

u32 max_pclk_khz;

u32 max_dp_lanes;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/msm/dp/dp_panel.c
Expand Up @@ -358,7 +358,7 @@ void dp_panel_dump_regs(struct dp_panel *dp_panel)
dp_catalog_dump_regs(catalog);
}

int dp_panel_timing_cfg(struct dp_panel *dp_panel)
int dp_panel_timing_cfg(struct dp_panel *dp_panel, bool wide_bus_en)
{
u32 data, total_ver, total_hor;
struct dp_catalog *catalog;
Expand Down Expand Up @@ -409,7 +409,7 @@ int dp_panel_timing_cfg(struct dp_panel *dp_panel)

catalog->dp_active = data;

dp_catalog_panel_timing_cfg(catalog);
dp_catalog_panel_timing_cfg(catalog, wide_bus_en);
panel->panel_on = true;

return 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/dp/dp_panel.h
Expand Up @@ -57,7 +57,7 @@ struct dp_panel {

int dp_panel_init_panel_info(struct dp_panel *dp_panel);
int dp_panel_deinit(struct dp_panel *dp_panel);
int dp_panel_timing_cfg(struct dp_panel *dp_panel);
int dp_panel_timing_cfg(struct dp_panel *dp_panel, bool wide_bus_en);
void dp_panel_dump_regs(struct dp_panel *dp_panel);
int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
struct drm_connector *connector);
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/msm/msm_drv.h
Expand Up @@ -379,6 +379,7 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display);
void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);

void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor);
bool msm_dp_wide_bus_enable(struct msm_dp *dp_display);

#else
static inline int __init msm_dp_register(void)
Expand Down Expand Up @@ -429,6 +430,11 @@ static inline void msm_dp_debugfs_init(struct msm_dp *dp_display,
{
}

bool msm_dp_wide_bus_enable(struct msm_dp *dp_display)
{
return false;
}

#endif

void __init msm_mdp_register(void);
Expand Down

0 comments on commit 87ad166

Please sign in to comment.