Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* PROBLEM: Hard lockup on Armada-385 with mvebu-mbus driver
From: Gregory CLEMENT @ 2017-12-20 17:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e120203dd2d847e0844133f8fa460fa5@svr-chch-ex1.atlnz.lc>

Hi Joshua,
 
 On mar., d?c. 19 2017, Joshua Scott <Joshua.Scott@alliedtelesis.co.nz> wrote:

> Hard lockup on Armada-385 with mvebu-mbus driver.
>
>
> Hi,
>
>
> We've come across an issue where we get a hard lockup (no more console output, JTAG debugger unable to connect) after receiving CPU traffic from a Marvell switch-chip (connected via PCI). The issue usually occurs within a minute of beginning the traffic stream. The issue only occurs when both cores of the processor are enabled, switching to single-core, the issue is unreproducible.
>
>
> Comparing the kernel we are using (4.4.6) to the one supplied by Marvell (where the issue does not occur), we were able to narrow the minimal change to fix the issue to the following:
>
>
> diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
> index c43c3d2baf..9e6b94cdef 100644
> --- a/drivers/bus/mvebu-mbus.c
> +++ b/drivers/bus/mvebu-mbus.c
> @@ -349,8 +349,6 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
>                 (attr << WIN_CTRL_ATTR_SHIFT)    |
>                 (target << WIN_CTRL_TGT_SHIFT)   |
>                 WIN_CTRL_ENABLE;
> -       if (mbus->hw_io_coherency)
> -               ctrl |= WIN_CTRL_SYNCBARRIER;
>

Without this then you have no more assurance that the dma transfer will
be coherent. I might be wrong but I am pretty sure it was the reason of
this bit. In the vendor kernel there are other changes around the MMU
configuration (that are not possible in mainline) that allow to not use
this bit. Maybe Thomas will be able to say more about it.


>         writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF);
>         writel(ctrl, addr + WIN_CTRL_OFF);
> @@ -1082,10 +1080,6 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
>         mbus->soc->setup_cpu_target(mbus);
>         mvebu_mbus_setup_cpu_target_nooverlap(mbus);
>  
> -       if (is_coherent)
> -               writel(UNIT_SYNC_BARRIER_ALL,
> -                      mbus->mbuswins_base + UNIT_SYNC_BARRIER_OFF);
> -
>         register_syscore_ops(&mvebu_mbus_syscore_ops);
>  
>         return 0;
>
>
> While we're not currently running the latest upstream kernel, it does appear that the offending lines above are still present in the latest upstream kernel. We're not yet sure exactly why this fixes the issue, but on our platform at least it does resolve the issue we were seeing.
>
>
> The main purpose of this email is to get the ball rolling on having
> this fix upstreamed, and perhaps to hear back from anyone involved
> with this code.


Recently I submitted some fixes in the dts to configure the L2 cache in
order to avoid the hard lockup. Did you try it?

cda80a82ac3e ("ARM: dts: mvebu: pl310-cache disable double-linefill")

It was merged at the end of the 4.14-rc released and is part of the 4.14
release now.

This patch is very ea sly backportable.

Gregory

>
>
>
> Cheers,
>
> Joshua Scott
>
>
>
> Environment:
>
>
> [root at awplus flash]# cat /proc/cpuinfo
> processor       : 0
> model name      : ARMv7 Processor rev 1 (v7l)
> BogoMIPS        : 50.00
> Features        : half thumb fastmult vfp edsp vfpv3 tls vfpd32
> CPU implementer : 0x41
> CPU architecture: 7
> CPU variant     : 0x4
> CPU part        : 0xc09
> CPU revision    : 1
>
> processor       : 1
> model name      : ARMv7 Processor rev 1 (v7l)
> BogoMIPS        : 50.00
> Features        : half thumb fastmult vfp edsp vfpv3 tls vfpd32
> CPU implementer : 0x41
> CPU architecture: 7
> CPU variant     : 0x4
> CPU part        : 0xc09
> CPU revision    : 1
>
> Hardware        : Marvell Armada 380/385 (Device Tree)
> Revision        : 0000
> Serial          : 0000000000000000
>
>
>
> [root at awplus flash]# cat /proc/modules
> tipc 115327 248 - Live 0x7f0c3000
> ip6_udp_tunnel 1679 1 tipc, Live 0x7f0bf000
> udp_tunnel 2053 1 tipc, Live 0x7f0bb000
> br_netfilter 12045 0 - Live 0x7f0b5000
> sha256_generic 8941 0 - Live 0x7f0af000
> jitterentropy_rng 5909 0 - Live 0x7f0aa000
> echainiv 2007 0 - Live 0x7f0a6000
> drbg 13108 0 - Live 0x7f09f000
> platform_driver 98540 1 - Live 0x7f048000 (O)
> ipifwd 239474 18 platform_driver,[permanent], Live 0x7f000000 (PO)
>
>
>
> [root at awplus flash]# cat /proc/ioports
> 00001000-000fffff : PCI I/O
>
>
>
> [root at awplus flash]# cat /proc/iomem
> 00000000-3fffffff : System RAM
>   00008000-00628aab : Kernel code
>   00666000-006b3087 : Kernel data
> a0000000-dfffffff : PCI MEM
>   a0000000-a5ffffff : PCI Bus 0000:01
>     a0000000-a3ffffff : 0000:01:00.0
>       a0000000-a3ffffff : prestera
>     a4000000-a47fffff : 0000:01:00.0
>       a4000000-a47fffff : prestera
>     a4800000-a48fffff : 0000:01:00.0
>       a4800000-a48fffff : prestera
> f1010410-f1010417 : /soc/devbus-cs1
> f1010680-f10106cf : /soc/internal-regs/spi at 10680
> f1011000-f101101f : /soc/internal-regs/i2c at 11000
> f1012000-f101201f : serial
> f1018000-f101801f : /soc/internal-regs/pinctrl at 18000
> f1018100-f101813f : /soc/internal-regs/gpio at 18100
> f1018140-f101817f : /soc/internal-regs/gpio at 18140
> f1020704-f1020707 : /soc/internal-regs/watchdog at 20300
> f1020800-f102080f : /soc/internal-regs/cpurst at 20800
> f1020a00-f1020ccf : /soc/internal-regs/interrupt-controller at 20a00
> f1021070-f10210c7 : /soc/internal-regs/interrupt-controller at 20a00
> f1022000-f1022fff : /soc/internal-regs/pmsu at 22000
> f1058000-f10584ff : /soc/internal-regs/usb at 58000
> f1080000-f1081fff : /soc/pcie-controller/pcie at 1,0
> f10d0000-f10d0053 : /soc/internal-regs/flash at d0000
> f4800000-f487ffff : f4800000.nvs
>
>
> [root at awplus flash]# lspci -vvv
> 00:01.0 Class 0604: Device 11ab:6820 (rev 04)
>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
>         Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0, Cache Line Size: 64 bytes
>         Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
>         I/O behind bridge: 0000f000-00000fff [empty]
>         Memory behind bridge: a0000000-a5ffffff [size=96M]
>         Prefetchable memory behind bridge: 00000000-000fffff [size=1M]
>         Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
>         BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
>                 PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
>         Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
>                 DevCap: MaxPayload 128 bytes, PhantFunc 0
>                         ExtTag- RBE+
>                 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
>                         RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
>                         MaxPayload 128 bytes, MaxReadReq 512 bytes
>                 DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
>                 LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <256ns, L1 unlimited
>                         ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
>                 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
>                         ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
>                 LnkSta: Speed 5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
>                 SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
>                         Slot #0, PowerLimit 0.000W; Interlock- NoCompl-
>                 SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
>                         Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
>                 SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
>                         Changed: MRL- PresDet- LinkState-
>                 RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
>                 RootCap: CRSVisible-
>                 RootSta: PME ReqID 0000, PMEStatus- PMEPending-
>                 DevCap2: Completion Timeout: Not Supported, TimeoutDis-, LTR-, OBFF Not Supported ARIFwd-
>                 AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
>                 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled ARIFwd-
>                 AtomicOpsCtl: ReqEn- EgressBlck-
>                 LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
>                          Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
>                          Compliance De-emphasis: -6dB
>                 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
>                          EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
>
> 01:00.0 Class 0200: Device 11ab:c804
>         Subsystem: Device 11ab:11ab
>         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
>         Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0, Cache Line Size: 64 bytes
>         Interrupt: pin A routed to IRQ 101
>         Region 0: Memory at a4800000 (64-bit, prefetchable) [size=1M]
>         Region 2: Memory at a0000000 (64-bit, prefetchable) [size=64M]
>         Region 4: Memory at a4000000 (64-bit, prefetchable) [size=8M]
>         Capabilities: [40] Power Management version 3
>                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
>                 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
>                 Address: 0000000000000000  Data: 0000
>         Capabilities: [60] Express (v2) Legacy Endpoint, MSI 00
>                 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <256ns, L1 <1us
>                         ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
>                 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
>                         RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
>                         MaxPayload 128 bytes, MaxReadReq 512 bytes
>                 DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
>                 LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <256ns, L1 unlimited
>                         ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp-
>                 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
>                         ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
>                 LnkSta: Speed 5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
>                 DevCap2: Completion Timeout: Not Supported, TimeoutDis-, LTR-, OBFF Not Supported
>                 AtomicOpsCap: 32bit- 64bit- 128bitCAS-
>                 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
>                 AtomicOpsCtl: ReqEn-
>                 LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
>                          Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
>                          Compliance De-emphasis: -6dB
>                 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
>                          EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
>         Capabilities: [100 v1] Advanced Error Reporting
>                 UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>                 UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>                 UESvrt: DLP+ SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
>                 CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
>                 CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
>                 AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-
>         Kernel driver in use: ATL Marvell CPSS PCI
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH v2] ARM: dts: imx7d-pico-pi: Separate into cpu and baseboard dts
From: Shawn Guo @ 2017-12-20 15:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1512064517-4144-1-git-send-email-vanessa.maegima@nxp.com>

On Thu, Nov 30, 2017 at 03:55:17PM -0200, Vanessa Maegima wrote:
> Separate the old imx7d-pico into cpu (imx7d-pico.dtsi) and baseboard
> (imx7d-pico-pi.dts) dts so the same cpu dtsi can be used in different
> baseboards variants.
> 
> Signed-off-by: Vanessa Maegima <vanessa.maegima@nxp.com>

Applied, thanks.

^ permalink raw reply

* [PATCH v2 01/11] ARM: dts: imx53: Move nodes which have no reg property out of bus
From: Shawn Guo @ 2017-12-20 15:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1511981684-13433-1-git-send-email-festevam@gmail.com>

On Wed, Nov 29, 2017 at 04:54:34PM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@nxp.com>
> 
> Move pmu, usbphy0 and usbphy1 nodes from soc node to root node.
> 
> The nodes that have been moved do not have any register properties and thus
> shouldn't be placed on the bus.
> 
> This fixes the following build warnings with W=1:
> 
> arch/arm/boot/dts/imx53-ard.dtb: Warning (unit_address_vs_reg): Node /memory has a reg or ranges property, but no unit name
> arch/arm/boot/dts/imx53-ard.dtb: Warning (simple_bus_reg): Node /soc/aips at 50000000/usbphy-0 missing or empty reg/ranges property
> arch/arm/boot/dts/imx53-ard.dtb: Warning (simple_bus_reg): Node /soc/aips at 50000000/usbphy-1 missing or empty reg/ranges property
> arch/arm/boot/dts/imx53-ard.dtb: Warning (simple_bus_reg): Node /soc/pmu missing or empty reg/ranges property
> 
> Based on a patch from Simon Horman for r8a7795.dtsi.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>

Applied all, thanks.

^ permalink raw reply

* [PATCH 2/2] mtd: spi-nor: cadence-quadspi: Add support for direct access mode
From: Cyrille Pitchen @ 2017-12-20 15:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171207063804.29436-3-vigneshr@ti.com>

Hi Vignesh,

