summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/bridge/adv7511
diff options
context:
space:
mode:
authorArchit Taneja <architt@codeaurora.org>2016-06-17 08:45:52 +0200
committerArchit Taneja <architt@codeaurora.org>2016-07-13 10:54:37 +0200
commit62b2f026cd8e42df53dc8a6ed76594e51ab41735 (patch)
treec381b4e82c07d6c24ede5f891a377ac69035e955 /drivers/gpu/drm/bridge/adv7511
parentdrm/bridge: adv7533: Use internal timing generator (diff)
downloadlinux-62b2f026cd8e42df53dc8a6ed76594e51ab41735.tar.xz
linux-62b2f026cd8e42df53dc8a6ed76594e51ab41735.zip
drm/bridge: adv7533: Change number of DSI lanes dynamically
Lower modes on ADV7533 require lower number of DSI lanes for correct operation. If ADV7533 is being used with 4 DSI lanes, then switch the lanes to 3 when the target mode's pixel clock is less than 80 Mhz. Based on patch by Andy Green <andy.green@linaro.org> Signed-off-by: Archit Taneja <architt@codeaurora.org>
Diffstat (limited to 'drivers/gpu/drm/bridge/adv7511')
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h6
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c3
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7533.c22
3 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 90a8c0993d00..161c923d6162 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -339,6 +339,7 @@ struct adv7511 {
#ifdef CONFIG_DRM_I2C_ADV7533
void adv7533_dsi_power_on(struct adv7511 *adv);
void adv7533_dsi_power_off(struct adv7511 *adv);
+void adv7533_mode_set(struct adv7511 *adv, struct drm_display_mode *mode);
int adv7533_patch_registers(struct adv7511 *adv);
void adv7533_uninit_cec(struct adv7511 *adv);
int adv7533_init_cec(struct adv7511 *adv);
@@ -354,6 +355,11 @@ static inline void adv7533_dsi_power_off(struct adv7511 *adv)
{
}
+static inline void adv7533_mode_set(struct adv7511 *adv,
+ struct drm_display_mode *mode)
+{
+}
+
static inline int adv7533_patch_registers(struct adv7511 *adv)
{
return -ENODEV;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index e0c353ea1f2f..ec8fb2ed3275 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -712,6 +712,9 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
regmap_update_bits(adv7511->regmap, 0x17,
0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
+ if (adv7511->type == ADV7533)
+ adv7533_mode_set(adv7511, adj_mode);
+
drm_mode_copy(&adv7511->curr_mode, adj_mode);
/*
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index d002ac4cefcc..5eebd15899b1 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -115,6 +115,28 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
regmap_write(adv->regmap_cec, 0x27, 0x0b);
}
+void adv7533_mode_set(struct adv7511 *adv, struct drm_display_mode *mode)
+{
+ struct mipi_dsi_device *dsi = adv->dsi;
+ int lanes, ret;
+
+ if (adv->num_dsi_lanes != 4)
+ return;
+
+ if (mode->clock > 80000)
+ lanes = 4;
+ else
+ lanes = 3;
+
+ if (lanes != dsi->lanes) {
+ mipi_dsi_detach(dsi);
+ dsi->lanes = lanes;
+ ret = mipi_dsi_attach(dsi);
+ if (ret)
+ dev_err(&dsi->dev, "failed to change host lanes\n");
+ }
+}
+
int adv7533_patch_registers(struct adv7511 *adv)
{
return regmap_register_patch(adv->regmap,