OMAPDSS: DSI: implement generic DSI pin config
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 28 Mar 2012 12:58:56 +0000 (15:58 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 9 May 2012 07:53:05 +0000 (10:53 +0300)
In preparation for device tree, this patch changes how the DSI pins are
configured. The current configuration method is only doable with board
files and the configuration data is OMAP specific.

This patch moves the configuration data to the panel's platform data,
and the data can easily be given via DT in the future. The configuration
data format is also changed to a generic one which should be suitable
for all platforms.

The new format is an array of pin numbers, where the array items start
from clock + and -, then data1 + and -, and so on. For example:

{
0, // pin num for clock lane +
1, // pin num for clock lane -
2, // pin num for data1 lane +
3, // pin num for data1 lane -
...
}

The pin numbers are translated by the DSI driver and used to configure
the hardware appropriately.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/board-4430sdp.c
drivers/video/omap2/displays/panel-taal.c
drivers/video/omap2/dss/dsi.c
include/video/omap-panel-nokia-dsi.h
include/video/omapdss.h

index 6cbb16fb381716b422a09c6a39fe6af135978b6b..b4ad706c145a123e767b415555082b1ee418ff12 100644 (file)
@@ -666,6 +666,10 @@ static struct nokia_dsi_panel_data dsi1_panel = {
                .use_ext_te     = false,
                .ext_te_gpio    = 101,
                .esd_interval   = 0,
+               .pin_config = {
+                       .num_pins       = 6,
+                       .pins           = { 0, 1, 2, 3, 4, 5 },
+               },
 };
 
 static struct omap_dss_device sdp4430_lcd_device = {
@@ -674,13 +678,6 @@ static struct omap_dss_device sdp4430_lcd_device = {
        .type                   = OMAP_DISPLAY_TYPE_DSI,
        .data                   = &dsi1_panel,
        .phy.dsi                = {
-               .clk_lane       = 1,
-               .clk_pol        = 0,
-               .data1_lane     = 2,
-               .data1_pol      = 0,
-               .data2_lane     = 3,
-               .data2_pol      = 0,
-
                .module         = 0,
        },
 
@@ -715,6 +712,10 @@ static struct nokia_dsi_panel_data dsi2_panel = {
                .use_ext_te     = false,
                .ext_te_gpio    = 103,
                .esd_interval   = 0,
+               .pin_config = {
+                       .num_pins       = 6,
+                       .pins           = { 0, 1, 2, 3, 4, 5 },
+               },
 };
 
 static struct omap_dss_device sdp4430_lcd2_device = {
@@ -723,12 +724,6 @@ static struct omap_dss_device sdp4430_lcd2_device = {
        .type                   = OMAP_DISPLAY_TYPE_DSI,
        .data                   = &dsi2_panel,
        .phy.dsi                = {
-               .clk_lane       = 1,
-               .clk_pol        = 0,
-               .data1_lane     = 2,
-               .data1_pol      = 0,
-               .data2_lane     = 3,
-               .data2_pol      = 0,
 
                .module         = 1,
        },
index 0888162e9ce9521025d1c8336e03cad968c1b09b..b2dd88b484209b46f5b213e9007cb2108b438c34 100644 (file)
@@ -1137,9 +1137,16 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
 static int taal_power_on(struct omap_dss_device *dssdev)
 {
        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+       struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
        u8 id1, id2, id3;
        int r;
 
+       r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
+       if (r) {
+               dev_err(&dssdev->dev, "failed to configure DSI pins\n");
+               goto err0;
+       };
+
        r = omapdss_dsi_display_enable(dssdev);
        if (r) {
                dev_err(&dssdev->dev, "failed to enable DSI\n");
index 662d14f8c2c382c4bdbe569c33863256314c122a..210a3c4f615012662769010e37d6cd54e28e61e3 100644 (file)
@@ -2076,65 +2076,6 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
        }
 }
 
-static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
-{
-       struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-       struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-       u8 lanes[DSI_MAX_NR_LANES];
-       u8 polarities[DSI_MAX_NR_LANES];
-       int num_lanes, i;
-
-       static const enum dsi_lane_function functions[] = {
-               DSI_LANE_CLK,
-               DSI_LANE_DATA1,
-               DSI_LANE_DATA2,
-               DSI_LANE_DATA3,
-               DSI_LANE_DATA4,
-       };
-
-       lanes[0] = dssdev->phy.dsi.clk_lane;
-       lanes[1] = dssdev->phy.dsi.data1_lane;
-       lanes[2] = dssdev->phy.dsi.data2_lane;
-       lanes[3] = dssdev->phy.dsi.data3_lane;
-       lanes[4] = dssdev->phy.dsi.data4_lane;
-       polarities[0] = dssdev->phy.dsi.clk_pol;
-       polarities[1] = dssdev->phy.dsi.data1_pol;
-       polarities[2] = dssdev->phy.dsi.data2_pol;
-       polarities[3] = dssdev->phy.dsi.data3_pol;
-       polarities[4] = dssdev->phy.dsi.data4_pol;
-
-       num_lanes = 0;
-
-       for (i = 0; i < dsi->num_lanes_supported; ++i)
-               dsi->lanes[i].function = DSI_LANE_UNUSED;
-
-       for (i = 0; i < dsi->num_lanes_supported; ++i) {
-               int num;
-
-               if (lanes[i] == DSI_LANE_UNUSED)
-                       break;
-
-               num = lanes[i] - 1;
-
-               if (num >= dsi->num_lanes_supported)
-                       return -EINVAL;
-
-               if (dsi->lanes[num].function != DSI_LANE_UNUSED)
-                       return -EINVAL;
-
-               dsi->lanes[num].function = functions[i];
-               dsi->lanes[num].polarity = polarities[i];
-               num_lanes++;
-       }
-
-       if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported)
-               return -EINVAL;
-
-       dsi->num_lanes_used = num_lanes;
-
-       return 0;
-}
-
 static int dsi_set_lane_config(struct omap_dss_device *dssdev)
 {
        struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -3975,6 +3916,74 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
        }
 }
 
+int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
+               const struct omap_dsi_pin_config *pin_cfg)
+{
+       struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+       struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+       int num_pins;
+       const int *pins;
+       struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
+       int num_lanes;
+       int i;
+
+       static const enum dsi_lane_function functions[] = {
+               DSI_LANE_CLK,
+               DSI_LANE_DATA1,
+               DSI_LANE_DATA2,
+               DSI_LANE_DATA3,
+               DSI_LANE_DATA4,
+       };
+
+       num_pins = pin_cfg->num_pins;
+       pins = pin_cfg->pins;
+
+       if (num_pins < 4 || num_pins > dsi->num_lanes_supported * 2
+                       || num_pins % 2 != 0)
+               return -EINVAL;
+
+       for (i = 0; i < DSI_MAX_NR_LANES; ++i)
+               lanes[i].function = DSI_LANE_UNUSED;
+
+       num_lanes = 0;
+
+       for (i = 0; i < num_pins; i += 2) {
+               u8 lane, pol;
+               int dx, dy;
+
+               dx = pins[i];
+               dy = pins[i + 1];
+
+               if (dx < 0 || dx >= dsi->num_lanes_supported * 2)
+                       return -EINVAL;
+
+               if (dy < 0 || dy >= dsi->num_lanes_supported * 2)
+                       return -EINVAL;
+
+               if (dx & 1) {
+                       if (dy != dx - 1)
+                               return -EINVAL;
+                       pol = 1;
+               } else {
+                       if (dy != dx + 1)
+                               return -EINVAL;
+                       pol = 0;
+               }
+
+               lane = dx / 2;
+
+               lanes[lane].function = functions[i / 2];
+               lanes[lane].polarity = pol;
+               num_lanes++;
+       }
+
+       memcpy(dsi->lanes, lanes, sizeof(dsi->lanes));
+       dsi->num_lanes_used = num_lanes;
+
+       return 0;
+}
+EXPORT_SYMBOL(omapdss_dsi_configure_pins);
+
 int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 {
        struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4339,12 +4348,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
        int dsi_module = dsi_get_dsidev_id(dsidev);
        int r;
 
-       r = dsi_parse_lane_config(dssdev);
-       if (r) {
-               DSSERR("illegal lane config");
-               goto err0;
-       }
-
        r = dsi_pll_init(dsidev, true, true);
        if (r)
                goto err0;
index 7dc71f9c13e6a2eece19e6f7c956f5a7048e5631..04219a2955397b63fefbf22149e64c7d8e1890b9 100644 (file)
@@ -11,6 +11,7 @@ struct omap_dss_device;
  * @esd_interval: interval of ESD checks, 0 = disabled (ms)
  * @ulps_timeout: time to wait before entering ULPS, 0 = disabled (ms)
  * @use_dsi_backlight: true if panel uses DSI command to control backlight
+ * @pin_config: DSI pin configuration
  */
 struct nokia_dsi_panel_data {
        const char *name;
@@ -24,6 +25,8 @@ struct nokia_dsi_panel_data {
        unsigned ulps_timeout;
 
        bool use_dsi_backlight;
+
+       struct omap_dsi_pin_config pin_config;
 };
 
 #endif /* __OMAP_NOKIA_DSI_PANEL_H */
index 483f67caa7ad42b0b360e99a3df2c1502dc1dae1..1c46a14341dd9892816a4398a274a7aa43cb5db1 100644 (file)
@@ -468,6 +468,21 @@ struct omap_overlay_manager {
        int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
 };
 
+/* 22 pins means 1 clk lane and 10 data lanes */
+#define OMAP_DSS_MAX_DSI_PINS 22
+
+struct omap_dsi_pin_config {
+       int num_pins;
+       /*
+        * pin numbers in the following order:
+        * clk+, clk-
+        * data1+, data1-
+        * data2+, data2-
+        * ...
+        */
+       int pins[OMAP_DSS_MAX_DSI_PINS];
+};
+
 struct omap_dss_device {
        struct device dev;
 
@@ -490,17 +505,6 @@ struct omap_dss_device {
                } sdi;
 
                struct {
-                       u8 clk_lane;
-                       u8 clk_pol;
-                       u8 data1_lane;
-                       u8 data1_pol;
-                       u8 data2_lane;
-                       u8 data2_pol;
-                       u8 data3_lane;
-                       u8 data3_pol;
-                       u8 data4_lane;
-                       u8 data4_pol;
-
                        int module;
 
                        bool ext_te;
@@ -687,6 +691,8 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
 int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
+int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
+               const struct omap_dsi_pin_config *pin_cfg);
 
 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,