Le 07/12/2017 ? 07:38, Vignesh R a ?crit :
> Cadence QSPI controller provides direct access mode through which flash
> can be accessed in a memory-mapped IO mode. This enables read/write to
> flash using memcpy*() functions. This mode provides higher throughput
> for both read/write operations when compared to current indirect mode of
> operation.
> 
> This patch therefore adds support to use QSPI in direct mode. If the
> window reserved in SoC's memory map for MMIO access is less that of
> flash size(like on most SoCFPGA variants), then the driver falls back
> to indirect mode of operation.
> 
> On TI's 66AK2G SoC, with ARM running at 600MHz and QSPI at 96MHz
> switching to direct mode improves read throughput from 3MB/s to 8MB/s.
> 
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/cadence-quadspi.c | 52 +++++++++++++++++++++++++++++++++--
>  1 file changed, 50 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
> index becc7d714ab8..f8721ed68bc6 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -58,6 +58,7 @@ struct cqspi_flash_pdata {
>  	u8		data_width;
>  	u8		cs;
>  	bool		registered;
> +	bool		use_direct_mode;
>  };
>  
>  struct cqspi_st {
> @@ -68,6 +69,7 @@ struct cqspi_st {
>  
>  	void __iomem		*iobase;
>  	void __iomem		*ahb_base;
> +	resource_size_t		ahb_size;
>  	struct completion	transfer_complete;
>  	struct mutex		bus_mutex;
>  
> @@ -103,6 +105,7 @@ struct cqspi_st {
>  /* Register map */
>  #define CQSPI_REG_CONFIG			0x00
>  #define CQSPI_REG_CONFIG_ENABLE_MASK		BIT(0)
> +#define CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL	BIT(7)
>  #define CQSPI_REG_CONFIG_DECODE_MASK		BIT(9)
>  #define CQSPI_REG_CONFIG_CHIPSELECT_LSB		10
>  #define CQSPI_REG_CONFIG_DMA_MASK		BIT(15)
> @@ -569,6 +572,21 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
>  	return ret;
>  }
>  
> +static int cqspi_direct_read_execute(struct spi_nor *nor, u8 *rxbuf,
> +				     loff_t from_addr, const size_t len)
> +{
> +	struct cqspi_flash_pdata *f_pdata = nor->priv;
> +	struct cqspi_st *cqspi = f_pdata->cqspi;
> +	u32 reg;
> +
> +	reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
> +	reg |= CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL;
> +	writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);

I guess setting the ENB_DIR_ACC_CTRL bit could be set once for all when you
set use_direct_mode to true, couldn't it?

It may improve the read performance even more. However not expecting much
difference for Page Program operations.

Then you could call directly call mempcy_fromio() from cqspi_read().
Not mandatory for me, since I also like the symmetry of the 2 functions:
cqspi_direct_read_execute() / cqspi_indirect_read_execute().

So it's up to you :)

> +	memcpy_fromio(rxbuf, cqspi->ahb_base + from_addr, len);
> +
> +	return 0;
> +}
> +
>  static int cqspi_write_setup(struct spi_nor *nor)
>  {
>  	unsigned int reg;
> @@ -671,6 +689,21 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
>  	return ret;
>  }
>  
> +static int cqspi_direct_write_execute(struct spi_nor *nor, loff_t to_addr,
> +				      const u8 *txbuf, const size_t len)
> +{
> +	struct cqspi_flash_pdata *f_pdata = nor->priv;
> +	struct cqspi_st *cqspi = f_pdata->cqspi;
> +	u32 reg;
> +
> +	reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
> +	reg |= CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL;
> +	writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);

Same comment here.

> +	memcpy_toio(cqspi->ahb_base + to_addr, txbuf, len);
> +
> +	return 0;
> +}
> +
>  static void cqspi_chipselect(struct spi_nor *nor)
>  {
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
> @@ -891,6 +924,7 @@ static int cqspi_set_protocol(struct spi_nor *nor, const int read)
>  static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  			   size_t len, const u_char *buf)
>  {
> +	struct cqspi_flash_pdata *f_pdata = nor->priv;
>  	int ret;
>  
>  	ret = cqspi_set_protocol(nor, 0);
> @@ -901,7 +935,10 @@ static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_write_execute(nor, to, buf, len);
> +	if (f_pdata->use_direct_mode)
> +		ret = cqspi_direct_write_execute(nor, to, buf, len);
> +	else
> +		ret = cqspi_indirect_write_execute(nor, to, buf, len);
>  	if (ret)
>  		return ret;
>  
> @@ -911,6 +948,7 @@ static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>  			  size_t len, u_char *buf)
>  {
> +	struct cqspi_flash_pdata *f_pdata = nor->priv;
>  	int ret;
>  
>  	ret = cqspi_set_protocol(nor, 1);
> @@ -921,7 +959,10 @@ static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_read_execute(nor, buf, from, len);
> +	if (f_pdata->use_direct_mode)
> +		ret = cqspi_direct_read_execute(nor, buf, from, len);
> +	else
> +		ret = cqspi_indirect_read_execute(nor, buf, from, len);
>  	if (ret)
>  		return ret;
>  
> @@ -1153,6 +1194,12 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np)
>  			goto err;
>  
>  		f_pdata->registered = true;
> +
> +		if (mtd->size <= cqspi->ahb_size) {
> +			f_pdata->use_direct_mode = true;
> +			dev_info(nor->dev, "using direct mode for %s\n",
> +				 mtd->name);

Please use dev_dbg() here insted of dev_info(). IMHO, this kind of output
is not really needed by regular users.

Otherwise, the series looks great!

Best regards,

Cyrille

> +		}
>  	}
>  
>  	return 0;
> @@ -1212,6 +1259,7 @@ static int cqspi_probe(struct platform_device *pdev)
>  		dev_err(dev, "Cannot remap AHB address.\n");
>  		return PTR_ERR(cqspi->ahb_base);
>  	}
> +	cqspi->ahb_size = resource_size(res_ahb);
>  
>  	init_completion(&cqspi->transfer_complete);
>  
> 

^ permalink raw reply

* [PATCH 1/2] mtd: spi-nor: cadence-quadspi: Refactor indirect read/write sequence.
From: Cyrille Pitchen @ 2017-12-20 15:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171207063804.29436-2-vigneshr@ti.com>

Hi Vignesh,

Le 07/12/2017 ? 07:38, Vignesh R a ?crit?:
> Move configuring of indirect read/write start address to
> cqspi_indirect_*_execute() function and rename cqspi_indirect_*_setup()
> function. This will help to reuse cqspi_indirect_*_setup() function for
> supporting direct access mode.
> 
> Signed-off-by: Vignesh R <vigneshr@ti.com>

This patch looks good to me.

Best regards,

Cyrille

> ---
>  drivers/mtd/spi-nor/cadence-quadspi.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
> index 75a2bc447a99..becc7d714ab8 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -450,8 +450,7 @@ static int cqspi_command_write_addr(struct spi_nor *nor,
>  	return cqspi_exec_flash_cmd(cqspi, reg);
>  }
>  
> -static int cqspi_indirect_read_setup(struct spi_nor *nor,
> -				     const unsigned int from_addr)
> +static int cqspi_read_setup(struct spi_nor *nor)
>  {
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
>  	struct cqspi_st *cqspi = f_pdata->cqspi;
> @@ -459,7 +458,6 @@ static int cqspi_indirect_read_setup(struct spi_nor *nor,
>  	unsigned int dummy_clk = 0;
>  	unsigned int reg;
>  
> -	writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
>  
>  	reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
>  	reg |= cqspi_calc_rdreg(nor, nor->read_opcode);
> @@ -493,8 +491,8 @@ static int cqspi_indirect_read_setup(struct spi_nor *nor,
>  	return 0;
>  }
>  
> -static int cqspi_indirect_read_execute(struct spi_nor *nor,
> -				       u8 *rxbuf, const unsigned n_rx)
> +static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
> +				       loff_t from_addr, const size_t n_rx)
>  {
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
>  	struct cqspi_st *cqspi = f_pdata->cqspi;
> @@ -504,6 +502,7 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor,
>  	unsigned int bytes_to_read = 0;
>  	int ret = 0;
>  
> +	writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
>  	writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES);
>  
>  	/* Clear all interrupts. */
> @@ -570,8 +569,7 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor,
>  	return ret;
>  }
>  
> -static int cqspi_indirect_write_setup(struct spi_nor *nor,
> -				      const unsigned int to_addr)
> +static int cqspi_write_setup(struct spi_nor *nor)
>  {
>  	unsigned int reg;
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
> @@ -584,8 +582,6 @@ static int cqspi_indirect_write_setup(struct spi_nor *nor,
>  	reg = cqspi_calc_rdreg(nor, nor->program_opcode);
>  	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
>  
> -	writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
> -
>  	reg = readl(reg_base + CQSPI_REG_SIZE);
>  	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
>  	reg |= (nor->addr_width - 1);
> @@ -593,8 +589,8 @@ static int cqspi_indirect_write_setup(struct spi_nor *nor,
>  	return 0;
>  }
>  
> -static int cqspi_indirect_write_execute(struct spi_nor *nor,
> -					const u8 *txbuf, const unsigned n_tx)
> +static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
> +					const u8 *txbuf, const size_t n_tx)
>  {
>  	const unsigned int page_size = nor->page_size;
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
> @@ -604,6 +600,7 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor,
>  	unsigned int write_bytes;
>  	int ret;
>  
> +	writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
>  	writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES);
>  
>  	/* Clear all interrupts. */
> @@ -900,11 +897,11 @@ static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_write_setup(nor, to);
> +	ret = cqspi_write_setup(nor);
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_write_execute(nor, buf, len);
> +	ret = cqspi_indirect_write_execute(nor, to, buf, len);
>  	if (ret)
>  		return ret;
>  
> @@ -920,11 +917,11 @@ static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_read_setup(nor, from);
> +	ret = cqspi_read_setup(nor);
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_read_execute(nor, buf, len);
> +	ret = cqspi_indirect_read_execute(nor, buf, from, len);
>  	if (ret)
>  		return ret;
>  
> 

^ permalink raw reply

* [PATCH] ARM: mediatek: use more generic prompts for SoCs with ARMv7
From: Matthias Brugger @ 2017-12-20 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e118518cb3ab8bf0ae45669b003153dc1a49ba2f.1513589301.git.sean.wang@mediatek.com>



On 12/18/2017 10:39 AM, sean.wang at mediatek.com wrote:
> From: Sean Wang <sean.wang@mediatek.com>
> 
> Supported MediaTek SoCs with ARMv7 are not limited within MT65xx or MT81xx
> and thus use more generic words to prompt users as the other vendors
> usually use.
> 
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> ---
>  arch/arm/mach-mediatek/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
> index 70e49d5..91cc461 100644
> --- a/arch/arm/mach-mediatek/Kconfig
> +++ b/arch/arm/mach-mediatek/Kconfig
> @@ -1,5 +1,5 @@
>  menuconfig ARCH_MEDIATEK
> -	bool "Mediatek MT65xx & MT81xx SoC"
> +	bool "MediaTek SoC Support"
>  	depends on ARCH_MULTI_V7
>  	select ARM_GIC
>  	select PINCTRL
> 

Applied to v4.15-next/soc

Thanks!

^ permalink raw reply

* [PATCH v1 4/4] arm64: dts: mediatek: add mt2712 cpufreq related device nodes
From: Matthias Brugger @ 2017-12-20 14:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7730089.t6jDuHQEn5@aspire.rjw.lan>



On 12/17/2017 07:05 PM, Rafael J. Wysocki wrote:
> On Tuesday, December 12, 2017 10:34:42 AM CET Matthias Brugger wrote:
>> Hi,
>>
>> On 12/12/2017 08:26 AM, Viresh Kumar wrote:
>>> On 12-12-17, 02:17, Rafael J. Wysocki wrote:
>>>> On Monday, December 11, 2017 8:57:19 AM CET Viresh Kumar wrote:
>>>>> On 08-12-17, 14:07, Andrew-sh Cheng wrote:
>>>>>> Add opp v2 information,
>>>>>> and also add clocks, regulators and opp information into cpu nodes
>>>>>>
>>>>>> Signed-off-by: Andrew-sh Cheng <andrew-sh.cheng@mediatek.com>
>>>>>> ---
>>>>>>  arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 27 ++++++++++++++
>>>>>>  arch/arm64/boot/dts/mediatek/mt2712e.dtsi   | 57 +++++++++++++++++++++++++++++
>>>>>>  2 files changed, 84 insertions(+)
>>>>>
>>>>> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
>>>>
>>>> Of course, DT bindings require ACKs from DT maintainers to be applied.
>>>
>>> I didn't knew that we need Acks from DT maintainers for dts files as well? Yeah,
>>> its very much required while defining new bindings for sure.
>>>
>>
>> I will take the dts parts through the Mediatek SoC tree, so you don't have to
>> worry about them.
>>
>> Please let me know when you take patch 1 and 2.
> 
> Applied now, thanks!
> 
> Do you need the branch containing them to be exposed?
> 

No, that's not necessary.

I pushed the two patches to v4.15-next/dts64 now.

^ permalink raw reply

* [PATCH V2 02/10] clk: reparent orphans after critical clocks enabled
From: Dong Aisheng @ 2017-12-20 14:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171102073609.GT30645@codeaurora.org>

On Thu, Nov 02, 2017 at 12:36:09AM -0700, Stephen Boyd wrote:
> On 07/13, Dong Aisheng wrote:
> > The orphan clocks reparent operation should be moved after the critical
> > clocks enabled, otherwise it may get a chance to disable a newly
> > registered critical clock which triggers the following warning.
> > 
> > Assuming we have two clocks: A and B, B is the parent of A.
> > Clock A has flag: CLK_OPS_PARENT_ENABLE
> > Clock B has flag: CLK_IS_CRITICAL
> > 
> > Step 1:
> > Clock A is registered, then it becomes orphan.
> > 
> > Step 2:
> > Clock B is registered. Before clock B reach the critical clock enable
> > operation, orphan A will find the newly registered parent B and do
> > reparent operation, then parent B will be finally disabled in
> > __clk_set_parent_after() due to CLK_OPS_PARENT_ENABLE flag as there's
> > still no users of B which will then trigger the following warning.
> > 
> > [    0.000000] WARNING: CPU: 0 PID: 0 at drivers/clk/clk.c:597 clk_core_disable+0xb4/0xe0
> > [    0.000000] Modules linked in:
> > [    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.11.0-rc1-00056-gdff1f66-dirty #1373
> > [    0.000000] Hardware name: Generic DT based system
> > [    0.000000] Backtrace:
> > [    0.000000] [<c010c4bc>] (dump_backtrace) from [<c010c764>] (show_stack+0x18/0x1c)
> > [    0.000000]  r6:600000d3 r5:00000000 r4:c0e26358 r3:00000000
> > [    0.000000] [<c010c74c>] (show_stack) from [<c040599c>] (dump_stack+0xb4/0xe8)
> > [    0.000000] [<c04058e8>] (dump_stack) from [<c0125c94>] (__warn+0xd8/0x104)
> > [    0.000000]  r10:c0c21cd0 r9:c048aa78 r8:00000255 r7:00000009 r6:c0c1cd90 r5:00000000
> > [    0.000000]  r4:00000000 r3:c0e01d34
> > [    0.000000] [<c0125bbc>] (__warn) from [<c0125d74>] (warn_slowpath_null+0x28/0x30)
> > [    0.000000]  r9:00000000 r8:ef00bf80 r7:c165ac4c r6:ef00bf80 r5:ef00bf80 r4:ef00bf80
> > [    0.000000] [<c0125d4c>] (warn_slowpath_null) from [<c048aa78>] (clk_core_disable+0xb4/0xe0)
> > [    0.000000] [<c048a9c4>] (clk_core_disable) from [<c048be88>] (clk_core_disable_lock+0x20/0x2c)
> > [    0.000000]  r4:000000d3 r3:c0e0af00
> > [    0.000000] [<c048be68>] (clk_core_disable_lock) from [<c048c224>] (clk_core_disable_unprepare+0x14/0x28)
> > [    0.000000]  r5:00000000 r4:ef00bf80
> > [    0.000000] [<c048c210>] (clk_core_disable_unprepare) from [<c048c270>] (__clk_set_parent_after+0x38/0x54)
> > [    0.000000]  r4:ef00bd80 r3:000010a0
> > [    0.000000] [<c048c238>] (__clk_set_parent_after) from [<c048daa8>] (clk_register+0x4d0/0x648)
> > [    0.000000]  r6:ef00d500 r5:ef00bf80 r4:ef00bd80 r3:ef00bfd4
> > [    0.000000] [<c048d5d8>] (clk_register) from [<c048dc30>] (clk_hw_register+0x10/0x1c)
> > [    0.000000]  r9:00000000 r8:00000003 r7:00000000 r6:00000824 r5:00000001 r4:ef00d500
> > [    0.000000] [<c048dc20>] (clk_hw_register) from [<c048e698>] (_register_divider+0xcc/0x120)
> > [    0.000000] [<c048e5cc>] (_register_divider) from [<c048e730>] (clk_register_divider+0x44/0x54)
> > [    0.000000]  r10:00000004 r9:00000003 r8:00000001 r7:00000000 r6:00000003 r5:00000001
> > [    0.000000]  r4:f0810030
> > [    0.000000] [<c048e6ec>] (clk_register_divider) from [<c0d3ff58>] (imx7ulp_clocks_init+0x558/0xe98)
> > [    0.000000]  r7:c0e296f8 r6:c165c808 r5:00000000 r4:c165c808
> > [    0.000000] [<c0d3fa00>] (imx7ulp_clocks_init) from [<c0d24db0>] (of_clk_init+0x118/0x1e0)
> > [    0.000000]  r10:00000001 r9:c0e01f68 r8:00000000 r7:c0e01f60 r6:ef7f8974 r5:ef0035c0
> > [    0.000000]  r4:00000006
> > [    0.000000] [<c0d24c98>] (of_clk_init) from [<c0d04a50>] (time_init+0x2c/0x38)
> > [    0.000000]  r10:efffed40 r9:c0d61a48 r8:c0e78000 r7:c0e07900 r6:ffffffff r5:c0e78000
> > [    0.000000]  r4:00000000
> > [    0.000000] [<c0d04a24>] (time_init) from [<c0d00b8c>] (start_kernel+0x218/0x394)
> > [    0.000000] [<c0d00974>] (start_kernel) from [<6000807c>] (0x6000807c)
> > [    0.000000]  r10:00000000 r9:410fc075 r8:6000406a r7:c0e0c930 r6:c0d61a44 r5:c0e07918
> > [    0.000000]  r4:c0e78294
> > [    0.000000] ---[ end trace 0000000000000000 ]---
> 
> Please remove timestamps from logs unless they're important.
> 

Got it.

> > 
> > Fixes: fc8726a2c021 ("clk: core: support clocks which requires parents enable (part 2)")
> > Cc: Stephen Boyd <sboyd@codeaurora.org>
> > Cc: Michael Turquette <mturquette@baylibre.com>
> > Cc: Shawn Guo <shawnguo@kernel.org>
> > Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> > 
> > ---
> > ChangeLog:
> > v1->v2:
> >  * add more detailed commit messages
> 
> Thanks for that. We shouldn't be touching the hardware during clk
> registration though, so something is wrong there. It seems that
> adding the flag to enable clks when touching their registers has
> exposed that we should just be doing the toggle of the bookeeping
> stuff underneath the enable lock here.
> 
> We know that the clk isn't enabled with any sort of prepare_count
> here so we don't need to enable anything to prevent a race. And
> we're holding the prepare mutex so set_rate/set_parent can't race
> here either.
> 

Well, it looks like a good suggestion and it does make sense.

> Can you try this patch instead?
> 
> ---8<----
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index c8d83acda006..416d44cc772c 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2476,14 +2476,17 @@ static int __clk_core_init(struct clk_core *core)
>  	 */
>  	hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
>  		struct clk_core *parent = __clk_init_parent(orphan);
> +		unsigned long flags;
>  
>  		/*
>  		 * we could call __clk_set_parent, but that would result in a
>  		 * redundant call to the .set_rate op, if it exists
>  		 */
>  		if (parent) {
> -			__clk_set_parent_before(orphan, parent);
> -			__clk_set_parent_after(orphan, parent, NULL);
> +			/* update the clk tree topology */
> +			flags = clk_enable_lock();
> +			clk_reparent(orphan, parent);
> +			clk_enable_unlock(flags);
>  			__clk_recalc_accuracies(orphan);
>  			__clk_recalc_rates(orphan, 0);
>  		}


I tested this change worked well.
I could resent the patch with this new method later.

Regards
Dong Aisheng

^ permalink raw reply

* [PATCH V2 01/10] clk: clk-divider: add CLK_DIVIDER_ZERO_GATE clk support
From: Dong Aisheng @ 2017-12-20 14:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171102075039.GU30645@codeaurora.org>

On Thu, Nov 02, 2017 at 12:50:39AM -0700, Stephen Boyd wrote:
> On 07/13, Dong Aisheng wrote:
> > diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
> > index 9bb472c..55f8c41 100644
> > --- a/drivers/clk/clk-divider.c
> > +++ b/drivers/clk/clk-divider.c
> > @@ -123,6 +123,9 @@ unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
> >  	struct clk_divider *divider = to_clk_divider(hw);
> >  	unsigned int div;
> >  
> > +	if (flags & CLK_DIVIDER_ZERO_GATE && !val)
> > +		return 0;
> > +
> >  	div = _get_div(table, val, flags, divider->width);
> >  	if (!div) {
> >  		WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
> > @@ -141,8 +144,13 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
> >  	struct clk_divider *divider = to_clk_divider(hw);
> >  	unsigned int val;
> >  
> > -	val = clk_readl(divider->reg) >> divider->shift;
> > -	val &= div_mask(divider->width);
> > +	if ((divider->flags & CLK_DIVIDER_ZERO_GATE) &&
> > +	    !clk_hw_is_enabled(hw)) {
> 
> This seems racy. Are we holding the register lock here?
> 

Would you please clarify what type of racy you mean?

Currently it only protects register write between set_rate and enable/disable,
and other register read are not protected.
e.g. in recalc_rate and is_enabled.

And i did see similar users, e.g.
drivers/clk/sunxi-ng/ccu_mult.c

Should we still need protect them here?

> > +		val = divider->cached_val;
> > +	} else {
> > +		val = clk_readl(divider->reg) >> divider->shift;
> > +		val &= div_mask(divider->width);
> > +	}
> >  
> >  	return divider_recalc_rate(hw, parent_rate, val, divider->table,
> >  				   divider->flags);
> > @@ -392,6 +400,12 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
> >  	value = divider_get_val(rate, parent_rate, divider->table,
> >  				divider->width, divider->flags);
> >  
> > +	if ((divider->flags & CLK_DIVIDER_ZERO_GATE) &&
> > +	    !clk_hw_is_enabled(hw)) {
> 
> Same racy comment here.
> 
> > +		divider->cached_val = value;
> > +		return 0;
> > +	}
> > +
> >  	if (divider->lock)
> >  		spin_lock_irqsave(divider->lock, flags);
> >  	else
> > @@ -414,10 +428,85 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
> >  	return 0;
> >  }
> >  
> > +static int clk_divider_enable(struct clk_hw *hw)
> > +{
> > +	struct clk_divider *divider = to_clk_divider(hw);
> > +	unsigned long flags = 0;
> > +	u32 val;
> > +
> > +	if (!(divider->flags & CLK_DIVIDER_ZERO_GATE))
> > +		return 0;
> 
> This is not good. We will always jump to these functions on
> enable/disable for a divider although 99.9% of all dividers that
> exist won't need to run this code at all.
> 

I absolutely understand this concern.

> Can you please move this logic into your own divider
> implementation? The flag can be added to the generic layer if
> necessary but I'd prefer to see this logic kept in the driver
> that uses it. If we get more than one driver doing the cached
> divider thing then we can think about moving it to the more
> generic place like here, but for now we should be able to keep
> this contained away from the basic types and handled by the
> quirky driver that needs it.
> 

If only for above issue, how about invent a clk_divider_gate_ops
to separate the users of normal divider and zero gate divider:

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 4ed516c..b51f3f9 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -125,6 +125,9 @@ unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
 
 	div = _get_div(table, val, flags, divider->width);
 	if (!div) {
+		if (flags & CLK_DIVIDER_ZERO_GATE)
+			return 0;
+
 		WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
 			"%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
 			clk_hw_get_name(hw));
@@ -148,6 +151,23 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
 				   divider->flags);
 }
 
+static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned int val;
+
+	if (!clk_hw_is_enabled(hw)) {
+		val = divider->cached_val;
+	} else {
+		val = clk_readl(divider->reg) >> divider->shift;
+		val &= div_mask(divider->width);
+	}
+
+	return divider_recalc_rate(hw, parent_rate, val, divider->table,
+				   divider->flags);
+}
+
 static bool _is_valid_table_div(const struct clk_div_table *table,
 							 unsigned int div)
 {
@@ -416,6 +436,89 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
+static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	int value;
+
+	if (!clk_hw_is_enabled(hw)) {
+		value = divider_get_val(rate, parent_rate, divider->table,
+					divider->width, divider->flags);
+		if (value < 0)
+			return value;
+
+		divider->cached_val = value;
+
+		return 0;
+	}
+
+	return clk_divider_set_rate(hw, rate, parent_rate);
+}
+
+static int clk_divider_enable(struct clk_hw *hw)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned long uninitialized_var(flags);
+	u32 val;
+
+	if (!divider->cached_val) {
+		pr_err("%s: no valid preset rate\n", clk_hw_get_name(hw));
+		return -EINVAL;
+	}
+
+	if (divider->lock)
+		spin_lock_irqsave(divider->lock, flags);
+	else
+		__acquire(divider->lock);
+
+	/* restore div val */
+	val = clk_readl(divider->reg);
+	val |= divider->cached_val << divider->shift;
+	clk_writel(val, divider->reg);
+
+	if (divider->lock)
+		spin_unlock_irqrestore(divider->lock, flags);
+	else
+		__release(divider->lock);
+
+	return 0;
+}
+
+static void clk_divider_disable(struct clk_hw *hw)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned long uninitialized_var(flags);
+	u32 val;
+
+	if (divider->lock)
+		spin_lock_irqsave(divider->lock, flags);
+	else
+		__acquire(divider->lock);
+
+	/* store the current div val */
+	val = clk_readl(divider->reg) >> divider->shift;
+	val &= div_mask(divider->width);
+	divider->cached_val = val;
+	clk_writel(0, divider->reg);
+
+	if (divider->lock)
+		spin_unlock_irqrestore(divider->lock, flags);
+	else
+		__release(divider->lock);
+}
+
+static int clk_divider_is_enabled(struct clk_hw *hw)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	u32 val;
+
+	val = clk_readl(divider->reg) >> divider->shift;
+	val &= div_mask(divider->width);
+
+	return val ? 1 : 0;
+}
+
 const struct clk_ops clk_divider_ops = {
 	.recalc_rate = clk_divider_recalc_rate,
 	.round_rate = clk_divider_round_rate,
@@ -423,6 +526,16 @@ const struct clk_ops clk_divider_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ops);
 
