From patchwork Mon Jul 27 06:16:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archit Taneja X-Patchwork-Id: 6869141 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 94EFFC05AC for ; Mon, 27 Jul 2015 06:17:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 88EF72062A for ; Mon, 27 Jul 2015 06:17:31 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id C74652062F for ; Mon, 27 Jul 2015 06:17:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F2B116E806; Sun, 26 Jul 2015 23:17:28 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.codeaurora.org (smtp.codeaurora.org [198.145.29.96]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2556A6E806 for ; Sun, 26 Jul 2015 23:17:27 -0700 (PDT) Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id BD5C7140FCA; Mon, 27 Jul 2015 06:17:26 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 486) id A0AD7140FCE; Mon, 27 Jul 2015 06:17:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost (unknown [202.46.23.61]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: architt@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id A4995140FCA; Mon, 27 Jul 2015 06:17:24 +0000 (UTC) From: Archit Taneja To: dri-devel@lists.freedesktop.org, lars@metafoo.de Subject: [PATCH 5/5] drm/i2c: adv7511: Create mipi_dsi_device for ADV7533 Date: Mon, 27 Jul 2015 11:46:59 +0530 Message-Id: <1437977819-24199-6-git-send-email-architt@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1437977819-24199-1-git-send-email-architt@codeaurora.org> References: <1437977819-24199-1-git-send-email-architt@codeaurora.org> X-Virus-Scanned: ClamAV using ClamSMTP Cc: linux-arm-msm@vger.kernel.org, andy.green@linaro.org, srinivas.kandagatla@linaro.org, laurent.pinchart@ideasonboard.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 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-Virus-Scanned: ClamAV using ClamSMTP In order to pass DSI specific parameters to the DSI host, we need the driver to create a mipi_dsi_device that attaches to the host. Use of_graph helpers to get the DSI host DT node. Create a dummy dsi device using this host. Finally, attach this device to the host. Populate few other DT parameters (number of data lanes etc) that are required for DSI RX to work correctly. Hardcode few other parameters (rgb, embedded_sync) for now. Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 106 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 10642e1..ccb57a9 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include "adv7511.h" @@ -58,6 +60,11 @@ struct adv7511 { struct gpio_desc *gpio_pd; + /* ADV7533 DSI RX related params */ + struct device_node *host_node; + struct mipi_dsi_device *dsi; + u8 num_dsi_lanes; + enum adv7511_type type; }; @@ -403,8 +410,10 @@ static void adv7511_dsi_receiver_dpms(struct adv7511 *adv7511) return; if (adv7511->powered) { - /* set number of dsi lanes (hardcoded to 4 for now) */ - regmap_write(adv7511->regmap_cec, 0x1c, 0x4 << 4); + struct mipi_dsi_device *dsi = adv7511->dsi; + + /* set number of dsi lanes */ + regmap_write(adv7511->regmap_cec, 0x1c, dsi->lanes << 4); /* disable internal timing generator */ regmap_write(adv7511->regmap_cec, 0x27, 0x0b); /* enable hdmi */ @@ -954,6 +963,48 @@ static void adv7533_bridge_mode_set(struct drm_bridge *bridge, adv7511_mode_set(adv, mode, adj_mode); } +static int adv7533_attach_dsi(struct adv7511 *adv7511) +{ + struct device *dev = &adv7511->i2c_main->dev; + struct mipi_dsi_device *dsi; + struct mipi_dsi_host *host; + int ret; + + host = of_find_mipi_dsi_host_by_node(adv7511->host_node); + if (!host) { + dev_err(dev, "failed to find dsi host\n"); + return -EPROBE_DEFER; + } + + /* can adv7533 virtual channel be non-zero? */ + dsi = mipi_dsi_new_dummy(host, 0); + if (IS_ERR(dsi)) { + dev_err(dev, "failed to create dummy dsi device\n"); + ret = PTR_ERR(dsi); + goto err_dsi_device; + } + + adv7511->dsi = dsi; + + dsi->lanes = adv7511->num_dsi_lanes; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE + | MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "failed to attach dsi to host\n"); + goto err_dsi_attach; + } + + return 0; + +err_dsi_attach: + mipi_dsi_unregister_device(dsi); +err_dsi_device: + return ret; +} + static int adv7533_bridge_attach(struct drm_bridge *bridge) { struct adv7511 *adv = bridge_to_adv7511(bridge); @@ -980,6 +1031,8 @@ static int adv7533_bridge_attach(struct drm_bridge *bridge) drm_helper_hpd_irq_event(adv->connector.dev); + adv7533_attach_dsi(adv); + return ret; } @@ -1079,6 +1132,41 @@ static int adv7511_parse_dt(struct device_node *np, return 0; } +static int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv7511) +{ + u32 num_lanes; + struct device_node *endpoint; + + of_property_read_u32(np, "adi,dsi-lanes", &num_lanes); + + if (num_lanes < 1 || num_lanes > 4) + return -EINVAL; + + adv7511->num_dsi_lanes = num_lanes; + + endpoint = of_graph_get_next_endpoint(np, NULL); + if (!endpoint) { + DRM_ERROR("adv dsi input endpoint not found\n"); + return -ENODEV; + } + + adv7511->host_node = of_graph_get_remote_port_parent(endpoint); + if (!adv7511->host_node) { + DRM_ERROR("dsi host node not found\n"); + of_node_put(endpoint); + return -ENODEV; + } + + of_node_put(endpoint); + of_node_put(adv7511->host_node); + + /* TODO: Check if these need to be parsed by DT or not */ + adv7511->rgb = true; + adv7511->embedded_sync = false; + + return 0; +} + static const int edid_i2c_addr = 0x7e; static const int packet_i2c_addr = 0x70; static const int cec_i2c_addr = 0x78; @@ -1121,11 +1209,12 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) memset(&link_config, 0, sizeof(link_config)); - if (adv7511->type == ADV7511) { + if (adv7511->type == ADV7511) ret = adv7511_parse_dt(dev->of_node, &link_config); - if (ret) - return ret; - } + else + ret = adv7533_parse_dt(dev->of_node, adv7511); + if (ret) + return ret; /* * The power down GPIO is optional. If present, toggle it from active to @@ -1247,8 +1336,11 @@ static int adv7511_remove(struct i2c_client *i2c) kfree(adv7511->edid); - if (adv7511->type == ADV7533) + if (adv7511->type == ADV7533) { + mipi_dsi_detach(adv7511->dsi); + mipi_dsi_unregister_device(adv7511->dsi); drm_bridge_remove(&adv7511->bridge); + } return 0; }