Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
From: Grant Likely @ 2014-02-11 12:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52FA0D6E.9090304@samsung.com>

On Tue, 11 Feb 2014 12:45:50 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Hello,
> 
> On 2014-02-05 12:05, Grant Likely wrote:
> > On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > This patch adds device tree support for contiguous and reserved memory
> > > regions defined in device tree.
> > >
> > > Large memory blocks can be reliably reserved only during early boot.
> > > This must happen before the whole memory management subsystem is
> > > initialized, because we need to ensure that the given contiguous blocks
> > > are not yet allocated by kernel. Also it must happen before kernel
> > > mappings for the whole low memory are created, to ensure that there will
> > > be no mappings (for reserved blocks) or mapping with special properties
> > > can be created (for CMA blocks). This all happens before device tree
> > > structures are unflattened, so we need to get reserved memory layout
> > > directly from fdt.
> > >
> > > Later, those reserved memory regions are assigned to devices on each
> > > device structure initialization.
> > >
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > [joshc: rework to implement new DT binding, provide mechanism for
> > >  plugging in new reserved-memory node handlers via
> > >  RESERVEDMEM_OF_DECLARE]
> > > Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> > > [mszyprow: little code cleanup]
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > ---
> > >  drivers/of/Kconfig                |    6 +
> > >  drivers/of/Makefile               |    1 +
> > >  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
> > >  drivers/of/platform.c             |    7 ++
> > >  include/asm-generic/vmlinux.lds.h |   11 ++
> > >  include/linux/of_reserved_mem.h   |   62 +++++++++++
> > >  6 files changed, 306 insertions(+)
> > >  create mode 100644 drivers/of/of_reserved_mem.c
> > >  create mode 100644 include/linux/of_reserved_mem.h
> > >
> > > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> > > index c6973f101a3e..aba13df56f3a 100644
> > > --- a/drivers/of/Kconfig
> > > +++ b/drivers/of/Kconfig
> > > @@ -75,4 +75,10 @@ config OF_MTD
> > >  	depends on MTD
> > >  	def_bool y
> > >
> > > +config OF_RESERVED_MEM
> > > +	depends on HAVE_MEMBLOCK
> > > +	def_bool y
> > > +	help
> > > +	  Helpers to allow for reservation of memory regions
> > > +
> > >  endmenu # OF
> > > diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> > > index efd05102c405..ed9660adad77 100644
> > > --- a/drivers/of/Makefile
> > > +++ b/drivers/of/Makefile
> > > @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> > >  obj-$(CONFIG_OF_PCI)	+= of_pci.o
> > >  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
> > >  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> > > +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> > > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> > > new file mode 100644
> > > index 000000000000..f17cd56e68d9
> > > --- /dev/null
> > > +++ b/drivers/of/of_reserved_mem.c
> > > @@ -0,0 +1,219 @@
> > > +/*
> > > + * Device tree based initialization code for reserved memory.
> > > + *
> > > + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> > > + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> > > + *		http://www.samsung.com
> > > + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> > > + * Author: Josh Cartwright <joshc@codeaurora.org>
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > + * modify it under the terms of the GNU General Public License as
> > > + * published by the Free Software Foundation; either version 2 of the
> > > + * License or (at your optional) any later version of the license.
> > > + */
> > > +#include <linux/memblock.h>
> > > +#include <linux/err.h>
> > > +#include <linux/of.h>
> > > +#include <linux/of_fdt.h>
> > > +#include <linux/of_platform.h>
> > > +#include <linux/mm.h>
> > > +#include <linux/sizes.h>
> > > +#include <linux/of_reserved_mem.h>
> > > +
> > > +#define MAX_RESERVED_REGIONS	16
> > > +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> > > +static int reserved_mem_count;
> > > +
> > > +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> > > +				   phys_addr_t *base, phys_addr_t *size)
> >
> > Useful utility function; move to drivers/of/fdt.c
> >
> > > +{
> > > +	unsigned long len;
> > > +	__be32 *prop;
> > > +
> > > +	prop = of_get_flat_dt_prop(node, "reg", &len);
> > > +	if (!prop)
> > > +		return -EINVAL;
> > > +
> > > +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> > > +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> > > +				uname);
> > > +		return -EINVAL;
> > > +	}
> >
> > This is /okay/ for an initial implementation, but it is naive. While I
> > suggested making #address-cells and #size-cells equal the root node
> > values for the purpose of simplicity, it should still be perfectly valid
> > to have different values if the ranges property is correctly formed.
> >
> > > +
> > > +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> > > +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> >
> > Future enhancement; allow for parsing more than just the first reg
> > tuple.
> 
> One more question. Does it really makes any sense to support more than
> one tuple for reg property? For consistency we should also allow more
> than one entry in size, align and alloc-ranges property, but I don't
> see any benefits for defining more than one range for a single region.
> Same can be achieved by defining more regions instead if one really
> needs such configuration.

Yes, if only because it is an define usage of the reg property. If a
devtree has multiple tuples in reg, then all of those tuples should be
treated as reserved, even if the kernel doesn't know how to use them.

I would not do the same for size/align/alloc-ranges unless there is a
very specific use case that you can define. These ones are different
from the static regions because they aren't ever used to protect
something that already exists in the memory.

g.

^ permalink raw reply

* [PATCH] ARM: ux500: drop DMA channel platform data for storage
From: Linus Walleij @ 2014-02-11 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

The MMC/SD interface driver (MMCI) already supports picking its
DMA channels out of the device tree, so there is no point in
overriding them with identical platform data as well.

Cc: Lee Jones <lee.jones@linaro.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ux500/board-mop500-sdi.c | 79 ----------------------------------
 1 file changed, 79 deletions(-)

diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index fcbf3a13a539..0addb1815fa6 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -11,13 +11,11 @@
 #include <linux/amba/mmci.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
-#include <linux/platform_data/dma-ste-dma40.h>
 
 #include <asm/mach-types.h>
 
 #include "db8500-regs.h"
 #include "board-mop500.h"
-#include "ste-dma40-db8500.h"
 
 /*
  * v2 has a new version of this block that need to be forced, the number found
@@ -29,20 +27,6 @@
  * SDI 0 (MicroSD slot)
  */
 
-#ifdef CONFIG_STE_DMA40
-struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type = DB8500_DMA_DEV29_SD_MM0,
-};
-
-static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV29_SD_MM0,
-};
-#endif
-
 struct mmci_platform_data mop500_sdi0_data = {
 	.f_max		= 100000000,
 	.capabilities	= MMC_CAP_4_BIT_DATA |
@@ -56,30 +40,11 @@ struct mmci_platform_data mop500_sdi0_data = {
 				MCI_ST_CMDDIREN |
 				MCI_ST_DATA0DIREN |
 				MCI_ST_DATA2DIREN,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &mop500_sdi0_dma_cfg_rx,
-	.dma_tx_param	= &mop500_sdi0_dma_cfg_tx,
-#endif
 };
 
 /*
  * SDI1 (SDIO WLAN)
  */
-#ifdef CONFIG_STE_DMA40
-static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type = DB8500_DMA_DEV32_SD_MM1,
-};
-
-static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV32_SD_MM1,
-};
-#endif
-
 struct mmci_platform_data mop500_sdi1_data = {
 	.ocr_mask	= MMC_VDD_29_30,
 	.f_max		= 100000000,
@@ -87,31 +52,12 @@ struct mmci_platform_data mop500_sdi1_data = {
 				MMC_CAP_NONREMOVABLE,
 	.gpio_cd	= -1,
 	.gpio_wp	= -1,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &sdi1_dma_cfg_rx,
-	.dma_tx_param	= &sdi1_dma_cfg_tx,
-#endif
 };
 
 /*
  * SDI 2 (POP eMMC, not on DB8500ed)
  */
 
-#ifdef CONFIG_STE_DMA40
-struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type =  DB8500_DMA_DEV28_SD_MM2,
-};
-
-static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV28_SD_MM2,
-};
-#endif
-
 struct mmci_platform_data mop500_sdi2_data = {
 	.ocr_mask	= MMC_VDD_165_195,
 	.f_max		= 100000000,
@@ -123,31 +69,11 @@ struct mmci_platform_data mop500_sdi2_data = {
 				MMC_CAP_CMD23,
 	.gpio_cd	= -1,
 	.gpio_wp	= -1,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &mop500_sdi2_dma_cfg_rx,
-	.dma_tx_param	= &mop500_sdi2_dma_cfg_tx,
-#endif
 };
 
 /*
  * SDI 4 (on-board eMMC)
  */
-
-#ifdef CONFIG_STE_DMA40
-struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type =  DB8500_DMA_DEV42_SD_MM4,
-};
-
-static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV42_SD_MM4,
-};
-#endif
-
 struct mmci_platform_data mop500_sdi4_data = {
 	.f_max		= 100000000,
 	.capabilities	= MMC_CAP_4_BIT_DATA |
@@ -158,9 +84,4 @@ struct mmci_platform_data mop500_sdi4_data = {
 				MMC_CAP_CMD23,
 	.gpio_cd	= -1,
 	.gpio_wp	= -1,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &mop500_sdi4_dma_cfg_rx,
-	.dma_tx_param	= &mop500_sdi4_dma_cfg_tx,
-#endif
 };
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 4/7] spi: pl022: attempt to get sspclk by name
From: Mark Brown @ 2014-02-11 12:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-5-git-send-email-mark.rutland@arm.com>

On Tue, Feb 11, 2014 at 11:37:09AM +0000, Mark Rutland wrote:

> -	pl022->clk = devm_clk_get(&adev->dev, NULL);
> +	/*
> +	 * For compatibility with old DTBs and platform data, fall back to the
> +	 * first clock if there's not an explicitly named "sspclk" entry.
> +	 */
> +	pl022->clk = devm_clk_get(&adev->dev, "sspclk");
> +	if (IS_ERR(pl022->clk))
> +		pl022->clk = devm_clk_get(&adev->dev, NULL);
> +

I'll just have a bit of a grumble here and point out that this sort of
stuff always worries me with the convention of using nameless clocks -
it causes hassle adding further clocks.

In any case you didn't CC me on the cover letter or any of the non-SPI
patches so I'm not sure what the dependencies are here (if there are
any), does the series need to go in as one?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140211/3074ea65/attachment.sig>

^ permalink raw reply

* [PATCH V6 07/12] phy: st-miphy-40lp: Add SPEAr1310 and SPEAr1340 PCIe phy support
From: Kishon Vijay Abraham I @ 2014-02-11 12:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f84ed875ae7a356a8056f4645a4d1e59c665c972.1392109054.git.mohit.kumar@st.com>

On Tuesday 11 February 2014 03:00 PM, Mohit Kumar wrote:
> From: Pratyush Anand <pratyush.anand@st.com>
> 
> SPEAr1310 and SPEAr1340 uses miphy40lp phy for PCIe. This driver adds
> support for the same.