+const struct clk_ops clk_divider_gate_ops = {
+	.recalc_rate = clk_divider_gate_recalc_rate,
+	.round_rate = clk_divider_round_rate,
+	.set_rate = clk_divider_gate_set_rate,
+	.enable = clk_divider_enable,
+	.disable = clk_divider_disable,
+	.is_enabled = clk_divider_is_enabled,
+};
+EXPORT_SYMBOL_GPL(clk_divider_gate_ops);
+
 const struct clk_ops clk_divider_ro_ops = {
 	.recalc_rate = clk_divider_recalc_rate,
 	.round_rate = clk_divider_round_rate,
@@ -438,6 +551,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
 	struct clk_divider *div;
 	struct clk_hw *hw;
 	struct clk_init_data init;
+	u32 val;
 	int ret;
 
 	if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
@@ -455,6 +569,8 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
 	init.name = name;
 	if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
 		init.ops = &clk_divider_ro_ops;
+	else if (clk_divider_flags & CLK_DIVIDER_ZERO_GATE)
+		init.ops = &clk_divider_gate_ops;
 	else
 		init.ops = &clk_divider_ops;
 	init.flags = flags | CLK_IS_BASIC;
@@ -470,6 +586,12 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
 	div->hw.init = &init;
 	div->table = table;
 
+	if (div->flags & CLK_DIVIDER_ZERO_GATE) {
+		val = clk_readl(reg) >> shift;
+		val &= div_mask(width);
+		div->cached_val = val;
+	}
+
 	/* register the clock */
 	hw = &div->hw;
 	ret = clk_hw_register(dev, hw);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 7c925e6..5f33b73 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -358,6 +358,7 @@ struct clk_div_table {
  * @shift:	shift to the divider bit field
  * @width:	width of the divider bit field
  * @table:	array of value/divider pairs, last entry should have div = 0
+ * @cached_val: cached div hw value used for CLK_DIVIDER_ZERO_GATE
  * @lock:	register lock
  *
  * Clock with an adjustable divider affecting its output frequency.  Implements
@@ -386,6 +387,12 @@ struct clk_div_table {
  * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED
  *	except when the value read from the register is zero, the divisor is
  *	2^width of the field.
+ * CLK_DIVIDER_ZERO_GATE - For dividers which are like CLK_DIVIDER_ONE_BASED
+ *	when the value read from the register is zero, it means the divisor
+ *	is gated. For this case, the cached_val will be used to store the
+ *	intermediate div for the normal rate operation, like set_rate/get_rate/
+ *	recalc_rate. When the divider is ungated, the driver will actually
+ *	program the hardware to have the requested divider value.
  */
 struct clk_divider {
 	struct clk_hw	hw;
@@ -394,6 +401,7 @@ struct clk_divider {
 	u8		width;
 	u8		flags;
 	const struct clk_div_table	*table;
+	u32		cached_val;
 	spinlock_t	*lock;
 };
 
@@ -406,6 +414,7 @@ struct clk_divider {
 #define CLK_DIVIDER_ROUND_CLOSEST	BIT(4)
 #define CLK_DIVIDER_READ_ONLY		BIT(5)
 #define CLK_DIVIDER_MAX_AT_ZERO		BIT(6)
+#define CLK_DIVIDER_ZERO_GATE		BIT(7)
 
 extern const struct clk_ops clk_divider_ops;
 extern const struct clk_ops clk_divider_ro_ops;

Anyway, if you still think it's not proper, i can put it in platform
driver as you wish, just in the cost of a few duplicated codes.

> > +
> > +	if (!divider->cached_val) {
> > +		pr_err("%s: no valid preset rate\n", clk_hw_get_name(hw));
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (divider->lock)
> > +		spin_lock_irqsave(divider->lock, flags);
> > +	else
> > +		__acquire(divider->lock);
> > +
> > +	/* restore div val */
> > +	val = clk_readl(divider->reg);
> > +	val |= divider->cached_val << divider->shift;
> > +	clk_writel(val, divider->reg);
> > +
> > +	if (divider->lock)
> > +		spin_unlock_irqrestore(divider->lock, flags);
> > +	else
> > +		__release(divider->lock);
> > +
> > +	return 0;
> > +}
> > +
> > +static void clk_divider_disable(struct clk_hw *hw)
> > +{
> > +	struct clk_divider *divider = to_clk_divider(hw);
> > +	unsigned long flags = 0;
> > +	u32 val;
> > +
> > +	if (!(divider->flags & CLK_DIVIDER_ZERO_GATE))
> > +		return;
> > +
> > +	if (divider->lock)
> > +		spin_lock_irqsave(divider->lock, flags);
> > +	else
> > +		__acquire(divider->lock);
> > +
> > +	/* store the current div val */
> > +	val = clk_readl(divider->reg) >> divider->shift;
> > +	val &= div_mask(divider->width);
> > +	divider->cached_val = val;
> > +	clk_writel(0, divider->reg);
> > +
> > +	if (divider->lock)
> > +		spin_unlock_irqrestore(divider->lock, flags);
> > +	else
> > +		__release(divider->lock);
> > +}
> > +
> > +static int clk_divider_is_enabled(struct clk_hw *hw)
> > +{
> > +	struct clk_divider *divider = to_clk_divider(hw);
> > +	u32 val;
> > +
> > +	if (!(divider->flags & CLK_DIVIDER_ZERO_GATE))
> > +		return __clk_get_enable_count(hw->clk);
> 
> The plan was to delete this API once OMAP stopped using it.
> clk_hw_is_enabled() doesn't work?

No, it did not work before because clk_hw_is_enabled will result
in the dead loop by calling .is_enabled() callback again.

That's why __clk_get_enable_count is used instead.

However, with above new patch method, this issue was gone.

> 
> > +
> > +	val = clk_readl(divider->reg) >> divider->shift;
> > +	val &= div_mask(divider->width);
> > +
> > +	return val ? 1 : 0;
> > +}
> > +
> >  const struct clk_ops clk_divider_ops = {
> >  	.recalc_rate = clk_divider_recalc_rate,
> >  	.round_rate = clk_divider_round_rate,
> >  	.set_rate = clk_divider_set_rate,
> > +	.enable = clk_divider_enable,
> > +	.disable = clk_divider_disable,
> > +	.is_enabled = clk_divider_is_enabled,
> >  };
> >  EXPORT_SYMBOL_GPL(clk_divider_ops);
> >  
> > @@ -436,6 +525,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
> >  	struct clk_divider *div;
> >  	struct clk_hw *hw;
> >  	struct clk_init_data init;
> > +	u32 val;
> >  	int ret;
> >  
> >  	if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
> > @@ -468,6 +558,12 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
> >  	div->hw.init = &init;
> >  	div->table = table;
> >  
> > +	if (div->flags & CLK_DIVIDER_ZERO_GATE) {
> > +		val = clk_readl(reg) >> shift;
> > +		val &= div_mask(width);
> > +		div->cached_val = val;
> > +	}
> 
> What if it isn't on? Setting cached_val to 0 is ok?
> 

If it isn't on, then the cache_val should be 0.
And recalc_rate will catch this case and return 0 as there's
no proper pre-set rate.

Regards
Dong Aisheng

> > +
> >  	/* register the clock */
> >  	hw = &div->hw;
> >  	ret = clk_hw_register(dev, hw);
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH] MAINTAINERS: Add self as extended maintainer for a slew of files
From: Arnd Bergmann @ 2017-12-20 14:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171220113054.10332-1-linus.walleij@linaro.org>

On Wed, Dec 20, 2017 at 12:30 PM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> Take over sole maintenance of Nomadik, U300 and Ux500. Since all are
> Device Tree converted and using standard format drivers this is not
> burdensome. Alessandro is not working on this platform any more.
>
> Suggested-by: Krzysztof Kozlowski <krzk@kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ARM SoC folks: please apply this directly where appropriate.

I'm sure you are doing this right, but it would be good out of principle
to have Alessandro on Cc and ask for an Ack from him.

> ---
>  MAINTAINERS | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index aa71ab52fd76..ac14e81ed38b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1634,14 +1634,18 @@ ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT
>  M:     Michael Petchkovsky <mkpetch@internode.on.net>
>  S:     Maintained
>
> -ARM/NOMADIK ARCHITECTURE
> -M:     Alessandro Rubini <rubini@unipv.it>
> +ARM/NOMADIK/U300/Ux500 ARCHITECTURE
>  M:     Linus Walleij <linus.walleij@linaro.org>
>  L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  S:     Maintained
>  F:     arch/arm/mach-nomadik/
> +F:     arch/arm/mach-u300/
> +F:     arch/arm/mach-ux500/
> +F:     arch/arm/boot/dts/ste-*
>  F:     drivers/pinctrl/nomadik/
>  F:     drivers/i2c/busses/i2c-nomadik.c
> +F:     Documentation/devicetree/bindings/arm/ste-*
> +F:     Documentation/devicetree/bindings/arm/ux500/
>  T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git

Shouldn't you remove the existing Ux500 and merge the remaining
contents in here?

       Arnd

^ permalink raw reply

* [PATCH, RFT] ARM: use --fix-v4bx to allow building ARMv4 with future gcc
From: Arnd Bergmann @ 2017-12-20 14:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_viATGXTQjywxv8Yyy2iP-nBnAJZBmtnfhsQvS-ueWUA@mail.gmail.com>

On Wed, Dec 20, 2017 at 2:46 PM, Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
> On 20 December 2017 at 13:00, Arnd Bergmann <arnd@arndb.de> wrote:
>> For consistency, I'm passing the --fix-v4bx flag for both the
>> vmlinux final link and the individual loadable modules.
>> The module loader code already interprets the R_ARM_V4BX relocations
>> in loadable modules and converts bx instructions into mov even
>> when running on ARMv4T or ARMv5 processors. This is now redundant
>> when we pass --fix-v4bx to the linker for building modules, but
>> I see no harm in leaving the current implementation and doing both.
>>
>
> Are you sure --fix-v4bx is taken into account during a partial link?

No. I made the patch a long time ago, so I don't remember what exactly
led me to this decision, but it should be fine as long as the linker
does the transformation at least once.

>> +tune-$(CONFIG_CPU_SA110)       =$(call cc-option,-mtune=strongarm110)
>> +tune-$(CONFIG_CPU_SA1100)      =$(call cc-option,-mtune=strongarm1100)
>>  tune-$(CONFIG_CPU_XSCALE)      =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
>>  tune-$(CONFIG_CPU_XSC3)                =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
>
> Shouldn't these two be updated as well?

All compilers that drop -mtune=strongarm110 support for now still support
mtune=xscale, so I don't think we need to change them. One thing we could
consider is passing -mtune=xscale when building for StrongARM, if that
produces better code than the default -mtune=arm7tdmi, but from looking
at the gcc-8 sources, it's not clear if that's better or worse. Neither arm7tdmi
nor strongarm have a custom cost function, but xscale has. The difference
between arm7tdmi and strongarm110 tuning is just the maximum number of
conditional instructions (5 vs 3).

A much bigger impact might be to tune for arm9e when building a kernel for
ARM926, no idea why we don't already do that (we do it for arm946, which
nobody really uses). Also, gcc has optimizations for many ARMv7-A cores
that we could use if we decide to make them known in Kconfig.

      Arnd

^ permalink raw reply

* [RFC PATCH 09/12] mmc: sdhci: Use software timer when timeout greater than hardware capablility
From: Adrian Hunter @ 2017-12-20 14:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171214130941.26666-10-kishon@ti.com>

On 14/12/17 15:09, Kishon Vijay Abraham I wrote:
> Errata i834 in AM572x Sitara Processors Silicon Revision 2.0, 1.1
> (SPRZ429K July 2014?Revised March 2017 [1]) mentions
> Under high speed HS200 and SDR104 modes, the functional clock for MMC
> modules will reach up to 192 MHz. At this frequency, the maximum obtainable
> timeout (DTO = 0xE) through MMC host controller is (1/192MHz)*2^27 = 700ms.
> Commands taking longer than 700ms may be affected by this small window
> frame. Workaround for this errata is use a software timer instead of
> hardware timer to provide the delay requested by the upper layer.
> 
> While this errata is specific to AM572x, it is applicable to all sdhci
> based controllers when a particular request require timeout greater
> than hardware capability.

It doesn't work for our controllers.  Even if the data timeout interrupt is
disabled, it seems like the timeout still "happens" in some fashion - after
which the host controller starts misbehaving.

So you will need to add a quirk.

> 
> Re-use the software timer already implemented in sdhci to program the
> correct timeout value and also disable the hardware timeout when
> the required timeout is greater than hardware capabiltiy in order to
> avoid spurious timeout interrupts.
> 
> This patch is based on the earlier patch implemented for omap_hsmmc [2]
> 
> [1] -> http://www.ti.com/lit/er/sprz429k/sprz429k.pdf
> [2] -> https://patchwork.kernel.org/patch/9791449/
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  drivers/mmc/host/sdhci.c | 41 +++++++++++++++++++++++++++++++++++++++--
>  drivers/mmc/host/sdhci.h | 11 +++++++++++
>  2 files changed, 50 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index e9290a3439d5..d0655e1d2cc7 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -673,6 +673,27 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
>  	}
>  }
>  
> +static void sdhci_calc_sw_timeout(struct sdhci_host *host,
> +				  struct mmc_command *cmd,
> +				  unsigned int target_timeout)
> +{
> +	struct mmc_host *mmc = host->mmc;
> +	struct mmc_ios *ios = &mmc->ios;
> +	struct mmc_data *data = cmd->data;
> +	unsigned long long transfer_time;
> +
> +	if (data) {
> +		transfer_time = MMC_BLOCK_TRANSFER_TIME_MS(data->blksz,
> +							   ios->bus_width,
> +							   ios->clock);

If it has a value, actual_clock is better than ios->clock.

> +		/* calculate timeout for the entire data */
> +		host->data_timeout = (data->blocks * (target_timeout +
> +						      transfer_time));
> +	} else if (cmd->flags & MMC_RSP_BUSY) {
> +		host->data_timeout = cmd->busy_timeout * MSEC_PER_SEC;

Doesn't need MSEC_PER_SEC multiplier.

> +	}
> +}
> +
>  static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
>  {
>  	u8 count;
> @@ -732,8 +753,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
>  	}
>  
>  	if (count >= 0xF) {
> -		DBG("Too large timeout 0x%x requested for CMD%d!\n",
> -		    count, cmd->opcode);
> +		DBG("Too large timeout.. using SW timeout for CMD%d!\n",
> +		    cmd->opcode);
> +		sdhci_calc_sw_timeout(host, cmd, target_timeout);
> +		host->ier &= ~SDHCI_INT_DATA_TIMEOUT;
> +		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
> +		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>  		count = 0xE;
>  	}
>  
> @@ -1198,6 +1223,14 @@ static void sdhci_finish_command(struct sdhci_host *host)
>  {
>  	struct mmc_command *cmd = host->cmd;
>  
> +	if (host->data_timeout) {
> +		unsigned long timeout;
> +
> +		timeout = jiffies +
> +			  msecs_to_jiffies(host->data_timeout);
> +		sdhci_mod_timer(host, host->cmd->mrq, timeout);

cmd could be the sbc or a stop cmd or a command during transfer, so this
needs more logic.

> +	}
> +
>  	host->cmd = NULL;
>  
>  	if (cmd->flags & MMC_RSP_PRESENT) {
> @@ -2341,6 +2374,10 @@ static bool sdhci_request_done(struct sdhci_host *host)
>  		return true;
>  	}
>  
> +	host->data_timeout = 0;
> +	host->ier |= SDHCI_INT_DATA_TIMEOUT;
> +	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
> +	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);

sdhci can have 2 requests in progress to allow for commands to be sent while
a data transfer is in progress, so this is not necessarily the data transfer
request that is done.  Also we want to avoid unnecessary register writes.

>  	sdhci_del_timer(host, mrq);
>  
>  	/*
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 54bc444c317f..e6e0278bea1a 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -332,6 +332,15 @@ struct sdhci_adma2_64_desc {
>  /* Allow for a a command request and a data request at the same time */
>  #define SDHCI_MAX_MRQS		2
>  
> +/*
> + * Time taken for transferring one block. It is multiplied by a constant
> + * factor '2' to account for any errors
> + */
> +#define MMC_BLOCK_TRANSFER_TIME_MS(blksz, bus_width, freq)		\
> +				   ((unsigned long long)		\
> +				   (2 * (((blksz) * MSEC_PER_SEC *	\
> +				   (8 / (bus_width))) / (freq))))

I don't think the macro helps make the code more readable.  Might just as
well write a nice function to calculate the entire data request timeout.

> +
>  enum sdhci_cookie {
>  	COOKIE_UNMAPPED,
>  	COOKIE_PRE_MAPPED,	/* mapped by sdhci_pre_req() */
> @@ -546,6 +555,8 @@ struct sdhci_host {
>  	/* Host SDMA buffer boundary. */
>  	u32			sdma_boundary;
>  
> +	unsigned long long	data_timeout;

msecs_to_jiffies() will truncate to 'unsigned int' anyway, so this might as
well be 'unsigned int'.

> +
>  	unsigned long private[0] ____cacheline_aligned;
>  };
>  
> 

^ permalink raw reply

* [PATCH v2 4/6] ARM: dts: imx6: Add support for phxBOARD-Mira i.MX 6 DualLight/Solo RDK
From: Lothar Waßmann @ 2017-12-20 14:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1513776567-30182-5-git-send-email-s.riedmueller@phytec.de>

Hi,

On Wed, 20 Dec 2017 14:29:25 +0100 Stefan Riedmueller wrote:
> From: Christian Hemp <c.hemp@phytec.de>
> 
> Add support for the PHYTEC phyBOARD-Mira Low-Cost Rapid Development Kit
> with i.MX 6DualLight/Solo with NAND.
> 
s/phxBOARD/phyBOARD/ in the subject line.


Lothar Wa?mann

^ permalink raw reply

* [PATCH V4 1/1] clk: bulk: add of_clk_bulk_get()
From: Dong Aisheng @ 2017-12-20 13:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170929224821.GM457@codeaurora.org>

On Fri, Sep 29, 2017 at 03:48:21PM -0700, Stephen Boyd wrote:
> On 09/26, Dong Aisheng wrote:
> > 'clock-names' property is optinal in DT, so of_clk_bulk_get() is introduced
> 
> s/optinal/optional/
> 

Got it.

> > here to handle this for DT users without 'clock-names' specified.
> > 
> > Cc: Stephen Boyd <sboyd@codeaurora.org>
> > Cc: Michael Turquette <mturquette@baylibre.com>
> > Cc: Russell King <linux@arm.linux.org.uk>
> > Reported-by: Shawn Guo <shawnguo@kernel.org>
> > Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> > 
> > ---
> > Changes since v3:
> >  * fix build warning on the SH platform
> > 
> > Changes since v2:
> >  * of_clk_bulk_get should return -ENOENT;
> > 
> > Changes since v1:
> >  * using %pOF instead of full_name
> > ---
> >  drivers/clk/clk-bulk.c | 31 +++++++++++++++++++++++++++++++
> >  include/linux/clk.h    |  8 ++++++++
> >  2 files changed, 39 insertions(+)
> > 
> > diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
> > index c834f5a..896aa3b 100644
> > --- a/drivers/clk/clk-bulk.c
> > +++ b/drivers/clk/clk-bulk.c
> > @@ -19,6 +19,37 @@
> >  #include <linux/clk.h>
> >  #include <linux/device.h>
> >  #include <linux/export.h>
> > +#include <linux/of.h>
> > +
> > +#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
> > +int __must_check of_clk_bulk_get(struct device_node *np, int num_clks,
> > +				 struct clk_bulk_data *clks)
> > +{
> > +	int ret;
> > +	int i;
> > +
> > +	for (i = 0; i < num_clks; i++)
> > +		clks[i].clk = NULL;
> > +
> > +	for (i = 0; i < num_clks; i++) {
> > +		clks[i].clk = of_clk_get(np, i);
> > +		if (IS_ERR(clks[i].clk)) {
> > +			ret = PTR_ERR(clks[i].clk);
> > +			pr_err("%pOF: Failed to get clk index: %d ret: %d\n",
> > +			       np, i, ret);
> > +			clks[i].clk = NULL;
> > +			goto err;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +
> > +err:
> > +	clk_bulk_put(i, clks);
> > +
> > +	return ret;
> > +}
> 
> Export the symbol?
> 

Got it.

> > +#endif
> >  
> >  void clk_bulk_put(int num_clks, struct clk_bulk_data *clks)
> >  {
> > diff --git a/include/linux/clk.h b/include/linux/clk.h
> > index 12c96d9..073cb3b 100644
> > --- a/include/linux/clk.h
> > +++ b/include/linux/clk.h
> > @@ -680,10 +680,18 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
> >  }
> >  
> >  #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
> > +int __must_check of_clk_bulk_get(struct device_node *np, int num_clks,
> > +				 struct clk_bulk_data *clks);
> >  struct clk *of_clk_get(struct device_node *np, int index);
> >  struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
> >  struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
> >  #else
> > +static inline int of_clk_bulk_get(struct device_node *np, int num_clks,
> 
> Do we need __must_check here too?

Yes, you're absolutely right.

of_clk_bulk_get is special as it returns error, so should add __must_check.

> We should do the same for the
> other bulk get APIs. Seems we missed that part last time.
> 

Currently for !CONFIG_HAVE_CLK case, all APIs return 0.
!CONFIG_HAVE_CLK
clk_bulk_get		return 0
devm_clk_bulk_get	return 0
clk_bulk_enable		return 0
clk_bulk_prepare	return 0

Do you think we still need add __must_check for them?

And for CONFIG_HAVE_CLK case, all __must_check already added.

int __must_check clk_bulk_get
int __must_check devm_clk_bulk_get
int __must_check clk_bulk_enable
int __must_check clk_bulk_prepare

And no need for void function.
void clk_bulk_put
void clk_bulk_unprepare
void clk_bulk_disable

> I'll fix all these things up when applying.
> 

I did not see this in latest tree.
Suppose i should resend it with above things fixed, right?

Regards
Dong Aisheng

^ permalink raw reply

* [PATCH v2 5/5] ARM: imx_v6_v7_defconfig: Enable DA0963 PMIC support.
From: jan.tuerk at emtrion.com @ 2017-12-20 13:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171220134710.64479-1-jan.tuerk@emtrion.com>

From: Jan Tuerk <jan.tuerk@emtrion.com>

All recent emtrion modules based on i.mx6 make use of the DA0963.
Therefore enable it with the following defaults:
	- CONFIG_MFD_DA9063=y
	- CONFIG_REGULATOR_DA9063=y
	- CONFIG_DA9063_WATCHDOG=m
	- CONFIG_RTC_DRV_DA9063=m
MFD and REGULATOR are built-in to have it at Kernel boot-time.
The WATCHDOG and RTC are optional and could be loaded from userspace.

Signed-off-by: Jan Tuerk <jan.tuerk@emtrion.com>
---
 arch/arm/configs/imx_v6_v7_defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 0d4494922561..09cd8048b0c1 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -215,8 +215,10 @@ CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_CPU_THERMAL=y
 CONFIG_IMX_THERMAL=y
 CONFIG_WATCHDOG=y
+CONFIG_DA9063_WATCHDOG=m
 CONFIG_IMX2_WDT=y
 CONFIG_MFD_DA9052_I2C=y
+CONFIG_MFD_DA9063=y
 CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
 CONFIG_MFD_STMPE=y
@@ -224,6 +226,7 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
 CONFIG_REGULATOR_DA9052=y
+CONFIG_REGULATOR_DA9063=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
@@ -349,6 +352,7 @@ CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_M41T80=y
 CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
+CONFIG_RTC_DRV_DA9063=m
 CONFIG_RTC_DRV_SNVS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
-- 
emtrion GmbH
Alter Schlachthof 45
76131 Karlsruhe
GERMANY
https://www.emtrion.de

Amtsgericht Mannheim
HRB 110 300
Gesch?ftsf?hrer: Dieter Baur, Ramona Maurer

^ permalink raw reply related

* [PATCH v2 4/5] ARM: dts: Add support for emtrion emCON-MX6 series
From: jan.tuerk at emtrion.com @ 2017-12-20 13:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171220134710.64479-1-jan.tuerk@emtrion.com>

From: Jan Tuerk <jan.tuerk@emtrion.com>

This patch adds support for the emtrion GmbH emCON-MX6 modules.
They are available with imx.6 Solo, Dual-Lite, Dual and Quad
equipped with Memory from 512MB to 2GB (configured by U-Boot).

Our default developer-Kit ships with the Avari baseboard and the
EDT ETM0700G0BDH6 Display (imx6[q|dl]-emcon-avari).

The devicetree is split into the common part providing all module
components and the basic support for all SoC versions
(imx6qdl-emcon.dtsi) and parts which are i.mx6 S|DL and D|Q relevant.
Finally the support for the avari baseboard in the developer-kit
configuration is provided by the emcon-avari dts files.

Signed-off-by: Jan Tuerk <jan.tuerk@emtrion.com>
---
Changes in v2:
 - Fixed typo (reg_prallel.. --> reg_parallel)
 - Removed trailing new-line
 - Fix uppercase addresses as Rob H. noted
 - Fix warning about lcd at di0 -> rename to disp0
 - Renamed some nodes regarding Rob H.

 Documentation/devicetree/bindings/arm/emtrion.txt |  13 +
 arch/arm/boot/dts/Makefile                        |   2 +
 arch/arm/boot/dts/imx6dl-emcon-avari.dts          | 233 ++++++
 arch/arm/boot/dts/imx6dl-emcon.dtsi               |  37 +
 arch/arm/boot/dts/imx6q-emcon-avari.dts           | 233 ++++++
 arch/arm/boot/dts/imx6q-emcon.dtsi                |  37 +
 arch/arm/boot/dts/imx6qdl-emcon.dtsi              | 848 ++++++++++++++++++++++
 7 files changed, 1403 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/emtrion.txt
 create mode 100644 arch/arm/boot/dts/imx6dl-emcon-avari.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-emcon.dtsi
 create mode 100644 arch/arm/boot/dts/imx6q-emcon-avari.dts
 create mode 100644 arch/arm/boot/dts/imx6q-emcon.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-emcon.dtsi

diff --git a/Documentation/devicetree/bindings/arm/emtrion.txt b/Documentation/devicetree/bindings/arm/emtrion.txt
new file mode 100644
index 000000000000..3ff6c6c2034d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/emtrion.txt
@@ -0,0 +1,13 @@
+Emtrion Devicetree Bindings
+===========================
+
+emCON Series:
+-------------
+
+Required root node properties
+	- compatible:
+	- "emtrion,emcon-mx6", "fsl,imx6q", "fsl,imx6dl"; : emCON-MX6 Generic SoM
+	- "emtrion,emcon-mx6", "fsl,imx6q"; 		: emCON-MX6D or emCON-MX6Q SoM
+	- "emtrion,emcon-mx6-avari", "fsl,imx6q";	: emCON-MX6D or emCON-MX6Q SoM on Avari Base
+	- "emtrion,emcon-mx6", "fsl,imx6dl"; 		: emCON-MX6S or emCON-MX6DL SoM
+	- "emtrion,emcon-mx6-avari", "fsl,imx6dl";	: emCON-MX6S or emCON-MX6DL SoM on Avari Base
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d0381e9caf21..5ce643ece228 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -373,6 +373,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-colibri-eval-v3.dtb \
 	imx6dl-cubox-i.dtb \
 	imx6dl-dfi-fs700-m60.dtb \
+	imx6dl-emcon-avari.dtb \
 	imx6dl-gw51xx.dtb \
 	imx6dl-gw52xx.dtb \
 	imx6dl-gw53xx.dtb \
@@ -424,6 +425,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6q-dfi-fs700-m60.dtb \
 	imx6q-display5-tianma-tm070-1280x768.dtb \
 	imx6q-dmo-edmqmx6.dtb \
+	imx6q-emcon-avari.dtb \
 	imx6q-evi.dtb \
 	imx6q-gk802.dtb \
 	imx6q-gw51xx.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-emcon-avari.dts b/arch/arm/boot/dts/imx6dl-emcon-avari.dts
new file mode 100644
index 000000000000..f1333a48d8c5
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-emcon-avari.dts
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2017 emtrion GmbH
+ * Author: Jan Tuerk  <jan.tuerk@emtrion.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-emcon.dtsi"
+#include "imx6dl-emcon.dtsi" /*Include camera2 pinmux*/
+
+/ {
+	model = "emtrion SoM emCON-MX6 Solo/Dual-Lite Avari";
+	compatible = "emtrion,emcon-mx6-avari", "fsl,imx6dl";
+
+	aliases {
+		mmc0 = &usdhc3;
+		mmc2 = &usdhc1;
+		mmc1 = &usdhc2;
+		mmc3 = &usdhc4;
+	};
+
+	chosen {
+		stdout-path = <&uart1>;
+	};
+
+	memory {
+		reg = <0x10000000 0x40000000>;
+	};
+
+	supplies {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		wallplug5p0: supply at 0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			regulator-name = "WALL-PLUG";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		base3p3: supply at 1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			vin-supply = <&wallplug5p0>;
+			regulator-name = "3V3-avari";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		base1p5: supply at 2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			vin-supply = <&base3p3>;
+			regulator-name = "1V5-avari";
+			regulator-min-microvolt = <1500000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		reg_usb_otg: otgvbus at 3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			vin-supply = <&wallplug5p0>;
+			regulator-name = "OTG_VBUS";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio1 8 GPIO_ACTIVE_LOW>;
+			regulator-always-on;
+		};
+
+	};
+
+
+	sndosc: 12MHZosc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency  = <12000000>;
+	};
+
+	sound {
+		compatible = "fsl,imx-audio-sgtl5000";
+		model = "emCON-avari-sgtl5000";
+		ssi-controller = <&ssi2>;
+		audio-codec = <&sgtl5000>;
+		audio-routing =
+			"Headphone Jack", "HP_OUT";
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+	};
+
+};
+
+
+&iomuxc {
+	pinctrl-names = "default";
+	/*Unused emCON-MX6 outputs on AVARI*/
+	pinctrl-0 = <
+				 &pinctrl_emcon_gpio1 &pinctrl_emcon_gpio2
+				 &pinctrl_emcon_gpio3 &pinctrl_emcon_gpio5
+				 &pinctrl_emcon_gpio6 &pinctrl_emcon_gpio7
+				 &pinctrl_emcon_gpio8 &pinctrl_emcon_irq_a
+				 &pinctrl_emcon_irq_b &pinctrl_emcon_irq_c
+				 &pinctrl_emcon_irq_pwr &pinctrl_nor_flash
+				 &pinctrl_usdhc2
+				 &pinctrl_spdif_out     &pinctrl_spdif_in
+				 &pinctrl_cpi1          &pinctrl_cpi2
+				>;
+};
+
+&audmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux>;
+	status = "okay";
+};
+
+
+
+&i2c3 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+
+	sgtl5000: audio-codec at 0a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		clocks = <&sndosc>;
+		VDDA-supply = <&base3p3>;
+		VDDIO-supply = <&base3p3>;
+	};
+
+	boardID: pca8754a at 3a {
+		compatible = "nxp,pca8574";
+		reg = <0x3a>;
+		gpio-controller;
+		#gpio-cells = <1>;
+	};
+
+	captouch: touchscreen at 38 {
+		reg = <0x38>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_irq_touch2 &pinctrl_emcon_gpio4>;
+		interrupt-parent = <&gpio6>;
+		interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
+		compatible = "edt,edt-ft5406";
+		wake-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+		wakeup-source;
+	};
+};
+
+&ssi2 {
+	status = "okay";
+};
+
+&rgb_encoder {
+	status = "okay";
+};
+
+&rgb_panel {
+	compatible = "edt,etm0700g0bdh6";
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
+
+&can1 {
+	status = "okay";
+};
+
+&can2 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+	uart-has-rtscts;
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&ecspi2 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-emcon.dtsi b/arch/arm/boot/dts/imx6dl-emcon.dtsi
new file mode 100644
index 000000000000..47f43bae5ac5
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-emcon.dtsi
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 emtrion GmbH
+ * Author: Jan Tuerk  <jan.tuerk@emtrion.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/ {
+	model = "emtrion SoM emCON-MX6 Solo/DualLite";
+	compatible = "emtrion,emcon-mx6","fsl,imx6dl";
+};
+
+&iomuxc {
+	pinctrl_cpi2: csi1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D17__IPU1_CSI1_PIXCLK	0x0b0b1
+			MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC		0x1b0b1
+			MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC		0x1b0b1
+			MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12	0x1b0b1
+			MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13	0x1b0b1
+			MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14	0x1b0b1
+			MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15	0x1b0b1
+			MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16	0x1b0b1
+			MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17	0x1b0b1
+			MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18	0x1b0b1
+			MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19	0x1b0b1
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-emcon-avari.dts b/arch/arm/boot/dts/imx6q-emcon-avari.dts
new file mode 100644
index 000000000000..c0b20c040790
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-emcon-avari.dts
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2017 emtrion GmbH
+ * Author: Jan Tuerk  <jan.tuerk@emtrion.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-emcon.dtsi"
+#include "imx6q-emcon.dtsi" /*Include camera2 pinmux*/
+
+/ {
+	model = "emtrion SoM emCON-MX6 Dual/Quad on Avari";
+	compatible = "emtrion,emcon-mx6-avari", "fsl,imx6q";
+
+	aliases {
+		mmc0 = &usdhc3;
+		mmc2 = &usdhc1;
+		mmc1 = &usdhc2;
+		mmc3 = &usdhc4;
+	};
+
+	chosen {
+		stdout-path = <&uart1>;
+	};
+
+	memory {
+		reg = <0x10000000 0x40000000>;
+	};
+
+	supplies {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		wallplug5p0: supply at 0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			regulator-name = "WALL-PLUG";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		base3p3: supply at 1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			vin-supply = <&wallplug5p0>;
+			regulator-name = "3V3-avari";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		base1p5: supply at 2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			vin-supply = <&base3p3>;
+			regulator-name = "1V5-avari";
+			regulator-min-microvolt = <1500000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		reg_usb_otg: otgvbus at 3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			vin-supply = <&wallplug5p0>;
+			regulator-name = "OTG_VBUS";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio1 8 GPIO_ACTIVE_LOW>;
+			regulator-always-on;
+		};
+
+	};
+
+
+	sndosc: 12MHZosc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency  = <12000000>;
+	};
+
+	sound {
+		compatible = "fsl,imx-audio-sgtl5000";
+		model = "emCON-avari-sgtl5000";
+		ssi-controller = <&ssi2>;
+		audio-codec = <&sgtl5000>;
+		audio-routing =
+			"Headphone Jack", "HP_OUT";
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+	};
+
+};
+
+
+&iomuxc {
+	pinctrl-names = "default";
+	/*Unused emCON-MX6 pingroups on AVARI baseboard, enable defaults*/
+	pinctrl-0 = <
+				 &pinctrl_emcon_gpio1 &pinctrl_emcon_gpio2
+				 &pinctrl_emcon_gpio3 &pinctrl_emcon_gpio5
+				 &pinctrl_emcon_gpio6 &pinctrl_emcon_gpio7
+				 &pinctrl_emcon_gpio8 &pinctrl_emcon_irq_a
+				 &pinctrl_emcon_irq_b &pinctrl_emcon_irq_c
+				 &pinctrl_emcon_irq_pwr &pinctrl_nor_flash
+				 &pinctrl_usdhc2
+				 &pinctrl_spdif_out     &pinctrl_spdif_in
+				 &pinctrl_cpi1          &pinctrl_cpi2
+				>;
+};
+
+&audmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux>;
+	status = "okay";
+};
+
+
+
+&i2c3 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+
+	sgtl5000: audo-codec at 0a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		clocks = <&sndosc>;
+		VDDA-supply = <&base3p3>;
+		VDDIO-supply = <&base3p3>;
+	};
+
+	boardID: pca8754a at 3a {
+		compatible = "nxp,pca8574";
+		reg = <0x3a>;
+		gpio-controller;
+		#gpio-cells = <1>;
+	};
+
+	captouch: touchscreen at 38 {
+		reg = <0x38>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_irq_touch2 &pinctrl_emcon_gpio4>;
+		interrupt-parent = <&gpio6>;
+		interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
+		compatible = "edt,edt-ft5406";
+		wake-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+		wakeup-source;
+	};
+};
+
+&ssi2 {
+	status = "okay";
+};
+
+&rgb_encoder {
+	status = "okay";
+};
+
+&rgb_panel {
+	compatible = "edt,etm0700g0bdh6";
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
+
+&can1 {
+	status = "okay";
+};
+
+&can2 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+	uart-has-rtscts;
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&ecspi2 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-emcon.dtsi b/arch/arm/boot/dts/imx6q-emcon.dtsi
new file mode 100644
index 000000000000..64fc0cd74c05
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-emcon.dtsi
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 emtrion GmbH
+ * Author: Jan Tuerk  <jan.tuerk@emtrion.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+/ {
+	model = "emtrion SoM emCON-MX6 Dual/Quad";
+	compatible = "emtrion,emcon-mx6","fsl,imx6q";
+};
+
+&iomuxc {
+	pinctrl_cpi2: csi1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D17__IPU2_CSI1_PIXCLK	0x0b0b1
+			MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC		0x1b0b1
+			MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC		0x1b0b1
+			MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12	0x1b0b1
+			MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13	0x1b0b1
+			MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14	0x1b0b1
+			MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15	0x1b0b1
+			MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16	0x1b0b1
+			MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17	0x1b0b1
+			MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18	0x1b0b1
+			MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19	0x1b0b1
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl-emcon.dtsi b/arch/arm/boot/dts/imx6qdl-emcon.dtsi
new file mode 100644
index 000000000000..f87d8ed6a1b1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-emcon.dtsi
@@ -0,0 +1,848 @@
+/*
+ * Copyright (C) 2017 emtrion GmbH
+ * Author: Jan Tuerk  <jan.tuerk@emtrion.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+
+	model = "emtrion SoM emCON-MX6";
+	compatible = "emtrion,emcon-mx6","fsl,imx6q", "fsl,imx6dl";
+
+	aliases {
+		mmc0 = &usdhc3;
+		mmc2 = &usdhc1;
+		mmc1 = &usdhc2;
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		reg_parallel_disp: regulator at 0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_rgb_bl_en>;
+			regulator-name = "LCD-Supply";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio7 9 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+
+		reg_lvds_disp: regulator at 1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "LVDS-Supply";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio7 10 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+	};
+
+	som_leds: leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_som_leds>;
+
+		green {
+			label = "som:green";
+			gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			default-state = "on";
+		};
+
+		red {
+			label = "som:red";
+			gpios = <&gpio3 1 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_emcon_wake>;
+
+		wake {
+			label = "Wake";
+			linux,code = <KEY_WAKEUP>;
+			gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+	};
+
+	pwm_fan: pwm-fan {
+		compatible = "pwm-fan";
+		cooling-min-state = <0>;
+		cooling-max-state = <4>;
+		#cooling-cells = <2>;
+		pwms = <&pwm4 0 50000>;
+		cooling-levels = <0 64 127 191 255>;
+		status = "disabled";
+	};
+
+	rgb_encoder: disp0 {
+		compatible = "fsl,imx-parallel-display";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_rgb24_display>;
+		status = "disabled";
+
+		port at 0 {
+			reg = <0>;
+			rgb_encoder_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+			rgb_encoder_out: endpoint {
+				remote-endpoint = <&rgb_panel_in>;
+			};
+		};
+	};
+
+	rgb_panel: panel {
+		backlight = <&rgb_backlight>;
+		power-supply = <&reg_parallel_disp>;
+		port {
+			rgb_panel_in: endpoint {
+				remote-endpoint = <&rgb_encoder_out>;
+			};
+		};
+	};
+
+	rgb_backlight: rgb-backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_rgb_bl>;
+		enable-gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
+		pwms = <&pwm3 0 5000000>;
+		brightness-levels = <250 176 160 144 128 112
+							96 80 64 48 32 16 8 1
+							>;
+		default-brightness-level = <13>;
+		status = "okay";
+	};
+
+	lvds_backlight: lvds-backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_lvds_bl>;
+		enable-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>;
+		pwms = <&pwm1 0 50000>;
+		brightness-levels = <0 4 8 16 32 64 80 96 112
+							128 144 160 176 250
+							>;
+		default-brightness-level = <13>;
+		status = "okay";
+	};
+};
+
+
+&iomuxc {
+
+	pinctrl_secure: securegrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_18__GPIO7_IO13			0x1b0b1
+		>;
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA	0x1b0b1
+			MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_DAT5__UART2_RTS_B		0x1b0b1
+			MX6QDL_PAD_SD4_DAT6__UART2_CTS_B		0x1b0b1
+			MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA		0x1b0b1
+			MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA		0x1b0b1
+		>;
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D24__UART3_TX_DATA		0x1b0b1
+			MX6QDL_PAD_EIM_D25__UART3_RX_DATA		0x1b0b1
+		>;
+	};
+
+	pinctrl_uart4: uart4grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL0__UART4_TX_DATA		0x1b0b1
+			MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA		0x1b0b1
+		>;
+	};
+
+	pinctrl_uart5: uart5grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL1__UART5_TX_DATA		0x1b0b1
+			MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA		0x1b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio1: emcongpio1 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D0__GPIO2_IO00			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio2: emcongpio2 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D1__GPIO2_IO01			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio3: emcongpio3 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D2__GPIO2_IO02			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio4: emcongpio4 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D3__GPIO2_IO03			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio5: emcongpio5 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D4__GPIO2_IO04			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio6: emcongpio6 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D5__GPIO2_IO05			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio7: emcongpio7 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D6__GPIO2_IO06			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_gpio8: emcongpio8 {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_D7__GPIO2_IO07			0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_irq_a: emconirqa {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CLE__GPIO6_IO07		0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_irq_b: emconirqb {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CS2__GPIO6_IO15		0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_irq_c: emconirqc {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CS3__GPIO6_IO16		0x0b0b1
+		>;
+	};
+
+	pinctrl_emcon_wake: emconwake {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_DA2__GPIO3_IO02			0x1b0b1
+		>;
+	};
+
+	pinctrl_emcon_irq_pwr: emconirqpwr {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D23__GPIO3_IO23			0x0b0b1
+		>;
+	};
+
+	pinctrl_som_leds: somledgrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_DA0__GPIO3_IO00			0x0b0b1
+			MX6QDL_PAD_EIM_DA1__GPIO3_IO01			0x0b0b1
+		>;
+	};
+
+	pinctrl_nor_flash: norflashgrp {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CS0__GPIO6_IO11		0x1b0b1
+			MX6QDL_PAD_EIM_D21__ECSPI4_SCLK			0x100b1
+			MX6QDL_PAD_EIM_D28__ECSPI4_MOSI			0x100b1
+			MX6QDL_PAD_EIM_D22__ECSPI4_MISO			0x100b1
+			MX6QDL_PAD_EIM_A25__GPIO5_IO02			0x100b1
+		>;
+	};
+
+	pinctrl_ecspi2: ecspi2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK			0x100b1
+			MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI			0x100b1
+			MX6QDL_PAD_EIM_OE__ECSPI2_MISO			0x100b1
+			MX6QDL_PAD_EIM_LBA__GPIO2_IO27			0x100b1
+			MX6QDL_PAD_EIM_RW__GPIO2_IO26			0x100b1
+		>;
+	};
+
+	pinctrl_pwm_fan: pwmfan {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_DAT2__PWM4_OUT			0x0b0b1
+		>;
+	};
+
+	pinctrl_can1: can1grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX		0x1b0b1
+			MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX		0x1b0b1
+		>;
+	};
+
+	pinctrl_can2: can2grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX		0x1b0b1
+			MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX		0x1b0b1
+		>;
+	};
+
+	pinctrl_spdif_out: spdifout {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_19__SPDIF_OUT			0x13091
+		>;
+	};
+
+	pinctrl_spdif_in: spdifin {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_16__SPDIF_IN			0x1b0b0
+		>;
+	};
+
+	pinctrl_cpi1: csi0grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0xb0b1
+			MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC	0x1b0b1
+			MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC	0x1b0b1
+			MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b1
+			MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b1
+			MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b1
+			MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b1
+			MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b1
+			MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b1
+			MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b1
+			MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b1
+		>;
+	};
+
+	/*camera2-pinctrl is in imx6q-emcon.dtsi or imx6dl-emcon.dtsi*/
+
+	pinctrl_pcie_ctrl: pciegrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_A16__GPIO2_IO22			0x1b0b1
+			MX6QDL_PAD_GPIO_17__GPIO7_IO12			0x1b0b1
+		>;
+	};
+
+	pinctrl_audmux: audmux {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD			0x130b0
+			MX6QDL_PAD_CSI0_DAT4__AUD3_TXC			0x1b060
+			MX6QDL_PAD_CSI0_DAT5__AUD3_TXD			0x130B0
+			MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS			0x1b060
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT8__I2C1_SDA		0x4001b8b1
+			MX6QDL_PAD_CSI0_DAT9__I2C1_SCL		0x4001b8b1
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001b8b1
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001b8b1
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_3__I2C3_SCL		0x4000b070
+			MX6QDL_PAD_GPIO_6__I2C3_SDA		0x4001b870
+		>;
+	};
+
+	pinctrl_pmic: pmicgrp {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_DAT0__GPIO2_IO08			0x0b0b1
+		>;
+	};
+
+	pinctrl_usb_host1: usbhgrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D31__USB_H1_PWR			0x1B058
+			MX6QDL_PAD_EIM_D30__USB_H1_OC			0x1B058
+		>;
+	};
+
+	pinctrl_usb_otg: usbotggrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID		0x17059
+			MX6QDL_PAD_GPIO_7__GPIO1_IO07			0x17059
+			MX6QDL_PAD_GPIO_8__GPIO1_IO08			0x17059
+		>;
+	};
+
+	pinctrl_lvds_reg: lvdsreggrp {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_CLK__GPIO7_IO10			0x0b0b1
+		>;
+	};
+
+	pinctrl_lvds_bl: lvdsbacklightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_9__PWM1_OUT			0x0b0b1
+			MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09		0x0b0b1
+		>;
+	};
+
+	pinctrl_irq_touch1: irqtouch1 {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_5__GPIO1_IO05			0x0b0b1
+		>;
+	};
+
+	pinctrl_rgb_bl_en: rgbenable {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_CMD__GPIO7_IO09			0x0b0b1
+		>;
+	};
+
+	pinctrl_irq_touch2: irqtouch2 {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_BCLK__GPIO6_IO31			0x0b0b1
+		>;
+	};
+
+	pinctrl_rgb_bl: rgbbacklightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_DAT1__PWM3_OUT			0x0b0b1
+			MX6QDL_PAD_NANDF_ALE__GPIO6_IO08		0x0b0b1
+		>;
+	};
+
+	pinctrl_rgb24_display: rgbgrp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15       0x10
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02        0x10
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03        0x10
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00   0x10
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01   0x10
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02   0x10
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03   0x10
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04   0x10
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05   0x10
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06   0x10
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07   0x10
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08   0x10
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09   0x10
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10  0x10
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11  0x10
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12  0x10
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13  0x10
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14  0x10
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15  0x10
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16  0x10
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17  0x10
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18  0x10
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19  0x10
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20  0x10
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21  0x10
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22  0x10
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23  0x10
+		>;
+	};
+
+	pinctrl_enet: enetgrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO			0x1b030
+			MX6QDL_PAD_ENET_MDC__ENET_MDC			0x1b030
+			MX6QDL_PAD_RGMII_TXC__RGMII_TXC			0x1b030
+			MX6QDL_PAD_RGMII_TD0__RGMII_TD0			0x1b030
+			MX6QDL_PAD_RGMII_TD1__RGMII_TD1			0x1b030
+			MX6QDL_PAD_RGMII_TD2__RGMII_TD2			0x1b030
+			MX6QDL_PAD_RGMII_TD3__RGMII_TD3			0x1b030
+			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x1b030
+			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x4001a0b1
+			MX6QDL_PAD_RGMII_RXC__RGMII_RXC			0x1b030
+			MX6QDL_PAD_RGMII_RD0__RGMII_RD0			0x1b030
+			MX6QDL_PAD_RGMII_RD1__RGMII_RD1			0x1b030
+			MX6QDL_PAD_RGMII_RD2__RGMII_RD2			0x1b030
+			MX6QDL_PAD_RGMII_RD3__RGMII_RD3			0x1b030
+			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+			MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20		0x1b058
+			MX6QDL_PAD_ENET_TXD0__GPIO1_IO30		0x1b0b0
+		 >;
+	};
+
+
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD3_CMD__SD3_CMD			0x17059
+			MX6QDL_PAD_SD3_CLK__SD3_CLK			0x10059
+			MX6QDL_PAD_SD3_DAT0__SD3_DATA0			0x17059
+			MX6QDL_PAD_SD3_DAT1__SD3_DATA1			0x17059
+			MX6QDL_PAD_SD3_DAT2__SD3_DATA2			0x17059
+			MX6QDL_PAD_SD3_DAT3__SD3_DATA3			0x17059
+			MX6QDL_PAD_SD3_DAT4__SD3_DATA4			0x17059
+			MX6QDL_PAD_SD3_DAT5__SD3_DATA5			0x17059
+			MX6QDL_PAD_SD3_DAT6__SD3_DATA6			0x17059
+			MX6QDL_PAD_SD3_DAT7__SD3_DATA7			0x17059
+			MX6QDL_PAD_SD3_RST__SD3_RESET			0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_CMD__SD1_CMD			0x17059
+			MX6QDL_PAD_SD1_CLK__SD1_CLK			0x10059
+			MX6QDL_PAD_SD1_DAT0__SD1_DATA0			0x17059
+			MX6QDL_PAD_SD1_DAT1__SD1_DATA1			0x17059
+			MX6QDL_PAD_SD1_DAT2__SD1_DATA2			0x17059
+			MX6QDL_PAD_SD1_DAT3__SD1_DATA3			0x17059
+			MX6QDL_PAD_GPIO_1__SD1_CD_B			0x1b0b1
+			MX6QDL_PAD_DI0_PIN4__SD1_WP			0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD2_CMD__SD2_CMD			0x17059
+			MX6QDL_PAD_SD2_CLK__SD2_CLK			0x10059
+			MX6QDL_PAD_SD2_DAT0__SD2_DATA0			0x17059
+			MX6QDL_PAD_SD2_DAT1__SD2_DATA1			0x17059
+			MX6QDL_PAD_SD2_DAT2__SD2_DATA2			0x17059
+			MX6QDL_PAD_SD2_DAT3__SD2_DATA3			0x17059
+			MX6QDL_PAD_GPIO_4__SD2_CD_B			0x1b0b1
+			MX6QDL_PAD_GPIO_2__SD2_WP			0x1b0b1
+		>;
+	};
+
+};
+
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	rtc: rtc at 68 {
+		compatible = "dallas,ds1307";
+		reg = <0x68>;
+	};
+
+	da9063: pmic at 58 {
+		compatible = "dlg,da9063";
+		reg = <0x58>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pmic>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+
+		onkey {
+			wakeup-source;
+			compatible = "dlg,da9063-onkey";
+		};
+
+		wdt {
+			compatible = "dlg,da9063-watchdog";
+			timeout-sec = <0>;
+		};
+
+		regulators {
+			vddcore_reg: bcore1 {
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1450000>;
+				regulator-ramp-delay = <20000>;
+				regulator-name = "DA9063_CORE";
+				regulator-always-on;
+			};
+
+			vddsoc_reg: bcore2 {
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1450000>;
+				regulator-ramp-delay = <20000>;
+				regulator-name = "DA9063_SOC";
+				regulator-always-on;
+			};
+
+			vdd_ddr3_reg: bpro {
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-ramp-delay = <20000>;
+				regulator-always-on;
+			};
+
+			vdd_3v3_reg: bperi {
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-ramp-delay = <20000>;
+				regulator-always-on;
+			};
+
+			vdd_sata_reg: ldo3 {
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-always-on;
+			};
+			vdd_mipi_reg: ldo4 {
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-always-on;
+			};
+
+			vdd_mx6_snvs_reg: ldo5 {
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vdd_hdmi_reg: ldo6 {
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vdd_pcie_reg: ldo7 {
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-always-on;
+			};
+
+			vdd_1V8_reg: ldo8 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			vdd_3V3_sdc_reg: ldo9 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vdd_1V2_reg: ldo10 {
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+};
+
+&uart5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	phy-mode = "rgmii";
+	phy-reset-gpios = <&gpio5 20 GPIO_ACTIVE_LOW>;
+	phy-reset-duration = <50>;
+	phy-supply = <&vdd_1V8_reg>;
+	phy-handle = <&ksz9031>;
+	status = "okay";
+
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ksz9031: phy at 0 {
+			reg = <0>;
+			compatible = "ethernet-phy-ieee802.3-c22";
+			interrupt-parent = <&gpio1>;
+			interrupts = <30 IRQ_TYPE_EDGE_FALLING>;
+			rxdv-skew-ps = <480>;
+			txen-skew-ps = <480>;
+			rxd0-skew-ps = <480>;
+			rxd1-skew-ps = <480>;
+			rxd2-skew-ps = <480>;
+			rxd3-skew-ps = <480>;
+			txd0-skew-ps = <420>;
+			txd1-skew-ps = <420>;
+			txd2-skew-ps = <360>;
+			txd3-skew-ps = <360>;
+			txc-skew-ps = <1020>;
+			rxc-skew-ps = <960>;
+		};
+	};
+};
+
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	non-removable;
+	bus-width = <8>;
+	status = "okay";
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie_ctrl>;
+	reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>;
+	disable-gpio = <&gpio2 22 GPIO_ACTIVE_LOW>;
+};
+
+&i2c2 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+};
+
+&usdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	fsl,wp-controller;
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	fsl,wp-controller;
+};
+
+
+&ipu1_di0_disp0 {
+	remote-endpoint = <&rgb_encoder_in>;
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&pwm3 {
+	status = "okay";
+};
+
+&pwm4 {
+	status = "okay";
+};
+
+&ecspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+	cs-gpios =  <&gpio2 25 GPIO_ACTIVE_HIGH>,
+				<&gpio2 26 GPIO_ACTIVE_HIGH>;
+};
+
+&ecspi4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nor_flash>;
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can1>;
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can2>;
+};
+
+&usbh1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb_host1>;
+};
+
+&usbotg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb_otg>;
+	vbus-supply = <&reg_usb_otg>;
+	dr_mode = "peripheral";
+};
+
+/******device power Management*********/
+
+&cpu0 {
+	voltage-tolerance = <2>;
+};
+
+&reg_arm {
+	vin-supply = <&vddcore_reg>;
+};
+
+&reg_soc {
+	vin-supply = <&vddsoc_reg>;
+};
+
+&reg_pu {
+	vin-supply = <&vddsoc_reg>;
+};
+
+
+
+/*******Disabled HW following***********/
+
+
+&weim {
+	status = "disabled";
+};
+
+&snvs_rtc {
+	status = "disabled";
+};
-- 
emtrion GmbH
Alter Schlachthof 45
76131 Karlsruhe
GERMANY
https://www.emtrion.de

