drm/bridge: adv7533: Change number of DSI lanes dynamically
authorArchit Taneja <architt@codeaurora.org>
Fri, 17 Jun 2016 06:45:52 +0000 (12:15 +0530)
committerArchit Taneja <architt@codeaurora.org>
Wed, 13 Jul 2016 08:54:37 +0000 (14:24 +0530)
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>
drivers/gpu/drm/bridge/adv7511/adv7511.h
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
drivers/gpu/drm/bridge/adv7511/adv7533.c

index 90a8c0993d00957e2d46b45addfafef137b2eecd..161c923d6162cfe65b70a8f41ac46b963237be1c 100644 (file)
@@ -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;
index e0c353ea1f2f871f6ba28d7a80e06a8a8a2da1af..ec8fb2ed3275b229920da1fe417e4a7c4d54e9d1 100644 (file)
@@ -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);
 
        /*
index d002ac4cefcc059eceb2718e619035ba9cf8d325..5eebd15899b112657cf4dd820fb78519dad0130d 100644 (file)
@@ -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,