From patchwork Fri Oct 31 22:54:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 5207441 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1E7719F387 for ; Fri, 31 Oct 2014 23:57:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 183B720176 for ; Fri, 31 Oct 2014 23:56:59 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 14E7920173 for ; Fri, 31 Oct 2014 23:56:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C53E36E870; Fri, 31 Oct 2014 16:56:40 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pd0-f178.google.com (mail-pd0-f178.google.com [209.85.192.178]) by gabe.freedesktop.org (Postfix) with ESMTP id 3E6CD891CC for ; Fri, 31 Oct 2014 15:57:23 -0700 (PDT) Received: by mail-pd0-f178.google.com with SMTP id fp1so8158985pdb.9 for ; Fri, 31 Oct 2014 15:57:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VgaKujrkNpWlQWO8kE7SzmtTa4E/lTscF6q4BKKpVP0=; b=aR8VuuAv0hRtw+gHU5t2J22Df3J6RUeY1ZQnSaA3zEYx/WI+UsU4vYrkdhxyiqLHLV nYnoqoktqwdClsY+qFauNM9r+4M33IakFp3dsYngXwhZKlJAYuX4TzuP27Wva3urszrJ cALkuXQ8BAKKIIf+M6nyIbYhszba23FILJwGv4Jo+8OXDYTmKO4jvQUiqwywO/ElAaJi qlWsMIAncLshviCvmoFQBGHNjBw4Agw883WCKVAy9lmRjfJO6v9Nbv39iztxTfVJNZVz 0F86Jjeh1t6fw41/jO+EisQAO+va/ydsF8EHPwAyUnelZpUQd/sBOaAJPKktwPTn6p7D KKFQ== X-Received: by 10.68.242.67 with SMTP id wo3mr26998940pbc.95.1414796242969; Fri, 31 Oct 2014 15:57:22 -0700 (PDT) Received: from mothership.mgc.mentorg.com (c-50-152-159-227.hsd1.ca.comcast.net. [50.152.159.227]) by mx.google.com with ESMTPSA id ev8sm10870656pdb.28.2014.10.31.15.57.22 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 31 Oct 2014 15:57:22 -0700 (PDT) From: Steve Longerbeam X-Google-Original-From: Steve Longerbeam To: dri-devel@lists.freedesktop.org Subject: [PATCH 42/72] imx-drm: imx-ldb: Implement imx_ldb_encoder_dpms() Date: Fri, 31 Oct 2014 15:54:25 -0700 Message-Id: <1414796095-10107-43-git-send-email-steve_longerbeam@mentor.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1414796095-10107-1-git-send-email-steve_longerbeam@mentor.com> References: <1414796095-10107-1-git-send-email-steve_longerbeam@mentor.com> X-Mailman-Approved-At: Fri, 31 Oct 2014 16:56:32 -0700 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-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, 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 Implement imx_ldb_encoder_dpms(). Two new functions are created to share poweroff and poweron code. imx_ldb_poweroff() is called by encoder dpms, prepare, and disable. imx_ldb_poweron() is called by encoder dpms and commit. Signed-off-by: Steve Longerbeam --- drivers/staging/imx-drm/imx-ldb.c | 139 +++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 73ff379..1eb632f 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -132,11 +132,86 @@ static struct drm_encoder *imx_ldb_connector_best_encoder( return &imx_ldb_ch->encoder; } +static void imx_ldb_poweroff(struct imx_ldb_channel *imx_ldb_ch) +{ + struct imx_ldb *ldb = imx_ldb_ch->ldb; + int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; + int chno = imx_ldb_ch->chno; + + if ((chno == 0 && (ldb->ldb_ctrl & LDB_CH0_MODE_EN_MASK) == 0) || + (chno == 1 && (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0)) + return; + + ldb->ldb_ctrl &= (chno == 0) ? + ~LDB_CH0_MODE_EN_MASK : ~LDB_CH1_MODE_EN_MASK; + + regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); + + if (dual) { + clk_disable_unprepare(ldb->clk[0]); + clk_disable_unprepare(ldb->clk[1]); + } else + clk_disable_unprepare(ldb->clk[chno]); +} + +static void imx_ldb_poweron(struct imx_ldb_channel *imx_ldb_ch) +{ + struct imx_ldb *ldb = imx_ldb_ch->ldb; + int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; + int chno = imx_ldb_ch->chno; + int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, + &imx_ldb_ch->encoder); + + if ((chno == 0 && (ldb->ldb_ctrl & LDB_CH0_MODE_EN_MASK)) || + (chno == 1 && (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK))) + return; + + if (dual) { + clk_prepare_enable(ldb->clk[0]); + clk_prepare_enable(ldb->clk[1]); + } else + clk_prepare_enable(ldb->clk[chno]); + + if (chno == 0 || dual) { + ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; + if (mux == 0 || ldb->lvds_mux) + ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0; + else if (mux == 1) + ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1; + } + if (chno == 1 || dual) { + ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK; + if (mux == 1 || ldb->lvds_mux) + ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1; + else if (mux == 0) + ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0; + } + + if (ldb->lvds_mux) { + const struct bus_mux *lvds_mux = NULL; + + if (chno == 0) + lvds_mux = &ldb->lvds_mux[0]; + else if (chno == 1) + lvds_mux = &ldb->lvds_mux[1]; + + regmap_update_bits(ldb->regmap, lvds_mux->reg, lvds_mux->mask, + mux << lvds_mux->shift); + } + + regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); +} + static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode) { struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); imx_ldb_dbg(imx_ldb_ch, "%s: %s\n", __func__, mode ? "OFF" : "ON"); + + if (mode) + imx_ldb_poweroff(imx_ldb_ch); + else + imx_ldb_poweron(imx_ldb_ch); } static bool imx_ldb_encoder_mode_fixup(struct drm_encoder *encoder, @@ -186,6 +261,8 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) imx_ldb_entry_dbg(imx_ldb_ch); + imx_ldb_poweroff(imx_ldb_ch); + if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { /* dual channel LVDS mode */ serial_clk = 3500UL * mode->clock; @@ -218,45 +295,10 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) static void imx_ldb_encoder_commit(struct drm_encoder *encoder) { struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); - struct imx_ldb *ldb = imx_ldb_ch->ldb; - int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; - int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder); imx_ldb_entry_dbg(imx_ldb_ch); - if (dual) { - clk_prepare_enable(ldb->clk[0]); - clk_prepare_enable(ldb->clk[1]); - } - - if (imx_ldb_ch == &ldb->channel[0] || dual) { - ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; - if (mux == 0 || ldb->lvds_mux) - ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0; - else if (mux == 1) - ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1; - } - if (imx_ldb_ch == &ldb->channel[1] || dual) { - ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK; - if (mux == 1 || ldb->lvds_mux) - ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1; - else if (mux == 0) - ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0; - } - - if (ldb->lvds_mux) { - const struct bus_mux *lvds_mux = NULL; - - if (imx_ldb_ch == &ldb->channel[0]) - lvds_mux = &ldb->lvds_mux[0]; - else if (imx_ldb_ch == &ldb->channel[1]) - lvds_mux = &ldb->lvds_mux[1]; - - regmap_update_bits(ldb->regmap, lvds_mux->reg, lvds_mux->mask, - mux << lvds_mux->shift); - } - - regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); + imx_ldb_poweron(imx_ldb_ch); } static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, @@ -296,33 +338,10 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, static void imx_ldb_encoder_disable(struct drm_encoder *encoder) { struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); - struct imx_ldb *ldb = imx_ldb_ch->ldb; imx_ldb_entry_dbg(imx_ldb_ch); - /* - * imx_ldb_encoder_disable is called by - * drm_helper_disable_unused_functions without - * the encoder being enabled before. - */ - if (imx_ldb_ch == &ldb->channel[0] && - (ldb->ldb_ctrl & LDB_CH0_MODE_EN_MASK) == 0) - return; - else if (imx_ldb_ch == &ldb->channel[1] && - (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0) - return; - - if (imx_ldb_ch == &ldb->channel[0]) - ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; - else if (imx_ldb_ch == &ldb->channel[1]) - ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK; - - regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); - - if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { - clk_disable_unprepare(ldb->clk[0]); - clk_disable_unprepare(ldb->clk[1]); - } + imx_ldb_poweroff(imx_ldb_ch); } static struct drm_connector_funcs imx_ldb_connector_funcs = {