From patchwork Mon Jun 9 16:04:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris BREZILLON X-Patchwork-Id: 4322751 Return-Path: X-Original-To: patchwork-linux-arm@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 822E4BEEE9 for ; Mon, 9 Jun 2014 16:07:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6544E20225 for ; Mon, 9 Jun 2014 16:07:54 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C51FF20272 for ; Mon, 9 Jun 2014 16:07:52 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Wu24O-0001E2-Qc; Mon, 09 Jun 2014 16:05:12 +0000 Received: from top.free-electrons.com ([176.31.233.9] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Wu23z-0000XO-By for linux-arm-kernel@lists.infradead.org; Mon, 09 Jun 2014 16:04:48 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 62899925; Mon, 9 Jun 2014 18:04:29 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id 54F037B5; Mon, 9 Jun 2014 18:04:28 +0200 (CEST) From: Boris BREZILLON To: Thierry Reding , Nicolas Ferre , David Airlie , Samuel Ortiz , Lee Jones Subject: [PATCH v2 1/7] mfd: add atmel-hlcdc driver Date: Mon, 9 Jun 2014 18:04:14 +0200 Message-Id: <1402329860-27520-2-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1402329860-27520-1-git-send-email-boris.brezillon@free-electrons.com> References: <1402329860-27520-1-git-send-email-boris.brezillon@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140609_090447_725924_0EB3197C X-CRM114-Status: GOOD ( 20.14 ) X-Spam-Score: 0.3 (/) Cc: devicetree@vger.kernel.org, Jean-Jacques Hiblot , linux-doc@vger.kernel.org, Boris BREZILLON , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org, Alexandre Belloni , Laurent Pinchart , Jean-Christophe Plagniol-Villard , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The HLCDC IP available on some Atmel SoCs (i.e. at91sam9n12, at91sam9x5 family or sama5d3 family) exposes 2 subdevices: - a display controller (controlled by a DRM driver) - a PWM chip Add support for the MFD device which will just retrieve HLCDC clocks and create a regmap so that subdevices can access the HLCDC register range concurrently. Signed-off-by: Boris BREZILLON --- .../devicetree/bindings/mfd/atmel-hlcdc.txt | 41 ++++++++ drivers/mfd/Kconfig | 11 ++ drivers/mfd/Makefile | 1 + drivers/mfd/atmel-hlcdc.c | 116 +++++++++++++++++++++ include/linux/mfd/atmel-hlcdc.h | 78 ++++++++++++++ 5 files changed, 247 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt create mode 100644 drivers/mfd/atmel-hlcdc.c create mode 100644 include/linux/mfd/atmel-hlcdc.h diff --git a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt new file mode 100644 index 0000000..f5b69cb --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt @@ -0,0 +1,41 @@ +Device-Tree bindings for Atmel's HLCDC (High LCD Controller) MFD driver + +Required properties: + - compatible: value should be one of the following: + "atmel,sama5d3-hlcdc" + - reg: base address and size of the HLCDC device registers. + - clock-names: the name of the 3 clocks requested by the HLCDC device. + Should contain "periph_clk", "sys_clk" and "slow_clk". + - clocks: should contain the 3 clocks requested by the HLCDC device. + +The HLCDC IP exposes two subdevices: + - a PWM chip: see Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt + - a Display Controller: see Documentation/devicetree/bindings/drm/atmel-hlcdc-dc.txt + +Example: + + hlcdc: hlcdc@f0030000 { + compatible = "atmel,sama5d3-hlcdc"; + reg = <0xf0030000 0x2000>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + status = "disabled"; + + hlcdc-display-controller { + compatible = "atmel,hlcdc-dc"; + interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default", "rgb-444", "rgb-565", "rgb-666", "rgb-888"; + pinctrl-0 = <&pinctrl_lcd_base>; + pinctrl-1 = <&pinctrl_lcd_base &pinctrl_lcd_rgb444>; + pinctrl-2 = <&pinctrl_lcd_base &pinctrl_lcd_rgb565>; + pinctrl-3 = <&pinctrl_lcd_base &pinctrl_lcd_rgb666>; + pinctrl-4 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>; + }; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index ee8204c..82777f6 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -59,6 +59,17 @@ config MFD_AAT2870_CORE additional drivers must be enabled in order to use the functionality of the device. +config MFD_ATMEL_HLCDC + tristate "Atmel HLCDC (High LCD Controller)" + select MFD_CORE + select REGMAP_MMIO + help + Choose this option if you have an ATMEL SoC with an HLCDC (High + LCD Controller) IP (i.e. at91sam9n12, at91sam9x5 family or sama5d3 + family). + This MFD device exposes two subdevices: a PWM chip and a Display + Controller. + config MFD_BCM590XX tristate "Broadcom BCM590xx PMUs" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 8afedba..5f25b0d 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -156,6 +156,7 @@ obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o +obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_PALMAS) += palmas.o obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c new file mode 100644 index 0000000..e4636e8 --- /dev/null +++ b/drivers/mfd/atmel-hlcdc.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include + +static const struct mfd_cell atmel_hlcdc_cells[] = { + { + .name = "atmel-hlcdc-pwm", + .of_compatible = "atmel,hlcdc-pwm", + }, + { + .name = "atmel-hlcdc-dc", + .of_compatible = "atmel,hlcdc-dc", + }, +}; + +static int atmel_hlcdc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap_config config; + struct atmel_hlcdc *hlcdc; + struct resource *res; + void __iomem *regs; + + hlcdc = devm_kzalloc(dev, sizeof(*hlcdc), GFP_KERNEL); + if (!hlcdc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs = devm_ioremap_resource(dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + hlcdc->periph_clk = devm_clk_get(dev, "periph_clk"); + if (IS_ERR(hlcdc->periph_clk)) { + dev_err(dev, "failed to get functional clock\n"); + return PTR_ERR(hlcdc->periph_clk); + } + + hlcdc->sys_clk = devm_clk_get(dev, "sys_clk"); + if (IS_ERR(hlcdc->sys_clk)) { + dev_err(dev, "failed to get functional clock\n"); + return PTR_ERR(hlcdc->sys_clk); + } + + hlcdc->slow_clk = devm_clk_get(dev, "slow_clk"); + if (IS_ERR(hlcdc->slow_clk)) { + dev_err(dev, "failed to get slow clock\n"); + return PTR_ERR(hlcdc->slow_clk); + } + + memset(&config, 0, sizeof(config)); + config.reg_bits = 32; + config.val_bits = 32; + config.reg_stride = 4; + config.max_register = (resource_size(res) / 4) - 1; + hlcdc->regmap = devm_regmap_init_mmio_clk(dev, "periph_clk", regs, + &config); + if (IS_ERR(hlcdc->regmap)) + return PTR_ERR(hlcdc->regmap); + + dev_set_drvdata(dev, hlcdc); + + return mfd_add_devices(dev, -1, atmel_hlcdc_cells, + ARRAY_SIZE(atmel_hlcdc_cells), + NULL, 0, NULL); +} + +static int atmel_hlcdc_remove(struct platform_device *pdev) +{ + mfd_remove_devices(&pdev->dev); + + dev_set_drvdata(&pdev->dev, NULL); + + return 0; +} + +static const struct of_device_id atmel_hlcdc_match[] = { + { .compatible = "atmel,sama5d3-hlcdc" }, + { }, +}; + +static struct platform_driver atmel_hlcdc_driver = { + .probe = atmel_hlcdc_probe, + .remove = atmel_hlcdc_remove, + .driver = { + .name = "atmel-hlcdc", + .owner = THIS_MODULE, + .of_match_table = atmel_hlcdc_match, + }, +}; +module_platform_driver(atmel_hlcdc_driver); + +MODULE_ALIAS("platform:atmel-hlcdc"); +MODULE_AUTHOR("Boris Brezillon "); +MODULE_DESCRIPTION("Atmel HLCDC driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h new file mode 100644 index 0000000..d7a5589 --- /dev/null +++ b/include/linux/mfd/atmel-hlcdc.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef __LINUX_MFD_HLCDC_H +#define __LINUX_MFD_HLCDC_H + +#include +#include + +#define ATMEL_HLCDC_CFG(i) ((i) * 0x4) +#define ATMEL_HLCDC_SIG_CFG LCDCFG(5) +#define ATMEL_HLCDC_HSPOL BIT(0) +#define ATMEL_HLCDC_VSPOL BIT(1) +#define ATMEL_HLCDC_VSPDLYS BIT(2) +#define ATMEL_HLCDC_VSPDLYE BIT(3) +#define ATMEL_HLCDC_DISPPOL BIT(4) +#define ATMEL_HLCDC_DITHER BIT(6) +#define ATMEL_HLCDC_DISPDLY BIT(7) +#define ATMEL_HLCDC_MODE_MASK 0x300 +#define ATMEL_HLCDC_PP BIT(10) +#define ATMEL_HLCDC_VSPSU BIT(12) +#define ATMEL_HLCDC_VSPHO BIT(13) +#define ATMEL_HLCDC_GUARDTIME_MASK 0x1f0000 + +#define ATMEL_HLCDC_EN 0x20 +#define ATMEL_HLCDC_DIS 0x24 +#define ATMEL_HLCDC_SR 0x28 +#define ATMEL_HLCDC_IER 0x2c +#define ATMEL_HLCDC_IDR 0x30 +#define ATMEL_HLCDC_IMR 0x34 +#define ATMEL_HLCDC_ISR 0x38 + +#define ATMEL_HLCDC_CLKPOL BIT(0) +#define ATMEL_HLCDC_CLKSEL BIT(2) +#define ATMEL_HLCDC_CLKPWMSEL BIT(3) +#define ATMEL_HLCDC_CGDIS(i) BIT(8 + (i)) +#define ATMEL_HLCDC_CLKDIV_SHFT 16 +#define ATMEL_HLCDC_CLKDIV_MASK (0xff << ATMEL_HLCDC_CLKDIV_SHFT) +#define ATMEL_HLCDC_CLKDIV(div) ((div - 2) << ATMEL_HLCDC_CLKDIV_SHFT) + +#define ATMEL_HLCDC_PIXEL_CLK BIT(0) +#define ATMEL_HLCDC_SYNC BIT(1) +#define ATMEL_HLCDC_DISP BIT(2) +#define ATMEL_HLCDC_PWM BIT(3) +#define ATMEL_HLCDC_SIP BIT(4) + +/** + * Structure shared by the MFD device and its subdevices. + * + * @regmap: register map used to access HLCDC IP registers + * @periph_clk: the hlcdc peripheral clock + * @sys_clk: the hlcdc system clock + * @slow_clk: the system slow clk + */ +struct atmel_hlcdc { + struct regmap *regmap; + struct clk *periph_clk; + struct clk *sys_clk; + struct clk *slow_clk; +}; + +#endif /* __LINUX_MFD_HLCDC_H */