What's up with SATA support for SPEAr1310? Do you have plans of adding it soon?
> 
> Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
> Tested-by: Mohit Kumar <mohit.kumar@st.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Viresh Kumar <viresh.linux@gmail.com>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: spear-devel at list.st.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  drivers/phy/phy-miphy40lp.c |  165 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 165 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/phy/phy-miphy40lp.c b/drivers/phy/phy-miphy40lp.c
> index 16da55b..dec67ed 100644
> --- a/drivers/phy/phy-miphy40lp.c
> +++ b/drivers/phy/phy-miphy40lp.c
> @@ -9,6 +9,7 @@
>   * published by the Free Software Foundation.
>   *
>   * 04/02/2014: Adding support of SATA mode for SPEAr1340.
> + * 04/02/2014: Adding support of PCIe mode for SPEAr1340 and SPEAr1310
>   */
>  
>  #include <linux/bitops.h>
> @@ -74,6 +75,80 @@
>  	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
>  			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
>  			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
> +/* SPEAr1310 Registers */
> +#define SPEAR1310_PCIE_SATA_CFG			0x3A4
> +	#define SPEAR1310_PCIE_SATA2_SEL_PCIE		(0 << 31)
> +	#define SPEAR1310_PCIE_SATA1_SEL_PCIE		(0 << 30)
> +	#define SPEAR1310_PCIE_SATA0_SEL_PCIE		(0 << 29)
> +	#define SPEAR1310_PCIE_SATA2_SEL_SATA		BIT(31)
> +	#define SPEAR1310_PCIE_SATA1_SEL_SATA		BIT(30)
> +	#define SPEAR1310_PCIE_SATA0_SEL_SATA		BIT(29)
> +	#define SPEAR1310_SATA2_CFG_TX_CLK_EN		BIT(27)
> +	#define SPEAR1310_SATA2_CFG_RX_CLK_EN		BIT(26)
> +	#define SPEAR1310_SATA2_CFG_POWERUP_RESET	BIT(25)
> +	#define SPEAR1310_SATA2_CFG_PM_CLK_EN		BIT(24)
> +	#define SPEAR1310_SATA1_CFG_TX_CLK_EN		BIT(23)
> +	#define SPEAR1310_SATA1_CFG_RX_CLK_EN		BIT(22)
> +	#define SPEAR1310_SATA1_CFG_POWERUP_RESET	BIT(21)
> +	#define SPEAR1310_SATA1_CFG_PM_CLK_EN		BIT(20)
> +	#define SPEAR1310_SATA0_CFG_TX_CLK_EN		BIT(19)
> +	#define SPEAR1310_SATA0_CFG_RX_CLK_EN		BIT(18)
> +	#define SPEAR1310_SATA0_CFG_POWERUP_RESET	BIT(17)
> +	#define SPEAR1310_SATA0_CFG_PM_CLK_EN		BIT(16)
> +	#define SPEAR1310_PCIE2_CFG_DEVICE_PRESENT	BIT(11)
> +	#define SPEAR1310_PCIE2_CFG_POWERUP_RESET	BIT(10)
> +	#define SPEAR1310_PCIE2_CFG_CORE_CLK_EN		BIT(9)
> +	#define SPEAR1310_PCIE2_CFG_AUX_CLK_EN		BIT(8)
> +	#define SPEAR1310_PCIE1_CFG_DEVICE_PRESENT	BIT(7)
> +	#define SPEAR1310_PCIE1_CFG_POWERUP_RESET	BIT(6)
> +	#define SPEAR1310_PCIE1_CFG_CORE_CLK_EN		BIT(5)
> +	#define SPEAR1310_PCIE1_CFG_AUX_CLK_EN		BIT(4)
> +	#define SPEAR1310_PCIE0_CFG_DEVICE_PRESENT	BIT(3)
> +	#define SPEAR1310_PCIE0_CFG_POWERUP_RESET	BIT(2)
> +	#define SPEAR1310_PCIE0_CFG_CORE_CLK_EN		BIT(1)
> +	#define SPEAR1310_PCIE0_CFG_AUX_CLK_EN		BIT(0)
> +
> +	#define SPEAR1310_PCIE_CFG_MASK(x) ((0xF << (x * 4)) | BIT((x + 29)))
> +	#define SPEAR1310_SATA_CFG_MASK(x) ((0xF << (x * 4 + 16)) | \
> +			BIT((x + 29)))
> +	#define SPEAR1310_PCIE_CFG_VAL(x) \
> +			(SPEAR1310_PCIE_SATA##x##_SEL_PCIE | \
> +			SPEAR1310_PCIE##x##_CFG_AUX_CLK_EN | \
> +			SPEAR1310_PCIE##x##_CFG_CORE_CLK_EN | \
> +			SPEAR1310_PCIE##x##_CFG_POWERUP_RESET | \
> +			SPEAR1310_PCIE##x##_CFG_DEVICE_PRESENT)
> +	#define SPEAR1310_SATA_CFG_VAL(x) \
> +			(SPEAR1310_PCIE_SATA##x##_SEL_SATA | \
> +			SPEAR1310_SATA##x##_CFG_PM_CLK_EN | \
> +			SPEAR1310_SATA##x##_CFG_POWERUP_RESET | \
> +			SPEAR1310_SATA##x##_CFG_RX_CLK_EN | \
> +			SPEAR1310_SATA##x##_CFG_TX_CLK_EN)
> +
> +#define SPEAR1310_PCIE_MIPHY_CFG_1		0x3A8
> +	#define SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT	BIT(31)
> +	#define SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2	BIT(28)
> +	#define SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(x)	(x << 16)
> +	#define SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT	BIT(15)
> +	#define SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2	BIT(12)
> +	#define SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(x)	(x << 0)
> +	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_MASK (0xFFFF)
> +	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK (0xFFFF << 16)
> +	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA \
> +			(SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
> +			SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 | \
> +			SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(60) | \
> +			SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
> +			SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 | \
> +			SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(60))
> +	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
> +			(SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(120))
> +	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE \
> +			(SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
> +			SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(25) | \
> +			SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
> +			SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(25))
> +
> +#define SPEAR1310_PCIE_MIPHY_CFG_2		0x3AC
>  
>  enum phy_mode {
>  	SATA,
> @@ -146,12 +221,35 @@ static int miphy40lp_spear1340_sata_exit(struct miphy40lp_priv *priv)
>  	return 0;
>  }
>  
> +static int miphy40lp_spear1340_pcie_init(struct miphy40lp_priv *priv)
> +{
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
> +			SPEAR1340_PCIE_MIPHY_CFG_MASK,
> +			SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE);
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
> +			SPEAR1340_PCIE_SATA_CFG_MASK, SPEAR1340_PCIE_CFG_VAL);
> +
> +	return 0;
> +}
> +
> +static int miphy40lp_spear1340_pcie_exit(struct miphy40lp_priv *priv)
> +{
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
> +			SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
> +			SPEAR1340_PCIE_SATA_CFG_MASK, 0);
> +
> +	return 0;
> +}
> +
>  static int miphy40lp_spear1340_init(struct miphy40lp_priv *priv)
>  {
>  	int ret = 0;
>  
>  	if (priv->mode == SATA)
>  		ret = miphy40lp_spear1340_sata_init(priv);
> +	else if (priv->mode == PCIE)
> +		ret = miphy40lp_spear1340_pcie_init(priv);
>  
>  	return ret;
>  }
> @@ -162,6 +260,8 @@ static int miphy40lp_spear1340_exit(struct miphy40lp_priv *priv)
>  
>  	if (priv->mode == SATA)
>  		ret = miphy40lp_spear1340_sata_exit(priv);
> +	else if (priv->mode == PCIE)
> +		ret = miphy40lp_spear1340_pcie_exit(priv);
>  
>  	return ret;
>  }
> @@ -193,6 +293,70 @@ static struct miphy40lp_plat_ops spear1340_phy_ops = {
>  	.plat_resume = miphy40lp_spear1340_resume,
>  };
>  
> +static int miphy40lp_spear1310_pcie_init(struct miphy40lp_priv *priv)
> +{
> +	u32 val;
> +
> +	regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
> +			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK,
> +			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE);
> +
> +	switch (priv->id) {

'id' should be made as optional dt property since it's not used for 1340 no?

Thanks
Kishon

^ permalink raw reply

* [PATCH] ARM: ux500: drop a chunk of GPIO definitions
From: Linus Walleij @ 2014-02-11 11:56 UTC (permalink / raw)
  To: linux-arm-kernel

The Ux500 GPIOs are now assigned dynamically from the device tree.
Drop this table of static assignments.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ux500/board-mop500.h | 69 --------------------------------------
 1 file changed, 69 deletions(-)

diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index bb408b8f48de..32cc0d8d8a0e 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -7,78 +7,9 @@
 #ifndef __BOARD_MOP500_H
 #define __BOARD_MOP500_H
 
-/* For NOMADIK_NR_GPIO */
-#include "irqs.h"
 #include <linux/platform_data/asoc-ux500-msp.h>
 #include <linux/amba/mmci.h>
 
-/* Snowball specific GPIO assignments, this board has no GPIO expander */
-#define SNOWBALL_ACCEL_INT1_GPIO	163
-#define SNOWBALL_ACCEL_INT2_GPIO	164
-#define SNOWBALL_MAGNET_DRDY_GPIO	165
-#define SNOWBALL_SDMMC_EN_GPIO		217
-#define SNOWBALL_SDMMC_1V8_3V_GPIO	228
-#define SNOWBALL_SDMMC_CD_GPIO		218
-
-/* HREFv60-specific GPIO assignments, this board has no GPIO expander */
-#define HREFV60_SDMMC_1V8_3V_GPIO	5
-#define HREFV60_CAMERA_FLASH_ENABLE	21
-#define HREFV60_MAGNET_DRDY_GPIO	32
-#define HREFV60_DISP1_RST_GPIO		65
-#define HREFV60_DISP2_RST_GPIO		66
-#define HREFV60_ACCEL_INT1_GPIO		82
-#define HREFV60_ACCEL_INT2_GPIO		83
-#define HREFV60_SDMMC_CD_GPIO		95
-#define HREFV60_XSHUTDOWN_SECONDARY_SENSOR 140
-#define HREFV60_TOUCH_RST_GPIO		143
-#define HREFV60_HAL_SW_GPIO		145
-#define HREFV60_SDMMC_EN_GPIO		169
-#define HREFV60_MMIO_XENON_CHARGE	170
-#define HREFV60_PROX_SENSE_GPIO		217
-
-/* MOP500 generic GPIOs */
-#define CAMERA_FLASH_INT_PIN		7
-#define CYPRESS_TOUCH_INT_PIN		84
-#define XSHUTDOWN_PRIMARY_SENSOR	141
-#define XSHUTDOWN_SECONDARY_SENSOR	142
-#define CYPRESS_TOUCH_RST_GPIO		143
-#define MOP500_HDMI_RST_GPIO		196
-#define CYPRESS_SLAVE_SELECT_GPIO	216
-
-/* GPIOs on the TC35892 expander */
-#define MOP500_EGPIO(x)			(NOMADIK_NR_GPIO + (x))
-#define GPIO_MAGNET_DRDY		MOP500_EGPIO(1)
-#define GPIO_SDMMC_CD			MOP500_EGPIO(3)
-#define GPIO_CAMERA_FLASH_ENABLE	MOP500_EGPIO(4)
-#define GPIO_MMIO_XENON_CHARGE		MOP500_EGPIO(5)
-#define GPIO_PROX_SENSOR		MOP500_EGPIO(7)
-#define GPIO_HAL_SENSOR			MOP500_EGPIO(8)
-#define GPIO_ACCEL_INT1			MOP500_EGPIO(10)
-#define GPIO_ACCEL_INT2			MOP500_EGPIO(11)
-#define GPIO_BU21013_CS			MOP500_EGPIO(13)
-#define MOP500_DISP2_RST_GPIO		MOP500_EGPIO(14)
-#define MOP500_DISP1_RST_GPIO		MOP500_EGPIO(15)
-#define GPIO_SDMMC_EN			MOP500_EGPIO(17)
-#define GPIO_SDMMC_1V8_3V_SEL		MOP500_EGPIO(18)
-#define MOP500_EGPIO_END		MOP500_EGPIO(24)
-
-/*
- * GPIOs on the AB8500 mixed-signals circuit
- * Notice that we subtract 1 from the number passed into the macro, this is
- * because the AB8500 GPIO pins are enumbered starting from 1, so the value in
- * parens matches the GPIO pin number in the data sheet.
- */
-#define MOP500_AB8500_PIN_GPIO(x)	(MOP500_EGPIO_END + (x) - 1)
-/*Snowball AB8500 GPIO */
-#define SNOWBALL_VSMPS2_1V8_GPIO	MOP500_AB8500_PIN_GPIO(1)	/* SYSCLKREQ2/GPIO1 */
-#define SNOWBALL_PM_GPIO1_GPIO		MOP500_AB8500_PIN_GPIO(2)	/* SYSCLKREQ3/GPIO2 */
-#define SNOWBALL_WLAN_CLK_REQ_GPIO	MOP500_AB8500_PIN_GPIO(3)	/* SYSCLKREQ4/GPIO3 */
-#define SNOWBALL_PM_GPIO4_GPIO		MOP500_AB8500_PIN_GPIO(4)	/* SYSCLKREQ6/GPIO4 */
-#define SNOWBALL_EN_3V6_GPIO		MOP500_AB8500_PIN_GPIO(16)	/* PWMOUT3/GPIO16 */
-#define SNOWBALL_PME_ETH_GPIO		MOP500_AB8500_PIN_GPIO(24)	/* SYSCLKREQ7/GPIO24 */
-#define SNOWBALL_EN_3V3_ETH_GPIO	MOP500_AB8500_PIN_GPIO(26)	/* GPIO26 */
-
-struct device;
 extern struct mmci_platform_data mop500_sdi0_data;
 extern struct mmci_platform_data mop500_sdi1_data;
 extern struct mmci_platform_data mop500_sdi2_data;
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v5] clk: sunxi: Add Allwinner A20/A31 GMAC clock unit
From: Chen-Yu Tsai @ 2014-02-11 11:53 UTC (permalink / raw)
  To: linux-arm-kernel

The Allwinner A20/A31 clock module controls the transmit clock source
and interface type of the GMAC ethernet controller. Model this as
a single clock for GMAC drivers to use.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---

Hi,

This is v5 of the Allwinner A20 GMAC clock patch. Hans noted a
compiler warning: unused variable in the previous version.
The DT bits remain the same, and Maxime has already taken them.

The Allwinner A20 SoC integrates an early version of dwmac
IP from Synopsys. On top of that is a hardware glue layer.
This layer needs to be configured before the dwmac can be
used.

Part of the glue layer is a clock mux, which controls the
source and direction of the TX clock used by GMAC.

Changes since v4:

  * Removed unused variable in GMAC clock driver left over from v3

Changes since v3:

  * Rework error checking in GMAC clock driver
  * Clarify required parent clock order for GMAC clock in DT bindings
  * Rewrite commit log for "ARM: dts: sun7i: Add ethernet alias for GMAC"
  * Corrected "a20-olinuxino-micro" in commit message
  * Rewrite comments in sun7i dtsi to clarify purpose of dummy clocks
  * Rebase onto Maxime's sunxi-next branch

Changes since v2:

  * Added more comments on GMAC clock driver
  * Drop CLK_SET_PARENT_GATE in GMAC clock driver
  * Use macro for max clock parents
  * Line wrapping

Changes since v1:

  * Added optional reset control to stmmac driver core
  * Added non CONFIG_RESET_CONROLLER routines for the above change
  * Extended callback API, as discussed with Srinivas
  * Used new stmmac_of_data to pass features and callbacks,
    instead of platform data, as discussed
  * Seperated clock module glue layer into clock driver


Cheers
ChenYu

---
 Documentation/devicetree/bindings/clock/sunxi.txt | 30 +++++++
 drivers/clk/sunxi/clk-sunxi.c                     | 96 +++++++++++++++++++++++
 2 files changed, 126 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 0cf679b..28421d2 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -37,6 +37,7 @@ Required properties:
 	"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
 	"allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
 	"allwinner,sun7i-a20-out-clk" - for the external output clocks
+	"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
 
 Required properties for all clocks:
 - reg : shall be the control register address for the clock.
@@ -50,6 +51,9 @@ Required properties for all clocks:
 	If the clock module only has one output, the name shall be the
 	module name.
 
+For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
+dummy clocks at 25 MHz and 125 MHz, respectively. See example.
+
 Clock consumers should specify the desired clocks they use with a
 "clocks" phandle cell. Consumers that are using a gated clock should
 provide an additional ID in their clock property. This ID is the
@@ -96,3 +100,29 @@ mmc0_clk: clk at 01c20088 {
 	clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 	clock-output-names = "mmc0";
 };
