From patchwork Thu Jun 5 19:10:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajay Kumar X-Patchwork-Id: 4309371 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 50AC5BEEAA for ; Fri, 6 Jun 2014 00:33:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3A96E20265 for ; Fri, 6 Jun 2014 00:33:09 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 2C4DB2020F for ; Fri, 6 Jun 2014 00:33:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 239D96E9F4; Thu, 5 Jun 2014 17:32:58 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) by gabe.freedesktop.org (Postfix) with ESMTP id 1A99B6E9BC for ; Thu, 5 Jun 2014 12:12:45 -0700 (PDT) Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N6P0045ZMP8UC40@mailout4.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 06 Jun 2014 04:12:44 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.126]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id A5.70.16580.B21C0935; Fri, 06 Jun 2014 04:12:43 +0900 (KST) X-AuditID: cbfee691-b7f2f6d0000040c4-5f-5390c12b546c Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 48.3D.08203.B21C0935; Fri, 06 Jun 2014 04:12:43 +0900 (KST) Received: from chromebld-server.sisodomain.com ([107.108.73.106]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N6P00FLRMOSKS30@mmp2.samsung.com>; Fri, 06 Jun 2014 04:12:43 +0900 (KST) From: Ajay Kumar To: dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH V3 4/8] drm/bridge: ptn3460: Support bridge chaining Date: Fri, 06 Jun 2014 00:40:48 +0530 Message-id: <1401995452-15798-5-git-send-email-ajaykumar.rs@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1401995452-15798-1-git-send-email-ajaykumar.rs@samsung.com> References: <1401995452-15798-1-git-send-email-ajaykumar.rs@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprIIsWRmVeSWpSXmKPExsWyRsSkTlf74IRggxW9NhYH3h9ksdjwZiGz xcKHd5ktrnx9z2Yx6f4EFovLCy+xWnzf9YXdYsb5fUwWqw5vYLd4vvAHs8Xcg7kWP3fNY3Hg 8dj7bQGLx85Zd9k9Fmwq9bjffZzJo2/LKkaPz5vkAtiiuGxSUnMyy1KL9O0SuDJev37BWPDD q+L4rI9sDYzvbbsYOTkkBEwkfq35wQphi0lcuLeerYuRi0NIYCmjxPXfjSwwRSceH2QCsYUE pjNKvL4nAlE0gUni4/GbzCAJNgFtiW3Tb4I1iAi4STQdnskKUsQs8I1R4s/5+0BjOTiEBVwk Ll1PBalhEVCVOPvxGthmXgEPia4X01hASiQEFCTmTLIBCXMKeErs3TuNBWKvh8SyiefAjpMQ OMUusf3ZcRaIOQIS3yYfguqVldh0gBniZkmJgytusExgFF7AyLCKUTS1ILmgOCm9yFSvODG3 uDQvXS85P3cTIzA6Tv97NnEH4/0D1ocYk4HGTWSWEk3OB0ZXXkm8obGZkYWpiamxkbmlGWnC SuK86Y+SgoQE0hNLUrNTUwtSi+KLSnNSiw8xMnFwSjUw2jGUtW5VqXnHLrbg6td3641VlGxa tkxPOyPNuvHDvqWnTN6IWjxokW492c7Tv/yibb7zole3Nm1uCjF9NfuO0Buv47WrNbImv3r5 TnHmgmSNh8t5H+9TLl4jNvl0/cUDjLySUzJr94XaCW6d5zjptV3MXtNEjissTj+mM56cJs2+ wnF26Po7F5VYijMSDbWYi4oTAeyVrrWkAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrHIsWRmVeSWpSXmKPExsVy+t9jQV3tgxOCDb7uMLQ48P4gi8WGNwuZ LRY+vMtsceXrezaLSfcnsFhcXniJ1eL7ri/sFjPO72OyWHV4A7vF84U/mC3mHsy1+LlrHosD j8febwtYPHbOusvusWBTqcf97uNMHn1bVjF6fN4kF8AW1cBok5GamJJapJCal5yfkpmXbqvk HRzvHG9qZmCoa2hpYa6kkJeYm2qr5OIToOuWmQN0o5JCWWJOKVAoILG4WEnfDtOE0BA3XQuY xghd35AguB4jAzSQsIYx4/XrF4wFP7wqjs/6yNbA+N62i5GTQ0LAROLE44NMELaYxIV769lA bCGB6YwSr++JdDFyAdkTmCQ+Hr/JDJJgE9CW2Db9JguILSLgJtF0eCYrSBGzwDdGiT/n7wN1 c3AIC7hIXLqeClLDIqAqcfbjNVYQm1fAQ6LrxTQWkBIJAQWJOZNsQMKcAp4Se/dOY4HY6yGx bOI5tgmMvAsYGVYxiqYWJBcUJ6XnGuoVJ+YWl+al6yXn525iBMfeM6kdjCsbLA4xCnAwKvHw BvRPCBZiTSwrrsw9xCjBwawkwsuxBSjEm5JYWZValB9fVJqTWnyIMRnoqInMUqLJ+cC0kFcS b2hsYm5qbGppYmFiZkmasJI474FW60AhgfTEktTs1NSC1CKYLUwcnFINjBGp1+5P9ip2Fk/2 Si3dVFT+933G6qMz1usWX1g1a++aCYE/+TI5K5IVfZ+s7DE+EnGRrbStxuxPxpms6BDBzxWX DXUvWj83vlqoeejXBl7OLTamXN65s68t51yWkDXjm1tJKDuf/UXmB+430pWYeQVnapusWZnu 3s8mJH6w59E8KTbzW4E/lViKMxINtZiLihMBmTp7+gEDAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected X-Mailman-Approved-At: Thu, 05 Jun 2014 17:32:52 -0700 Cc: seanpaul@google.com, daniel.vetter@ffwll.ch, joshi@samsung.com, ajaynumb@gmail.com, prashanth.g@samsung.com, Ajay Kumar X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Modify the driver to invoke callbacks for the next bridge in the bridge chain. Also, remove the drm_connector implementation from ptn3460, since the same is implemented using panel_binder. Signed-off-by: Ajay Kumar --- drivers/gpu/drm/bridge/ptn3460.c | 136 +++++-------------------------- drivers/gpu/drm/exynos/exynos_dp_core.c | 16 ++-- include/drm/bridge/ptn3460.h | 15 ++-- 3 files changed, 39 insertions(+), 128 deletions(-) diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c index 98fd17a..21e9db8 100644 --- a/drivers/gpu/drm/bridge/ptn3460.c +++ b/drivers/gpu/drm/bridge/ptn3460.c @@ -34,37 +34,15 @@ #define PTN3460_EDID_SRAM_LOAD_ADDR 0x85 struct ptn3460_bridge { - struct drm_connector connector; struct i2c_client *client; struct drm_encoder *encoder; struct drm_bridge *bridge; - struct edid *edid; int gpio_pd_n; int gpio_rst_n; u32 edid_emulation; bool enabled; }; -static int ptn3460_read_bytes(struct ptn3460_bridge *ptn_bridge, char addr, - u8 *buf, int len) -{ - int ret; - - ret = i2c_master_send(ptn_bridge->client, &addr, 1); - if (ret <= 0) { - DRM_ERROR("Failed to send i2c command, ret=%d\n", ret); - return ret; - } - - ret = i2c_master_recv(ptn_bridge->client, buf, len); - if (ret <= 0) { - DRM_ERROR("Failed to recv i2c data, ret=%d\n", ret); - return ret; - } - - return 0; -} - static int ptn3460_write_byte(struct ptn3460_bridge *ptn_bridge, char addr, char val) { @@ -126,6 +104,8 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge) gpio_set_value(ptn_bridge->gpio_rst_n, 1); } + drm_next_bridge_pre_enable(bridge); + /* * There's a bug in the PTN chip where it falsely asserts hotplug before * it is fully functional. We're forced to wait for the maximum start up @@ -142,6 +122,7 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge) static void ptn3460_enable(struct drm_bridge *bridge) { + drm_next_bridge_enable(bridge); } static void ptn3460_disable(struct drm_bridge *bridge) @@ -153,6 +134,8 @@ static void ptn3460_disable(struct drm_bridge *bridge) ptn_bridge->enabled = false; + drm_next_bridge_disable(bridge); + if (gpio_is_valid(ptn_bridge->gpio_rst_n)) gpio_set_value(ptn_bridge->gpio_rst_n, 1); @@ -162,6 +145,7 @@ static void ptn3460_disable(struct drm_bridge *bridge) static void ptn3460_post_disable(struct drm_bridge *bridge) { + drm_next_bridge_post_disable(bridge); } void ptn3460_bridge_destroy(struct drm_bridge *bridge) @@ -173,6 +157,9 @@ void ptn3460_bridge_destroy(struct drm_bridge *bridge) gpio_free(ptn_bridge->gpio_pd_n); if (gpio_is_valid(ptn_bridge->gpio_rst_n)) gpio_free(ptn_bridge->gpio_rst_n); + + drm_next_bridge_destroy(bridge); + /* Nothing else to free, we've got devm allocated memory */ } @@ -184,81 +171,10 @@ struct drm_bridge_funcs ptn3460_bridge_funcs = { .destroy = ptn3460_bridge_destroy, }; -int ptn3460_get_modes(struct drm_connector *connector) -{ - struct ptn3460_bridge *ptn_bridge; - u8 *edid; - int ret, num_modes; - bool power_off; - - ptn_bridge = container_of(connector, struct ptn3460_bridge, connector); - - if (ptn_bridge->edid) - return drm_add_edid_modes(connector, ptn_bridge->edid); - - power_off = !ptn_bridge->enabled; - ptn3460_pre_enable(ptn_bridge->bridge); - - edid = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (!edid) { - DRM_ERROR("Failed to allocate edid\n"); - return 0; - } - - ret = ptn3460_read_bytes(ptn_bridge, PTN3460_EDID_ADDR, edid, - EDID_LENGTH); - if (ret) { - kfree(edid); - num_modes = 0; - goto out; - } - - ptn_bridge->edid = (struct edid *)edid; - drm_mode_connector_update_edid_property(connector, ptn_bridge->edid); - - num_modes = drm_add_edid_modes(connector, ptn_bridge->edid); - -out: - if (power_off) - ptn3460_disable(ptn_bridge->bridge); - - return num_modes; -} - -struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector) -{ - struct ptn3460_bridge *ptn_bridge; - - ptn_bridge = container_of(connector, struct ptn3460_bridge, connector); - - return ptn_bridge->encoder; -} - -struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = { - .get_modes = ptn3460_get_modes, - .best_encoder = ptn3460_best_encoder, -}; - -enum drm_connector_status ptn3460_detect(struct drm_connector *connector, - bool force) -{ - return connector_status_connected; -} - -void ptn3460_connector_destroy(struct drm_connector *connector) -{ - drm_connector_cleanup(connector); -} - -struct drm_connector_funcs ptn3460_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .fill_modes = drm_helper_probe_single_connector_modes, - .detect = ptn3460_detect, - .destroy = ptn3460_connector_destroy, -}; - -int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, - struct i2c_client *client, struct device_node *node) +struct drm_bridge *ptn3460_init(struct drm_device *dev, + struct drm_encoder *encoder, + struct i2c_client *client, + struct device_node *node) { int ret; struct drm_bridge *bridge; @@ -267,13 +183,13 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, bridge = devm_kzalloc(dev->dev, sizeof(*bridge), GFP_KERNEL); if (!bridge) { DRM_ERROR("Failed to allocate drm bridge\n"); - return -ENOMEM; + return NULL; } ptn_bridge = devm_kzalloc(dev->dev, sizeof(*ptn_bridge), GFP_KERNEL); if (!ptn_bridge) { DRM_ERROR("Failed to allocate ptn bridge\n"); - return -ENOMEM; + return NULL; } ptn_bridge->client = client; @@ -285,7 +201,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, GPIOF_OUT_INIT_HIGH, "PTN3460_PD_N"); if (ret) { DRM_ERROR("Request powerdown-gpio failed (%d)\n", ret); - return ret; + return NULL; } } @@ -300,7 +216,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, if (ret) { DRM_ERROR("Request reset-gpio failed (%d)\n", ret); gpio_free(ptn_bridge->gpio_pd_n); - return ret; + return NULL; } } @@ -318,26 +234,18 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, } bridge->driver_private = ptn_bridge; - encoder->bridge = bridge; - ret = drm_connector_init(dev, &ptn_bridge->connector, - &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS); - if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); - goto err; - } - drm_connector_helper_add(&ptn_bridge->connector, - &ptn3460_connector_helper_funcs); - drm_sysfs_connector_add(&ptn_bridge->connector); - drm_mode_connector_attach_encoder(&ptn_bridge->connector, encoder); + if (!encoder->bridge) + /* First entry in the bridge chain */ + encoder->bridge = bridge; - return 0; + return bridge; err: if (gpio_is_valid(ptn_bridge->gpio_pd_n)) gpio_free(ptn_bridge->gpio_pd_n); if (gpio_is_valid(ptn_bridge->gpio_rst_n)) gpio_free(ptn_bridge->gpio_rst_n); - return ret; + return NULL; } EXPORT_SYMBOL(ptn3460_init); diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index 5e05dbc..414f5e5 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -979,19 +979,19 @@ static bool find_bridge(const char *compat, struct bridge_init *bridge) return true; } -/* returns the number of bridges attached */ -static int exynos_drm_attach_lcd_bridge(struct drm_device *dev, +static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp, struct drm_encoder *encoder) { struct bridge_init bridge; - int ret; + struct drm_bridge *bridge_chain = NULL; + bool connector_created = false; if (find_bridge("nxp,ptn3460", &bridge)) { - ret = ptn3460_init(dev, encoder, bridge.client, bridge.node); - if (!ret) - return 1; + bridge_chain = ptn3460_init(dp->drm_dev, encoder, bridge.client, + bridge.node); } - return 0; + + return connector_created; } static int exynos_dp_create_connector(struct exynos_drm_display *display, @@ -1004,7 +1004,7 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, dp->encoder = encoder; /* Pre-empt DP connector creation if there's a bridge */ - ret = exynos_drm_attach_lcd_bridge(dp->drm_dev, encoder); + ret = exynos_drm_attach_lcd_bridge(dp, encoder); if (ret) return 0; diff --git a/include/drm/bridge/ptn3460.h b/include/drm/bridge/ptn3460.h index ff62344..f612b9b 100644 --- a/include/drm/bridge/ptn3460.h +++ b/include/drm/bridge/ptn3460.h @@ -21,15 +21,18 @@ struct device_node; #if defined(CONFIG_DRM_PTN3460) || defined(CONFIG_DRM_PTN3460_MODULE) -int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, - struct i2c_client *client, struct device_node *node); +struct drm_bridge *ptn3460_init(struct drm_device *dev, + struct drm_encoder *encoder, + struct i2c_client *client, + struct device_node *node); #else -static inline int ptn3460_init(struct drm_device *dev, - struct drm_encoder *encoder, struct i2c_client *client, - struct device_node *node) +static inline struct drm_bridge *ptn3460_init(struct drm_device *dev, + struct drm_encoder *encoder, + struct i2c_client *client, + struct device_node *node) { - return 0; + return NULL; } #endif