Amtsgericht Mannheim
HRB 110 300
Gesch?ftsf?hrer: Dieter Baur, Ramona Maurer

^ permalink raw reply related

* [PATCH v2 3/5] ARM: dts: imx: Add an cpu0 label for imx6dl devices.
From: jan.tuerk at emtrion.com @ 2017-12-20 13:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171220134710.64479-1-jan.tuerk@emtrion.com>

From: Jan Tuerk <jan.tuerk@emtrion.com>

Adding the label cpu0 allows the adjustment of cpu-parameters
by reference in overlaying dtsi files in the same way as it
is possible for imx6q devices.

Signed-off-by: Jan Tuerk <jan.tuerk@emtrion.com>
Reviewed-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm/boot/dts/imx6dl.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index 4d693a75ce98..623c12519b81 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -21,7 +21,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		cpu at 0 {
+		cpu0: cpu at 0 {
 			compatible = "arm,cortex-a9";
 			device_type = "cpu";
 			reg = <0>;
-- 
emtrion GmbH
Alter Schlachthof 45
76131 Karlsruhe
GERMANY
https://www.emtrion.de

Amtsgericht Mannheim
HRB 110 300
Gesch?ftsf?hrer: Dieter Baur, Ramona Maurer

^ permalink raw reply related

* [PATCH v2 2/5] dt-bindings: Add vendor prefix for emtrion GmbH
From: jan.tuerk at emtrion.com @ 2017-12-20 13:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171220134710.64479-1-jan.tuerk@emtrion.com>

From: Jan Tuerk <jan.tuerk@emtrion.com>

emtrion is a system integrator and manufacturer of embedded systems.

Website: https://www.emtrion.de

Signed-off-by: Jan Tuerk <jan.tuerk@emtrion.com>
Reviewed-by: Andreas F?rber <afaerber@suse.de>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 0994bdd82cd3..5215c5767260 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -102,6 +102,7 @@ eeti	eGalax_eMPIA Technology Inc
 elan	Elan Microelectronic Corp.
 embest	Shenzhen Embest Technology Co., Ltd.
 emmicro	EM Microelectronic
+emtrion	emtrion GmbH
 energymicro	Silicon Laboratories (formerly Energy Micro AS)
 engicam	Engicam S.r.l.
 epcos	EPCOS AG
-- 
emtrion GmbH
Alter Schlachthof 45
76131 Karlsruhe
GERMANY
https://www.emtrion.de

Amtsgericht Mannheim
HRB 110 300
Gesch?ftsf?hrer: Dieter Baur, Ramona Maurer

^ permalink raw reply related

* [PATCH v2 1/5] drm/panel: Add support for the EDT ETM0700G0BDH6
From: jan.tuerk at emtrion.com @ 2017-12-20 13:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171220134710.64479-1-jan.tuerk@emtrion.com>

From: Jan Tuerk <jan.tuerk@emtrion.com>

The Emerging Display Technology ETM0700G0BDH6 is exactly
the same display as the ETM0700G0DH6, exept the pixelclock
polarity. Therefore re-use the ETM0700G0DH6 modes. It is
used by default on emtrion Avari based development kits.

Signed-off-by: Jan Tuerk <jan.tuerk@emtrion.com>
---
 .../bindings/display/panel/edt,etm0700g0bdh6.txt          |  9 +++++++++
 drivers/gpu/drm/panel/panel-simple.c                      | 15 +++++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/edt,etm0700g0bdh6.txt

diff --git a/Documentation/devicetree/bindings/display/panel/edt,etm0700g0bdh6.txt b/Documentation/devicetree/bindings/display/panel/edt,etm0700g0bdh6.txt
new file mode 100644
index 000000000000..099e30bfa17f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/edt,etm0700g0bdh6.txt
@@ -0,0 +1,9 @@
+Emerging Display Technology Corp. ETM0700G0BDH6 7.0" WVGA TFT LCD panel
+
+Required properties:
+	compatible: "edt,etm0700g0bdh6"
+
+This panel is exactly the same as ETM0700G0DH6 except the pixelclock polarity.
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index b7c4709f7b34..42442034b53e 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -886,6 +886,18 @@ static const struct panel_desc edt_etm0700g0dh6 = {
 	.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
 };
 
+static const struct panel_desc edt_etm0700g0bdh6 = {
+	.modes = &edt_etm0700g0dh6_mode,
+	.num_modes = 1,
+	.bpc = 6,
+	.size = {
+		.width = 152,
+		.height = 91,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
+};
+
 static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = {
 	.clock = 32260,
 	.hdisplay = 800,
@@ -2029,6 +2041,9 @@ static const struct of_device_id platform_of_match[] = {
 		.compatible = "edt,etm0700g0dh6",
 		.data = &edt_etm0700g0dh6,
 	}, {
+		.compatible = "edt,etm0700g0bdh6",
+		.data = &edt_etm0700g0bdh6,
+	}, {
 		.compatible = "foxlink,fl500wvr00-a0t",
 		.data = &foxlink_fl500wvr00_a0t,
 	}, {
-- 
emtrion GmbH
Alter Schlachthof 45
76131 Karlsruhe
GERMANY
https://www.emtrion.de

Amtsgericht Mannheim
HRB 110 300
Gesch?ftsf?hrer: Dieter Baur, Ramona Maurer

^ permalink raw reply related

* [PATCH v2 0/5] Add basic support for emtrion emCON-MX6 modules
From: jan.tuerk at emtrion.com @ 2017-12-20 13:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171123125600.41562-1-jan.tuerk@emtrion.com>

From: Jan Tuerk <jan.tuerk@emtrion.com>

The following patch-series adds support for emtrion's emCON-MX6 modules 
with all their dependencies. 
The focus is based on the emtrion standard developer-kit configuration. 
It includes a new vendor-prefix, an new simple-panel type, 
a small modification of the imx6dl.dtsi, 
as well as modifications of the common imx_v6_v7_defconfig.
And finally the board devicetrees themselves.

For V2 there are some changes and small fixes following below. 
The smtp issue which was converting tabs into spaces should be fixed now, 
so checkpatch should only warn about the new Documentation files and the
new devicetree bindings which are documented in the corresponding patch.

The documentation for the EDT display is kept as an extra file currently,
as it is done by the most displays in the documentation. Also a new 
new Vartiant of the EDT already arrived. So merging their documentations
should be discussed separately.

  [PATCH v2 1/5] drm/panel: Add support for the EDT ETM0700G0BDH6
	No changes, resend.

  [PATCH v2 2/5] dt-bindings: Add vendor prefix for emtrion GmbH
	v2:
	 - Reviewed-by: Andreas F?rber <afaerber@suse.de>
	 - Acked-by: Rob Herring <robh@kernel.org>

  [PATCH v2 3/5] ARM: dts: imx: Add an cpu0 label for imx6dl devices.
	v2:
	 - Reviewed-by: Andreas F?rber <afaerber@suse.de>

  [PATCH v2 4/5] ARM: dts: Add support for emtrion emCON-MX6 series
	Changes in v2:
	 - Fixed typo (reg_prallel.. --> reg_parallel)
	 - Removed trailing new-line
	 - Fix uppercase addresses as Rob H. noted
	 - Fix warning about lcd at di0 -> rename to disp0
	 - Renamed some nodes regarding Rob H.

  [PATCH v2 5/5] ARM: imx_v6_v7_defconfig: Enable DA0963 PMIC support.
	No changes, resend.


 Documentation/devicetree/bindings/arm/emtrion.txt  |  13 +
 .../bindings/display/panel/edt,etm0700g0bdh6.txt   |   9 +
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/imx6dl-emcon-avari.dts           | 233 ++++++
 arch/arm/boot/dts/imx6dl-emcon.dtsi                |  37 +
 arch/arm/boot/dts/imx6dl.dtsi                      |   2 +-
 arch/arm/boot/dts/imx6q-emcon-avari.dts            | 233 ++++++
 arch/arm/boot/dts/imx6q-emcon.dtsi                 |  37 +
 arch/arm/boot/dts/imx6qdl-emcon.dtsi               | 848 ++++++++++++++++
 arch/arm/configs/imx_v6_v7_defconfig               |   4 +
 drivers/gpu/drm/panel/panel-simple.c               |  15 +
 12 files changed, 1433 insertions(+), 1 deletion(-)

-- 
emtrion GmbH
Alter Schlachthof 45
76131 Karlsruhe
GERMANY
https://www.emtrion.de

Amtsgericht Mannheim
HRB 110 300
Gesch?ftsf?hrer: Dieter Baur, Ramona Maurer

^ permalink raw reply

* [PATCH, RFT] ARM: use --fix-v4bx to allow building ARMv4 with future gcc
From: Ard Biesheuvel @ 2017-12-20 13:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171220130016.3156090-1-arnd@arndb.de>

Hi Arnd,

On 20 December 2017 at 13:00, Arnd Bergmann <arnd@arndb.de> wrote:
> gcc-6.0 and later marks support for ARMv3 and ARMv4 as 'deprecated',
> meaning that this is expected to be removed at some point in the future,
> with gcc-8.0 as the earliest.
>
> When building the kernel, the difference between ARMv4 and ARMv4T
> is relatively small because the kernel never runs THUMB instructions
> on ARMv4T and does not need any support for interworking.
>
> For any future compiler that does not support -march=armv4, we now
> fall back to -march=armv4t as the architecture level selection,
> but keep using -march=armv4 by default as long as that is supported
> by the compiler.
>
> Similarly, the -mtune=strongarm110 and -mtune=strongarm1100 options
> will go away at the same time as -march=armv4, so this adds a check
> to see if the compiler supports them, falling back to no -mtune
> option otherwise.
>
> Compiling with -march=armv4t leads the compiler to using 'bx reg'
> instructions instead of 'mov pc,reg'. This is not supported on
> ARMv4 based CPUs, but the linker can work around this by rewriting
> those instructions to the ARMv4 version if we pass --fix-v4bx
> to the linker. This should work with binutils-2.15 (released
> May 2004) or higher, and we can probably assume that anyone using
> gcc-7.x will have a much more recent binutils version as well.
>
> However, in order to still allow users of old toolchains to link
> the kernel, we only pass the option to linkers that support it,
> based on a $(ld-option ...) call. I'm intentionally passing the
> flag to all linker versions here regardless of whether it's needed
> or not, so we can more easily spot any regressions if something
> goes wrong.
>
> For consistency, I'm passing the --fix-v4bx flag for both the
> vmlinux final link and the individual loadable modules.
> The module loader code already interprets the R_ARM_V4BX relocations
> in loadable modules and converts bx instructions into mov even
> when running on ARMv4T or ARMv5 processors. This is now redundant
> when we pass --fix-v4bx to the linker for building modules, but
> I see no harm in leaving the current implementation and doing both.
>

Are you sure --fix-v4bx is taken into account during a partial link?

> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> Please test by making the -march=armv4t switch unconditional
> and see if that results in a working kernel
>
>  arch/arm/Makefile | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index e83f5161fdd8..33b7eb4502aa 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -19,6 +19,11 @@ LDFLAGS_vmlinux      += --be8
>  KBUILD_LDFLAGS_MODULE  += --be8
>  endif
>
> +ifeq ($(CONFIG_CPU_32v4),y)
> +LDFLAGS_vmlinux        += $(call ld-option,--fix-v4bx)
> +LDFLAGS_MODULE += $(call ld-option,--fix-v4bx)
> +endif
> +
>  ifeq ($(CONFIG_ARM_MODULE_PLTS),y)
>  KBUILD_LDFLAGS_MODULE  += -T $(srctree)/arch/arm/kernel/module.lds
>  endif
> @@ -76,7 +81,7 @@ arch-$(CONFIG_CPU_32v6K)      =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,
>  endif
>  arch-$(CONFIG_CPU_32v5)                =-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
>  arch-$(CONFIG_CPU_32v4T)       =-D__LINUX_ARM_ARCH__=4 -march=armv4t
> -arch-$(CONFIG_CPU_32v4)                =-D__LINUX_ARM_ARCH__=4 -march=armv4
> +arch-$(CONFIG_CPU_32v4)                =-D__LINUX_ARM_ARCH__=4 $(call cc-option,-march=armv4,-march=armv4t)
>  arch-$(CONFIG_CPU_32v3)                =-D__LINUX_ARM_ARCH__=3 -march=armv3
>
>  # Evaluate arch cc-option calls now
> @@ -94,8 +99,8 @@ tune-$(CONFIG_CPU_ARM922T)    =-mtune=arm9tdmi
>  tune-$(CONFIG_CPU_ARM925T)     =-mtune=arm9tdmi
>  tune-$(CONFIG_CPU_ARM926T)     =-mtune=arm9tdmi
>  tune-$(CONFIG_CPU_FA526)       =-mtune=arm9tdmi
> -tune-$(CONFIG_CPU_SA110)       =-mtune=strongarm110
> -tune-$(CONFIG_CPU_SA1100)      =-mtune=strongarm1100
> +tune-$(CONFIG_CPU_SA110)       =$(call cc-option,-mtune=strongarm110)
> +tune-$(CONFIG_CPU_SA1100)      =$(call cc-option,-mtune=strongarm1100)
>  tune-$(CONFIG_CPU_XSCALE)      =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
>  tune-$(CONFIG_CPU_XSC3)                =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale

Shouldn't these two be updated as well?

>  tune-$(CONFIG_CPU_FEROCEON)    =$(call cc-option,-mtune=marvell-f,-mtune=xscale)
> --
> 2.9.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v5 0/4] ARM: ep93xx: ts72xx: Add support for BK3 board
From: Alexander Sverdlin @ 2017-12-20 13:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a363oaDdBSV3k2uAE0UVUbuBsHUeo94OBMX4F_7jC-T5Q@mail.gmail.com>

Hi Arnd!

On Wed Dec 20 14:14:07 2017 Arnd Bergmann <arnd@arndb.de> wrote:
> > If it will be still possible to build the binary kernel of the same
> > size after the conversion, I'm in for testing, otherwise it will not
> > fit into Flash any more...
> 
> I think there is an increase in code size that comes mainly from the
> common clock layer itself, plus a few bytes here and there. Obviously
> the increase is much bigger if you actually enable multiple platforms.
> 
> Here is the size of the uncompressed vmlinux file with the current
> clk implementation, compared to a build with a build containing the
> common clk code but no clock driver, and the separate clock
> implementation we have today:
> 
>? ? ?  text? ? ?  data? ? ? ?  bss? ? ? ?  dec? ? ? ?  hex filename
> 4752655 1036028 128260 5916943 5a490f build/tmp/vmlinux-old-clk
> 4780174 1040524 128284 5948982 5ac636 build/tmp/vmlinux-common-clk
>? ? ?  2491? ? ?  1700? ? ? ? ? ?  0? ? ?  4191? ? ?  105f
> build/tmp/arch/arm/mach-ep93xx/clock.o
> 
> The difference would come to about 0.7% of the current image size,
> I guess around 1% when the other changes are included. Is that within
> the margins you have, or is this already critical?

No, your numbers are promising, I was afraid of the increase of other orders of magnitude. So this should be fine.

Thanks for this info.

--
Alex.

^ permalink raw reply

* [PATCH v2 6/6] ARM: imx_v6_v7_defconfig: Enable Dialog Semiconductor DA9062 driver
From: Stefan Riedmueller @ 2017-12-20 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1513776567-30182-1-git-send-email-s.riedmueller@phytec.de>

The phyCORE-i.MX 6 uses the DA9062/63 PMIC, RTC and Watchdog driver.

Enable these options by default.

Signed-off-by: Stefan Riedmueller <s.riedmueller@phytec.de>
---
 arch/arm/configs/imx_v6_v7_defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 6726c83..e3c4163 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -216,8 +216,10 @@ CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_CPU_THERMAL=y
 CONFIG_IMX_THERMAL=y
 CONFIG_WATCHDOG=y
+CONFIG_DA9062_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_MFD_DA9052_I2C=y
+CONFIG_MFD_DA9062=y
 CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
 CONFIG_MFD_STMPE=y
@@ -225,6 +227,7 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
 CONFIG_REGULATOR_DA9052=y
+CONFIG_REGULATOR_DA9062=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
@@ -348,6 +351,7 @@ CONFIG_RTC_DRV_ISL1208=y
 CONFIG_RTC_DRV_PCF8523=y
 CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_M41T80=y
+CONFIG_RTC_DRV_DA9063=y
 CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
 CONFIG_RTC_DRV_SNVS=y
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 5/6] ARM: dts: imx6: Add support for phyBOARD-Mira with i.MX 6QuadPlus
From: Stefan Riedmueller @ 2017-12-20 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1513776567-30182-1-git-send-email-s.riedmueller@phytec.de>

From: Enrico Scholz <enrico.scholz@sigma-chemnitz.de>

Add support for the PHYTEC phyBOARD-Mira with i.MX 6QuadPlus with NAND.
It is based on the phyBOARD-Mira with i.MX 6Quad/Dual and supports the
same interfaces.

Signed-off-by: Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
Signed-off-by: Stefan Lengfeld <s.lengfeld@phytec.de>
Signed-off-by: Christian Hemp <c.hemp@phytec.de>
Signed-off-by: Stefan Riedmueller <s.riedmueller@phytec.de>
---
 arch/arm/boot/dts/Makefile                        |  1 +
 arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts | 72 +++++++++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 07d99a1..d42b522 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -479,6 +479,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6q-zii-rdu2.dtb \
 	imx6qp-nitrogen6_max.dtb \
 	imx6qp-nitrogen6_som2.dtb \
+	imx6qp-phytec-mira-rdk-nand.dtb \
 	imx6qp-sabreauto.dtb \
 	imx6qp-sabresd.dtb \
 	imx6qp-tx6qp-8037.dtb \
diff --git a/arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts b/arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts
new file mode 100644
index 0000000..57818c1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2017 PHYTEC Messtechnik GmbH
+ * Author: Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
+ */
+
+/dts-v1/;
+#include "imx6qp.dtsi"
+#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
+
+/ {
+	model = "PHYTEC phyBOARD-Mira QuadPlus Carrier-Board with NAND";
+	compatible = "phytec,imx6qp-pbac06-nand", "phytec,imx6qp-pbac06",
+		     "phytec,imx6qdl-pcm058", "fsl,imx6qp";
+
+	chosen {
+		linux,stdout-path = &uart2;
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&fec {
+	status = "okay";
+};
+
+&flash {
+	status = "okay";
+};
+
+&gpmi {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c_rtc {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 4/6] ARM: dts: imx6: Add support for phxBOARD-Mira i.MX 6 DualLight/Solo RDK
From: Stefan Riedmueller @ 2017-12-20 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1513776567-30182-1-git-send-email-s.riedmueller@phytec.de>

From: Christian Hemp <c.hemp@phytec.de>

Add support for the PHYTEC phyBOARD-Mira Low-Cost Rapid Development Kit
with i.MX 6DualLight/Solo with NAND.

Following interfaces are supported:
- 100 MBit Ethernet
- USB Host
- RS232
- HDMI

Signed-off-by: Christian Hemp <c.hemp@phytec.de>
Signed-off-by: Stefan Christ <s.christ@phytec.de>
Signed-off-by: Stefan Riedmueller <s.riedmueller@phytec.de>
---
 arch/arm/boot/dts/Makefile                        |  1 +
 arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts | 64 +++++++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b793617..07d99a1 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -388,6 +388,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-icore-rqs.dtb \
 	imx6dl-nit6xlite.dtb \
 	imx6dl-nitrogen6x.dtb \
+	imx6dl-phytec-mira-rdk-nand.dtb \
 	imx6dl-phytec-pbab01.dtb \
 	imx6dl-rex-basic.dtb \
 	imx6dl-riotboard.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts b/arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts
new file mode 100644
index 0000000..f56c20f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2017 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
+
+/ {
+	model = "PHYTEC phyBOARD-Mira DualLite/Solo Carrier-Board with NAND";
+	compatible = "phytec,imx6dl-pbac06-nand", "phytec,imx6dl-pbac06",
+		     "phytec,imx6qdl-pcm058", "fsl,imx6dl";
+
+	chosen {
+		linux,stdout-path = &uart2;
+	};
+};
+
+&ethphy {
+	max-speed = <100>;
+};
+
+&fec {
+	status = "okay";
+};
+
+&gpmi {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c_rtc {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
-- 
2.7.4

^ permalink raw reply related


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