+
+mii_phy_tx_clk: clk at 2 {
+	#clock-cells = <0>;
+	compatible = "fixed-clock";
+	clock-frequency = <25000000>;
+	clock-output-names = "mii_phy_tx";
+};
+
+gmac_int_tx_clk: clk at 3 {
+	#clock-cells = <0>;
+	compatible = "fixed-clock";
+	clock-frequency = <125000000>;
+	clock-output-names = "gmac_int_tx";
+};
+
+gmac_clk: clk at 01c20164 {
+	#clock-cells = <0>;
+	compatible = "allwinner,sun7i-a20-gmac-clk";
+	reg = <0x01c20164 0x4>;
+	/*
+	 * The first clock must be fixed at 25MHz;
+	 * the second clock must be fixed at 125MHz
+	 */
+	clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
+	clock-output-names = "gmac";
+};
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 736fb60..54a5d55 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -379,6 +379,102 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
 
 
 /**
+ * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module
+ *
+ * This clock looks something like this
+ *                               ________________________
+ *  MII TX clock from PHY >-----|___________    _________|----> to GMAC core
+ *  GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY
+ *  Ext. 125MHz RGMII TX clk >--|__divider__/            |
+ *                              |________________________|
+ *
+ * The external 125 MHz reference is optional, i.e. GMAC can use its
+ * internal TX clock just fine. The A31 GMAC clock module does not have
+ * the divider controls for the external reference.
+ *
+ * To keep it simple, let the GMAC use either the MII TX clock for MII mode,
+ * and its internal TX clock for GMII and RGMII modes. The GMAC driver should
+ * select the appropriate source and gate/ungate the output to the PHY.
+ *
+ * Only the GMAC should use this clock. Altering the clock so that it doesn't
+ * match the GMAC's operation parameters will result in the GMAC not being
+ * able to send traffic out. The GMAC driver should set the clock rate and
+ * enable/disable this clock to configure the required state. The clock
+ * driver then responds by auto-reparenting the clock.
+ */
+
+#define SUN7I_A20_GMAC_GPIT	2
+#define SUN7I_A20_GMAC_MASK	0x3
+#define SUN7I_A20_GMAC_PARENTS	2
+
+static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
+{
+	struct clk *clk;
+	struct clk_mux *mux;
+	struct clk_gate *gate;
+	const char *clk_name = node->name;
+	const char *parents[SUN7I_A20_GMAC_PARENTS];
+	void *reg;
+
+	if (of_property_read_string(node, "clock-output-names", &clk_name))
+		return;
+
+	/* allocate mux and gate clock structs */
+	mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+	if (!mux)
+		return;
+
+	gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+	if (!gate)
+		goto free_mux;
+
+	/* gmac clock requires exactly 2 parents */
+	parents[0] = of_clk_get_parent_name(node, 0);
+	parents[1] = of_clk_get_parent_name(node, 1);
+	if (!parents[0] || !parents[1])
+		goto free_gate;
+
+	reg = of_iomap(node, 0);
+	if (!reg)
+		goto free_gate;
+
+	/* set up gate and fixed rate properties */
+	gate->reg = reg;
+	gate->bit_idx = SUN7I_A20_GMAC_GPIT;
+	gate->lock = &clk_lock;
+	mux->reg = reg;
+	mux->mask = SUN7I_A20_GMAC_MASK;
+	mux->flags = CLK_MUX_INDEX_BIT;
+	mux->lock = &clk_lock;
+
+	clk = clk_register_composite(NULL, clk_name,
+			parents, SUN7I_A20_GMAC_PARENTS,
+			&mux->hw, &clk_mux_ops,
+			NULL, NULL,
+			&gate->hw, &clk_gate_ops,
+			0);
+
+	if (IS_ERR(clk))
+		goto iounmap_reg;
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	clk_register_clkdev(clk, clk_name, NULL);
+
+	return;
+
+iounmap_reg:
+	iounmap(reg);
+free_gate:
+	kfree(gate);
+free_mux:
+	kfree(mux);
+}
+CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk",
+		sun7i_a20_gmac_clk_setup);
+
+
+
+/**
  * sunxi_factors_clk_setup() - Setup function for factor clocks
  */
 
-- 
1.9.0.rc3

^ permalink raw reply related

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
From: Grant Likely @ 2014-02-11 11:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52FA00FA.1090400@samsung.com>

On Tue, 11 Feb 2014 11:52:42 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> 
> On 2014-02-10 22:59, Grant Likely wrote:
> > On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > Hello,
> > >
> > > On 2014-02-05 11:15, Grant Likely wrote:
> > > > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > > > Enable reserved memory initialization from device tree.
> > > > >
> > > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > > > ---
> > > > >  arch/arm/mm/init.c |    3 +++
> > > > >  1 file changed, 3 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > > > index 804d61566a53..ebafdb479410 100644
> > > > > --- a/arch/arm/mm/init.c
> > > > > +++ b/arch/arm/mm/init.c
> > > > > @@ -17,6 +17,7 @@
> > > > >  #include <linux/nodemask.h>
> > > > >  #include <linux/initrd.h>
> > > > >  #include <linux/of_fdt.h>
> > > > > +#include <linux/of_reserved_mem.h>
> > > > >  #include <linux/highmem.h>
> > > > >  #include <linux/gfp.h>
> > > > >  #include <linux/memblock.h>
> > > > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > > > >  	if (mdesc->reserve)
> > > > >  		mdesc->reserve();
> > > > >
> > > > > +	early_init_dt_scan_reserved_mem();
> > > > > +
> > > >
> > > > The new binding is being made fundamental. If the reserved-memory node
> > > > is present, then it needs to be honored, even if the kernel doesn't know
> > > > how to use the regions. Therefore, This needs to be unconditional for
> > > > all architectures. The hook should be called in early_init_dt_scan()
> > > > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > > > hook.
> > >
> > > In theory this will be the best solution, but it practice there is a
> > > problem. early_init_dt_scan() is called as the first function from kernel
> > > booting code. That time there is no memory yet added to the system, so it
> > > would be really hard to reserve anything. Memory nodes are being added
> > > later either with memblock_add() or by some other arch specific way.
> >
> > Hmmm, depends on the architecture. On ARM the memory is loaded into the
> > meminfo structure first, and it isn't until arm_memblock_init() that
> > memblock_add() gets called on all the regions. Some architectures do the
> > memblock_add() directly from early_init_dt_add_memory_arch() function.
> >
> > The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
> > overridden by ARM and a number of other architectures. However...
> >
> > > Finally, once all memory has been added to the system we can parse and
> > > reserve all regions defined in the device tree. This really requires
> > > creating another function which will be called by arch specific code.
> >
> > ...Or it means getting rid of meminfo entirely so that memblock is
> > available earlier. Laura Abbott has just posted v2 of her series to do
> > exactly that. If you base on that then you should be able to do exactly
> > what I suggested.
> 
> I've checked Laura's patches and in fact it is possible to do memory
> reservation as a last step in early_init_dt_scan_memory(). However still
> see some problem which I have no idea how to resolve. Right now I focus
> only on ARM, so I have no idea how it is solved by other architectures.

It isn't at the moment because no other architectures are doing dynamic
allocation of regions in this way.

> On of the key features of the new binding is the ability to automatically
> allocate reserved regions of the given size. However kernel, initrd, dt
> and other sub-arch specific critical regions are marked/allocated in
> arm_memblock_init(), which is called after setup_machine_fdt(). This
> might lead to some serious failures when automatically reserved region
> overlaps with some critical resources. Do you have any idea how to solve
> this without a new callback?

Not without moving the kernel/initrd/fdt reservation earlier, which can
certainly be done after Laura's series is applied. It would also be
possible to split up the fixed regions from the dynamic regions so that
the dynamic stuff would be done later.

However, I don't want to block this series on Laura's rework. Go ahead
and keep it as a separate hook, but make the other changes I suggested,
particularly with regard to making the hook architecture independent.
Further rework can be done later after Laura's series is merged.

g.

^ permalink raw reply

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
From: Marek Szyprowski @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140205110538.99E47C40A89@trevor.secretlab.ca>

Hello,

On 2014-02-05 12:05, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > This patch adds device tree support for contiguous and reserved memory
> > regions defined in device tree.
> >
> > Large memory blocks can be reliably reserved only during early boot.
> > This must happen before the whole memory management subsystem is
> > initialized, because we need to ensure that the given contiguous blocks
> > are not yet allocated by kernel. Also it must happen before kernel
> > mappings for the whole low memory are created, to ensure that there will
> > be no mappings (for reserved blocks) or mapping with special properties
> > can be created (for CMA blocks). This all happens before device tree
> > structures are unflattened, so we need to get reserved memory layout
> > directly from fdt.
> >
> > Later, those reserved memory regions are assigned to devices on each
> > device structure initialization.
> >
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Laura Abbott <lauraa@codeaurora.org>
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > [joshc: rework to implement new DT binding, provide mechanism for
> >  plugging in new reserved-memory node handlers via
> >  RESERVEDMEM_OF_DECLARE]
> > Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> > [mszyprow: little code cleanup]
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > ---
> >  drivers/of/Kconfig                |    6 +
> >  drivers/of/Makefile               |    1 +
> >  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
> >  drivers/of/platform.c             |    7 ++
> >  include/asm-generic/vmlinux.lds.h |   11 ++
> >  include/linux/of_reserved_mem.h   |   62 +++++++++++
> >  6 files changed, 306 insertions(+)
> >  create mode 100644 drivers/of/of_reserved_mem.c
> >  create mode 100644 include/linux/of_reserved_mem.h
> >
> > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> > index c6973f101a3e..aba13df56f3a 100644
> > --- a/drivers/of/Kconfig
> > +++ b/drivers/of/Kconfig
> > @@ -75,4 +75,10 @@ config OF_MTD
> >  	depends on MTD
> >  	def_bool y
> >
> > +config OF_RESERVED_MEM
> > +	depends on HAVE_MEMBLOCK
> > +	def_bool y
> > +	help
> > +	  Helpers to allow for reservation of memory regions
> > +
> >  endmenu # OF
> > diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> > index efd05102c405..ed9660adad77 100644
> > --- a/drivers/of/Makefile
> > +++ b/drivers/of/Makefile
> > @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> >  obj-$(CONFIG_OF_PCI)	+= of_pci.o
> >  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
> >  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> > +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> > new file mode 100644
> > index 000000000000..f17cd56e68d9
> > --- /dev/null
> > +++ b/drivers/of/of_reserved_mem.c
> > @@ -0,0 +1,219 @@
> > +/*
> > + * Device tree based initialization code for reserved memory.
> > + *
> > + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> > + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> > + *		http://www.samsung.com
> > + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> > + * Author: Josh Cartwright <joshc@codeaurora.org>
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of the
> > + * License or (at your optional) any later version of the license.
> > + */
> > +#include <linux/memblock.h>
> > +#include <linux/err.h>
> > +#include <linux/of.h>
> > +#include <linux/of_fdt.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/mm.h>
> > +#include <linux/sizes.h>
> > +#include <linux/of_reserved_mem.h>
> > +
> > +#define MAX_RESERVED_REGIONS	16
> > +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> > +static int reserved_mem_count;
> > +
> > +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> > +				   phys_addr_t *base, phys_addr_t *size)
>
> Useful utility function; move to drivers/of/fdt.c
>
> > +{
> > +	unsigned long len;
> > +	__be32 *prop;
> > +
> > +	prop = of_get_flat_dt_prop(node, "reg", &len);
> > +	if (!prop)
> > +		return -EINVAL;
> > +
> > +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> > +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> > +				uname);
> > +		return -EINVAL;
> > +	}
>
> This is /okay/ for an initial implementation, but it is naive. While I
> suggested making #address-cells and #size-cells equal the root node
> values for the purpose of simplicity, it should still be perfectly valid
> to have different values if the ranges property is correctly formed.
>
> > +
> > +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> > +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
>
> Future enhancement; allow for parsing more than just the first reg
> tuple.

One more question. Does it really makes any sense to support more than 
one tuple
for reg property? For consistency we should also allow more than one 
entry in
size, align and alloc-ranges property, but I don't see any benefits for 
defining
more than one range for a single region. Same can be achieved by 
defining more
regions instead if one really needs such configuration.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* [RFC PATCH v2 4/4] ARM: dts: imx6qdl: Add ports and endpoints to IPU DIs
From: Philipp Zabel @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392119144-27868-1-git-send-email-p.zabel@pengutronix.de>

This connects the IPU and display encoder (HDMI, LVDS, MIPI)
device tree nodes using the bindings described in
Documentation/devicetree/bindings/media/video-interfaces.txt

The IPU ports correspond to the two display interfaces. The
order of endpoints in the ports is arbitrary.

Each encoder with an associated input multiplexer has multiple
input ports in the device tree. The order and reg property of
the ports must correspond to the multiplexer input order.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/arm/boot/dts/imx6dl.dtsi  |   9 ++-
 arch/arm/boot/dts/imx6q.dtsi   | 115 ++++++++++++++++++++++++++++++++--
 arch/arm/boot/dts/imx6qdl.dtsi | 137 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 248 insertions(+), 13 deletions(-)

diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index 6dc3970..be63e41 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -72,6 +72,10 @@
 	};
 };
 
+&hdmi {
+	compatible = "fsl,imx6dl-hdmi";
+};
+
 &ldb {
 	clocks = <&clks 33>, <&clks 34>,
 		 <&clks 39>, <&clks 40>,
@@ -88,8 +92,3 @@
 		crtcs = <&ipu1 0>, <&ipu1 1>;
 	};
 };
-
-&hdmi {
-	compatible = "fsl,imx6dl-hdmi";
-	crtcs = <&ipu1 0>, <&ipu1 1>;
-};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 187fe33..f36f739 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -132,13 +132,75 @@
 		};
 
 		ipu2: ipu at 02800000 {
-			#crtc-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "fsl,imx6q-ipu";
 			reg = <0x02800000 0x400000>;
 			interrupts = <0 8 0x4 0 7 0x4>;
 			clocks = <&clks 133>, <&clks 134>, <&clks 137>;
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 4>;
+
+			port at 2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <2>;
+
+				ipu2_di0_disp0: endpoint at 0 {
+				};
+
+				ipu2_di0_hdmi: endpoint at 1 {
+					remote-endpoint = <&hdmi_mux_2>;
+				};
+
+				ipu2_di0_mipi: endpoint at 2 {
+				};
+
+				ipu2_di0_lvds0: endpoint at 3 {
+				};
+
+				ipu2_di0_lvds1: endpoint at 4 {
+				};
+			};
+
+			port at 3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+
+				ipu2_di1_hdmi: endpoint at 1 {
+					remote-endpoint = <&hdmi_mux_3>;
+				};
+
+				ipu2_di1_mipi: endpoint at 2 {
+				};
+
+				ipu2_di1_lvds0: endpoint at 3 {
+				};
+
+				ipu2_di1_lvds1: endpoint at 4 {
+				};
+			};
+		};
+	};
+};
+
+&hdmi {
+	compatible = "fsl,imx6q-hdmi";
+
+	port at 2 {
+		reg = <2>;
+
+		hdmi_mux_2: endpoint {
+			remote-endpoint = <&ipu2_di0_hdmi>;
+		};
+	};
+
+	port at 3 {
+		reg = <3>;
+
+		hdmi_mux_3: endpoint {
+			remote-endpoint = <&ipu2_di1_hdmi>;
 		};
 	};
 };
