drm/msm/dp: enable widebus feature for display port
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 by setting wide_bus_en flag to true within msm_dp_desc struct. 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 Changes in v5: -- DP_INTF_CONFIG_DATABUS_WIDEN Changes in v6: -- static inline bool msm_dp_wide_bus_enable() in msm_drv.h Changes in v7: -- add Tested-by Changes in v9: -- add wide_bus_en to msm_dp_desc Changes in v10: -- add wide_bus_en boolean to dp_catalog struc to avoid passing it as parameter Changes in v11: -- add const to dp_catalog_hw_revision() -- add const to msm_dp_wide_bus_available() Changes in v12: -- dp_catalog_hw_revision(const struct dp_catalog *dp_catalog) -- msm_dp_wide_bus_available(const struct msm_dp *dp_display) Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com> Reported-by: kernel test robot <lkp@intel.com> Tested-by: Bjorn Andersson <bjorn.andersson@linaro.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Patchwork: https://patchwork.freedesktop.org/patch/476283/ Link: https://lore.kernel.org/r/1645824192-29670-5-git-send-email-quic_khsieh@quicinc.com [DB: fixed the compilation] Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
This commit is contained in:
parent
3309a75639
commit
757a2f36ab
|
@ -2076,6 +2076,9 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
|
||||||
timer_setup(&dpu_enc->vsync_event_timer,
|
timer_setup(&dpu_enc->vsync_event_timer,
|
||||||
dpu_encoder_vsync_event_handler,
|
dpu_encoder_vsync_event_handler,
|
||||||
0);
|
0);
|
||||||
|
else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
|
||||||
|
dpu_enc->wide_bus_en = msm_dp_wide_bus_available(
|
||||||
|
priv->dp[disp_info->h_tile_instance[0]]);
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
|
INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
|
||||||
dpu_encoder_off_work);
|
dpu_encoder_off_work);
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#define DP_INTERRUPT_STATUS_ACK_SHIFT 1
|
#define DP_INTERRUPT_STATUS_ACK_SHIFT 1
|
||||||
#define DP_INTERRUPT_STATUS_MASK_SHIFT 2
|
#define DP_INTERRUPT_STATUS_MASK_SHIFT 2
|
||||||
|
|
||||||
|
#define DP_INTF_CONFIG_DATABUS_WIDEN BIT(4)
|
||||||
|
|
||||||
#define DP_INTERRUPT_STATUS1 \
|
#define DP_INTERRUPT_STATUS1 \
|
||||||
(DP_INTR_AUX_I2C_DONE| \
|
(DP_INTR_AUX_I2C_DONE| \
|
||||||
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
|
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
|
||||||
|
@ -80,7 +82,7 @@ static inline void dp_write_aux(struct dp_catalog_private *catalog,
|
||||||
writel(data, catalog->io->dp_controller.aux.base + offset);
|
writel(data, catalog->io->dp_controller.aux.base + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 dp_read_ahb(struct dp_catalog_private *catalog, u32 offset)
|
static inline u32 dp_read_ahb(const struct dp_catalog_private *catalog, u32 offset)
|
||||||
{
|
{
|
||||||
return readl_relaxed(catalog->io->dp_controller.ahb.base + offset);
|
return readl_relaxed(catalog->io->dp_controller.ahb.base + offset);
|
||||||
}
|
}
|
||||||
|
@ -482,6 +484,22 @@ int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_catalog_hw_revision() - retrieve DP hw revision
|
||||||
|
*
|
||||||
|
* @dp_catalog: DP catalog structure
|
||||||
|
*
|
||||||
|
* Return: DP controller hw revision
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
u32 dp_catalog_hw_revision(const struct dp_catalog *dp_catalog)
|
||||||
|
{
|
||||||
|
const struct dp_catalog_private *catalog = container_of(dp_catalog,
|
||||||
|
struct dp_catalog_private, dp_catalog);
|
||||||
|
|
||||||
|
return dp_read_ahb(catalog, REG_DP_HW_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_catalog_ctrl_reset() - reset DP controller
|
* dp_catalog_ctrl_reset() - reset DP controller
|
||||||
*
|
*
|
||||||
|
@ -743,6 +761,7 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog)
|
||||||
{
|
{
|
||||||
struct dp_catalog_private *catalog = container_of(dp_catalog,
|
struct dp_catalog_private *catalog = container_of(dp_catalog,
|
||||||
struct dp_catalog_private, dp_catalog);
|
struct dp_catalog_private, dp_catalog);
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
dp_write_link(catalog, REG_DP_TOTAL_HOR_VER,
|
dp_write_link(catalog, REG_DP_TOTAL_HOR_VER,
|
||||||
dp_catalog->total);
|
dp_catalog->total);
|
||||||
|
@ -751,7 +770,18 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog)
|
||||||
dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY,
|
dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY,
|
||||||
dp_catalog->width_blanking);
|
dp_catalog->width_blanking);
|
||||||
dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active);
|
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 (dp_catalog->wide_bus_en)
|
||||||
|
reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
|
||||||
|
else
|
||||||
|
reg &= ~DP_INTF_CONFIG_DATABUS_WIDEN;
|
||||||
|
|
||||||
|
|
||||||
|
DRM_DEBUG_DP("wide_bus_en=%d reg=%#x\n", dp_catalog->wide_bus_en, reg);
|
||||||
|
|
||||||
|
dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct dp_catalog {
|
||||||
enum dp_catalog_audio_sdp_type sdp_type;
|
enum dp_catalog_audio_sdp_type sdp_type;
|
||||||
enum dp_catalog_audio_header_type sdp_header;
|
enum dp_catalog_audio_header_type sdp_header;
|
||||||
u32 audio_data;
|
u32 audio_data;
|
||||||
|
bool wide_bus_en;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Debug module */
|
/* Debug module */
|
||||||
|
@ -95,6 +96,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,
|
void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate,
|
||||||
u32 stream_rate_khz, bool fixed_nvid);
|
u32 stream_rate_khz, bool fixed_nvid);
|
||||||
int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, u32 pattern);
|
int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, u32 pattern);
|
||||||
|
u32 dp_catalog_hw_revision(const struct dp_catalog *dp_catalog);
|
||||||
void dp_catalog_ctrl_reset(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);
|
bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog);
|
||||||
void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
|
void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
|
||||||
|
|
|
@ -1802,6 +1802,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool mainlink_ready = false;
|
bool mainlink_ready = false;
|
||||||
struct dp_ctrl_private *ctrl;
|
struct dp_ctrl_private *ctrl;
|
||||||
|
unsigned long pixel_rate_orig;
|
||||||
|
|
||||||
if (!dp_ctrl)
|
if (!dp_ctrl)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -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;
|
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",
|
DRM_DEBUG_DP("rate=%d, num_lanes=%d, pixel_rate=%d\n",
|
||||||
ctrl->link->link_params.rate,
|
ctrl->link->link_params.rate,
|
||||||
ctrl->link->link_params.num_lanes, ctrl->dp_ctrl.pixel_rate);
|
ctrl->link->link_params.num_lanes, ctrl->dp_ctrl.pixel_rate);
|
||||||
|
@ -1849,7 +1854,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
|
||||||
|
|
||||||
dp_catalog_ctrl_config_msa(ctrl->catalog,
|
dp_catalog_ctrl_config_msa(ctrl->catalog,
|
||||||
ctrl->link->link_params.rate,
|
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);
|
dp_ctrl_setup_tr_unit(ctrl);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ struct dp_ctrl {
|
||||||
bool orientation;
|
bool orientation;
|
||||||
atomic_t aborted;
|
atomic_t aborted;
|
||||||
u32 pixel_rate;
|
u32 pixel_rate;
|
||||||
|
bool wide_bus_en;
|
||||||
};
|
};
|
||||||
|
|
||||||
int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl);
|
int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl);
|
||||||
|
|
|
@ -116,12 +116,15 @@ struct dp_display_private {
|
||||||
struct dp_event event_list[DP_EVENT_Q_MAX];
|
struct dp_event event_list[DP_EVENT_Q_MAX];
|
||||||
spinlock_t event_lock;
|
spinlock_t event_lock;
|
||||||
|
|
||||||
|
bool wide_bus_en;
|
||||||
|
|
||||||
struct dp_audio *audio;
|
struct dp_audio *audio;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msm_dp_desc {
|
struct msm_dp_desc {
|
||||||
phys_addr_t io_start;
|
phys_addr_t io_start;
|
||||||
unsigned int connector_type;
|
unsigned int connector_type;
|
||||||
|
bool wide_bus_en;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msm_dp_config {
|
struct msm_dp_config {
|
||||||
|
@ -138,8 +141,8 @@ static const struct msm_dp_config sc7180_dp_cfg = {
|
||||||
|
|
||||||
static const struct msm_dp_config sc7280_dp_cfg = {
|
static const struct msm_dp_config sc7280_dp_cfg = {
|
||||||
.descs = (const struct msm_dp_desc[]) {
|
.descs = (const struct msm_dp_desc[]) {
|
||||||
[MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
[MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||||
[MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP },
|
[MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
|
||||||
},
|
},
|
||||||
.num_descs = 2,
|
.num_descs = 2,
|
||||||
};
|
};
|
||||||
|
@ -845,6 +848,10 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
|
||||||
goto error_ctrl;
|
goto error_ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* populate wide_bus_en to differernt layers */
|
||||||
|
dp->ctrl->wide_bus_en = dp->wide_bus_en;
|
||||||
|
dp->catalog->wide_bus_en = dp->wide_bus_en;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
error_ctrl:
|
error_ctrl:
|
||||||
|
@ -1296,6 +1303,7 @@ static int dp_display_probe(struct platform_device *pdev)
|
||||||
dp->pdev = pdev;
|
dp->pdev = pdev;
|
||||||
dp->name = "drm_dp";
|
dp->name = "drm_dp";
|
||||||
dp->dp_display.connector_type = desc->connector_type;
|
dp->dp_display.connector_type = desc->connector_type;
|
||||||
|
dp->wide_bus_en = desc->wide_bus_en;
|
||||||
|
|
||||||
rc = dp_init_sub_modules(dp);
|
rc = dp_init_sub_modules(dp);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -1488,6 +1496,15 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
|
||||||
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
|
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
|
||||||
|
{
|
||||||
|
struct dp_display_private *dp;
|
||||||
|
|
||||||
|
dp = container_of(dp_display, struct dp_display_private, dp_display);
|
||||||
|
|
||||||
|
return dp->wide_bus_en;
|
||||||
|
}
|
||||||
|
|
||||||
void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
|
void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
|
||||||
{
|
{
|
||||||
struct dp_display_private *dp;
|
struct dp_display_private *dp;
|
||||||
|
|
|
@ -24,6 +24,8 @@ struct msm_dp {
|
||||||
|
|
||||||
hdmi_codec_plugged_cb plugged_cb;
|
hdmi_codec_plugged_cb plugged_cb;
|
||||||
|
|
||||||
|
bool wide_bus_en;
|
||||||
|
|
||||||
u32 max_pclk_khz;
|
u32 max_pclk_khz;
|
||||||
|
|
||||||
u32 max_dp_lanes;
|
u32 max_dp_lanes;
|
||||||
|
|
|
@ -342,6 +342,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_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);
|
void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor);
|
||||||
|
bool msm_dp_wide_bus_available(const struct msm_dp *dp_display);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline int __init msm_dp_register(void)
|
static inline int __init msm_dp_register(void)
|
||||||
|
@ -392,6 +393,11 @@ static inline void msm_dp_debugfs_init(struct msm_dp *dp_display,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_MSM_MDP4
|
#ifdef CONFIG_DRM_MSM_MDP4
|
||||||
|
|
Loading…
Reference in New Issue