From patchwork Mon Jan 30 11:05:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 9544813 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 F0F5460417 for ; Mon, 30 Jan 2017 11:05:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D1AB427F17 for ; Mon, 30 Jan 2017 11:05:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C653828399; Mon, 30 Jan 2017 11:05:30 +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.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 38D0E27F17 for ; Mon, 30 Jan 2017 11:05:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1C0586E3E3; Mon, 30 Jan 2017 11:05:28 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x230.google.com (mail-wm0-x230.google.com [IPv6:2a00:1450:400c:c09::230]) by gabe.freedesktop.org (Postfix) with ESMTPS id 019426E3E2 for ; Mon, 30 Jan 2017 11:05:25 +0000 (UTC) Received: by mail-wm0-x230.google.com with SMTP id 196so6179406wmm.1 for ; Mon, 30 Jan 2017 03:05:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bLhXJicrm5ijAKo5z6rAyUQWD6ur18ryOOwwgoE7Aqg=; b=NX7jjAYZVbCD4lY9wQjL3Z0BjZmdCz8DuIZMMOlQ4ECiuJsBsUKHXkGglaCMCs/VZC HB7aCv0tMbMZzRY3u3BxWz8gHzLMrdq7miZxuCk0OC3MVl8e/Yl9W3X4gIfplZ4+hnIf 69UOwN4XxWUR8UZ5nsBlT1Lt3h2SR1OiHQu8NzralXM2sxyu9AHSuXcqS/Ya23Yb+XZH SYn/9zS+J6GbaX1ku4mUumQqakF3neM8f7sSjeDVdqUpbDxOkAkLMAVUWfc6IQrdIC6K d+bQUtZguD6fNJbvx1jeQ0DQstJPJjQ3g3X7tb7GSBPtV2yRxELWdPmKUzp8R5ARrOj7 Zw6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=bLhXJicrm5ijAKo5z6rAyUQWD6ur18ryOOwwgoE7Aqg=; b=ktRCf+qUUMCf47M29v6lD/rMsKTZ5GxEoJwnKkJgkrRrlj0GGRMF8Ks1yIsCGb1p8s /JqtQAg29+3rgfpIPfbQF+8Sc1XUjqhVUKMaUmrKwSJK1Dr8rcMQDvNFnQ220Y/zoo9Q 0q2+WmJiJ4D6z4lj1v9W3pKHUv+x3BdqIL3RQQ0FEEF7FJRcaQ+XyGhdlfHwdD+OWvK9 QXbWMIqP8M2MWfK00UezSpKWYyEj058T6mEK4WYXHdtc3dXFq3+5qTQ0h73af/v32BJl yNkRaEcfgb/kXQWL2/VcaKV+ZdVfh4nng/sAPtRIfrf82dzMkABeNvRQtE+bWHB+gBjA e+BQ== X-Gm-Message-State: AIkVDXIqUENuFOcIEMSbRnGqWly0Zdj22U7P7PL1S8lg8ZOx3HkPr57CFjTOXQiiP4wPHwl2 X-Received: by 10.28.128.150 with SMTP id b144mr14578186wmd.119.1485774323515; Mon, 30 Jan 2017 03:05:23 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id k195sm18165651wmd.7.2017.01.30.03.05.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Jan 2017 03:05:22 -0800 (PST) From: Neil Armstrong To: dri-devel@lists.freedesktop.org, laurent.pinchart+renesas@ideasonboard.com Subject: [PATCH 1/4] drm: bridge: dw-hdmi: Switch to regmap for register access Date: Mon, 30 Jan 2017 12:05:15 +0100 Message-Id: <1485774318-21916-2-git-send-email-narmstrong@baylibre.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1485774318-21916-1-git-send-email-narmstrong@baylibre.com> References: <1485774318-21916-1-git-send-email-narmstrong@baylibre.com> Cc: Jose.Abreu@synopsys.com, linux-amlogic@lists.infradead.org, kieran.bingham@ideasonboard.com, linux-kernel@vger.kernel.org, Neil Armstrong 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 The Synopsys Designware HDMI TX Controller does not enforce register access on platforms instanciating it. The current driver supports two different types of memory-mapped flat register access, but in order to support the Amlogic Meson SoCs integration, and provide a more generic way to handle all sorts of register mapping, switch the register access to use the regmap infrastructure. In the case of registers that are not flat memory-mapped or do not conform to the current driver implementation, a regmap struct can be given in the plat_data and be used at probe or bind. Since the AHB audio driver is only available with direct memory access, only allow the I2S audio driver to be registered is directly memory-mapped. Signed-off-by: Neil Armstrong Reviewed-by: Laurent Pinchart Tested-by: Laurent Pinchart --- drivers/gpu/drm/bridge/dw-hdmi.c | 109 +++++++++++++++++++++------------------ include/drm/bridge/dw_hdmi.h | 1 + 2 files changed, 59 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index ca9d0ce..674ab05 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -167,8 +168,8 @@ struct dw_hdmi { unsigned int audio_n; bool audio_enable; - void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); - u8 (*read)(struct dw_hdmi *hdmi, int offset); + unsigned int reg_shift; + struct regmap *regm; }; #define HDMI_IH_PHY_STAT0_RX_SENSE \ @@ -179,42 +180,23 @@ struct dw_hdmi { (HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \ HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3) -static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset) -{ - writel(val, hdmi->regs + (offset << 2)); -} - -static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset) -{ - return readl(hdmi->regs + (offset << 2)); -} - -static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) -{ - writeb(val, hdmi->regs + offset); -} - -static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset) -{ - return readb(hdmi->regs + offset); -} - static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) { - hdmi->write(hdmi, val, offset); + regmap_write(hdmi->regm, offset << hdmi->reg_shift, val); } static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) { - return hdmi->read(hdmi, offset); + unsigned int val = 0; + + regmap_read(hdmi->regm, offset << hdmi->reg_shift, &val); + + return val; } static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) { - u8 val = hdmi_readb(hdmi, reg) & ~mask; - - val |= data & mask; - hdmi_writeb(hdmi, val, reg); + regmap_update_bits(hdmi->regm, reg << hdmi->reg_shift, mask, data); } static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, @@ -1949,6 +1931,20 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) return 0; } +static const struct regmap_config hdmi_regmap_8bit_config = { + .reg_bits = 32, + .val_bits = 8, + .reg_stride = 1, + .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR, +}; + +static const struct regmap_config hdmi_regmap_32bit_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2, +}; + static struct dw_hdmi * __dw_hdmi_probe(struct platform_device *pdev, const struct dw_hdmi_plat_data *plat_data) @@ -1958,7 +1954,7 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) struct platform_device_info pdevinfo; struct device_node *ddc_node; struct dw_hdmi *hdmi; - struct resource *iores; + struct resource *iores = NULL; int irq; int ret; u32 val = 1; @@ -1982,22 +1978,6 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) mutex_init(&hdmi->audio_mutex); spin_lock_init(&hdmi->audio_lock); - of_property_read_u32(np, "reg-io-width", &val); - - switch (val) { - case 4: - hdmi->write = dw_hdmi_writel; - hdmi->read = dw_hdmi_readl; - break; - case 1: - hdmi->write = dw_hdmi_writeb; - hdmi->read = dw_hdmi_readb; - break; - default: - dev_err(dev, "reg-io-width must be 1 or 4\n"); - return ERR_PTR(-EINVAL); - } - ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); @@ -2011,11 +1991,38 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) dev_dbg(hdmi->dev, "no ddc property found\n"); } - iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs = devm_ioremap_resource(dev, iores); - if (IS_ERR(hdmi->regs)) { - ret = PTR_ERR(hdmi->regs); - goto err_res; + if (!plat_data->regm) { + const struct regmap_config *reg_config; + + of_property_read_u32(np, "reg-io-width", &val); + switch (val) { + case 4: + reg_config = &hdmi_regmap_32bit_config; + hdmi->reg_shift = 2; + break; + case 1: + reg_config = &hdmi_regmap_8bit_config; + break; + default: + dev_err(dev, "reg-io-width must be 1 or 4\n"); + return ERR_PTR(-EINVAL); + } + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hdmi->regs = devm_ioremap_resource(dev, iores); + if (IS_ERR(hdmi->regs)) { + ret = PTR_ERR(hdmi->regs); + goto err_res; + } + + hdmi->regm = devm_regmap_init_mmio(dev, hdmi->regs, reg_config); + if (IS_ERR(hdmi->regm)) { + dev_err(dev, "Failed to configure regmap\n"); + ret = PTR_ERR(hdmi->regm); + goto err_res; + } + } else { + hdmi->regm = plat_data->regm; } hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); @@ -2123,7 +2130,7 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); - if (config3 & HDMI_CONFIG3_AHBAUDDMA) { + if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) { struct dw_hdmi_audio_data audio; audio.phys = iores->start; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 735a8ab..163842d 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -60,6 +60,7 @@ struct dw_hdmi_plat_data { unsigned long mpixelclock); enum drm_mode_status (*mode_valid)(struct drm_connector *connector, struct drm_display_mode *mode); + struct regmap *regm; }; int dw_hdmi_probe(struct platform_device *pdev,