@@ -152,15 +214,56 @@
 		      "di0", "di1";
 
 	lvds-channel at 0 {
-		crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+		port at 2 {
+			reg = <2>;
+
+			lvds0_mux_2: endpoint {
+				remote-endpoint = <&ipu2_di0_lvds0>;
+			};
+		};
+
+		port at 3 {
+			reg = <3>;
+
+			lvds0_mux_3: endpoint {
+				remote-endpoint = <&ipu2_di1_lvds0>;
+			};
+		};
 	};
 
 	lvds-channel at 1 {
-		crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+		port at 2 {
+			reg = <2>;
+
+			lvds1_mux_2: endpoint {
+				remote-endpoint = <&ipu2_di0_lvds1>;
+			};
+		};
+
+		port at 3 {
+			reg = <3>;
+
+			lvds1_mux_3: endpoint {
+				remote-endpoint = <&ipu2_di1_lvds1>;
+			};
+		};
 	};
 };
 
-&hdmi {
-	compatible = "fsl,imx6q-hdmi";
-	crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+&mipi_dsi {
+	port at 2 {
+		reg = <2>;
+
+		mipi_mux_2: endpoint {
+			remote-endpoint = <&ipu2_di0_mipi>;
+		};
+	};
+
+	port at 3 {
+		reg = <3>;
+
+		mipi_mux_3: endpoint {
+			remote-endpoint = <&ipu2_di1_mipi>;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 930ebe0..098fcc7 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1358,23 +1358,87 @@
 				status = "disabled";
 
 				lvds-channel at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
 					reg = <0>;
 					status = "disabled";
+
+					port at 0 {
+						reg = <0>;
+
+						lvds0_mux_0: endpoint {
+							remote-endpoint = <&ipu1_di0_lvds0>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+
+						lvds0_mux_1: endpoint {
+							remote-endpoint = <&ipu1_di1_lvds0>;
+						};
+					};
+
+					port at 4 {
+						lvds0: endpoint {
+						};
+					};
 				};
 
 				lvds-channel at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
 					reg = <1>;
 					status = "disabled";
+
+					port at 0 {
+						reg = <0>;
+
+						lvds1_mux_0: endpoint {
+							remote-endpoint = <&ipu1_di0_lvds1>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+
+						lvds1_mux_1: endpoint {
+							remote-endpoint = <&ipu1_di1_lvds1>;
+						};
+					};
+
+					port at 4 {
+						lvds1: endpoint {
+						};
+					};
 				};
 			};
 
 			hdmi: hdmi at 0120000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
 				reg = <0x00120000 0x9000>;
 				interrupts = <0 115 0x04>;
 				gpr = <&gpr>;
 				clocks = <&clks 123>, <&clks 124>;
 				clock-names = "iahb", "isfr";
 				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					hdmi_mux_0: endpoint {
+						remote-endpoint = <&ipu1_di0_hdmi>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					hdmi_mux_1: endpoint {
+						remote-endpoint = <&ipu1_di1_hdmi>;
+					};
+				};
 			};
 
 			dcic1: dcic at 020e4000 {
@@ -1588,8 +1652,26 @@
 				reg = <0x021dc000 0x4000>;
 			};
 
-			mipi at 021e0000 { /* MIPI-DSI */
+			mipi_dsi: mipi at 021e0000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
 				reg = <0x021e0000 0x4000>;
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_mux_0: endpoint {
+						remote-endpoint = <&ipu1_di0_mipi>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					mipi_mux_1: endpoint {
+						remote-endpoint = <&ipu1_di1_mipi>;
+					};
+				};
 			};
 
 			vdoa at 021e4000 {
@@ -1643,13 +1725,64 @@
 		};
 
 		ipu1: ipu at 02400000 {
-			#crtc-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "fsl,imx6q-ipu";
 			reg = <0x02400000 0x400000>;
 			interrupts = <0 6 0x4 0 5 0x4>;
 			clocks = <&clks 130>, <&clks 131>, <&clks 132>;
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 2>;
+
+			port at 2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <2>;
+
+				ipu1_di0_disp0: endpoint at 0 {
+				};
+
+				ipu1_di0_hdmi: endpoint at 1 {
+					remote-endpoint = <&hdmi_mux_0>;
+				};
+
+				ipu1_di0_mipi: endpoint at 2 {
+					remote-endpoint = <&mipi_mux_0>;
+				};
+
+				ipu1_di0_lvds0: endpoint at 3 {
+					remote-endpoint = <&lvds0_mux_0>;
+				};
+
+				ipu1_di0_lvds1: endpoint at 4 {
+					remote-endpoint = <&lvds1_mux_0>;
+				};
+			};
+
+			port at 3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+
+				ipu1_di0_disp1: endpoint at 0 {
+				};
+
+				ipu1_di1_hdmi: endpoint at 1 {
+					remote-endpoint = <&hdmi_mux_1>;
+				};
+
+				ipu1_di1_mipi: endpoint at 2 {
+					remote-endpoint = <&mipi_mux_1>;
+				};
+
+				ipu1_di1_lvds0: endpoint at 3 {
+					remote-endpoint = <&lvds0_mux_1>;
+				};
+
+				ipu1_di1_lvds1: endpoint at 4 {
+					remote-endpoint = <&lvds1_mux_1>;
+				};
+			};
 		};
 	};
 };
-- 
1.8.5.3

^ permalink raw reply related

* [RFC PATCH v2 3/4] staging: imx-drm-core: associate crtc devices with di port nodes
From: Philipp Zabel @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392119144-27868-1-git-send-email-p.zabel@pengutronix.de>

To connect the graph in the device tree, each display interface
needs to have an associated port node in the device tree. We can
associate this node with the crtc device and use it to find the
crtc corresponding to a given node instead of using a combination
of parent device node and id.
Explicitly converting the void* cookie to the port device tree node
allows to get rid of the ipu_id and di_id fields. The multiplexer
setting now can be obtained from the port reg property in the
device tree.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/staging/imx-drm/imx-drm-core.c | 63 +++++++++++++++++++---------------
 drivers/staging/imx-drm/imx-drm.h      |  5 +--
 drivers/staging/imx-drm/imx-hdmi.c     |  2 +-
 drivers/staging/imx-drm/imx-ldb.c      |  4 +--
 drivers/staging/imx-drm/ipuv3-crtc.c   | 39 ++++++++++++++++++---
 5 files changed, 77 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
index fecc357..63852bb 100644
--- a/drivers/staging/imx-drm/imx-drm-core.c
+++ b/drivers/staging/imx-drm/imx-drm-core.c
@@ -41,9 +41,7 @@ struct imx_drm_crtc {
 	struct drm_crtc				*crtc;
 	int					pipe;
 	struct imx_drm_crtc_helper_funcs	imx_drm_helper_funcs;
-	void					*cookie;
-	int					id;
-	int					mux_id;
+	struct device_node			*port;
 };
 
 static int legacyfb_depth = 16;
@@ -341,14 +339,11 @@ err_kms:
 
 /*
  * imx_drm_add_crtc - add a new crtc
- *
- * The return value if !NULL is a cookie for the caller to pass to
- * imx_drm_remove_crtc later.
  */
 int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
 		struct imx_drm_crtc **new_crtc,
 		const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
-		void *cookie, int id)
+		struct device_node *port)
 {
 	struct imx_drm_device *imxdrm = drm->dev_private;
 	struct imx_drm_crtc *imx_drm_crtc;
@@ -370,9 +365,7 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
 
 	imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
 	imx_drm_crtc->pipe = imxdrm->pipes++;
-	imx_drm_crtc->cookie = cookie;
-	imx_drm_crtc->id = id;
-	imx_drm_crtc->mux_id = imx_drm_crtc->pipe;
+	imx_drm_crtc->port = port;
 	imx_drm_crtc->crtc = crtc;
 
 	imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc;
@@ -416,7 +409,7 @@ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
 EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
 
 /*
- * Find the DRM CRTC possible mask for the device node cookie/id.
+ * Find the DRM CRTC possible mask for the connected endpoint.
  *
  * The encoder possible masks are defined by their position in the
  * mode_config crtc_list.  This means that CRTCs must not be added
@@ -425,26 +418,17 @@ EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
 static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm,
 	struct device_node *endpoint)
 {
-	struct device_node *remote_port;
-	void *cookie;
+	struct device_node *port;
 	unsigned i;
-	int id = 0;
 
-	remote_port = imx_drm_of_get_remote_port(endpoint);
-	if (remote_port)
-		of_property_read_u32(remote_port, "reg", &id);
-	else
+	port = imx_drm_of_get_remote_port(endpoint);
+	if (!port)
 		return 0;
-	cookie = remote_port->parent;
-	of_node_put(remote_port);
-
-	/* IPU specific: CSI0/1 at 0/1, DI0/1 at 2/3 */
-	id -= 2;
+	of_node_put(port);
 
 	for (i = 0; i < MAX_CRTC; i++) {
 		struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i];
-		if (imx_drm_crtc && imx_drm_crtc->id == id &&
-		    imx_drm_crtc->cookie == cookie)
+		if (imx_drm_crtc && imx_drm_crtc->port == port)
 			return drm_crtc_mask(imx_drm_crtc->crtc);
 	}
 
@@ -496,11 +480,36 @@ int imx_drm_encoder_parse_of(struct drm_device *drm,
 }
 EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
 
-int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder)
+/*
+ * @node: device tree node containing encoder input ports
+ * @encoder: drm_encoder
+ */
+int imx_drm_encoder_get_mux_id(struct device_node *node,
+			       struct drm_encoder *encoder)
 {
 	struct imx_drm_crtc *imx_crtc = imx_drm_find_crtc(encoder->crtc);
+	struct device_node *ep = NULL;
+	struct device_node *port;
+	int id, ret;
+
+	if (!node || !imx_crtc)
+		return -EINVAL;
+
+	do {
+		ep = imx_drm_of_get_next_endpoint(node, ep);
+		if (!ep)
+			break;
+
+		port = imx_drm_of_get_remote_port(ep);
+		of_node_put(port);
+		if (port == imx_crtc->port) {
+			ret = of_property_read_u32(ep->parent, "reg", &id);
+			of_node_put(ep);
+			return ret ? ret : id;
+		}
+	} while (ep);
 
-	return imx_crtc ? imx_crtc->mux_id : -EINVAL;
+	return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id);
 
diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h
index 9af4a82..4afda6b 100644
--- a/drivers/staging/imx-drm/imx-drm.h
+++ b/drivers/staging/imx-drm/imx-drm.h
@@ -30,7 +30,7 @@ struct imx_drm_crtc_helper_funcs {
 int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
 		struct imx_drm_crtc **new_crtc,
 		const struct imx_drm_crtc_helper_funcs *imx_helper_funcs,
-		void *cookie, int id);
+		struct device_node *port);
 int imx_drm_remove_crtc(struct imx_drm_crtc *);
 int imx_drm_init_drm(struct platform_device *pdev,
 		int preferred_bpp);
@@ -49,7 +49,8 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder,
 int imx_drm_panel_format(struct drm_encoder *encoder,
 		u32 interface_pix_fmt);
 
-int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder);
+int imx_drm_encoder_get_mux_id(struct device_node *node,
+		struct drm_encoder *encoder);
 int imx_drm_encoder_parse_of(struct drm_device *drm,
 	struct drm_encoder *encoder, struct device_node *np);
 
diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c
index a677e33..8509814 100644
--- a/drivers/staging/imx-drm/imx-hdmi.c
+++ b/drivers/staging/imx-drm/imx-hdmi.c
@@ -1453,7 +1453,7 @@ static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
 static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
 {
 	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-	int mux = imx_drm_encoder_get_mux_id(encoder);
+	int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 
 	imx_hdmi_set_ipu_di_mux(hdmi, mux);
 
diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c
index 5168c76..301c430 100644
--- a/drivers/staging/imx-drm/imx-ldb.c
+++ b/drivers/staging/imx-drm/imx-ldb.c
@@ -168,7 +168,7 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
 	u32 pixel_fmt;
 	unsigned long serial_clk;
 	unsigned long di_clk = mode->clock * 1000;
-	int mux = imx_drm_encoder_get_mux_id(encoder);
+	int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
 
 	if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
 		/* dual channel LVDS mode */
@@ -203,7 +203,7 @@ 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(encoder);
+	int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
 
 	if (dual) {
 		clk_prepare_enable(ldb->clk[0]);
diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c
index e646017..627515a 100644
--- a/drivers/staging/imx-drm/ipuv3-crtc.c
+++ b/drivers/staging/imx-drm/ipuv3-crtc.c
@@ -350,10 +350,8 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
 		return ret;
 	}
 
-	ret = imx_drm_add_crtc(drm, &ipu_crtc->base,
-			&ipu_crtc->imx_crtc,
-			&ipu_crtc_helper_funcs,
-			ipu_crtc->dev->parent->of_node, pdata->di);
+	ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc,
+			&ipu_crtc_helper_funcs, ipu_crtc->dev->of_node);
 	if (ret) {
 		dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
 		goto err_put_resources;
@@ -401,6 +399,28 @@ err_put_resources:
 	return ret;
 }
 
