drm/exynos: Implement lvds bridge discovery to DP driver
authorSean Paul <seanpaul@chromium.org>
Mon, 24 Feb 2014 10:20:15 +0000 (19:20 +0900)
committerInki Dae <daeinki@gmail.com>
Sun, 23 Mar 2014 15:36:37 +0000 (00:36 +0900)
This patch implements the lvds bridge discovery and connector pre-emption
code to the dp driver.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos_dp_core.c

index af2c9d2cfca0676cbed338c39c5f34f694b66f6d..a59bca9f16e122fd1e732c14ebcb2d4d9c66197b 100644 (file)
@@ -25,6 +25,7 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/bridge/ptn3460.h>
 
 #include "exynos_drm_drv.h"
 #include "exynos_dp_core.h"
 #define ctx_from_connector(c)  container_of(c, struct exynos_dp_device, \
                                        connector)
 
+struct bridge_init {
+       struct i2c_client *client;
+       struct device_node *node;
+};
+
 static int exynos_dp_init_dp(struct exynos_dp_device *dp)
 {
        exynos_dp_reset(dp);
@@ -973,6 +979,35 @@ static int exynos_dp_initialize(struct exynos_drm_display *display,
        return 0;
 }
 
+static bool find_bridge(const char *compat, struct bridge_init *bridge)
+{
+       bridge->client = NULL;
+       bridge->node = of_find_compatible_node(NULL, NULL, compat);
+       if (!bridge->node)
+               return false;
+
+       bridge->client = of_find_i2c_device_by_node(bridge->node);
+       if (!bridge->client)
+               return false;
+
+       return true;
+}
+
+/* returns the number of bridges attached */
+static int exynos_drm_attach_lcd_bridge(struct drm_device *dev,
+               struct drm_encoder *encoder)
+{
+       struct bridge_init bridge;
+       int ret;
+
+       if (find_bridge("nxp,ptn3460", &bridge)) {
+               ret = ptn3460_init(dev, encoder, bridge.client, bridge.node);
+               if (!ret)
+                       return 1;
+       }
+       return 0;
+}
+
 static int exynos_dp_create_connector(struct exynos_drm_display *display,
                                struct drm_encoder *encoder)
 {
@@ -981,6 +1016,12 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
        int ret;
 
        dp->encoder = encoder;
+
+       /* Pre-empt DP connector creation if there's a bridge */
+       ret = exynos_drm_attach_lcd_bridge(dp->drm_dev, encoder);
+       if (ret)
+               return 0;
+
        connector->polled = DRM_CONNECTOR_POLL_HPD;
 
        ret = drm_connector_init(dp->drm_dev, connector,