From patchwork Wed Jun 8 10:27:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archit Taneja X-Patchwork-Id: 9164199 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4CBFC60832 for ; Wed, 8 Jun 2016 10:28:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C7AA28345 for ; Wed, 8 Jun 2016 10:28:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3136228358; Wed, 8 Jun 2016 10:28:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9D0628345 for ; Wed, 8 Jun 2016 10:28:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 297D56E96F; Wed, 8 Jun 2016 10:28:55 +0000 (UTC) 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 E42116E96B for ; Wed, 8 Jun 2016 10:28:26 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 9C3DA61483; Wed, 8 Jun 2016 10:28:26 +0000 (UTC) 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 6D0D461470; Wed, 8 Jun 2016 10:28:23 +0000 (UTC) From: Archit Taneja To: dri-devel@lists.freedesktop.org, treding@nvidia.com, laurent.pinchart@ideasonboard.com, xinliang.liu@linaro.org Subject: [PATCH v5 5/7] drm/i2c: adv7533: Use internal timing generator Date: Wed, 8 Jun 2016 15:57:51 +0530 Message-Id: <1465381673-32471-6-git-send-email-architt@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1465381673-32471-1-git-send-email-architt@codeaurora.org> References: <1463395270-3100-1-git-send-email-architt@codeaurora.org> <1465381673-32471-1-git-send-email-architt@codeaurora.org> Cc: linux-arm-msm@vger.kernel.org, amit.kucheria@linaro.org, srinivas.kandagatla@linaro.org 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 ADV7533 provides an internal timing generator for certain modes that it can't use the DSI clock directly. We've observed that HDMI is more stable with the internal timing generator, especially if there are instabilities in the DSI clock source. The data spec also seems to recommend the usage of the timing generator for all modes. However, on some platforms, it's reported that enabling the timing generator causes instabilities with the HDMI output. Create a DT parameter that lets a platform explicitly disable the timing generator. The timing generator is enabled by default. Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 2 ++ drivers/gpu/drm/i2c/adv7511.h | 3 +++ drivers/gpu/drm/i2c/adv7533.c | 60 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 6586c52..e0c353e 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -712,6 +712,8 @@ static void adv7511_mode_set(struct adv7511 *adv7511, regmap_update_bits(adv7511->regmap, 0x17, 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); + drm_mode_copy(&adv7511->curr_mode, adj_mode); + /* * TODO Test first order 4:2:2 to 4:4:4 up conversion method, which is * supposed to give better results. diff --git a/drivers/gpu/drm/i2c/adv7511.h b/drivers/gpu/drm/i2c/adv7511.h index 056f747..a9745ea 100644 --- a/drivers/gpu/drm/i2c/adv7511.h +++ b/drivers/gpu/drm/i2c/adv7511.h @@ -306,6 +306,8 @@ struct adv7511 { enum drm_connector_status status; bool powered; + struct drm_display_mode curr_mode; + unsigned int f_tmds; unsigned int current_edid_segment; @@ -329,6 +331,7 @@ struct adv7511 { struct device_node *host_node; struct mipi_dsi_device *dsi; u8 num_dsi_lanes; + bool use_timing_gen; enum adv7511_type type; }; diff --git a/drivers/gpu/drm/i2c/adv7533.c b/drivers/gpu/drm/i2c/adv7533.c index ecbcaa0..d002ac4 100644 --- a/drivers/gpu/drm/i2c/adv7533.c +++ b/drivers/gpu/drm/i2c/adv7533.c @@ -39,14 +39,65 @@ static const struct regmap_config adv7533_cec_regmap_config = { .cache_type = REGCACHE_RBTREE, }; +static void adv7511_dsi_config_timing_gen(struct adv7511 *adv) +{ + struct mipi_dsi_device *dsi = adv->dsi; + struct drm_display_mode *mode = &adv->curr_mode; + unsigned int hsw, hfp, hbp, vsw, vfp, vbp; + u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */ + + hsw = mode->hsync_end - mode->hsync_start; + hfp = mode->hsync_start - mode->hdisplay; + hbp = mode->htotal - mode->hsync_end; + vsw = mode->vsync_end - mode->vsync_start; + vfp = mode->vsync_start - mode->vdisplay; + vbp = mode->vtotal - mode->vsync_end; + + /* set pixel clock divider mode */ + regmap_write(adv->regmap_cec, 0x16, + clock_div_by_lanes[dsi->lanes - 2] << 3); + + /* horizontal porch params */ + regmap_write(adv->regmap_cec, 0x28, mode->htotal >> 4); + regmap_write(adv->regmap_cec, 0x29, (mode->htotal << 4) & 0xff); + regmap_write(adv->regmap_cec, 0x2a, hsw >> 4); + regmap_write(adv->regmap_cec, 0x2b, (hsw << 4) & 0xff); + regmap_write(adv->regmap_cec, 0x2c, hfp >> 4); + regmap_write(adv->regmap_cec, 0x2d, (hfp << 4) & 0xff); + regmap_write(adv->regmap_cec, 0x2e, hbp >> 4); + regmap_write(adv->regmap_cec, 0x2f, (hbp << 4) & 0xff); + + /* vertical porch params */ + regmap_write(adv->regmap_cec, 0x30, mode->vtotal >> 4); + regmap_write(adv->regmap_cec, 0x31, (mode->vtotal << 4) & 0xff); + regmap_write(adv->regmap_cec, 0x32, vsw >> 4); + regmap_write(adv->regmap_cec, 0x33, (vsw << 4) & 0xff); + regmap_write(adv->regmap_cec, 0x34, vfp >> 4); + regmap_write(adv->regmap_cec, 0x35, (vfp << 4) & 0xff); + regmap_write(adv->regmap_cec, 0x36, vbp >> 4); + regmap_write(adv->regmap_cec, 0x37, (vbp << 4) & 0xff); +} + void adv7533_dsi_power_on(struct adv7511 *adv) { struct mipi_dsi_device *dsi = adv->dsi; + if (adv->use_timing_gen) + adv7511_dsi_config_timing_gen(adv); + /* set number of dsi lanes */ regmap_write(adv->regmap_cec, 0x1c, dsi->lanes << 4); - /* disable internal timing generator */ - regmap_write(adv->regmap_cec, 0x27, 0x0b); + + if (adv->use_timing_gen) { + /* reset internal timing generator */ + regmap_write(adv->regmap_cec, 0x27, 0xcb); + regmap_write(adv->regmap_cec, 0x27, 0x8b); + regmap_write(adv->regmap_cec, 0x27, 0xcb); + } else { + /* disable internal timing generator */ + regmap_write(adv->regmap_cec, 0x27, 0x0b); + } + /* enable hdmi */ regmap_write(adv->regmap_cec, 0x03, 0x89); /* disable test mode */ @@ -60,6 +111,8 @@ void adv7533_dsi_power_off(struct adv7511 *adv) { /* disable hdmi */ regmap_write(adv->regmap_cec, 0x03, 0x0b); + /* disable internal timing generator */ + regmap_write(adv->regmap_cec, 0x27, 0x0b); } int adv7533_patch_registers(struct adv7511 *adv) @@ -179,6 +232,9 @@ int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv) of_node_put(endpoint); of_node_put(adv->host_node); + adv->use_timing_gen = !of_property_read_bool(np, + "adi,disable-timing-generator"); + /* TODO: Check if these need to be parsed by DT or not */ adv->rgb = true; adv->embedded_sync = false;