+static struct device_node *ipu_drm_get_port_by_id(struct device_node *parent,
+						  int port_id)
+{
+	struct device_node *port;
+	int id, ret;
+
+	port = of_get_child_by_name(parent, "port");
+	while (port) {
+		ret = of_property_read_u32(port, "reg", &id);
+		if (!ret && id == port_id)
+			return port;
+
+		do {
+			port = of_get_next_child(parent, port);
+			if (!port)
+				return NULL;
+		} while (of_node_cmp(port->name, "port"));
+	}
+
+	return NULL;
+}
+
 static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
 {
 	struct ipu_client_platformdata *pdata = dev->platform_data;
@@ -414,6 +434,17 @@ static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
 
 	ipu_crtc->dev = dev;
 
+	if (!dev->of_node) {
+		/* Associate crtc device with the corresponding DI port node */
+		dev->of_node = ipu_drm_get_port_by_id(dev->parent->of_node,
+						      pdata->di + 2);
+		if (!dev->of_node) {
+			dev_err(dev, "missing port@%d node in %s\n",
+				pdata->di + 2, dev->parent->of_node->full_name);
+			return -ENODEV;
+		}
+	}
+
 	ret = ipu_crtc_init(ipu_crtc, pdata, drm);
 	if (ret)
 		return ret;
-- 
1.8.5.3

^ permalink raw reply related

* [RFC PATCH v2 2/4] staging: imx-drm-core: Use graph to find connection between crtc and encoder
From: Philipp Zabel @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392119144-27868-1-git-send-email-p.zabel@pengutronix.de>

This patch adds support to find the connections between crtcs and encoder
using the OF graph bindings documented for video interfaces in
Documentation/devicetree/bindings/media/video-interfaces.txt

This patch uses temporary copies of the V4L2 OF graph parsers that can be
removed again once those are moved to a generic place.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/staging/imx-drm/imx-drm-core.c | 43 +++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
index dcba518..fecc357 100644
--- a/drivers/staging/imx-drm/imx-drm-core.c
+++ b/drivers/staging/imx-drm/imx-drm-core.c
@@ -423,9 +423,23 @@ EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
  * or removed once the DRM device has been fully initialised.
  */
 static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm,
-	void *cookie, int id)
+	struct device_node *endpoint)
 {
+	struct device_node *remote_port;
+	void *cookie;
 	unsigned i;
+	int id = 0;
+
+	remote_port = imx_drm_of_get_remote_port(endpoint);
+	if (remote_port)
+		of_property_read_u32(remote_port, "reg", &id);
+	else
+		return 0;
+	cookie = remote_port->parent;
+	of_node_put(remote_port);
+
+	/* IPU specific: CSI0/1 at 0/1, DI0/1 at 2/3 */
+	id -= 2;
 
 	for (i = 0; i < MAX_CRTC; i++) {
 		struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i];
@@ -441,24 +455,18 @@ int imx_drm_encoder_parse_of(struct drm_device *drm,
 	struct drm_encoder *encoder, struct device_node *np)
 {
 	struct imx_drm_device *imxdrm = drm->dev_private;
+	struct device_node *ep = NULL;
 	uint32_t crtc_mask = 0;
-	int i, ret = 0;
+	int i;
 
-	for (i = 0; !ret; i++) {
-		struct of_phandle_args args;
+	for (i = 0; i < MAX_CRTC; i++) {
 		uint32_t mask;
-		int id;
 
-		ret = of_parse_phandle_with_args(np, "crtcs", "#crtc-cells", i,
-						 &args);
-		if (ret == -ENOENT)
+		ep = imx_drm_of_get_next_endpoint(np, ep);
+		if (!ep)
 			break;
-		if (ret < 0)
-			return ret;
 
-		id = args.args_count > 0 ? args.args[0] : 0;
-		mask = imx_drm_find_crtc_mask(imxdrm, args.np, id);
-		of_node_put(args.np);
+		mask = imx_drm_find_crtc_mask(imxdrm, ep);
 
 		/*
 		 * If we failed to find the CRTC(s) which this encoder is
@@ -466,12 +474,19 @@ int imx_drm_encoder_parse_of(struct drm_device *drm,
 		 * not been registered yet.  Defer probing, and hope that
 		 * the required CRTC is added later.
 		 */
-		if (mask == 0)
+		if (mask == 0) {
+			of_node_put(ep);
 			return -EPROBE_DEFER;
+		}
 
 		crtc_mask |= mask;
 	}
 
+	if (ep)
+		of_node_put(ep);
+	if (i == 0)
+		return -ENOENT;
+
 	encoder->possible_crtcs = crtc_mask;
 
 	/* FIXME: this is the mask of outputs which can clone this output. */
-- 
1.8.5.3

^ permalink raw reply related

* [RFC PATCH v2 1/4] staging: imx-drm: Add temporary copies of v4l2-of parsing functions
From: Philipp Zabel @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392119144-27868-1-git-send-email-p.zabel@pengutronix.de>

From: Philipp Zabel <philipp.zabel@gmail.com>

The video interface bindings described in
Documentation/device-tree/bindings/media/video-interfaces.txt
are useful for DRM drivers, too. To decouple development,
duplicate the v4l2-of parser functions temporarily. Also modify
imx_drm_of_get_next_endpoint to decrement the refcount of prev.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 drivers/staging/imx-drm/Makefile     |   2 +-
 drivers/staging/imx-drm/imx-drm-of.c | 106 +++++++++++++++++++++++++++++++++++
 drivers/staging/imx-drm/imx-drm.h    |   4 ++
 3 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/imx-drm/imx-drm-of.c

diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile
index 129e3a3..743b875 100644
--- a/drivers/staging/imx-drm/Makefile
+++ b/drivers/staging/imx-drm/Makefile
@@ -1,5 +1,5 @@
 
-imxdrm-objs := imx-drm-core.o
+imxdrm-objs := imx-drm-core.o imx-drm-of.o
 
 obj-$(CONFIG_DRM_IMX) += imxdrm.o
 
diff --git a/drivers/staging/imx-drm/imx-drm-of.c b/drivers/staging/imx-drm/imx-drm-of.c
new file mode 100644
index 0000000..12f37eb
--- /dev/null
+++ b/drivers/staging/imx-drm/imx-drm-of.c
@@ -0,0 +1,106 @@
+/*
+ * Video Interface OF binding parsing library
+ *
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Copyright (C) 2012 Renesas Electronics Corp.
+ * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+/**
+ * imx_drm_get_next_endpoint() - get next endpoint node
+ * @parent: pointer to the parent device node
+ * @prev: previous endpoint node, or NULL to get first
+ *
+ * Return: An 'endpoint' node pointer with refcount incremented. Refcount
+ * of the passed @prev node is decremented.
+ */
+struct device_node *imx_drm_of_get_next_endpoint(
+		const struct device_node *parent, struct device_node *prev)
+{
+	struct device_node *endpoint;
+	struct device_node *port = NULL;
+
+	if (!parent)
+		return NULL;
+
+	if (!prev) {
+		struct device_node *node;
+		/*
+		 * It's the first call, we have to find a port subnode
+		 * within this node or within an optional 'ports' node.
+		 */
+		node = of_get_child_by_name(parent, "ports");
+		if (node)
+			parent = node;
+
+		port = of_get_child_by_name(parent, "port");
+
+		if (port) {
+			/* Found a port, get an endpoint. */
+			endpoint = of_get_next_child(port, NULL);
+			of_node_put(port);
+		} else {
+			endpoint = NULL;
+		}
+
+		if (!endpoint)
+			pr_err("%s(): no endpoint nodes specified for %s\n",
+			       __func__, parent->full_name);
+		of_node_put(node);
+	} else {
+		port = of_get_parent(prev);
+		if (!port) {
+			/* Hm, has someone given us the root node ?... */
+			of_node_put(prev);
+			return NULL;
+		}
+
+		endpoint = of_get_next_child(port, prev);
+		if (endpoint) {
+			of_node_put(port);
+			return endpoint;
+		}
+
+		/* No more endpoints under this port, try the next one. */
+		do {
+			port = of_get_next_child(parent, port);
+			if (!port)
+				return NULL;
+		} while (of_node_cmp(port->name, "port"));
+
+		/* Pick up the first endpoint in this port. */
+		endpoint = of_get_next_child(port, NULL);
+		of_node_put(port);
+	}
+
+	return endpoint;
+}
+EXPORT_SYMBOL_GPL(imx_drm_of_get_next_endpoint);
+
+/**
+ * imx_drm_of_get_remote_port() - get remote port node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote port node associated with remote endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *imx_drm_of_get_remote_port(const struct device_node *node)
+{
+	struct device_node *np;
+
+	/* Get remote endpoint node. */
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+	if (!np)
+		return NULL;
+	return of_get_next_parent(np);
+}
+EXPORT_SYMBOL_GPL(imx_drm_of_get_remote_port);
diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h
index aa21028..9af4a82 100644
--- a/drivers/staging/imx-drm/imx-drm.h
+++ b/drivers/staging/imx-drm/imx-drm.h
@@ -58,4 +58,8 @@ int imx_drm_connector_mode_valid(struct drm_connector *connector,
 void imx_drm_connector_destroy(struct drm_connector *connector);
 void imx_drm_encoder_destroy(struct drm_encoder *encoder);
 
+struct device_node *imx_drm_of_get_next_endpoint(
+		const struct device_node *parent, struct device_node *prev);
+struct device_node *imx_drm_of_get_remote_port(const struct device_node *node);
+
 #endif /* _IMX_DRM_H_ */
-- 
1.8.5.3

^ permalink raw reply related

* [RFC PATCH v2 0/4] imx-drm dt bindings
From: Philipp Zabel @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

these patches apply on top of Russell's second preview of the
imx-drm cleanup series. I have added device tree bindings between
IPU and the encoders as documented in
Documentation/devicetree/bindings/media/video-interfaces.txt
and used those to determine the possible_crtcs and mux_id.

The crtc cookie is replaced with a the port device tree node,
which is unique and therefore allows to get rid of the di_id
comparison. Storing the multiplexer input numbers in the device
tree removes the need to know the ipu_id. This should also allow
to replace IPU2 with LCDIF on i.MX6 Solo more easily.

In v2 I've added temporary copies of the v4l2_of helpers to imx-drm
and tested it on the SolidRun Hummingboard.

regards
Philipp


Philipp Zabel (4):
  staging: imx-drm: Add temporary copies of v4l2-of parsing functions
  staging: imx-drm-core: Use graph to find connection between crtc and
    encoder
  staging: imx-drm-core: associate crtc devices with di port nodes
  ARM: dts: imx6qdl: Add ports and endpoints to IPU DIs

 arch/arm/boot/dts/imx6dl.dtsi          |   9 +--
 arch/arm/boot/dts/imx6q.dtsi           | 115 +++++++++++++++++++++++++--
 arch/arm/boot/dts/imx6qdl.dtsi         | 137 ++++++++++++++++++++++++++++++++-
 drivers/staging/imx-drm/Makefile       |   2 +-
 drivers/staging/imx-drm/imx-drm-core.c |  82 +++++++++++++-------
 drivers/staging/imx-drm/imx-drm-of.c   | 106 +++++++++++++++++++++++++
 drivers/staging/imx-drm/imx-drm.h      |   9 ++-
 drivers/staging/imx-drm/imx-hdmi.c     |   2 +-
 drivers/staging/imx-drm/imx-ldb.c      |   4 +-
 drivers/staging/imx-drm/ipuv3-crtc.c   |  39 +++++++++-
 10 files changed, 453 insertions(+), 52 deletions(-)
 create mode 100644 drivers/staging/imx-drm/imx-drm-of.c

-- 
1.8.5.3

^ permalink raw reply

* [PATCH] can: xilinx CAN controller support.
From: Michal Simek @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F4A960.10809@pengutronix.de>

Hi Marc,

On 02/07/2014 10:37 AM, Marc Kleine-Budde wrote:
> On 02/07/2014 09:42 AM, Appana Durga Kedareswara Rao wrote:
>>>> ---
>>>> This patch is rebased on the 3.14 rc1 kernel.
>>>> ---
>>>>  .../devicetree/bindings/net/can/xilinx_can.txt     |   43 +
>>>>  drivers/net/can/Kconfig                            |    8 +
>>>>  drivers/net/can/Makefile                           |    1 +
>>>>  drivers/net/can/xilinx_can.c                       | 1150 ++++++++++++++++++++
>>>>  4 files changed, 1202 insertions(+), 0 deletions(-)  create mode
>>>> 100644 Documentation/devicetree/bindings/net/can/xilinx_can.txt
>>>>  create mode 100644 drivers/net/can/xilinx_can.c
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/net/can/xilinx_can.txt
>>>> b/Documentation/devicetree/bindings/net/can/xilinx_can.txt
>>>> new file mode 100644
>>>> index 0000000..34f9643
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/net/can/xilinx_can.txt
>>>> @@ -0,0 +1,43 @@
>>>> +Xilinx Axi CAN/Zynq CANPS controller Device Tree Bindings
>>>> +---------------------------------------------------------
>>>> +
>>>> +Required properties:
>>>> +- compatible               : Should be "xlnx,zynq-can-1.00.a" for Zynq
>>> CAN
>>>> +                     controllers and "xlnx,axi-can-1.00.a" for Axi CAN
>>>> +                     controllers.
>>>> +- reg                      : Physical base address and size of the Axi CAN/Zynq
>>>> +                     CANPS registers map.
>>>> +- interrupts               : Property with a value describing the interrupt
>>>> +                     number.
>>>> +- interrupt-parent : Must be core interrupt controller
>>>> +- clock-names              : List of input clock names - "ref_clk",
>>> "aper_clk"
>>>> +                     (See clock bindings for details. Two clocks are
>>>> +                      required for Zynq CAN. For Axi CAN
>>>> +                      case it is one(ref_clk)).
>>>> +- clocks           : Clock phandles (see clock bindings for details).
>>>> +- xlnx,can-tx-dpth : Can Tx fifo depth (Required for Axi CAN).
>>>> +- xlnx,can-rx-dpth : Can Rx fifo depth (Required for Axi CAN).
>>>> +
>>>> +
>>>> +Example:
>>>> +
>>>> +For Zynq CANPS Dts file:
>>>> +   zynq_can_0: zynq-can at e0008000 {
>>>> +                   compatible = "xlnx,zynq-can-1.00.a";
>>>> +                   clocks = <&clkc 19>, <&clkc 36>;
>>>> +                   clock-names = "ref_clk", "aper_clk";
>>>> +                   reg = <0xe0008000 0x1000>;
>>>> +                   interrupts = <0 28 4>;
>>>> +                   interrupt-parent = <&intc>;
>>>
>>> Above xlnx,can-{rx,tx}-dpth is mentioned as required, but it's not in the
>>> Zynq example.
>>
>> One of the Difference b/w the AXI CAN and zynq CAN is in AXI CAN the fifo depth(tx,rx)
>> Is user configurable. But in case of ZYNQ CAN  the fifo depth  is fixed for tx and rx fifo's(64)
>> Xlnx,can-{rx,tx}-dpth is required only for AXI CAN case it is not required for zynq CAN.
>> That's why didn't putted that property in device tree.
> 
> The device tree should be a hardware only description and should not
> hold any user configurable data. Please split your patch into two
> patches. The first one should add the driver with a fixed fifo size
> (e.g. 0x40) for the AXI, too. The second patch should make the fifo
> configurable via device tree.

can-rx/tx-dpth is not user configurable data as you think.
This is FPGA where you can configure this parameter in design tools.
It means these 2 values just describe real hardware and user can't just change it
for different software behaviour.

Also I don't think it is worth to create 2 patches for the same driver
where the first one is useless for axi can device. But if you think
that it is worth to do we can create 2 patches as you suggested.

Also what we can do is to define that this property is required also
for zynq which is 0x40 and change code according too.

> If it's acceptable to describe the fifo usage by device tree, I'd like
> to make it a generic CAN driver option. But we have to look around, e.g.
> what the Ethernet driver use to configure their hardware.

I think the real question is not if this is acceptable or not. It is just
reality that we can setup hardware fifo depth and driver has to reflect this
because without it driver just doesn't work for axi can.

The only remaining question is if we should create generic DT binding
for fifo depth. Arnd, Rob: Any opinion about it?
Definitely will be worth to have one generic binding if this is generic feature.
But if this is just specific feature for us then current properties should
be fine.

In general all these xlnx,XXX properties just reflect all configurable options
which you can setup in design tool which means that provide full hw description
with all variants and they are automatically generated from tools.

Please let me know what you think.

Thanks,
Michal

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 264 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140211/cf038ad6/attachment.sig>

^ permalink raw reply

* [PATCH 7/7] Documentation: devicetree: loosen primecell clock requirements
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-1-git-send-email-mark.rutland@arm.com>

The primecell binding requires the APB PCLK (named "apb_pclk") to be the
first entry in the clocks list, yet existing drivers and dts files
expect other clocks first, in clear violation of this requirement.
Additionally, the code handling the apb_pclk always acquires the clock
by name rather than index, making the requirement irrelevant.

As there are no other implementations handling the primecell bindings,
this patch loosens the requirements to an apb_pclk entry existing in the
clocks list. This is compatible with existing software, and any new
software handling the weaker requirements will be able to use existing
dts. Any software relying on the original stricter requirements will be
unable to use many existing dts, so the loosened requirement aids
compatibility rather than hindering it.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 Documentation/devicetree/bindings/arm/primecell.txt | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/primecell.txt b/Documentation/devicetree/bindings/arm/primecell.txt
index 0df6aca..0a66506 100644
--- a/Documentation/devicetree/bindings/arm/primecell.txt
+++ b/Documentation/devicetree/bindings/arm/primecell.txt
@@ -13,9 +13,10 @@ Required properties:
 Optional properties:
 
 - arm,primecell-periphid : Value to override the h/w value with
-- clocks : From common clock binding. First clock is phandle to clock for apb
-	pclk. Additional clocks are optional and specific to those peripherals.
-- clock-names : From common clock binding. Shall be "apb_pclk" for first clock.
+- clocks : From common clock binding. One clock must be the apb pclk.
+           Additional clocks are optional and specific to those peripherals.
+- clock-names : From common clock binding. Shall include "apb_pclk" for the apb
+                pclk.
 - dmas : From common DMA binding. If present, refers to one or more dma channels.
 - dma-names : From common DMA binding, needs to match the 'dmas' property.
               Devices with exactly one receive and transmit channel shall name
@@ -31,8 +32,8 @@ serial at fff36000 {
 	compatible = "arm,pl011", "arm,primecell";
 	arm,primecell-periphid = <0x00341011>;
 
-	clocks = <&pclk>;
-	clock-names = "apb_pclk";
+	clocks = <&refclk>, <&pclk>;
+	clock-names = "uartclk", "apb_pclk";
 
 	dmas = <&dma-controller 4>, <&dma-controller 5>;
 	dma-names = "rx", "tx";	
-- 
1.8.1.1

^ permalink raw reply related

* [PATCH 6/7] mmc: arm-mmci: attempt to get mclk by name
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-1-git-send-email-mark.rutland@arm.com>

The primecell device tree binding (from which the pl18x binding is
derived from) states that the apb_pclk clock input should be listed
first for all primecell devices. The arm-mmci driver requires the mclk
clock input, but the way it currently grabs the clock means that it
always gets the first clock (which should be apb_pclk).

As the AMBA bus code grabs apb_pclk by name, some existing dts provide
apb_pclk as the second clock in the clocks list to work around this, in
violation of both the primecell binding. The pl18x binding does not
mention clocks at all, so the first clock (MCLK) is given an arbitrary
name.

This patch attempts to fix the mess my having the arm-mmci driver first
attempt to get mclk by name. If this fails, it falls back to the old
behaviour of simply acquiring the first clock. This is compatible with
any old dtb, whether it lists mclk by name or not, and allows the driver
to support dtbs which do not violate the bindings. Hopefully this will
lead to future uniformity across dtbs.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Chris Ball <cjb@laptop.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 drivers/mmc/host/mmci.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index b931226..4af962c 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1470,7 +1470,14 @@ static int mmci_probe(struct amba_device *dev,
 	dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
 	dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
 
-	host->clk = devm_clk_get(&dev->dev, NULL);
+	/*
+	 * For compatibility with old DTBs and platform data, fall back to the
+	 * first clock if there's not an explicitly named "mclk" entry.
+	 */
+	host->clk = devm_clk_get(&dev->dev, "mclk");
+	if (IS_ERR(host->clk))
+		host->clk = devm_clk_get(&dev->dev, NULL);
+
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
 		goto host_free;
-- 
1.8.1.1

^ permalink raw reply related

* [PATCH 5/7] Documentation: devicetree: fix up pl18x clocks
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-1-git-send-email-mark.rutland@arm.com>

Currently the pl18x driver expects clocks, and dts provide them, yet the
binding does not mention clocks at all.

This patch adds a description of the clocks, "apb_pclk" (as required by
the primecell binding) and "mclk" for the pl18x itself. The "mclk"
name was chosen to match the official documentation, as currently a
variety of names are used in its place; it is expected that any
operating system supporting these can continue to do so in the absence
of an "mclk" entry.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Chris Ball <cjb@laptop.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 Documentation/devicetree/bindings/mmc/mmci.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmci.txt b/Documentation/devicetree/bindings/mmc/mmci.txt
index 2b584ca..1b72d4d 100644
--- a/Documentation/devicetree/bindings/mmc/mmci.txt
+++ b/Documentation/devicetree/bindings/mmc/mmci.txt
@@ -9,6 +9,10 @@ by mmc.txt and the properties used by the mmci driver.
 Required properties:
 - compatible             : contains "arm,pl18x", "arm,primecell".
 - arm,primecell-periphid : contains the PrimeCell Peripheral ID.
+- clocks : a list of phandles + clock-specifiers, one for each entry in
+           clock-names.
+- clock-names : should contain "apb_pclk" and "mclk".
+
 
 Optional properties:
 - mmc-cap-mmc-highspeed  : indicates whether MMC is high speed capable
-- 
1.8.1.1

^ permalink raw reply related

* [PATCH 4/7] spi: pl022: attempt to get sspclk by name
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-1-git-send-email-mark.rutland@arm.com>

The primecell device tree binding (from which the pl022 binding is
derived from) states that the apb_pclk clock input should be listed
first for all primecell devices. The spi-pl022 driver requires the
sspclk clock input to enable the SPI bus, but the way it currently grabs
the clock means that it always gets the first clock (which should be
apb_pclk).

As the AMBA bus code grabs apb_pclk by name, some existing dts provide
apb_pclk as the second clock in the clocks list to work around this, in
violation of both the primecell binding. The pl022 binding does not
mention clocks at all, so the first clock (SSPCLK) is given an arbitrary
name.

This patch attempts to fix the mess my having the spi-pl022 driver first
attempt to get sspclk by name. If this fails, it falls back to the old
behaviour of simply acquiring the first clock. This is compatible with
any old dtb, whether it lists sspclk by name or not, and allows the
driver to support dtbs which do not violate the bindings. Hopefully this
will lead to future uniformity across dtbs.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 drivers/spi/spi-pl022.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 2789b45..4b3941a 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2176,7 +2176,14 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 	dev_info(&adev->dev, "mapped registers from %pa to %p\n",
 		&adev->res.start, pl022->virtbase);
 
-	pl022->clk = devm_clk_get(&adev->dev, NULL);
+	/*
+	 * For compatibility with old DTBs and platform data, fall back to the
+	 * first clock if there's not an explicitly named "sspclk" entry.
+	 */
+	pl022->clk = devm_clk_get(&adev->dev, "sspclk");
+	if (IS_ERR(pl022->clk))
+		pl022->clk = devm_clk_get(&adev->dev, NULL);
+
 	if (IS_ERR(pl022->clk)) {
 		status = PTR_ERR(pl022->clk);
 		dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
-- 
1.8.1.1

^ permalink raw reply related

* [PATCH 3/7] Documentation: devicetree: fix up pl022 clocks
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-1-git-send-email-mark.rutland@arm.com>

Currently the pl022 driver expects clocks, and dts provide them, yet the
binding does not mention clocks at all.

This patch adds a description of the clocks, "apb_pclk" (as required by
the primecell binding) and "sspclk" for the pl022 itself. The "sspclk"
name was chosen to match the official documentation, as currently a
variety of names are used in its place; it is expected that any
operating system supporting these can continue to do so in the absence
of an "sspclk" entry.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 Documentation/devicetree/bindings/spi/spi_pl022.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi_pl022.txt b/Documentation/devicetree/bindings/spi/spi_pl022.txt
index 22ed679..326e8e2 100644
--- a/Documentation/devicetree/bindings/spi/spi_pl022.txt
+++ b/Documentation/devicetree/bindings/spi/spi_pl022.txt
@@ -21,6 +21,8 @@ Optional properties:
 - dma-names: Names for the dma channels, if present. There must be at
 	     least one channel named "tx" for transmit and named "rx" for
              receive.
+- clocks: phandle + clock-specifiers, one for each entry in clock-names.
+- clock-names: should contain "apb_pclk" and "sspclk".
 
 
 SPI slave nodes must be children of the SPI master node and can
-- 
1.8.1.1

^ permalink raw reply related

* [PATCH 2/7] serial: amba-pl011: attempt to get uartclk by name
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-1-git-send-email-mark.rutland@arm.com>

The primecell device tree binding (from which the pl011 binding is
derived from) states that the apb_pclk clock input should be listed
first for all primecell devices. The amba-pl011 driver requires the
uartclk clock input to enable the uart and calculate the correct uart
baud rate, but the way it currently grabs the clock means that it always
gets the first clock (which should be apb_pclk).

As the AMBA bus code grabs apb_pclk by name, some existing dts provide
uartclk then apb_pclk by name to work around this, in violation of both
the primecell binding and the pl011 binding. Some dtbs only provide
apb_pclk, which is evidently at a similar enough frequency to uartclk on
those platforms to allow the driver to function.

This patch attempts to fix the mess my having the amba-pl011 driver
first attempt to get uartclk by name. If this fails, it falls back to
the old behaviour of simply acquiring the first clock. This is
compatible with any old dtb, whether it lists uartclk by name or not,
and allows the driver to support dtbs which do not violate either
binding.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 drivers/tty/serial/amba-pl011.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index d58783d..067952a 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2123,7 +2123,14 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
 		goto out;
 	}
 
-	uap->clk = devm_clk_get(&dev->dev, NULL);
+	/*
+	 * For compatibility with old DTBs and platform data, fall back to the
+	 * first clock if there's not an explicitly named "uartclk" entry.
+	 */
+	uap->clk = devm_clk_get(&dev->dev, "uartclk");
+	if (IS_ERR(uap->clk))
+		uap->clk = devm_clk_get(&dev->dev, NULL);
+
 	if (IS_ERR(uap->clk)) {
 		ret = PTR_ERR(uap->clk);
 		goto out;
-- 
1.8.1.1

^ permalink raw reply related

* [PATCH 1/7] Documentation: devicetree: fix up pl011 clocks
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392118632-11312-1-git-send-email-mark.rutland@arm.com>

The "arm,pl011" device tree binding only describes the apb_pclk clock
input, which is not sufficient to use the device. Knowledge of the
uartclk clock input is required to be able to change the baud rate, as
the baud rate is derived from the reference uartclk input. On systems
where the uartclk input is not initially enabled, it is also required to
use the device in any fashion.

This patch adds the uartclk input to the pl011 device tree binding. The
clock-names property is also described, as it is an implied requirement
of the primecell binding the pl011 binding is derived from.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 Documentation/devicetree/bindings/serial/pl011.txt | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/pl011.txt b/Documentation/devicetree/bindings/serial/pl011.txt
index 5d2e840..f0a9e77 100644
--- a/Documentation/devicetree/bindings/serial/pl011.txt
+++ b/Documentation/devicetree/bindings/serial/pl011.txt
@@ -8,8 +8,10 @@ Required properties:
 Optional properties:
 - pinctrl: When present, must have one state named "sleep"
 	   and one state named "default"
-- clocks:  When present, must refer to exactly one clock named
-	   "apb_pclk"
+- clocks:  When present, must refer to a clock named
+           "apb_pclk", and optionally "uartclk".
+- clock-names: When present, should include "apb_pclk" and
+	   "uartclk", matching the clocks property.
 - dmas:	   When present, may have one or two dma channels.
 	   The first one must be named "rx", the second one
 	   must be named "tx".
-- 
1.8.1.1

^ permalink raw reply related

* [PATCH 0/7] primecell: make correct clock parsing possible
From: Mark Rutland @ 2014-02-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel

Currently either the drivers for primecell peripherals and their bindings
disagree, or those bindings disagree with the primecell binding which they
derive from. It is impossible in some cases to meet the requirements of both
bindings and drivers.

These patches attempt to harmonize the bindings and the drivers with what's in
use today, in a backwards compatible fashion, relieving us of our present
Kafkaesque nightmare. Each peripheral's clock(s) are given explicit names which
can be used, though code will fall back to the existing behaviour if said names
are not provided. Additionally the currently unmet ordering requirement of
apb_pclk is dropped, given all existing that code requires this to be named
anyway.

I've used IS_ERR to test is a clock wasn't provided by name, but this isn't
always right. In the case of a dodgy clock specifier we might get an error,
even if the expected name was provided explicitly in clock-names. For that case
it would be nice to fail rather than grabbing an almost certainly incorrect
clock. I'm not entirely sure how to check for that with the current
infrastructure though, and while it's possible to use of_property_match_string
to achieve the desired effect, it feels like working around the abstraction we
have in place today.

There are some other issues in the area which remain:

* The pl041 exists in DTs, but has no binding.

* Both pl110 and pl111 have no binding, but appear to be in use on OF
  platforms, with the nspire code proving some sideband data via
  OF_DEV_AUXDATA. The driver grabs a clock (CLCDCLK) without using a name.

* I'm not sure what to do with sp804. The bindings imply a given set of names
  with a specific ordering, but all the dts do something different and the
  driver doesn't bother with names. The given binding is incompatible with the
  primecell binding's ordering requirement for apb_plck.

* There's no binding for the sp805, which grabs a clock with no name.

* There's no binding for the pl341 or pl354. Both seem to be unused yet exist
  in DTs.

* The PL330 docs don't mention clocks at all, though the apb_pclk is required.
  Use of PCLKEN isn't supported, but this doesn't seem to be a problem so far.

Thanks,
Mark.

Mark Rutland (7):
  Documentation: devicetree: fix up pl011 clocks
  serial: amba-pl011: attempt to get uartclk by name
  Documentation: devicetree: fix up pl022 clocks
  spi: pl022: attempt to get sspclk by name
  Documentation: devicetree: fix up pl18x clocks
  mmc: arm-mmci: attempt to get mclk by name
  Documentation: devicetree: loosen primecell clock requirements

 Documentation/devicetree/bindings/arm/primecell.txt | 11 ++++++-----
 Documentation/devicetree/bindings/mmc/mmci.txt      |  4 ++++
 Documentation/devicetree/bindings/serial/pl011.txt  |  6 ++++--
 Documentation/devicetree/bindings/spi/spi_pl022.txt |  2 ++
 drivers/mmc/host/mmci.c                             |  9 ++++++++-
 drivers/spi/spi-pl022.c                             |  9 ++++++++-
 drivers/tty/serial/amba-pl011.c                     |  9 ++++++++-
 7 files changed, 40 insertions(+), 10 deletions(-)

-- 
1.8.1.1

^ permalink raw reply

* [PATCH V6 06/12] SPEAr13xx: Fixup: Move SPEAr1340 SATA platform code to phy driver
From: Kishon Vijay Abraham I @ 2014-02-11 11:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <15e900d387a71e48387cf322ca065e38691c50e5.1392109054.git.mohit.kumar@st.com>

Hi,

On Tuesday 11 February 2014 03:00 PM, Mohit Kumar wrote:
> From: Pratyush Anand <pratyush.anand@st.com>
> 
> ahci driver needs some platform specific functions which are called at
> init, exit, suspend and resume conditions. Till now these functions were
> present in a platform driver with a fixme notes.
> 
> Similar functions modifying same set of registers will also be needed in
> case of PCIe phy init/exit.
> 
> So move all these SATA platform code to phy-miphy40lp driver.
> 
> Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
> Tested-by: Mohit Kumar <mohit.kumar@st.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Viresh Kumar <viresh.linux@gmail.com>
> Cc: Tejun Heo <tj@kernel.org>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: spear-devel at list.st.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  arch/arm/boot/dts/spear1310-evb.dts |    4 +
>  arch/arm/boot/dts/spear1310.dtsi    |   39 +++++++++-
>  arch/arm/boot/dts/spear1340-evb.dts |    4 +
>  arch/arm/boot/dts/spear1340.dtsi    |   13 +++-
>  arch/arm/boot/dts/spear13xx.dtsi    |    5 +
>  arch/arm/mach-spear/Kconfig         |    2 +
>  arch/arm/mach-spear/spear1340.c     |  127 +------------------------------
>  drivers/phy/phy-miphy40lp.c         |  144 +++++++++++++++++++++++++++++++++++
>  8 files changed, 208 insertions(+), 130 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
> index b56a801..d42c84b 100644
> --- a/arch/arm/boot/dts/spear1310-evb.dts
> +++ b/arch/arm/boot/dts/spear1310-evb.dts
> @@ -106,6 +106,10 @@
>  			status = "okay";
>  		};
>  
> +		miphy at eb800000 {
> +			status = "okay";
> +		};
> +
>  		cf at b2800000 {
>  			status = "okay";
>  		};
> diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
> index 122ae94..64e7dd5 100644
> --- a/arch/arm/boot/dts/spear1310.dtsi
> +++ b/arch/arm/boot/dts/spear1310.dtsi
> @@ -29,24 +29,57 @@
>  			#gpio-cells = <2>;
>  		};
>  
> -		ahci at b1000000 {
> +		miphy0: miphy at eb800000 {
> +			compatible = "st,miphy", "st,spear1310-miphy";
> +			reg = <0xeb800000 0x4000>;
> +			misc = <&misc>;
> +			phy-id = <0>;
> +			#phy-cells = <1>;
> +			status = "disabled";
> +		};
> +
> +		miphy1: miphy at eb804000 {
> +			compatible = "st,miphy", "st,spear1310-miphy";
> +			reg = <0xeb804000 0x4000>;
> +			misc = <&misc>;
> +			phy-id = <1>;
> +			#phy-cells = <1>;
> +			status = "disabled";
> +		};
> +
> +		miphy2: miphy at eb808000 {
> +			compatible = "st,miphy", "st,spear1310-miphy";
> +			reg = <0xeb808000 0x4000>;
> +			misc = <&misc>;
> +			phy-id = <2>;
> +			#phy-cells = <1>;
> +			status = "disabled";
> +		};
> +
> +		ahci0: ahci at b1000000 {
>  			compatible = "snps,spear-ahci";
>  			reg = <0xb1000000 0x10000>;
>  			interrupts = <0 68 0x4>;
> +			phys = <&miphy0 0>;
> +			phy-names = "sata-phy";
>  			status = "disabled";
>  		};
>  
> -		ahci at b1800000 {
> +		ahci1: ahci at b1800000 {
>  			compatible = "snps,spear-ahci";
>  			reg = <0xb1800000 0x10000>;
>  			interrupts = <0 69 0x4>;
> +			phys = <&miphy1 0>;
> +			phy-names = "sata-phy";
>  			status = "disabled";
>  		};
>  
> -		ahci at b4000000 {
> +		ahci2: ahci at b4000000 {
>  			compatible = "snps,spear-ahci";
>  			reg = <0xb4000000 0x10000>;
>  			interrupts = <0 70 0x4>;
> +			phys = <&miphy2 0>;
> +			phy-names = "sata-phy";
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
> index d6c30ae..b23e05e 100644
> --- a/arch/arm/boot/dts/spear1340-evb.dts
> +++ b/arch/arm/boot/dts/spear1340-evb.dts
> @@ -122,6 +122,10 @@
>  			status = "okay";
>  		};
>  
> +		miphy at eb800000 {
> +			status = "okay";
> +		};
> +
>  		dma at ea800000 {
>  			status = "okay";
>  		};
> diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
> index 54d128d..7e3a04b 100644
> --- a/arch/arm/boot/dts/spear1340.dtsi
> +++ b/arch/arm/boot/dts/spear1340.dtsi
> @@ -31,10 +31,21 @@
>  			status = "disabled";
>  		};
>  
> -		ahci at b1000000 {
> +		miphy0: miphy at eb800000 {
> +			compatible = "st,miphy", "st,spear1340-miphy";
> +			reg = <0xeb800000 0x4000>;
> +			misc = <&misc>;
> +			phy-id = <0>;
> +			#phy-cells = <1>;
> +			status = "disabled";
> +		};
> +
> +		ahci0: ahci at b1000000 {
>  			compatible = "snps,spear-ahci";
>  			reg = <0xb1000000 0x10000>;
>  			interrupts = <0 72 0x4>;
> +			phys = <&miphy0 0>;
> +			phy-names = "sata-phy";
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
> index 4382547..3a72508 100644
> --- a/arch/arm/boot/dts/spear13xx.dtsi
> +++ b/arch/arm/boot/dts/spear13xx.dtsi
> @@ -220,6 +220,11 @@
>  				  0xd8000000 0xd8000000 0x01000000
>  				  0xe0000000 0xe0000000 0x10000000>;
>  
> +			misc: syscon at e0700000 {
> +				compatible = "st,spear1340-misc", "syscon";
> +				reg = <0xe0700000 0x1000>;
> +			};
> +
>  			gpio0: gpio at e0600000 {
>  				compatible = "arm,pl061", "arm,primecell";
>  				reg = <0xe0600000 0x1000>;
> diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
> index ac1710e..7e7f1b0 100644
> --- a/arch/arm/mach-spear/Kconfig
> +++ b/arch/arm/mach-spear/Kconfig
> @@ -26,6 +26,8 @@ config ARCH_SPEAR13XX
>  	select MIGHT_HAVE_CACHE_L2X0
>  	select PINCTRL
>  	select USE_OF
> +	select MFD_SYSCON
> +	select PHY_ST_MIPHY40LP
>  	help
>  	  Supports for ARM's SPEAR13XX family
>  
> diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
> index 3fb6834..8e27093 100644
> --- a/arch/arm/mach-spear/spear1340.c
> +++ b/arch/arm/mach-spear/spear1340.c
> @@ -11,138 +11,13 @@
>   * warranty of any kind, whether express or implied.
>   */
>  
> -#define pr_fmt(fmt) "SPEAr1340: " fmt
> -
> -#include <linux/ahci_platform.h>
> -#include <linux/amba/serial.h>
> -#include <linux/delay.h>
>  #include <linux/of_platform.h>
>  #include <asm/mach/arch.h>
>  #include "generic.h"
> -#include <mach/spear.h>
> -
> -/* FIXME: Move SATA PHY code into a standalone driver */
> -
> -/* Base addresses */
> -#define SPEAR1340_SATA_BASE			UL(0xB1000000)
> -
> -/* Power Management Registers */
> -#define SPEAR1340_PCM_CFG			(VA_MISC_BASE + 0x100)
> -#define SPEAR1340_PCM_WKUP_CFG			(VA_MISC_BASE + 0x104)
> -#define SPEAR1340_SWITCH_CTR			(VA_MISC_BASE + 0x108)
> -
> -#define SPEAR1340_PERIP1_SW_RST			(VA_MISC_BASE + 0x318)
> -#define SPEAR1340_PERIP2_SW_RST			(VA_MISC_BASE + 0x31C)
> -#define SPEAR1340_PERIP3_SW_RST			(VA_MISC_BASE + 0x320)
> -
> -/* PCIE - SATA configuration registers */
> -#define SPEAR1340_PCIE_SATA_CFG			(VA_MISC_BASE + 0x424)
> -	/* PCIE CFG MASks */
> -	#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT	(1 << 11)
> -	#define SPEAR1340_PCIE_CFG_POWERUP_RESET	(1 << 10)
> -	#define SPEAR1340_PCIE_CFG_CORE_CLK_EN		(1 << 9)
> -	#define SPEAR1340_PCIE_CFG_AUX_CLK_EN		(1 << 8)
> -	#define SPEAR1340_SATA_CFG_TX_CLK_EN		(1 << 4)
> -	#define SPEAR1340_SATA_CFG_RX_CLK_EN		(1 << 3)
> -	#define SPEAR1340_SATA_CFG_POWERUP_RESET	(1 << 2)
> -	#define SPEAR1340_SATA_CFG_PM_CLK_EN		(1 << 1)
> -	#define SPEAR1340_PCIE_SATA_SEL_PCIE		(0)
> -	#define SPEAR1340_PCIE_SATA_SEL_SATA		(1)
> -	#define SPEAR1340_SATA_PCIE_CFG_MASK		0xF1F
> -	#define SPEAR1340_PCIE_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_PCIE | \
> -			SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
> -			SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
> -			SPEAR1340_PCIE_CFG_POWERUP_RESET | \
> -			SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
> -	#define SPEAR1340_SATA_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_SATA | \
> -			SPEAR1340_SATA_CFG_PM_CLK_EN | \
> -			SPEAR1340_SATA_CFG_POWERUP_RESET | \
> -			SPEAR1340_SATA_CFG_RX_CLK_EN | \
> -			SPEAR1340_SATA_CFG_TX_CLK_EN)
> -
> -#define SPEAR1340_PCIE_MIPHY_CFG		(VA_MISC_BASE + 0x428)
> -	#define SPEAR1340_MIPHY_OSC_BYPASS_EXT		(1 << 31)
> -	#define SPEAR1340_MIPHY_CLK_REF_DIV2		(1 << 27)
> -	#define SPEAR1340_MIPHY_CLK_REF_DIV4		(2 << 27)
> -	#define SPEAR1340_MIPHY_CLK_REF_DIV8		(3 << 27)
> -	#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)	(x << 0)
> -	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
> -			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
> -			SPEAR1340_MIPHY_CLK_REF_DIV2 | \
> -			SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
> -	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
> -			(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
> -	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
> -			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
> -			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
> -
> -/* SATA device registration */
> -static int sata_miphy_init(struct device *dev, void __iomem *addr)
> -{
> -	writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
> -	writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
> -			SPEAR1340_PCIE_MIPHY_CFG);
> -	/* Switch on sata power domain */
> -	writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
> -	msleep(20);
> -	/* Disable PCIE SATA Controller reset */
> -	writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
> -			SPEAR1340_PERIP1_SW_RST);
> -	msleep(20);
> -
> -	return 0;
> -}
> -
> -void sata_miphy_exit(struct device *dev)
> -{
> -	writel(0, SPEAR1340_PCIE_SATA_CFG);
> -	writel(0, SPEAR1340_PCIE_MIPHY_CFG);
> -
> -	/* Enable PCIE SATA Controller reset */
> -	writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
> -			SPEAR1340_PERIP1_SW_RST);
> -	msleep(20);
> -	/* Switch off sata power domain */
> -	writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
> -	msleep(20);
> -}
> -
> -int sata_suspend(struct device *dev)
> -{
> -	if (dev->power.power_state.event == PM_EVENT_FREEZE)
> -		return 0;
> -
> -	sata_miphy_exit(dev);
> -
> -	return 0;
> -}
> -
> -int sata_resume(struct device *dev)
> -{
> -	if (dev->power.power_state.event == PM_EVENT_THAW)
> -		return 0;
> -
> -	return sata_miphy_init(dev, NULL);
> -}
> -
> -static struct ahci_platform_data sata_pdata = {
> -	.init = sata_miphy_init,
> -	.exit = sata_miphy_exit,
> -	.suspend = sata_suspend,
> -	.resume = sata_resume,
> -};
> -
> -/* Add SPEAr1340 auxdata to pass platform data */
> -static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
> -	OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
> -			&sata_pdata),
> -	{}
> -};
>  
>  static void __init spear1340_dt_init(void)
>  {
> -	of_platform_populate(NULL, of_default_bus_match_table,
> -			spear1340_auxdata_lookup, NULL);
> +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
>  }
>  
>  static const char * const spear1340_dt_board_compat[] = {
> diff --git a/drivers/phy/phy-miphy40lp.c b/drivers/phy/phy-miphy40lp.c
> index 98859ff..16da55b 100644
> --- a/drivers/phy/phy-miphy40lp.c
> +++ b/drivers/phy/phy-miphy40lp.c
> @@ -8,8 +8,10 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   *
> + * 04/02/2014: Adding support of SATA mode for SPEAr1340.
>   */
>  
> +#include <linux/bitops.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/kernel.h>
> @@ -19,6 +21,60 @@
>  #include <linux/phy/phy.h>
>  #include <linux/regmap.h>
>  
> +/* SPEAr1340 Registers */
> +/* Power Management Registers */
> +#define SPEAR1340_PCM_CFG			0x100
> +	#define SPEAR1340_PCM_CFG_SATA_POWER_EN		BIT(11)

No tabs in the beginning. Just my personal preference though. No strong feelings.
> +#define SPEAR1340_PCM_WKUP_CFG			0x104
> +#define SPEAR1340_SWITCH_CTR			0x108
> +
> +#define SPEAR1340_PERIP1_SW_RST			0x318
> +	#define SPEAR1340_PERIP1_SW_RSATA		BIT(12)
> +#define SPEAR1340_PERIP2_SW_RST			0x31C
> +#define SPEAR1340_PERIP3_SW_RST			0x320
> +
> +/* PCIE - SATA configuration registers */
> +#define SPEAR1340_PCIE_SATA_CFG			0x424
> +	/* PCIE CFG MASks */
> +	#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT	BIT(11)
> +	#define SPEAR1340_PCIE_CFG_POWERUP_RESET	BIT(10)
> +	#define SPEAR1340_PCIE_CFG_CORE_CLK_EN		BIT(9)
> +	#define SPEAR1340_PCIE_CFG_AUX_CLK_EN		BIT(8)
> +	#define SPEAR1340_SATA_CFG_TX_CLK_EN		BIT(4)
> +	#define SPEAR1340_SATA_CFG_RX_CLK_EN		BIT(3)
> +	#define SPEAR1340_SATA_CFG_POWERUP_RESET	BIT(2)
> +	#define SPEAR1340_SATA_CFG_PM_CLK_EN		BIT(1)
> +	#define SPEAR1340_PCIE_SATA_SEL_PCIE		(0)
> +	#define SPEAR1340_PCIE_SATA_SEL_SATA		(1)
> +	#define SPEAR1340_PCIE_SATA_CFG_MASK		0xF1F
> +	#define SPEAR1340_PCIE_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_PCIE | \
> +			SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
> +			SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
> +			SPEAR1340_PCIE_CFG_POWERUP_RESET | \
> +			SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
> +	#define SPEAR1340_SATA_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_SATA | \
> +			SPEAR1340_SATA_CFG_PM_CLK_EN | \
> +			SPEAR1340_SATA_CFG_POWERUP_RESET | \
> +			SPEAR1340_SATA_CFG_RX_CLK_EN | \
> +			SPEAR1340_SATA_CFG_TX_CLK_EN)
> +
> +#define SPEAR1340_PCIE_MIPHY_CFG		0x428
> +	#define SPEAR1340_MIPHY_OSC_BYPASS_EXT		BIT(31)
> +	#define SPEAR1340_MIPHY_CLK_REF_DIV2		BIT(27)
> +	#define SPEAR1340_MIPHY_CLK_REF_DIV4		(2 << 27)
> +	#define SPEAR1340_MIPHY_CLK_REF_DIV8		(3 << 27)

This doesn't look very nice. But I'm not sure if there are similar macros to
handle sequence of bits.
> +	#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)	(x << 0)
> +	#define SPEAR1340_PCIE_MIPHY_CFG_MASK		0xF80000FF
> +	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
> +			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
> +			SPEAR1340_MIPHY_CLK_REF_DIV2 | \
> +			SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
> +	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
> +			(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
> +	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
> +			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
> +			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
> +
>  enum phy_mode {
>  	SATA,
>  	PCIE,
> @@ -50,6 +106,93 @@ struct miphy40lp_priv {
>  	const struct miphy40lp_plat_ops	*plat_ops;
>  };
>  
> +static int miphy40lp_spear1340_sata_init(struct miphy40lp_priv *priv)
> +{
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
> +			SPEAR1340_PCIE_SATA_CFG_MASK, SPEAR1340_SATA_CFG_VAL);
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
> +			SPEAR1340_PCIE_MIPHY_CFG_MASK,
> +			SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK);
> +	/* Switch on sata power domain */
> +	regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
> +			SPEAR1340_PCM_CFG_SATA_POWER_EN,
> +			SPEAR1340_PCM_CFG_SATA_POWER_EN);
> +	msleep(20);
> +	/* Disable PCIE SATA Controller reset */
> +	regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
> +			SPEAR1340_PERIP1_SW_RSATA, 0);
> +	msleep(20);
> +
> +	return 0;
> +}
> +
> +static int miphy40lp_spear1340_sata_exit(struct miphy40lp_priv *priv)
> +{
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
> +			SPEAR1340_PCIE_SATA_CFG_MASK, 0);
> +	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
> +			SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
> +
> +	/* Enable PCIE SATA Controller reset */
> +	regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
> +			SPEAR1340_PERIP1_SW_RSATA,
> +			SPEAR1340_PERIP1_SW_RSATA);
> +	msleep(20);
> +	/* Switch off sata power domain */
> +	regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
> +			SPEAR1340_PCM_CFG_SATA_POWER_EN, 0);
> +	msleep(20);
> +
> +	return 0;
> +}
> +
> +static int miphy40lp_spear1340_init(struct miphy40lp_priv *priv)
> +{
> +	int ret = 0;
> +
> +	if (priv->mode == SATA)
> +		ret = miphy40lp_spear1340_sata_init(priv);
> +
> +	return ret;
> +}
> +
> +static int miphy40lp_spear1340_exit(struct miphy40lp_priv *priv)
> +{
> +	int ret = 0;
> +
> +	if (priv->mode == SATA)
> +		ret = miphy40lp_spear1340_sata_exit(priv);
> +
> +	return ret;
> +}
> +
> +static int miphy40lp_spear1340_suspend(struct miphy40lp_priv *priv)
> +{
> +	int ret = 0;
> +
> +	if (priv->mode == SATA)
> +		ret = miphy40lp_spear1340_sata_exit(priv);
> +
> +	return ret;
> +}
> +
> +static int miphy40lp_spear1340_resume(struct miphy40lp_priv *priv)
> +{
> +	int ret = 0;
> +
> +	if (priv->mode == SATA)
> +		ret = miphy40lp_spear1340_sata_init(priv);
> +
> +	return ret;
> +}
> +
> +static struct miphy40lp_plat_ops spear1340_phy_ops = {
> +	.plat_init = miphy40lp_spear1340_init,
> +	.plat_exit = miphy40lp_spear1340_exit,
> +	.plat_suspend = miphy40lp_spear1340_suspend,
> +	.plat_resume = miphy40lp_spear1340_resume,
> +};
> +
>  static int miphy40lp_init(struct phy *phy)
>  {
>  	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
> @@ -100,6 +243,7 @@ static int miphy40lp_power_on(struct phy *phy)
>  
>  static const struct of_device_id miphy40lp_of_match[] = {
>  	{ .compatible = "st,miphy40lp-phy", .data = NULL },

Do we still need this compatible? Because it doesn't do anything anyways?

Thanks
Kishon

^ permalink raw reply

* [PATCH] ARM: mm: report both sections from PMD
From: Catalin Marinas @ 2014-02-11 11:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGXu5jL0asY2L9xvnEDwBPQoWYZAVHjtG+U7nyz=JfZtXFK34A@mail.gmail.com>

On Mon, Feb 10, 2014 at 05:26:28PM +0000, Kees Cook wrote:
> On Mon, Feb 10, 2014 at 2:41 AM, Catalin Marinas
> <catalin.marinas@arm.com> wrote:
> > On Mon, Feb 10, 2014 at 10:29:35AM +0000, Catalin Marinas wrote:
> >> On Sun, Feb 09, 2014 at 10:18:26PM +0000, Kees Cook wrote:
> >> > diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
> >> > index 1f7b1e13d945..ff1559f9200c 100644
> >> > --- a/arch/arm/mm/dump.c
> >> > +++ b/arch/arm/mm/dump.c
> >> > @@ -264,6 +264,9 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
> >> >                     note_page(st, addr, 3, pmd_val(*pmd));
> >> >             else
> >> >                     walk_pte(st, pmd, addr);
> >> > +
> >> > +           if (SECTION_SIZE < PMD_SIZE && pmd_sect(*pmd))
> >> > +                   note_page(st, addr + SECTION_SIZE, 3, pmd_val(pmd[1]));
> >>
> >> You can  use pmd_large() here as well.
> >>
> >> But I think this function is broken (the "for" statement not shown
> >> here). The pmd_t is 32-bit with classic MMU and it uses pmd++ while the
> >> address grows by PMD_SIZE (two pmd_t entries).
> >
> > Actually it's ok since PTRS_PER_PMD is 1, so it only goes through this
> > loop once.
> >
> > But in your patch shouldn't you check for pmd_large(*(pmd+1))? The first
> > pmd is already caught by the 'if' statement.
> 
> It wasn't clear to me what the logic should be here. If PTRS_PER_PMD
> is 1, then why is there this second pmd after the first? Shouldn't
> PTRS_PER_PMD be 2 if that's the case?

The reason is that a hardware pte has only 256 entries (classic MMU),
this is 1KB. We put two pte tables together and it gives us 2KB. The
other 2KB in the page are used for Linux pte bits. Because we have two
hw pte tables in a page, we need two corresponding pmd entries.

A side effect is that even though we don't actually have a pmd (normally
we should have included pgtable-nopmd.h), we still pretend we have one
and __pmd_populate takes care of writing two consecutive entries. If we
set PTRS_PER_PMD to 2, we should modify pte_alloc_one() to allocate a
single hw pte (1KB + 1KB for software bits). I don't think this would be
more efficient (there may have been other kernel restrictions in the
past to require a full pte table page).

> If that's not the case, then I figured the state of needing to report
> the 2nd pmd depended on the type of the first one, so that's what I
> wrote instead of trying to figure out why PTRS_PER_PMD wasn't 2.

I don't remember whether we can have the first pmd being a table and the
second one being a section. I don't think we restrict this but Russell
should know more.

> There's clearly something I'm not understanding in here. :)

I happen to understand it from time to time but it doesn't last ;).

-- 
Catalin

^ permalink raw reply

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
From: Marek Szyprowski @ 2014-02-11 10:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210215929.4473BC408F7@trevor.secretlab.ca>


On 2014-02-10 22:59, Grant Likely wrote:
> On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > Hello,
> >
> > On 2014-02-05 11:15, Grant Likely wrote:
> > > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > > Enable reserved memory initialization from device tree.
> > > >
> > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > > ---
> > > >  arch/arm/mm/init.c |    3 +++
> > > >  1 file changed, 3 insertions(+)
> > > >
> > > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > > index 804d61566a53..ebafdb479410 100644
> > > > --- a/arch/arm/mm/init.c
> > > > +++ b/arch/arm/mm/init.c
> > > > @@ -17,6 +17,7 @@
> > > >  #include <linux/nodemask.h>
> > > >  #include <linux/initrd.h>
> > > >  #include <linux/of_fdt.h>
> > > > +#include <linux/of_reserved_mem.h>
> > > >  #include <linux/highmem.h>
> > > >  #include <linux/gfp.h>
> > > >  #include <linux/memblock.h>
> > > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > > >  	if (mdesc->reserve)
> > > >  		mdesc->reserve();
> > > >
> > > > +	early_init_dt_scan_reserved_mem();
> > > > +
> > >
> > > The new binding is being made fundamental. If the reserved-memory node
> > > is present, then it needs to be honored, even if the kernel doesn't know
> > > how to use the regions. Therefore, This needs to be unconditional for
> > > all architectures. The hook should be called in early_init_dt_scan()
> > > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > > hook.
> >
> > In theory this will be the best solution, but it practice there is a
> > problem. early_init_dt_scan() is called as the first function from kernel
> > booting code. That time there is no memory yet added to the system, so it
> > would be really hard to reserve anything. Memory nodes are being added
> > later either with memblock_add() or by some other arch specific way.
>
> Hmmm, depends on the architecture. On ARM the memory is loaded into the
> meminfo structure first, and it isn't until arm_memblock_init() that
> memblock_add() gets called on all the regions. Some architectures do the
> memblock_add() directly from early_init_dt_add_memory_arch() function.
>
> The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
> overridden by ARM and a number of other architectures. However...
>
> > Finally, once all memory has been added to the system we can parse and
> > reserve all regions defined in the device tree. This really requires
> > creating another function which will be called by arch specific code.
>
> ...Or it means getting rid of meminfo entirely so that memblock is
> available earlier. Laura Abbott has just posted v2 of her series to do
> exactly that. If you base on that then you should be able to do exactly
> what I suggested.

I've checked Laura's patches and in fact it is possible to do memory
reservation as a last step in early_init_dt_scan_memory(). However still
see some problem which I have no idea how to resolve. Right now I focus
only on ARM, so I have no idea how it is solved by other architectures.
On of the key features of the new binding is the ability to automatically
allocate reserved regions of the given size. However kernel, initrd, dt
and other sub-arch specific critical regions are marked/allocated in
arm_memblock_init(), which is called after setup_machine_fdt(). This
might lead to some serious failures when automatically reserved region
overlaps with some critical resources. Do you have any idea how to solve
this without a new callback?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox