Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] ARM: dts: Switch to new DSA binding
From: Florian Fainelli @ 2017-01-17  1:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170105192957.14304-1-f.fainelli@gmail.com>

On 01/05/2017 11:29 AM, Florian Fainelli wrote:
> Hi all,
> 
> This patch series converts the in-tree users to utilize the new (relatively)
> DSA binding that was introduced with commit 8c5ad1d6179d ("net: dsa: Document
> new binding"). The legacy binding node is kept included, but is marked
> disabled.
> 
> Changes in v2:
> 
> - patch 1: Use an hexadecimal reg property
> - patch 2: fixed the subject
> - patch 3: s/okay/disabled/ for the legacy DSA node
> - patches 7/8: fixed a stray whitespace
> 
> In about 2-3 releases we may consider removing the old DSA binding entirely
> from the kernel.

Gregory, are you going to take this for 4.11? Thanks

> 
> Thank you!
> 
> Florian Fainelli (8):
>   ARM: dts: armada-370-rd: Utilize new DSA binding
>   ARM: dts: armada-385-linksys: Utilize new DSA binding
>   ARM: dts: armada-388-clearfog: Utilize new DSA binding
>   ARM: dts: armada-xp-linksys-mamba: Utilize new DSA binding
>   ARM: dts: kirkwood-dir665: Utilize new DSA binding
>   ARM: dts: kirkwood-linksys-viper: Utilize new DSA binding
>   ARM: dts: kirkwood-mv88f6281gtw-ge: Utilize new DSA binding
>   ARM: dts: kirkwood-rd88f6281: Utilize new DSA binding
> 
>  arch/arm/boot/dts/armada-370-rd.dts            | 44 +++++++++++++++++
>  arch/arm/boot/dts/armada-385-linksys.dtsi      | 52 ++++++++++++++++++++-
>  arch/arm/boot/dts/armada-388-clearfog.dts      | 65 ++++++++++++++++++++++++++
>  arch/arm/boot/dts/armada-xp-linksys-mamba.dts  | 53 +++++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-dir665.dts          | 49 +++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-linksys-viper.dts   | 49 +++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 49 +++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts    | 11 +++++
>  arch/arm/boot/dts/kirkwood-rd88f6281.dtsi      | 44 +++++++++++++++++
>  9 files changed, 415 insertions(+), 1 deletion(-)
> 


-- 
Florian

^ permalink raw reply

* [PATCH 0/4] video: ARM CLCD: add support of an optional GPIO to enable panel
From: Vladimir Zapolskiy @ 2017-01-17  1:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3057141.7Vn8X5ONyT@amdc3058>

On 01/13/2017 01:08 PM, Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Thursday, January 12, 2017 11:26:14 PM Vladimir Zapolskiy wrote:
>> On 01/12/2017 10:27 AM, Linus Walleij wrote:
>>> On Thu, Jan 12, 2017 at 1:05 AM, Vladimir Zapolskiy <vz@mleia.com> wrote:
>>>> On 01/11/2017 05:16 PM, Linus Walleij wrote:
>>>>> On Tue, Jan 10, 2017 at 2:47 PM, Vladimir Murzin
>>>>> <vladimir.murzin@arm.com> wrote:
>>>>>
>>>>>> In another thread Benjamin pointed at patch [1] in drm/kms part for noMMU.
>>>>>>
>>>>>> [1] https://cgit.freedesktop.org/drm/drm-misc/commit/?id=62a0d98a188cc4ebd8ea54b37d274ec20465e464
>>>>>
>>>>> Problem solved?
>>>>>
>>>>> Vladimir: I do not require in any way that you create a CLCD driver for DRM,
>>>>> I just think it would be very very nice...
>>>>>
>>>>
>>>> I have no other option, this series is unreviewed and thus unlikely it will
>>>> be applied, still a panel PCB on my board needs power management support.
>>>
>>> Hm I can ACK it I guess, but mergeing it into an unmaintained subsystem
>>> is another issue, just not very optimal. 
>>
>> + Bartlomiej
>>
>> Linus, your ack is always more than appreciated.
> 
> +1
> 
>> To all appearance Bartlomiej is a new honoured framebuffer layer maintainer.
>>
>> Bartlomiej, do you have the changes under discussion in your mailbox or
>> should I resend them to you directly for review?
> 
> No need for resend, I picked them from the list and they are on TODO.
> 

Bartlomiej, Linus,

I've noticed that 4/4 requires special attention due to the anticipated
change of devm_get_gpiod_from_child() interface.

If you have any concerns regarding 4/4, please review and consider to
apply the first three clean-up patches in the series, basically I've
achieved my goal of describing a power supply for a panel in DTS by
introducing a DRM driver (see a note below), however support of
"enable-gpios" property mentioned in the "panel-dpi" device tree binding
documentation still is seen as beneficial for the CLCD fbdev driver.

> 
>>> If you get it working on your system I can look into migrating all the old
>>> users to DRM as well.
>>>
>>
>> Sure, I started development of a simple CLCD DRM driver as an own attractive
>> exercise, I'll keep you informed of the progress.
>>

Some updates, now I've developed a simple CLCD DRM driver which works
nicely on one of my boards powered by LPC3250 (has MMU), but I still
have to find enough time and check that the driver works on MMU-less
LPC4357 with the applied DRM core change referenced by Vladimir earlier.

Most probably I'll complete polishing the driver on this weekend and
send it for review on the next week.

One more comment, I've found a discussion when DT support to the CLCD
fbdev driver was added [1], there are some comments about panel device
node and endpoints incompatibility in comparison to the common layout
for Linux-ish DRM devices, and I do confirm that this incompatibility
exists. I have both versions though, but you guess that DRM flavour
is cleaner, and for CLCD DRM driver I'm going to use it.

The legacy DT layout can be supported in the same driver in parallel,
but unfortunately it makes the driver not so cute, and I decide to
drop it in the initial version. It implies that CLCD fbdev users with
the controller and panel descriptions in DT and who want to switch to
CLCD DRM driver should update DTS. Sorry, I know it is inconvenient...

[1] https://patchwork.kernel.org/patch/3777391/

--
With best wishes,
Vladimir

^ permalink raw reply

* arm: Add livepatch arch specific code
From: Jessica Yu @ 2017-01-17  2:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170117002239.GF9045@packer-debian-8-amd64.digitalocean.com>

+++ Jessica Yu [16/01/17 19:22 -0500]:
>+++ Miroslav Benes [16/01/17 17:47 +0100]:
>>On Tue, 6 Dec 2016, Abel Vesa wrote:
>>
>>>klp_get_ftrace_location is used by ftrace to get the entry for a
>>>specific function from the mcount list. klp_arch_set_pc is used
>>>to set the pc from the regs passed as an argument to the
>>>ftrace_ops_no_ops function to the starting address of the patched
>>>function. klp_write_module_reloc is not doing anything at this
>>>moment.
>>>
>>>Signed-off-by: Abel Vesa <abelvesa@linux.com>
>>>---
>>> MAINTAINERS                      |  3 +++
>>> arch/arm/include/asm/livepatch.h | 46 ++++++++++++++++++++++++++++++++++++++++
>>> arch/arm/kernel/livepatch.c      | 43 +++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 92 insertions(+)
>>> create mode 100644 arch/arm/include/asm/livepatch.h
>>> create mode 100644 arch/arm/kernel/livepatch.c
>>>
>>>diff --git a/MAINTAINERS b/MAINTAINERS
>>>index bd182a1..d43b790 100644
>>>--- a/MAINTAINERS
>>>+++ b/MAINTAINERS
>>>@@ -7466,12 +7466,15 @@ M:	Josh Poimboeuf <jpoimboe@redhat.com>
>>> M:	Jessica Yu <jeyu@redhat.com>
>>> M:	Jiri Kosina <jikos@kernel.org>
>>> M:	Miroslav Benes <mbenes@suse.cz>
>>>+M:	Abel Vesa <abelvesa@linux.com>
>>> R:	Petr Mladek <pmladek@suse.com>
>>> S:	Maintained
>>> F:	kernel/livepatch/
>>> F:	include/linux/livepatch.h
>>> F:	arch/x86/include/asm/livepatch.h
>>> F:	arch/x86/kernel/livepatch.c
>>>+F:	arch/arm/include/asm/livepatch.h
>>>+F:	arch/arm/kernel/livepatch.c
>>> F:	Documentation/livepatch/
>>> F:	Documentation/ABI/testing/sysfs-kernel-livepatch
>>> F:	samples/livepatch/
>>
>>Thanks for the offer but I think we manage quite well ;)
>>
>>>diff --git a/arch/arm/include/asm/livepatch.h b/arch/arm/include/asm/livepatch.h
>>>new file mode 100644
>>>index 0000000..d4e3ff0
>>>--- /dev/null
>>>+++ b/arch/arm/include/asm/livepatch.h
>>>@@ -0,0 +1,46 @@
>>>+/*
>>>+ * livepatch.h - arm specific Kernel Live Patching Core
>>>+ *
>>>+ * Copyright (C) 2016 Abel Vesa <abelvesa@linux.com>
>>>+ *
>>>+ * This program is free software; you can redistribute it and/or
>>>+ * modify it under the terms of the GNU General Public License
>>>+ * as published by the Free Software Foundation; either version 2
>>>+ * of the License, or (at your option) any later version.
>>>+ *
>>>+ * This program is distributed in the hope that it will be useful,
>>>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>>+ * GNU General Public License for more details.
>>>+ *
>>>+ * You should have received a copy of the GNU General Public License
>>>+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
>>>+ */
>>>+
>>>+#ifndef _ASM_ARM_LIVEPATCH_H
>>>+#define _ASM_ARM_LIVEPATCH_H
>>>+
>>>+#include <asm/setup.h>
>>>+#include <linux/module.h>
>>>+#include <linux/ftrace.h>
>>>+
>>>+static inline int klp_check_compiler_support(void)
>>>+{
>>>+	return 0;
>>>+}
>>>+
>>>+int klp_write_module_reloc(struct module *mod, unsigned long type,
>>>+			   unsigned long loc, unsigned long value);
>>
>>This is not needed. See below.
>>
>>>+
>>>+static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip)
>>>+{
>>>+	regs->uregs[15] = ip;
>>>+}
>>>+
>>>+#define klp_get_ftrace_location klp_get_ftrace_location
>>>+static inline unsigned long klp_get_ftrace_location(unsigned long faddr)
>>>+{
>>>+	return ftrace_location_range(faddr, faddr + 24);
>>
>>Comment here about +24 would be great. See similar in powerpc header file.
>>
>>>+}
>>>+
>>>+#endif /* _ASM_ARM_LIVEPATCH_H */
>>>diff --git a/arch/arm/kernel/livepatch.c b/arch/arm/kernel/livepatch.c
>>>new file mode 100644
>>>index 0000000..0656cd6
>>>--- /dev/null
>>>+++ b/arch/arm/kernel/livepatch.c
>>>@@ -0,0 +1,43 @@
>>>+/*
>>>+ * livepatch.c - arm specific Kernel Live Patching Core
>>>+ *
>>>+ * Copyright (C) 2016 Abel Vesa <abelvesa@linux.com>
>>>+ *
>>>+ * This program is free software; you can redistribute it and/or
>>>+ * modify it under the terms of the GNU General Public License
>>>+ * as published by the Free Software Foundation; either version 2
>>>+ * of the License, or (at your option) any later version.
>>>+ *
>>>+ * This program is distributed in the hope that it will be useful,
>>>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>>+ * GNU General Public License for more details.
>>>+ *
>>>+ * You should have received a copy of the GNU General Public License
>>>+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
>>>+ */
>>>+
>>>+#include <linux/module.h>
>>>+#include <linux/uaccess.h>
>>>+#include <linux/ftrace.h>
>>>+#include <asm/elf.h>
>>>+#include <asm/livepatch.h>
>>>+#include <asm/insn.h>
>>>+#include <asm/ftrace.h>
>>>+
>>>+/**
>>>+ * klp_write_module_reloc() - write a relocation in a module
>>>+ * @mod:	module in which the section to be modified is found
>>>+ * @type:	ELF relocation type (see asm/elf.h)
>>>+ * @loc:	address that the relocation should be written to
>>>+ * @value:	relocation value (sym address + addend)
>>>+ *
>>>+ * This function writes a relocation to the specified location for
>>>+ * a particular module.
>>>+ */
>>>+int klp_write_module_reloc(struct module *mod, unsigned long type,
>>>+			   unsigned long loc, unsigned long value)
>>>+{
>>>+	/* Not implemented yet */
>>>+	return 0;
>>>+}
>>
>>This whole file is not needed. Livepatching uses kernel's internal
>>apply_relocate_add() for dealing with relocations. The only thing you need
>>to do is to make sure that all needed arch-specific info is preserved
>>during a module loading. Specifically mod_arch_specific structure needs to
>>be examined in this respect.
>
>Yup. Since we rely on apply_relocate_add() to apply relocations, just
>make sure that you preserve anything (e.g., plt tables) you need to
>make that call post-module init. In the case of s390, we needed to
>make sure we kept mod->arch.syminfo, so that the call to
>apply_relocate_add() would succeed.
>
>>But apply_relocate_add() is not implemented on arm yet. I guess it would
>>nice to have it... otherwise we could get to an unpleasant situation.
>>Livepatch module can rely on its livepatching relocations (that is, there
>>are some). apply_relocate_add() returns 0 on arm, so everything seems to
>>be nice and then boom some time later.
>
>Doesn't it return -ENOEXEC? MODULES_USE_ELF_RELA is not defined
>on arm, I think (see moduleloader.h).

...And I should have looked at the whole patchset first before
replying :-) I see now that a placeholder was added in patch 3/7.

Jessica

^ permalink raw reply

* [PATCH v11 03/12] drm/mediatek: add *driver_data for different hardware settings
From: CK Hu @ 2017-01-17  2:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484117473-46644-4-git-send-email-yt.shen@mediatek.com>

Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> There are some hardware settings changed, between MT8173 & MT2701:
> DISP_OVL address offset changed, color format definition changed.
> DISP_RDMA fifo size changed.
> DISP_COLOR offset changed.
> MIPI_TX pll setting changed.
> And add prefix for mtk_ddp_main & mtk_ddp_ext & mutex_mod.
> 
> Signed-off-by: YT Shen <yt.shen@mediatek.com>

Acked-by: CK Hu <ck.hu@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 41 ++++++++++++-----
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c    | 18 +++++++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c      | 71 +++++++++++++++--------------
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 57 +++++++++++++++++++----
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 25 +++++++---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |  8 ++++
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c      | 24 +++++++++-
>  7 files changed, 181 insertions(+), 63 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index ce2759f..4552178 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -35,18 +35,27 @@
>  #define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
> -#define DISP_REG_OVL_ADDR(n)			(0x0f40 + 0x20 * (n))
> +#define DISP_REG_OVL_ADDR_MT8173		0x0f40
> +#define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n))
>  
>  #define	OVL_RDMA_MEM_GMC	0x40402020
>  
>  #define OVL_CON_BYTE_SWAP	BIT(24)
> -#define OVL_CON_CLRFMT_RGB565	(0 << 12)
> -#define OVL_CON_CLRFMT_RGB888	(1 << 12)
> +#define OVL_CON_CLRFMT_RGB	(1 << 12)
>  #define OVL_CON_CLRFMT_RGBA8888	(2 << 12)
>  #define OVL_CON_CLRFMT_ARGB8888	(3 << 12)
> +#define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
> +					0 : OVL_CON_CLRFMT_RGB)
> +#define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
> +					OVL_CON_CLRFMT_RGB : 0)
>  #define	OVL_CON_AEN		BIT(8)
>  #define	OVL_CON_ALPHA		0xff
>  
> +struct mtk_disp_ovl_data {
> +	unsigned int addr;
> +	bool fmt_rgb565_is_0;
> +};
> +
>  /**
>   * struct mtk_disp_ovl - DISP_OVL driver structure
>   * @ddp_comp - structure containing type enum and hardware resources
> @@ -55,6 +64,7 @@
>  struct mtk_disp_ovl {
>  	struct mtk_ddp_comp		ddp_comp;
>  	struct drm_crtc			*crtc;
> +	const struct mtk_disp_ovl_data	*data;
>  };
>  
>  static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
> @@ -141,18 +151,18 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
>  	writel(0x0, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
>  }
>  
> -static unsigned int ovl_fmt_convert(unsigned int fmt)
> +static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
>  {
>  	switch (fmt) {
>  	default:
>  	case DRM_FORMAT_RGB565:
> -		return OVL_CON_CLRFMT_RGB565;
> +		return OVL_CON_CLRFMT_RGB565(ovl);
>  	case DRM_FORMAT_BGR565:
> -		return OVL_CON_CLRFMT_RGB565 | OVL_CON_BYTE_SWAP;
> +		return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;
>  	case DRM_FORMAT_RGB888:
> -		return OVL_CON_CLRFMT_RGB888;
> +		return OVL_CON_CLRFMT_RGB888(ovl);
>  	case DRM_FORMAT_BGR888:
> -		return OVL_CON_CLRFMT_RGB888 | OVL_CON_BYTE_SWAP;
> +		return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
>  	case DRM_FORMAT_RGBX8888:
>  	case DRM_FORMAT_RGBA8888:
>  		return OVL_CON_CLRFMT_ARGB8888;
> @@ -171,6 +181,7 @@ static unsigned int ovl_fmt_convert(unsigned int fmt)
>  static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
>  				 struct mtk_plane_state *state)
>  {
> +	struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
>  	struct mtk_plane_pending_state *pending = &state->pending;
>  	unsigned int addr = pending->addr;
>  	unsigned int pitch = pending->pitch & 0xffff;
> @@ -182,7 +193,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
>  	if (!pending->enable)
>  		mtk_ovl_layer_off(comp, idx);
>  
> -	con = ovl_fmt_convert(fmt);
> +	con = ovl_fmt_convert(ovl, fmt);
>  	if (idx != 0)
>  		con |= OVL_CON_AEN | OVL_CON_ALPHA;
>  
> @@ -190,7 +201,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
>  	writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
>  	writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
>  	writel_relaxed(offset, comp->regs + DISP_REG_OVL_OFFSET(idx));
> -	writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(idx));
> +	writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(ovl, idx));
>  
>  	if (pending->enable)
>  		mtk_ovl_layer_on(comp, idx);
> @@ -267,6 +278,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	priv->data = of_device_get_match_data(dev);
> +
>  	platform_set_drvdata(pdev, priv);
>  
>  	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> @@ -290,8 +303,14 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
> +	.addr = DISP_REG_OVL_ADDR_MT8173,
> +	.fmt_rgb565_is_0 = true,
> +};
> +
>  static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> -	{ .compatible = "mediatek,mt8173-disp-ovl", },
> +	{ .compatible = "mediatek,mt8173-disp-ovl",
> +	  .data = &mt8173_ovl_driver_data},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 21eff6f..e5e5318 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -38,6 +38,11 @@
>  #define RDMA_FIFO_UNDERFLOW_EN				BIT(31)
>  #define RDMA_FIFO_PSEUDO_SIZE(bytes)			(((bytes) / 16) << 16)
>  #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes)		((bytes) / 16)
> +#define RDMA_FIFO_SIZE(rdma)			((rdma)->data->fifo_size)
> +
> +struct mtk_disp_rdma_data {
> +	unsigned int fifo_size;
> +};
>  
>  /**
>   * struct mtk_disp_rdma - DISP_RDMA driver structure
> @@ -47,6 +52,7 @@
>  struct mtk_disp_rdma {
>  	struct mtk_ddp_comp		ddp_comp;
>  	struct drm_crtc			*crtc;
> +	const struct mtk_disp_rdma_data	*data;
>  };
>  
>  static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
> @@ -114,6 +120,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
>  {
>  	unsigned int threshold;
>  	unsigned int reg;
> +	struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
>  
>  	rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xfff, width);
>  	rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_1, 0xfffff, height);
> @@ -126,7 +133,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
>  	 */
>  	threshold = width * height * vrefresh * 4 * 7 / 1000000;
>  	reg = RDMA_FIFO_UNDERFLOW_EN |
> -	      RDMA_FIFO_PSEUDO_SIZE(SZ_8K) |
> +	      RDMA_FIFO_PSEUDO_SIZE(RDMA_FIFO_SIZE(rdma)) |
>  	      RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
>  	writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
>  }
> @@ -211,6 +218,8 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	priv->data = of_device_get_match_data(dev);
> +
>  	platform_set_drvdata(pdev, priv);
>  
>  	ret = component_add(dev, &mtk_disp_rdma_component_ops);
> @@ -227,8 +236,13 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
> +	.fifo_size = SZ_8K,
> +};
> +
>  static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
> -	{ .compatible = "mediatek,mt8173-disp-rdma", },
> +	{ .compatible = "mediatek,mt8173-disp-rdma",
> +	  .data = &mt8173_rdma_driver_data},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index 17ba935..8030769 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -36,21 +36,21 @@
>  #define DISP_REG_MUTEX_MOD(n)	(0x2c + 0x20 * (n))
>  #define DISP_REG_MUTEX_SOF(n)	(0x30 + 0x20 * (n))
>  
> -#define MUTEX_MOD_DISP_OVL0		BIT(11)
> -#define MUTEX_MOD_DISP_OVL1		BIT(12)
> -#define MUTEX_MOD_DISP_RDMA0		BIT(13)
> -#define MUTEX_MOD_DISP_RDMA1		BIT(14)
> -#define MUTEX_MOD_DISP_RDMA2		BIT(15)
> -#define MUTEX_MOD_DISP_WDMA0		BIT(16)
> -#define MUTEX_MOD_DISP_WDMA1		BIT(17)
> -#define MUTEX_MOD_DISP_COLOR0		BIT(18)
> -#define MUTEX_MOD_DISP_COLOR1		BIT(19)
> -#define MUTEX_MOD_DISP_AAL		BIT(20)
> -#define MUTEX_MOD_DISP_GAMMA		BIT(21)
> -#define MUTEX_MOD_DISP_UFOE		BIT(22)
> -#define MUTEX_MOD_DISP_PWM0		BIT(23)
> -#define MUTEX_MOD_DISP_PWM1		BIT(24)
> -#define MUTEX_MOD_DISP_OD		BIT(25)
> +#define MT8173_MUTEX_MOD_DISP_OVL0		BIT(11)
> +#define MT8173_MUTEX_MOD_DISP_OVL1		BIT(12)
> +#define MT8173_MUTEX_MOD_DISP_RDMA0		BIT(13)
> +#define MT8173_MUTEX_MOD_DISP_RDMA1		BIT(14)
> +#define MT8173_MUTEX_MOD_DISP_RDMA2		BIT(15)
> +#define MT8173_MUTEX_MOD_DISP_WDMA0		BIT(16)
> +#define MT8173_MUTEX_MOD_DISP_WDMA1		BIT(17)
> +#define MT8173_MUTEX_MOD_DISP_COLOR0		BIT(18)
> +#define MT8173_MUTEX_MOD_DISP_COLOR1		BIT(19)
> +#define MT8173_MUTEX_MOD_DISP_AAL		BIT(20)
> +#define MT8173_MUTEX_MOD_DISP_GAMMA		BIT(21)
> +#define MT8173_MUTEX_MOD_DISP_UFOE		BIT(22)
> +#define MT8173_MUTEX_MOD_DISP_PWM0		BIT(23)
> +#define MT8173_MUTEX_MOD_DISP_PWM1		BIT(24)
> +#define MT8173_MUTEX_MOD_DISP_OD		BIT(25)
>  
>  #define MUTEX_SOF_SINGLE_MODE		0
>  #define MUTEX_SOF_DSI0			1
> @@ -77,24 +77,25 @@ struct mtk_ddp {
>  	struct clk			*clk;
>  	void __iomem			*regs;
>  	struct mtk_disp_mutex		mutex[10];
> +	const unsigned int		*mutex_mod;
>  };
>  
> -static const unsigned int mutex_mod[DDP_COMPONENT_ID_MAX] = {
> -	[DDP_COMPONENT_AAL] = MUTEX_MOD_DISP_AAL,
> -	[DDP_COMPONENT_COLOR0] = MUTEX_MOD_DISP_COLOR0,
> -	[DDP_COMPONENT_COLOR1] = MUTEX_MOD_DISP_COLOR1,
> -	[DDP_COMPONENT_GAMMA] = MUTEX_MOD_DISP_GAMMA,
> -	[DDP_COMPONENT_OD] = MUTEX_MOD_DISP_OD,
> -	[DDP_COMPONENT_OVL0] = MUTEX_MOD_DISP_OVL0,
> -	[DDP_COMPONENT_OVL1] = MUTEX_MOD_DISP_OVL1,
> -	[DDP_COMPONENT_PWM0] = MUTEX_MOD_DISP_PWM0,
> -	[DDP_COMPONENT_PWM1] = MUTEX_MOD_DISP_PWM1,
> -	[DDP_COMPONENT_RDMA0] = MUTEX_MOD_DISP_RDMA0,
> -	[DDP_COMPONENT_RDMA1] = MUTEX_MOD_DISP_RDMA1,
> -	[DDP_COMPONENT_RDMA2] = MUTEX_MOD_DISP_RDMA2,
> -	[DDP_COMPONENT_UFOE] = MUTEX_MOD_DISP_UFOE,
> -	[DDP_COMPONENT_WDMA0] = MUTEX_MOD_DISP_WDMA0,
> -	[DDP_COMPONENT_WDMA1] = MUTEX_MOD_DISP_WDMA1,
> +static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> +	[DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
> +	[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
> +	[DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
> +	[DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA,
> +	[DDP_COMPONENT_OD] = MT8173_MUTEX_MOD_DISP_OD,
> +	[DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0,
> +	[DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1,
> +	[DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0,
> +	[DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1,
> +	[DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0,
> +	[DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1,
> +	[DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2,
> +	[DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE,
> +	[DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0,
> +	[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
>  };
>  
>  static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
> @@ -247,7 +248,7 @@ void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
>  		break;
>  	default:
>  		reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
> -		reg |= mutex_mod[id];
> +		reg |= ddp->mutex_mod[id];
>  		writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
>  		return;
>  	}
> @@ -273,7 +274,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
>  		break;
>  	default:
>  		reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
> -		reg &= ~mutex_mod[id];
> +		reg &= ~(ddp->mutex_mod[id]);
>  		writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
>  		break;
>  	}
> @@ -326,6 +327,8 @@ static int mtk_ddp_probe(struct platform_device *pdev)
>  		return PTR_ERR(ddp->regs);
>  	}
>  
> +	ddp->mutex_mod = of_device_get_match_data(dev);
> +
>  	platform_set_drvdata(pdev, ddp);
>  
>  	return 0;
> @@ -337,7 +340,7 @@ static int mtk_ddp_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id ddp_driver_dt_match[] = {
> -	{ .compatible = "mediatek,mt8173-disp-mutex" },
> +	{ .compatible = "mediatek,mt8173-disp-mutex", .data = mt8173_mutex_mod},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, ddp_driver_dt_match);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 48cc01f..3ff788c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -39,9 +39,10 @@
>  #define DISP_REG_UFO_START			0x0000
>  
>  #define DISP_COLOR_CFG_MAIN			0x0400
> -#define DISP_COLOR_START			0x0c00
> -#define DISP_COLOR_WIDTH			0x0c50
> -#define DISP_COLOR_HEIGHT			0x0c54
> +#define DISP_COLOR_START_MT8173			0x0c00
> +#define DISP_COLOR_START(comp)			((comp)->data->color_offset)
> +#define DISP_COLOR_WIDTH(comp)			(DISP_COLOR_START(comp) + 0x50)
> +#define DISP_COLOR_HEIGHT(comp)			(DISP_COLOR_START(comp) + 0x54)
>  
>  #define DISP_AAL_EN				0x0000
>  #define DISP_AAL_SIZE				0x0030
> @@ -80,6 +81,20 @@
>  #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
>  #define DITHER_ADD_RSHIFT_G(x)			(((x) & 0x7) << 0)
>  
> +struct mtk_disp_color_data {
> +	unsigned int color_offset;
> +};
> +
> +struct mtk_disp_color {
> +	struct mtk_ddp_comp			ddp_comp;
> +	const struct mtk_disp_color_data	*data;
> +};
> +
> +static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)
> +{
> +	return container_of(comp, struct mtk_disp_color, ddp_comp);
> +}
> +
>  void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
>  		    unsigned int CFG)
>  {
> @@ -107,15 +122,19 @@ static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
>  			     unsigned int h, unsigned int vrefresh,
>  			     unsigned int bpc)
>  {
> -	writel(w, comp->regs + DISP_COLOR_WIDTH);
> -	writel(h, comp->regs + DISP_COLOR_HEIGHT);
> +	struct mtk_disp_color *color = comp_to_color(comp);
> +
> +	writel(w, comp->regs + DISP_COLOR_WIDTH(color));
> +	writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
>  }
>  
>  static void mtk_color_start(struct mtk_ddp_comp *comp)
>  {
> +	struct mtk_disp_color *color = comp_to_color(comp);
> +
>  	writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
>  	       comp->regs + DISP_COLOR_CFG_MAIN);
> -	writel(0x1, comp->regs + DISP_COLOR_START);
> +	writel(0x1, comp->regs + DISP_COLOR_START(color));
>  }
>  
>  static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
> @@ -264,6 +283,16 @@ struct mtk_ddp_comp_match {
>  	[DDP_COMPONENT_WDMA1]	= { MTK_DISP_WDMA,	1, NULL },
>  };
>  
> +static const struct mtk_disp_color_data mt8173_color_driver_data = {
> +	.color_offset = DISP_COLOR_START_MT8173,
> +};
> +
> +static const struct of_device_id mtk_disp_color_driver_dt_match[] = {
> +	{ .compatible = "mediatek,mt8173-disp-color",
> +	  .data = &mt8173_color_driver_data},
> +	{},
> +};
> +
>  int mtk_ddp_comp_get_id(struct device_node *node,
>  			enum mtk_ddp_comp_type comp_type)
>  {
> @@ -286,10 +315,24 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
>  	enum mtk_ddp_comp_type type;
>  	struct device_node *larb_node;
>  	struct platform_device *larb_pdev;
> +	const struct of_device_id *match;
> +	struct mtk_disp_color *color;
>  
>  	if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
>  		return -EINVAL;
>  
> +	type = mtk_ddp_matches[comp_id].type;
> +	if (type == MTK_DISP_COLOR) {
> +		devm_kfree(dev, comp);
> +		color = devm_kzalloc(dev, sizeof(*color), GFP_KERNEL);
> +		if (!color)
> +			return -ENOMEM;
> +
> +		match = of_match_node(mtk_disp_color_driver_dt_match, node);
> +		color->data = match->data;
> +		comp = &color->ddp_comp;
> +	}
> +
>  	comp->id = comp_id;
>  	comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
>  
> @@ -308,8 +351,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
>  	if (IS_ERR(comp->clk))
>  		comp->clk = NULL;
>  
> -	type = mtk_ddp_matches[comp_id].type;
> -
>  	/* Only DMA capable components need the LARB property */
>  	comp->larb_dev = NULL;
>  	if (type != MTK_DISP_OVL &&
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 4b7fe7e..074fe31 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -128,7 +128,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
>  	.atomic_commit = mtk_atomic_commit,
>  };
>  
> -static const enum mtk_ddp_comp_id mtk_ddp_main[] = {
> +static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
>  	DDP_COMPONENT_OVL0,
>  	DDP_COMPONENT_COLOR0,
>  	DDP_COMPONENT_AAL,
> @@ -139,7 +139,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
>  	DDP_COMPONENT_PWM0,
>  };
>  
> -static const enum mtk_ddp_comp_id mtk_ddp_ext[] = {
> +static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = {
>  	DDP_COMPONENT_OVL1,
>  	DDP_COMPONENT_COLOR1,
>  	DDP_COMPONENT_GAMMA,
> @@ -147,6 +147,13 @@ static int mtk_atomic_commit(struct drm_device *drm,
>  	DDP_COMPONENT_DPI0,
>  };
>  
> +static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
> +	.main_path = mt8173_mtk_ddp_main,
> +	.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
> +	.ext_path = mt8173_mtk_ddp_ext,
> +	.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
> +};
> +
>  static int mtk_drm_kms_init(struct drm_device *drm)
>  {
>  	struct mtk_drm_private *private = drm->dev_private;
> @@ -189,17 +196,19 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  	 * and each statically assigned to a crtc:
>  	 * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
>  	 */
> -	ret = mtk_drm_crtc_create(drm, mtk_ddp_main, ARRAY_SIZE(mtk_ddp_main));
> +	ret = mtk_drm_crtc_create(drm, private->data->main_path,
> +				  private->data->main_len);
>  	if (ret < 0)
>  		goto err_component_unbind;
>  	/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
> -	ret = mtk_drm_crtc_create(drm, mtk_ddp_ext, ARRAY_SIZE(mtk_ddp_ext));
> +	ret = mtk_drm_crtc_create(drm, private->data->ext_path,
> +				  private->data->ext_len);
>  	if (ret < 0)
>  		goto err_component_unbind;
>  
>  	/* Use OVL device for all DMA memory allocations */
> -	np = private->comp_node[mtk_ddp_main[0]] ?:
> -	     private->comp_node[mtk_ddp_ext[0]];
> +	np = private->comp_node[private->data->main_path[0]] ?:
> +	     private->comp_node[private->data->ext_path[0]];
>  	pdev = of_find_device_by_node(np);
>  	if (!pdev) {
>  		ret = -ENODEV;
> @@ -362,6 +371,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  
>  	mutex_init(&private->commit.lock);
>  	INIT_WORK(&private->commit.work, mtk_atomic_work);
> +	private->data = of_device_get_match_data(dev);
>  
>  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	private->config_regs = devm_ioremap_resource(dev, mem);
> @@ -513,7 +523,8 @@ static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, mtk_drm_sys_suspend,
>  			 mtk_drm_sys_resume);
>  
>  static const struct of_device_id mtk_drm_of_ids[] = {
> -	{ .compatible = "mediatek,mt8173-mmsys", },
> +	{ .compatible = "mediatek,mt8173-mmsys",
> +	  .data = &mt8173_mmsys_driver_data},
>  	{ }
>  };
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index aa93894..fa0b106 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -28,6 +28,13 @@
>  struct drm_property;
>  struct regmap;
>  
> +struct mtk_mmsys_driver_data {
> +	const enum mtk_ddp_comp_id *main_path;
> +	unsigned int main_len;
> +	const enum mtk_ddp_comp_id *ext_path;
> +	unsigned int ext_len;
> +};
> +
>  struct mtk_drm_private {
>  	struct drm_device *drm;
>  	struct device *dma_dev;
> @@ -40,6 +47,7 @@ struct mtk_drm_private {
>  	void __iomem *config_regs;
>  	struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
>  	struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX];
> +	const struct mtk_mmsys_driver_data *data;
>  
>  	struct {
>  		struct drm_atomic_state *state;
> diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> index 1c366f8..c4a0165 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> @@ -16,6 +16,7 @@
>  #include <linux/delay.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/phy/phy.h>
>  
> @@ -87,6 +88,9 @@
>  
>  #define MIPITX_DSI_PLL_CON2	0x58
>  
> +#define MIPITX_DSI_PLL_TOP	0x64
> +#define RG_DSI_MPPLL_PRESERVE		(0xff << 8)
> +
>  #define MIPITX_DSI_PLL_PWR	0x68
>  #define RG_DSI_MPPLL_SDM_PWR_ON		BIT(0)
>  #define RG_DSI_MPPLL_SDM_ISO_EN		BIT(1)
> @@ -123,10 +127,15 @@
>  #define SW_LNT2_HSTX_PRE_OE		BIT(24)
>  #define SW_LNT2_HSTX_OE			BIT(25)
>  
> +struct mtk_mipitx_data {
> +	const u32 mppll_preserve;
> +};
> +
>  struct mtk_mipi_tx {
>  	struct device *dev;
>  	void __iomem *regs;
>  	unsigned int data_rate;
> +	const struct mtk_mipitx_data *driver_data;
>  	struct clk_hw pll_hw;
>  	struct clk *pll;
>  };
> @@ -243,6 +252,10 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
>  	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
>  			       RG_DSI_MPPLL_SDM_SSC_EN);
>  
> +	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
> +				RG_DSI_MPPLL_PRESERVE,
> +				mipi_tx->driver_data->mppll_preserve);
> +
>  	return 0;
>  }
>  
> @@ -255,6 +268,9 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
>  	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
>  			       RG_DSI_MPPLL_PLL_EN);
>  
> +	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
> +				RG_DSI_MPPLL_PRESERVE, 0);
> +
>  	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
>  				RG_DSI_MPPLL_SDM_ISO_EN |
>  				RG_DSI_MPPLL_SDM_PWR_ON,
> @@ -391,6 +407,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
>  	if (!mipi_tx)
>  		return -ENOMEM;
>  
> +	mipi_tx->driver_data = of_device_get_match_data(dev);
>  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	mipi_tx->regs = devm_ioremap_resource(dev, mem);
>  	if (IS_ERR(mipi_tx->regs)) {
> @@ -448,8 +465,13 @@ static int mtk_mipi_tx_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static const struct mtk_mipitx_data mt8173_mipitx_data = {
> +	.mppll_preserve = (0 << 8)
> +};
> +
>  static const struct of_device_id mtk_mipi_tx_match[] = {
> -	{ .compatible = "mediatek,mt8173-mipi-tx", },
> +	{ .compatible = "mediatek,mt8173-mipi-tx",
> +	  .data = &mt8173_mipitx_data },
>  	{},
>  };
>  

^ permalink raw reply

* [PATCH v11 04/12] drm/mediatek: add shadow register support
From: CK Hu @ 2017-01-17  2:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484117473-46644-5-git-send-email-yt.shen@mediatek.com>

Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> We need to acquire mutex before using the resources,
> and need to release it after finished.
> So we don't need to write registers in the blanking period.
> 
> Signed-off-by: YT Shen <yt.shen@mediatek.com>

Acked-by: CK Hu <ck.hu@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 75 ++++++++++++++++++++-------------
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 25 +++++++++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |  2 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  1 +
>  4 files changed, 74 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 01a21dd..b9b82e5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -329,6 +329,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
>  	pm_runtime_put(drm->dev);
>  }
>  
> +static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
> +{
> +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> +	struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> +	struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
> +	unsigned int i;
> +
> +	/*
> +	 * TODO: instead of updating the registers here, we should prepare
> +	 * working registers in atomic_commit and let the hardware command
> +	 * queue update module registers on vblank.
> +	 */
> +	if (state->pending_config) {
> +		mtk_ddp_comp_config(ovl, state->pending_width,
> +				    state->pending_height,
> +				    state->pending_vrefresh, 0);
> +
> +		state->pending_config = false;
> +	}
> +
> +	if (mtk_crtc->pending_planes) {
> +		for (i = 0; i < OVL_LAYER_NR; i++) {
> +			struct drm_plane *plane = &mtk_crtc->planes[i];
> +			struct mtk_plane_state *plane_state;
> +
> +			plane_state = to_mtk_plane_state(plane->state);
> +
> +			if (plane_state->pending.config) {
> +				mtk_ddp_comp_layer_config(ovl, i, plane_state);
> +				plane_state->pending.config = false;
> +			}
> +		}
> +		mtk_crtc->pending_planes = false;
> +	}
> +}
> +
>  static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
>  {
>  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> @@ -405,6 +441,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
>  				      struct drm_crtc_state *old_crtc_state)
>  {
>  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> +	struct mtk_drm_private *priv = crtc->dev->dev_private;
>  	unsigned int pending_planes = 0;
>  	int i;
>  
> @@ -426,6 +463,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
>  	if (crtc->state->color_mgmt_changed)
>  		for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
>  			mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
> +
> +	if (priv->data->shadow_register) {
> +		mtk_disp_mutex_acquire(mtk_crtc->mutex);
> +		mtk_crtc_ddp_config(crtc);
> +		mtk_disp_mutex_release(mtk_crtc->mutex);
> +	}
>  }
>  
>  static const struct drm_crtc_funcs mtk_crtc_funcs = {
> @@ -471,36 +514,10 @@ static int mtk_drm_crtc_init(struct drm_device *drm,
>  void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
>  {
>  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> -	struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> -	unsigned int i;
> +	struct mtk_drm_private *priv = crtc->dev->dev_private;
>  
> -	/*
> -	 * TODO: instead of updating the registers here, we should prepare
> -	 * working registers in atomic_commit and let the hardware command
> -	 * queue update module registers on vblank.
> -	 */
> -	if (state->pending_config) {
> -		mtk_ddp_comp_config(ovl, state->pending_width,
> -				    state->pending_height,
> -				    state->pending_vrefresh, 0);
> -
> -		state->pending_config = false;
> -	}
> -
> -	if (mtk_crtc->pending_planes) {
> -		for (i = 0; i < OVL_LAYER_NR; i++) {
> -			struct drm_plane *plane = &mtk_crtc->planes[i];
> -			struct mtk_plane_state *plane_state;
> -
> -			plane_state = to_mtk_plane_state(plane->state);
> -
> -			if (plane_state->pending.config) {
> -				mtk_ddp_comp_layer_config(ovl, i, plane_state);
> -				plane_state->pending.config = false;
> -			}
> -		}
> -		mtk_crtc->pending_planes = false;
> -	}
> +	if (!priv->data->shadow_register)
> +		mtk_crtc_ddp_config(crtc);
>  
>  	mtk_drm_finish_page_flip(mtk_crtc);
>  }
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index 8030769..b77d456 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -12,6 +12,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/iopoll.h>
>  #include <linux/module.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> @@ -32,10 +33,13 @@
>  #define DISP_REG_CONFIG_MMSYS_CG_CON0		0x100
>  
>  #define DISP_REG_MUTEX_EN(n)	(0x20 + 0x20 * (n))
> +#define DISP_REG_MUTEX(n)	(0x24 + 0x20 * (n))
>  #define DISP_REG_MUTEX_RST(n)	(0x28 + 0x20 * (n))
>  #define DISP_REG_MUTEX_MOD(n)	(0x2c + 0x20 * (n))
>  #define DISP_REG_MUTEX_SOF(n)	(0x30 + 0x20 * (n))
>  
> +#define INT_MUTEX				BIT(1)
> +
>  #define MT8173_MUTEX_MOD_DISP_OVL0		BIT(11)
>  #define MT8173_MUTEX_MOD_DISP_OVL1		BIT(12)
>  #define MT8173_MUTEX_MOD_DISP_RDMA0		BIT(13)
> @@ -300,6 +304,27 @@ void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex)
>  	writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
>  }
>  
> +void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex)
> +{
> +	struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
> +					   mutex[mutex->id]);
> +	u32 tmp;
> +
> +	writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
> +	writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id));
> +	if (readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id),
> +				      tmp, tmp & INT_MUTEX, 1, 10000))
> +		pr_err("could not acquire mutex %d\n", mutex->id);
> +}
> +
> +void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex)
> +{
> +	struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
> +					   mutex[mutex->id]);
> +
> +	writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id));
> +}
> +
>  static int mtk_ddp_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
> index 92c1175..f9a7991 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
> @@ -37,5 +37,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
>  				enum mtk_ddp_comp_id id);
>  void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex);
>  void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex);
> +void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex);
> +void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex);
>  
>  #endif /* MTK_DRM_DDP_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index fa0b106..94f8b66 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -33,6 +33,7 @@ struct mtk_mmsys_driver_data {
>  	unsigned int main_len;
>  	const enum mtk_ddp_comp_id *ext_path;
>  	unsigned int ext_len;
> +	bool shadow_register;
>  };
>  
>  struct mtk_drm_private {

^ permalink raw reply

* [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
From: Sebastian Reichel @ 2017-01-17  3:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170102163723.7939-9-quentin.schulz@free-electrons.com>

Hi Quentin,

The driver looks mostly fine. I do have a two comments, though.

On Mon, Jan 02, 2017 at 05:37:08PM +0100, Quentin Schulz wrote:
> [...]
>
> +static int axp20x_ac_power_probe(struct platform_device *pdev)
> +{
> +	static const char * const axp20x_irq_names[] = { "ACIN_PLUGIN",
> +		"ACIN_REMOVAL", NULL };
>
> +	static const char * const *irq_names;
> +	const struct power_supply_desc *ac_power_desc;
> +	int i, irq, ret;
> +
> +	if (!of_device_is_available(pdev->dev.of_node))
> +		return -ENODEV;
> +
> +	if (!axp20x) {
> +		dev_err(&pdev->dev, "Parent drvdata not set\n");
> +		return -EINVAL;
> +	}

axp20x will no longer be needed after implementing below
comments.

> [...]
> +	irq_names = axp20x_irq_names;

Just rename axp20x_irq_names into irq_names, since its only used
here.

> [...]
>
> +	power->np = pdev->dev.of_node;

This can be dropped, it's not used at all.

> +	power->regmap = axp20x->regmap;

power->regmap = dev_get_regmap(pdev->dev.parent, NULL);

> [...]
> +	/* Request irqs after registering, as irqs may trigger immediately */
> +	for (i = 0; irq_names[i]; i++) {
> +		irq = platform_get_irq_byname(pdev, irq_names[i]);
> +		if (irq < 0) {
> +			dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
> +				 irq_names[i], irq);
> +			continue;
> +		}
> +		irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq);

The mapping should actually happen in the mfd driver, so that
the platform resource contains a valid irq.

> +		ret = devm_request_any_context_irq(&pdev->dev, irq,
> +						   axp20x_ac_power_irq, 0,
> +						   DRVNAME, power);
> +		if (ret < 0)
> +			dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n",
> +				 irq_names[i], ret);
> +	}

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170117/37a1e7d4/attachment.sig>

^ permalink raw reply

* [PATCH 0/2] ARM64: meson-gxm: R-Box Pro enablement
From: Andreas Färber @ 2017-01-17  3:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This mini-series adds initial support for the Amlogic S912 based
R-Box Pro TV boxes.

Patch 1 should apply today, patch 2 depends on Martin's Bluetooth series.

Wifi further depends on: https://patchwork.kernel.org/patch/9518447/
(and /etc/wifi/AP6255/nvram.txt as /lib/firmware/brcm/brcmfmac43455-sdio.txt)

Regards,
Andreas

Cc: devicetree at vger.kernel.org

Andreas F?rber (2):
  ARM64: dts: meson-gxm: Add R-Box Pro
  ARM64: dts: meson-gxm-rbox-pro: Enable Bluetooth

 arch/arm64/boot/dts/amlogic/Makefile               |   1 +
 arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts | 249 +++++++++++++++++++++
 2 files changed, 250 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts

-- 
2.10.2

^ permalink raw reply

* [PATCH 1/2] ARM64: dts: meson-gxm: Add R-Box Pro
From: Andreas Färber @ 2017-01-17  3:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170117030611.23827-1-afaerber@suse.de>

The R-Box Pro is a TV box derived from Amlogic q200 reference design.
It uses an AP6255 Wifi module. It features an LED tube that lights a
surrounding stripe and the top logo in blue or red or pink'ish - blue
is on by default, and red (i.e., pink) is configured as panic indicator.

This device is available in at least two models, with 2 GB vs. 3 GB RAM
as well as varying eMMC size. The intent is to handle this with a single
.dts that gets the actual RAM size from U-Boot.

The vendor prefix remains to be clarified, therefore no dedicated board
compatible string yet.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm64/boot/dts/amlogic/Makefile               |   1 +
 arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts | 240 +++++++++++++++++++++
 2 files changed, 241 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 0d7bfbf7d922..66bc809a5eae 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-nexbox-a95x.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-q200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-q201.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
new file mode 100644
index 000000000000..9f04fa4e5aec
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * Based on nexbox-a1:
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "meson-gxm.dtsi"
+
+/ {
+	compatible = "amlogic,s912", "amlogic,meson-gxm";
+	model = "R-Box Pro";
+
+	aliases {
+		serial0 = &uart_AO;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>; /* 2 GiB or 3 GiB */
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		blue {
+			label = "rbox-pro:blue:on";
+			gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		red {
+			label = "rbox-pro:red:standby";
+			gpios = <&gpio GPIODV_28 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			retain-state-suspended;
+			panic-indicator;
+		};
+	};
+
+	vddio_boot: regulator-vddio-boot {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_BOOT";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vddao_3v3: regulator-vddao-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc_3v3: regulator-vcc-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>;
+	pinctrl-names = "default";
+
+	/* Select external PHY by default */
+	phy-handle = <&external_phy>;
+
+	snps,reset-gpio = <&gpio GPIOZ_14 0>;
+	snps,reset-delays-us = <0 10000 1000000>;
+	snps,reset-active-low;
+
+	amlogic,tx-delay-ns = <2>;
+
+	/* External PHY is in RGMII */
+	phy-mode = "rgmii";
+};
+
+&external_mdio {
+	external_phy: ethernet-phy at 0 {
+		compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+		max-speed = <1000>;
+	};
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&clkc CLKID_FCLK_DIV4>;
+	clock-names = "clkin0";
+};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-names = "default";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+
+	brcmf: brcmf at 1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
+};
+
+/* SD card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_pins>;
+	pinctrl-names = "default";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_pins>;
+	pinctrl-names = "default";
+
+	bus-width = <8>;
+	cap-sd-highspeed;
+	cap-mmc-highspeed;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
-- 
2.10.2

^ permalink raw reply related

* [PATCH 2/2] ARM64: dts: meson-gxm-rbox-pro: Enable Bluetooth
From: Andreas Färber @ 2017-01-17  3:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170117030611.23827-1-afaerber@suse.de>

Add an SDIO reset GPIO and enable the serial used by the AP6255
Bluetooth module. Based on work by Martin Blumenstingl.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
index 9f04fa4e5aec..6ea225f584bd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
@@ -58,6 +58,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		serial1 = &uart_A;
 	};
 
 	chosen {
@@ -122,7 +123,8 @@
 
 	sdio_pwrseq: sdio-pwrseq {
 		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>,
+				<&gpio GPIOX_17 GPIO_ACTIVE_LOW>;
 		clocks = <&wifi32k>;
 		clock-names = "ext_clock";
 	};
@@ -238,3 +240,10 @@
 	pinctrl-0 = <&uart_ao_a_pins>;
 	pinctrl-names = "default";
 };
+
+&uart_A {
+	status = "okay";
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+};
-- 
2.10.2

^ permalink raw reply related

* [PATCH v3 1/3] dt: bindings: add documentation for zx2967 family reset controller
From: Baoyou Xie @ 2017-01-17  3:22 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds dt-binding documentation for zx2967 family
reset controller.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
Reviewed-by: Shawn Guo <shawnguo@kernel.org>
---
 .../devicetree/bindings/reset/zte,zx2967-reset.txt   | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt

diff --git a/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
new file mode 100644
index 0000000..b015508
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
@@ -0,0 +1,20 @@
+ZTE zx2967 SoCs Reset Controller
+=======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: should be one of the following.
+	* zte,zx296718-reset
+- reg: physical base address of the controller and length of memory mapped
+	region.
+- #reset-cells: must be 1.
+
+example:
+
+	reset: reset-controller at 1461060 {
+		compatible = "zte,zx296718-reset";
+		reg = <0x01461060 0x8>;
+		#reset-cells = <1>;
+	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 2/3] MAINTAINERS: add zx2967 reset controller driver to ARM ZTE architecture
From: Baoyou Xie @ 2017-01-17  3:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484623377-16208-1-git-send-email-baoyou.xie@linaro.org>

Add the zx2967 reset controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e63063b..5fb9b62 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1987,9 +1987,11 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/mach-zx/
 F:	drivers/clk/zte/
+F:	drivers/reset/reset-zx2967.c
 F:	drivers/soc/zte/
 F:	Documentation/devicetree/bindings/arm/zte.txt
 F:	Documentation/devicetree/bindings/clock/zx296702-clk.txt
+F:	Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
 F:	Documentation/devicetree/bindings/soc/zte/
 F:	include/dt-bindings/soc/zx*.h
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 3/3] reset: zx2967: add reset controller driver for ZTE's zx2967 family
From: Baoyou Xie @ 2017-01-17  3:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484623377-16208-1-git-send-email-baoyou.xie@linaro.org>

This patch adds reset controller driver for ZTE's zx2967 family.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
 drivers/reset/Kconfig        |   6 +++
 drivers/reset/Makefile       |   1 +
 drivers/reset/reset-zx2967.c | 106 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 drivers/reset/reset-zx2967.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 172dc96..f4cdfe9 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -86,6 +86,12 @@ config RESET_UNIPHIER
 	  Say Y if you want to control reset signals provided by System Control
 	  block, Media I/O block, Peripheral Block.
 
+config RESET_ZX2967
+	bool "ZTE ZX2967 Reset Driver"
+	depends on ARCH_ZX || COMPILE_TEST
+	help
+	  This enables the reset controller driver for ZTE's zx2967 family.
+
 config RESET_ZYNQ
 	bool "ZYNQ Reset Driver" if COMPILE_TEST
 	default ARCH_ZYNQ
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 13b346e..2cd3f6c 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -13,4 +13,5 @@ obj-$(CONFIG_RESET_STM32) += reset-stm32.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o
 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
+obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o
 obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c
new file mode 100644
index 0000000..5d82151
--- /dev/null
+++ b/drivers/reset/reset-zx2967.c
@@ -0,0 +1,106 @@
+/*
+ * ZTE's zx2967 family reset controller driver
+ *
+ * Copyright (C) 2017 ZTE Ltd.
+ *
+ * Author: Baoyou Xie <baoyou.xie@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+struct zx2967_reset {
+	void __iomem			*reg_base;
+	spinlock_t			lock;
+	struct reset_controller_dev	rcdev;
+};
+
+static int zx2967_reset_act(struct reset_controller_dev *rcdev,
+			    unsigned long id, bool assert)
+{
+	struct zx2967_reset *reset = NULL;
+	int bank = id / 32;
+	int offset = id % 32;
+	u32 reg;
+	unsigned long flags;
+
+	reset = container_of(rcdev, struct zx2967_reset, rcdev);
+
+	spin_lock_irqsave(&reset->lock, flags);
+
+	reg = readl_relaxed(reset->reg_base + (bank * 4));
+	if (assert)
+		reg &= ~BIT(offset);
+	else
+		reg |= BIT(offset);
+	writel_relaxed(reg, reset->reg_base + (bank * 4));
+
+	spin_unlock_irqrestore(&reset->lock, flags);
+
+	return 0;
+}
+
+static int zx2967_reset_assert(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	return zx2967_reset_act(rcdev, id, true);
+}
+
+static int zx2967_reset_deassert(struct reset_controller_dev *rcdev,
+				 unsigned long id)
+{
+	return zx2967_reset_act(rcdev, id, false);
+}
+
+static struct reset_control_ops zx2967_reset_ops = {
+	.assert		= zx2967_reset_assert,
+	.deassert	= zx2967_reset_deassert,
+};
+
+static int zx2967_reset_probe(struct platform_device *pdev)
+{
+	struct zx2967_reset *reset;
+	struct resource *res;
+
+	reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
+	if (!reset)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	reset->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(reset->reg_base))
+		return PTR_ERR(reset->reg_base);
+
+	spin_lock_init(&reset->lock);
+
+	reset->rcdev.owner = THIS_MODULE;
+	reset->rcdev.nr_resets = resource_size(res) * 8;
+	reset->rcdev.ops = &zx2967_reset_ops;
+	reset->rcdev.of_node = pdev->dev.of_node;
+
+	return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
+}
+
+static const struct of_device_id zx2967_reset_dt_ids[] = {
+	 { .compatible = "zte,zx296718-reset", },
+	 {},
+};
+MODULE_DEVICE_TABLE(of, zx2967_reset_dt_ids);
+
+static struct platform_driver zx2967_reset_driver = {
+	.probe	= zx2967_reset_probe,
+	.driver = {
+		.name		= "zx2967-reset",
+		.of_match_table	= zx2967_reset_dt_ids,
+	},
+};
+
+builtin_platform_driver(zx2967_reset_driver);
+
+MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
+MODULE_DESCRIPTION("ZTE zx2967 Reset Controller Driver");
+MODULE_LICENSE("GPL");
-- 
2.7.4

^ permalink raw reply related

* [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Thomas Petazzoni @ 2017-01-17  3:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170113175628.1793f433@bbrezillon>

Hello,

On Fri, 13 Jan 2017 17:56:28 +0100, Boris Brezillon wrote:

> because both compatible are referring to very specific IP version. It's
> not the same as
> 
> 	compatible = "mediatek,mt8173-nor", "mediatek,mt81xx-nor";

mt81xx-nor is a bogus compatible string, and DT binding maintainers
will not accept it. They don't want compatible strings with "wildcards".

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH 1/2] ARM64: dts: meson-gxm: Add R-Box Pro
From: Andreas Färber @ 2017-01-17  3:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170117030611.23827-2-afaerber@suse.de>

Am 17.01.2017 um 04:06 schrieb Andreas F?rber:
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		blue {
> +			label = "rbox-pro:blue:on";
> +			gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
> +			default-state = "on";
> +		};
> +
> +		red {
> +			label = "rbox-pro:red:standby";
> +			gpios = <&gpio GPIODV_28 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +			retain-state-suspended;
> +			panic-indicator;
> +		};
> +	};

The original property names for these two were led and red. If anyone
has better label names than the above, please speak up. Ditto for
vega-s95. On the odroidc2 it's called alive but uses heartbeat there.

The vendor device tree had a third "mcu" GPIO in the sysled node,
GPIOAO_6, which leads to immediate power-off. I tried using
"gpio-poweroff" to configure this pin, but that driver fails to
initialize because some pm callback is already registered - I assume
from psci, which apparently succeeds to power-off the system, too. For
comparison, the S905 based Vega S95 Telos has no such mcu property. Any
thoughts?

Also, any ideas how best to switch from blue to red for suspend? Add
pinctrl properties above? systemd service doing echo from userspace? I
assume in Android the Amlogic sysled driver handles all that logic -
didn't find any suspend equivalent to gpio-poweroff.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

^ permalink raw reply

* [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Thomas Petazzoni @ 2017-01-17  3:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170116094032.6f471f11@bbrezillon>

Hello,

(Side note: you guys should learn about stripping irrelevant parts of
an e-mail when replying!)

On Mon, 16 Jan 2017 09:40:32 +0100, Boris Brezillon wrote:

> > Well this is OK I guess, but then you can also use "mediatek,mt8173-nor"
> > as the oldest supported compatible and be done with it, no ? It looks a
> > bit crappy though, I admit that ...
> 
> Let's stop bikeshedding and wait for DT maintainers feedback
> before taking a decision ;-).
> 
> Rob, Mark, any opinion?

I agree that a clarification would be good. There are really two
options:

 1. Have two compatible strings in the DT, the one that matches the
    exact SoC where the IP is found (first compatible string) and the
    one that matches some other SoC where the same IP is found (second
    compatible string). Originally, Linux only supports the second
    compatible string in its device driver, but if it happens that a
    difference is found between two IPs that we thought were the same,
    we can add support for the first compatible string in the driver,
    with a slightly different behavior.

 2. Have a single compatible string in the DT, matching the exact SoC
    where the IP is found. This involves adding immediately this
    compatible string in the corresponding driver.

I've not really been able to figure out which of the two options is the
most future-proof/appropriate.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
From: Sebastian Reichel @ 2017-01-17  3:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170102163723.7939-18-quentin.schulz@free-electrons.com>

Hi Quentin,

Just a couple of small things in this patch.

On Mon, Jan 02, 2017 at 05:37:17PM +0100, Quentin Schulz wrote:
> [...]
> +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> +		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
> +				  &reg);
> +		if (ret)
> +			return ret;
> +
> +		if (reg & AXP20X_PWR_STATUS_BAT_CHARGING)
> +			chan = axp20x_batt->batt_chrg_i;
> +		else
> +			chan = axp20x_batt->batt_dischrg_i;
> +
> +		ret = iio_read_channel_processed(chan, &val->intval);
> +		if (ret)
> +			return ret;
> +
> +		/*
> +		 * IIO framework gives mV but Power Supply framework gives ?V.
> +		 */

Nit: Volt -> Ampere

> +		val->intval *= 1000;
> +		break;
>
> [...]
>
> +static int axp20x_power_probe(struct platform_device *pdev)
> +{
> +	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +	struct axp20x_batt_ps *axp20x_batt;
> +	struct power_supply_config psy_cfg = {};
> +
> +	axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
> +				   GFP_KERNEL);
> +	if (!axp20x_batt)
> +		return -ENOMEM;
> +
> +	axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
> +	if (IS_ERR(axp20x_batt->batt_v)) {
> +		if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV)
> +			return -EPROBE_DEFER;
> +		return PTR_ERR(axp20x_batt->batt_v);
> +	}
> +
> +	axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
> +							"batt_chrg_i");
> +	if (IS_ERR(axp20x_batt->batt_chrg_i)) {
> +		if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV)
> +			return -EPROBE_DEFER;
> +		return PTR_ERR(axp20x_batt->batt_chrg_i);
> +	}
> +
> +	axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
> +							   "batt_dischrg_i");
> +	if (IS_ERR(axp20x_batt->batt_dischrg_i)) {
> +		if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV)
> +			return -EPROBE_DEFER;
> +		return PTR_ERR(axp20x_batt->batt_dischrg_i);
> +	}
> +
> +	axp20x_batt->regmap = axp20x->regmap;
> +	platform_set_drvdata(pdev, axp20x_batt);

Please use drv_get_regmap(pdev->dev.parent, NULL) instead (and drop
axp20x).

> +	psy_cfg.drv_data = axp20x_batt;
> +	psy_cfg.of_node = pdev->dev.of_node;
> +
> +	axp20x_batt->axp_id = (int)of_device_get_match_data(&pdev->dev);

use (uintptr_t) to avoid compiler warnings on systems with sizeof
int != sizeof ptr.

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170117/a8f71c66/attachment.sig>

^ permalink raw reply

* [Question] A question about arm64 pte
From: Yisheng Xie @ 2017-01-17  3:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170116143601.GB6832@e104818-lin.cambridge.arm.com>



On 2017/1/16 22:36, Catalin Marinas wrote:
> On Mon, Jan 16, 2017 at 08:39:56PM +0800, Yisheng Xie wrote:
>> On 2017/1/16 19:56, Catalin Marinas wrote:
>>> On Mon, Jan 16, 2017 at 06:08:47PM +0800, Yisheng Xie wrote:
>>>
>> However?when use memset to write the region it still works well, and
>> the bit PTE_RDONLY is also cleared. Is there anywhere clear the
>> PTE_RDONLY before write that page ?
> 
> See handle_pte_fault(). On the first access to a writable+clean page
> (PTE_WRITE set, PTE_RDONLY set, PTE_DIRTY cleared), the kernel traps it
> and, if pte_write() is true (your case), it calls pte_mkdirty(). The
> subsequently called ptep_set_access_flags() function would clear
> PTE_RDONLY, giving you a writable mapping.
> 
hi Catalin?
Sorry to disturb, but why page fault will happened here, for pte already
present with AF bit set?

Here is what I get when mmap a reserved memory region 0x39ef 0000~0x3a00 0000
use /dev/mem:
[  442.704228] pgd = ffff802785f14000
[  442.707641] [ffff86e4b000] *pgd=000000279080c003, *pud=0000002785f01003, *pmd=0000002783f5b003, *pte=0168000039ef0fd3

Thanks,
Yisheng Xie.

^ permalink raw reply

* [PATCH 01/12] soc: samsung: pmu: Use common device name to let others to find it easily
From: Tomasz Figa @ 2017-01-17  4:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484549107-5957-2-git-send-email-m.szyprowski@samsung.com>

Hi Marek,

2017-01-16 15:44 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch always set device name to "exynos-pmu" to let other drivers to
> find PMU device easily. This is done mainly to get regmap to access PMU
> registers from other drivers. This way it can be avoided to add phandle to
> the PMU node to almost all drivers in the SoC just to get a regmap access
> in the drivers. PMU is something like a SoC wide service, so there is no
> point modeling it as hardware dependency for all devices in device tree.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/soc/samsung/exynos-pmu.c       |  1 +
>  include/linux/soc/samsung/exynos-pmu.h | 19 +++++++++++++++++++
>  2 files changed, 20 insertions(+)
>
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index 0acdfd82e751..63bb471845cb 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -120,6 +120,7 @@ static int exynos_pmu_probe(struct platform_device *pdev)
>                 pmu_context->pmu_data->pmu_init();
>
>         platform_set_drvdata(pdev, pmu_context);
> +       dev_set_name(dev, EXYNOS_PMU_DEV_NAME);
>
>         dev_dbg(dev, "Exynos PMU Driver probe done\n");
>         return 0;
> diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
> index e2e9de1acc5b..90d9205805ea 100644
> --- a/include/linux/soc/samsung/exynos-pmu.h
> +++ b/include/linux/soc/samsung/exynos-pmu.h
> @@ -12,6 +12,10 @@
>  #ifndef __LINUX_SOC_EXYNOS_PMU_H
>  #define __LINUX_SOC_EXYNOS_PMU_H
>
> +#include <linux/mfd/syscon.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
>  enum sys_powerdown {
>         SYS_AFTR,
>         SYS_LPA,
> @@ -21,4 +25,19 @@ enum sys_powerdown {
>
>  extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
>
> +#define EXYNOS_PMU_DEV_NAME "exynos-pmu"
> +
> +static inline struct regmap *exynos_get_pmu_regs(void)
> +{
> +       struct device *dev = bus_find_device_by_name(&platform_bus_type, NULL,
> +                                                    EXYNOS_PMU_DEV_NAME);
> +       if (dev) {
> +               struct regmap *regs = syscon_node_to_regmap(dev->of_node);
> +               put_device(dev);
> +               if (!IS_ERR(regs))
> +                       return regs;
> +       }
> +       return NULL;

As discussed offline, since this function relies on the PMU driver
probing, we need to defer here if someone calls this function before
that. Since PMU is something that should be assumed to be available in
any Exynos system (it controls to many critical aspects of the SoC), I
think we can simply return ERR_PTR(-EDEFER_PROBE) here instead of
NULL. Maybe also a pr_debug() before deferring could be useful to
debug PMU probe failures.

Best regards,
Tomasz

^ permalink raw reply

* [PATCH 06/12] pinctrl: samsung: Add missing initconst annotation
From: Tomasz Figa @ 2017-01-17  4:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170116191400.ehm3ivkmz4csynvq@kozik-lap>

2017-01-17 4:14 GMT+09:00 Krzysztof Kozlowski <krzk@kernel.org>:
> On Mon, Jan 16, 2017 at 07:45:01AM +0100, Marek Szyprowski wrote:
>> Exynos5433 support has been added in parallel to adding initconst
>> annotation to most of the init data structures, so add those
>> annotations also to Exynos5433 structures.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>  drivers/pinctrl/samsung/pinctrl-exynos.c | 22 +++++++++++-----------
>>  1 file changed, 11 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
>> index bf753a596209..70b94ad10cc1 100644
>> --- a/drivers/pinctrl/samsung/pinctrl-exynos.c
>> +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
>> @@ -1266,7 +1266,7 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
>>  };
>>
>>  /* pin banks of exynos5433 pin-controller - ALIVE */
>> -static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = {
>> +static const struct samsung_pin_bank_data exynos5433_pin_banks0[] __initconst = {
>>       EXYNOS5433_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
>>       EXYNOS5433_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
>>       EXYNOS5433_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
>> @@ -1279,28 +1279,28 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
>>  };
>
> Your change is aligned with existing code... but after I started to look
> into it I think this should not be initconst.
>
> The pin_banks (initconst) are referenced in pin_ctrl (initconst) which
> is referenced in samsung_pinctrl_dt_match (NOT initconst). The dt_match
> then is used in samsung_pinctrl_driver (for obvious reasons not
> initconst).
>
> We suppress the bind so this looks safe - this data should not be ever used
> after init - but it is not correct strictly speaking.
>
> Let's imagine some weird future platform which will use DT overlays with
> pinctrl. I think the overlays could affect the tree after the init
> stage.

I think it's not very realistic to have a Samsung on-SoC pin
controller in an overlay. AFAIR we already assume in several places
that this driver fully initializes in init stage, so we can save some
memory by discarding this data

Still, I guess we could add some measure to make sure nothing attempts
to probe this driver after the data is discarded.

Best regards,
Tomasz

^ permalink raw reply

* arm: module: Add apply_relocate_add
From: Jessica Yu @ 2017-01-17  4:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481043967-15602-4-git-send-email-abelvesa@linux.com>

+++ Abel Vesa [06/12/16 17:06 +0000]:
>It was only added to fix compiler error. It is not implemented
>yet.
>
>Signed-off-by: Abel Vesa <abelvesa@linux.com>
>---
> arch/arm/kernel/module.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
>diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
>index 4f14b5c..bf94922 100644
>--- a/arch/arm/kernel/module.c
>+++ b/arch/arm/kernel/module.c
>@@ -52,6 +52,15 @@ void *module_alloc(unsigned long size)
> #endif
>
> int
>+apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
>+		   unsigned int symindex, unsigned int relindex,
>+		   struct module *module)
>+{
>+	/* Not implemented yet */
>+	return 0;
>+}

Are SHT_RELA relocation sections actually supported on 32-bit arm? It looks
like there's only support for SHT_REL.

arch/arm/Kconfig:84:	select MODULES_USE_ELF_REL

If we support SHT_REL sections, the correct fix is to probably have
klp_write_object_relocations() check if the relocation section is
SHT_REL or SHT_RELA, and call the appropriate function (apply_relocate
or apply_relocate_add), similar to how the module loader does it.

Jessica

^ permalink raw reply

* [PATCH 09/12] pinctrl: samsung: Add infrastructure for pin-bank retention control
From: Tomasz Figa @ 2017-01-17  4:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484549107-5957-10-git-send-email-m.szyprowski@samsung.com>

Hi Marek,

2017-01-16 15:45 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> Pad retention control after suspend/resume cycle should be done from pin
> controller driver instead of PMU (power management unit) driver to avoid
> possible ordering and logical dependencies. Till now it worked fine only
> because PMU driver registered its sys_ops after pin controller.
>
> This patch adds infrastructure to handle pad retention during pin control
> driver resume.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/pinctrl/samsung/pinctrl-samsung.c | 12 ++++++---
>  drivers/pinctrl/samsung/pinctrl-samsung.h | 42 +++++++++++++++++++++++++++++++
>  2 files changed, 51 insertions(+), 3 deletions(-)

Please see my comments inline.

> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
> index 86f23842f681..95a84086a2e9 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
> @@ -1075,6 +1075,9 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
>                 ctrl->eint_gpio_init(drvdata);
>         if (ctrl->eint_wkup_init)
>                 ctrl->eint_wkup_init(drvdata);
> +       if (ctrl->retention_data && ctrl->retention_data->init)
> +               drvdata->retention_ctrl = ctrl->retention_data->init(drvdata,
> +                                                         ctrl->retention_data);

Is there really a use case for init being optional? Also maybe it
could make sense to add a pr_debug() in case retention_data is not
present (maybe even a warning would make sense, since the old code
should be deprecated...).

>
>         platform_set_drvdata(pdev, drvdata);
>
> @@ -1127,15 +1130,15 @@ static void samsung_pinctrl_suspend_dev(
>
>         if (drvdata->suspend)
>                 drvdata->suspend(drvdata);
> +       if (drvdata->retention_ctrl && drvdata->retention_ctrl->on)
> +               drvdata->retention_ctrl->on(drvdata);
> +

nit: Stray blank line.

>  }
>
>  /**
>   * samsung_pinctrl_resume_dev - restore pinctrl state from suspend for a device
>   *
>   * Restore one of the banks that was saved during suspend.
> - *
> - * We don't bother doing anything complicated to avoid glitching lines since
> - * we're called before pad retention is turned off.

I think the comment is still valid. Just could be adjusted to take
into account that now we are in charge of turning off the retention
after restoring the registers.

>   */
>  static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
>  {
> @@ -1174,6 +1177,9 @@ static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
>                         if (widths[type])
>                                 writel(bank->pm_save[type], reg + offs[type]);
>         }
> +
> +       if (drvdata->retention_ctrl && drvdata->retention_ctrl->off)
> +               drvdata->retention_ctrl->off(drvdata);
>  }
>
>  /**
> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
> index 6f7ce7539a00..6079142422f8 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.h
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
> @@ -185,10 +185,48 @@ struct samsung_pin_bank {
>  };
>
>  /**
> + * struct samsung_retention_data: runtime pin-bank retention control data.
> + * @regs: array of PMU registers to control pad retention.
> + * @nr_regs: number of registers in @regs array.
> + * @value: value to store to registers to turn off retention.
> + * @refcnt: atomic counter if retention control affects more than one bank.
> + * @priv: retention control code private data
> + * @on: platform specific callback to enter retention mode.
> + * @off: platform specific callback to exit retention mode.
> + **/
> +struct samsung_retention_ctrl {
> +       const u32       *regs;
> +       int             nr_regs;
> +       u32             value;
> +       atomic_t        *refcnt;
> +       void            *priv;
> +       void            (*on)(struct samsung_pinctrl_drv_data *);
> +       void            (*off)(struct samsung_pinctrl_drv_data *);

bikeshed: I think enable/disable is more commonly used for this kind
of operations.

Best regards,
Tomasz

^ permalink raw reply

* [PATCH] clocksource: exynos_mct: clear irq at stop local mct to fix suspend
From: Joonyoung Shim @ 2017-01-17  4:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CGME20170117045403epcas1p1c64f1563c31947059430e0fbf370ee75@epcas1p1.samsung.com>

This patch adds clear interrupt to exynos4_mct_dying_cpu(). Without
clearing, after turning on non boot cpu at wakeup from suspend to
ram, not cleared tick interrupt occurs and it causes following null
deference for MCT_INT_SPI type mct.

[   51.251378] Unable to handle kernel NULL pointer dereference at virtual address 00000040
[   51.257980] pgd = c0004000
[   51.260666] [00000040] *pgd=00000000
[   51.264222] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[   51.269503] Modules linked in:
[   51.272541] CPU: 7 PID: 53 Comm: ksoftirqd/7 Tainted: G        W 4.9.0-rc7-next-20161201-00007-g74076859ec44 #140
[   51.283282] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   51.289348] task: ee942d00 task.stack: ee960000
[   51.293861] PC is at tick_periodic+0x38/0xb0
[   51.298102] LR is at tick_handle_periodic+0x1c/0x90
[   51.302956] pc : [<c0183358>]    lr : [<c01833ec>]    psr: 20000093
[   51.302956] sp : ee961e18  ip : f0806000  fp : 00000100
[   51.314391] r10: c0c0ef6a  r9 : 0000000b  r8 : eebcf080
[   51.319591] r7 : ee961e7c  r6 : 00000000  r5 : 00000007  r4 : ef013ec0
[   51.326090] r3 : 00000000  r2 : 2e4ac000  r1 : c09ae9a8  r0 : 00000007
[   51.332591] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM Segment none
[   51.339781] Control: 10c5387d  Table: 4000406a  DAC: 00000051
[   51.345501] Process ksoftirqd/7 (pid: 53, stack limit = 0xee960210)
[   51.351740] Stack: (0xee961e18 to 0xee962000)
[   51.356073] 1e00: ef014db0 c0c03dac
[   51.364222] 1e20: 00000000 ef013ec0 ee854100 00000000 ee961e7c 00000039 ee854100 c0c0ef6a
[   51.372367] 1e40: 00000100 c055bd44 ee852840 c0164a18 00000000 00000001 ee854100 ee854100
[   51.380512] 1e60: c0c03f24 c0b6324c c0c02080 c0c02080 40000006 c0164ac4 00000000 00000000
[   51.388658] 1e80: 00000100 ee854100 ee854160 c0164b38 ee854100 ee854160 c0c03f24 c0167e9c
[   51.396804] 1ea0: 00000039 c0c0cbac c0c0cbac c0b6324c c0c02080 c01675e0 c0c0cc5c c0c0cc60
[   51.404949] 1ec0: 00000000 c011fd3c 00000000 00000006 c0c02098 ee960000 c0c02080 c011ff6c
[   51.413095] 1ee0: ee961f0c c06fb4a4 ee961ee0 c0c47f80 0000000a ffff9ed5 c0c03900 04208040
[   51.421240] 1f00: c0c0a174 ee960000 ee867b00 00000007 00000001 c0c0a174 00000002 00000000
[   51.429385] 1f20: 00000000 c01200b8 ee960000 c013a50c 00000000 ee867b80 ee867b00 c013a3b0
[   51.437530] 1f40: 00000000 00000000 00000000 c0136cbc ffffffff 00000001 00000007 ee867b00
[   51.445676] 1f60: 00000000 00270027 dead4ead ffffffff ffffffff ee961f74 ee961f74 00000000
[   51.453822] 1f80: 00000000 dead4ead ffffffff ffffffff ee961f90 ee961f90 ee961fac ee867b80
[   51.461967] 1fa0: c0136be0 00000000 00000000 c0107a78 00000000 00000000 00000000 00000000
[   51.470112] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   51.478258] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff
[   51.486409] [<c0183358>] (tick_periodic) from [<ef013ec0>] (0xef013ec0)
[   51.492990] Code: ee1d2f90 e34c30b6 e8bd4070 e7923003 (e5933040)
[   51.499057] ---[ end trace 995703fe1bede0b4 ]---

Fixes: 56a94f13919c ("clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier")
Cc: stable at vger.kernel.org #v4.2+ #v4.1.4+ #3.18.18+ #v3.16.18+ #v3.12.46+
Reported-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
---
 drivers/clocksource/exynos_mct.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 4da1dc2..670ff0f 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -495,6 +495,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu)
 	if (mct_int_type == MCT_INT_SPI) {
 		if (evt->irq != -1)
 			disable_irq_nosync(evt->irq);
+		exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
 	} else {
 		disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
 	}
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 05/12] drm/mediatek: add BLS component
From: CK Hu @ 2017-01-17  5:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484117473-46644-6-git-send-email-yt.shen@mediatek.com>

Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> Add BLS component for PWM + GAMMA function
> 
> Signed-off-by: YT Shen <yt.shen@mediatek.com>

Acked-by: CK Hu <ck.hu@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 5 ++++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 ++
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 3ff788c..f6e853a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -255,6 +255,7 @@ static void mtk_gamma_set(struct mtk_ddp_comp *comp,
>  	[MTK_DISP_PWM] = "pwm",
>  	[MTK_DISP_MUTEX] = "mutex",
>  	[MTK_DISP_OD] = "od",
> +	[MTK_DISP_BLS] = "bls",
>  };
>  
>  struct mtk_ddp_comp_match {
> @@ -265,6 +266,7 @@ struct mtk_ddp_comp_match {
>  
>  static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>  	[DDP_COMPONENT_AAL]	= { MTK_DISP_AAL,	0, &ddp_aal },
> +	[DDP_COMPONENT_BLS]	= { MTK_DISP_BLS,	0, NULL },
>  	[DDP_COMPONENT_COLOR0]	= { MTK_DISP_COLOR,	0, &ddp_color },
>  	[DDP_COMPONENT_COLOR1]	= { MTK_DISP_COLOR,	1, &ddp_color },
>  	[DDP_COMPONENT_DPI0]	= { MTK_DPI,		0, NULL },
> @@ -336,7 +338,8 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
>  	comp->id = comp_id;
>  	comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
>  
> -	if (comp_id == DDP_COMPONENT_DPI0 ||
> +	if (comp_id == DDP_COMPONENT_BLS ||
> +	    comp_id == DDP_COMPONENT_DPI0 ||
>  	    comp_id == DDP_COMPONENT_DSI0 ||
>  	    comp_id == DDP_COMPONENT_PWM0) {
>  		comp->regs = NULL;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 22a33ee..0828cf8 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -36,11 +36,13 @@ enum mtk_ddp_comp_type {
>  	MTK_DISP_PWM,
>  	MTK_DISP_MUTEX,
>  	MTK_DISP_OD,
> +	MTK_DISP_BLS,
>  	MTK_DDP_COMP_TYPE_MAX,
>  };
>  
>  enum mtk_ddp_comp_id {
>  	DDP_COMPONENT_AAL,
> +	DDP_COMPONENT_BLS,
>  	DDP_COMPONENT_COLOR0,
>  	DDP_COMPONENT_COLOR1,
>  	DDP_COMPONENT_DPI0,

^ permalink raw reply

* [PATCH v11 06/12] drm/mediatek: update display module connections
From: CK Hu @ 2017-01-17  5:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484117473-46644-7-git-send-email-yt.shen@mediatek.com>

Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> update connections for OVL, RDMA, BLS, DSI
> 
> Signed-off-by: YT Shen <yt.shen@mediatek.com>

Acked-by: CK Hu <ck.hu@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index b77d456..a9b209c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -32,6 +32,10 @@
>  #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN	0x0c8
>  #define DISP_REG_CONFIG_MMSYS_CG_CON0		0x100
>  
> +#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN	0x030
> +#define DISP_REG_CONFIG_OUT_SEL			0x04c
> +#define DISP_REG_CONFIG_DSI_SEL			0x050
> +
>  #define DISP_REG_MUTEX_EN(n)	(0x20 + 0x20 * (n))
>  #define DISP_REG_MUTEX(n)	(0x24 + 0x20 * (n))
>  #define DISP_REG_MUTEX_RST(n)	(0x28 + 0x20 * (n))
> @@ -71,6 +75,10 @@
>  #define DPI0_SEL_IN_RDMA1		0x1
>  #define COLOR1_SEL_IN_OVL1		0x1
>  
> +#define OVL_MOUT_EN_RDMA		0x1
> +#define BLS_TO_DSI_RDMA1_TO_DPI1	0x8
> +#define DSI_SEL_IN_BLS			0x0
> +
>  struct mtk_disp_mutex {
>  	int id;
>  	bool claimed;
> @@ -111,6 +119,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
>  	if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
>  		*addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
>  		value = OVL0_MOUT_EN_COLOR0;
> +	} else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
> +		*addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
> +		value = OVL_MOUT_EN_RDMA;
>  	} else if (cur == DDP_COMPONENT_OD && next == DDP_COMPONENT_RDMA0) {
>  		*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
>  		value = OD_MOUT_EN_RDMA0;
> @@ -148,6 +159,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
>  	} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
>  		*addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
>  		value = COLOR1_SEL_IN_OVL1;
> +	} else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
> +		*addr = DISP_REG_CONFIG_DSI_SEL;
> +		value = DSI_SEL_IN_BLS;
>  	} else {
>  		value = 0;
>  	}
> @@ -155,6 +169,15 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
>  	return value;
>  }
>  
> +static void mtk_ddp_sout_sel(void __iomem *config_regs,
> +			     enum mtk_ddp_comp_id cur,
> +			     enum mtk_ddp_comp_id next)
> +{
> +	if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0)
> +		writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
> +			       config_regs + DISP_REG_CONFIG_OUT_SEL);
> +}
> +
>  void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
>  			      enum mtk_ddp_comp_id cur,
>  			      enum mtk_ddp_comp_id next)
> @@ -167,6 +190,8 @@ void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
>  		writel_relaxed(reg, config_regs + addr);
>  	}
>  
> +	mtk_ddp_sout_sel(config_regs, cur, next);
> +
>  	value = mtk_ddp_sel_in(cur, next, &addr);
>  	if (value) {
>  		reg = readl_relaxed(config_regs + addr) | value;

^ permalink raw reply

* [PATCH v4 3/3] thermal: zx2967: add thermal driver for ZTE's zx2967 family
From: Eduardo Valentin @ 2017-01-17  5:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484304418-17489-3-git-send-email-baoyou.xie@linaro.org>

Hello,

On Fri, Jan 13, 2017 at 06:46:58PM +0800, Baoyou Xie wrote:
> This patch adds thermal driver for ZTE's zx2967 family.

Please consider the comments I sent on your v3. They still apply here.

and also the following:

> 
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>


<cut>

> +static int zx2967_thermal_get_temp(void *data, int *temp)
> +{
> +	void __iomem *regs;
> +	struct zx2967_thermal_sensor *sensor = data;
> +	struct zx2967_thermal_priv *priv = sensor->priv;
> +	unsigned long timeout = jiffies + msecs_to_jiffies(100);
> +	u32 val, sel_id;
> +
> +	regs = priv->regs;
> +	mutex_lock(&priv->lock);
> +
> +	writel_relaxed(0, regs + ZX2967_THERMAL_POWER_MODE);
> +	writel_relaxed(2, regs + ZX2967_THERMAL_DCF);
> +
> +	val = readl_relaxed(regs + ZX2967_THERMAL_SEL);
> +	val &= ~ZX2967_THERMAL_ID_MASK;
> +	sel_id = sensor->id ? ZX2967_THERMAL_ID0 : ZX2967_THERMAL_ID1;
> +	val |= sel_id;
> +	writel_relaxed(val, regs + ZX2967_THERMAL_SEL);
> +
> +	usleep_range(100, 300);
> +	val = readl_relaxed(regs + ZX2967_THERMAL_CTRL);
> +	while (!(val & ZX2967_THERMAL_READY)) {
> +		if (time_after(jiffies, timeout)) {
> +			dev_err(priv->dev, "Thermal sensor %d data timeout\n",
> +				sensor->id);
> +			mutex_unlock(&priv->lock);
> +			return -ETIMEDOUT;
> +		}
> +		val = readl_relaxed(regs + ZX2967_THERMAL_CTRL);

should you usleep_range() in between loops iterations?

> +	}
> +
> +	writel_relaxed(3, regs + ZX2967_THERMAL_DCF);
> +	val = readl_relaxed(regs + ZX2967_THERMAL_CTRL)
> +			 & ZX2967_THERMAL_TEMP_MASK;
> +	writel_relaxed(1, regs + ZX2967_THERMAL_POWER_MODE);
> +
> +	/*
> +	 * Calculate temperature
> +	 *   922	initial value of calibration cure
> +	 *   1.951	slope of calibration cure
> +	 */
> +	*temp = DIV_ROUND_CLOSEST((val - 922) * 1000, 1951);
> +
> +	mutex_unlock(&priv->lock);
> +
> +	return 0;
> +}
> +
> +static struct thermal_zone_of_device_ops zx2967_of_thermal_ops = {
> +	.get_temp = zx2967_thermal_get_temp,
> +};
> +
> +static int zx2967_thermal_probe(struct platform_device *pdev)
> +{
> +	struct zx2967_thermal_priv *priv;
> +	struct resource *res;
> +	int ret, i;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	priv->regs = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(priv->regs))
> +		return PTR_ERR(priv->regs);
> +
> +	priv->clk_gate = devm_clk_get(&pdev->dev, "gate");
> +	if (IS_ERR(priv->clk_gate)) {
> +		ret = PTR_ERR(priv->clk_gate);
> +		dev_err(&pdev->dev, "failed to get clock gate: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(priv->clk_gate);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	priv->pclk = devm_clk_get(&pdev->dev, "pclk");
> +	if (IS_ERR(priv->pclk)) {
> +		ret = PTR_ERR(priv->pclk);
> +		dev_err(&pdev->dev, "failed to get apb clock: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(priv->pclk);
> +	if (ret) {
> +		clk_disable_unprepare(priv->clk_gate);
> +		dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	mutex_init(&priv->lock);
> +	for (i = 0; i < NUM_SENSORS; i++) {
> +		struct zx2967_thermal_sensor *sensor = &priv->sensors[i];
> +
> +		sensor->priv = priv;
> +		sensor->id = i;
> +		sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev,
> +					i, sensor, &zx2967_of_thermal_ops);
> +		if (IS_ERR(sensor->tzd)) {
> +			ret = PTR_ERR(sensor->tzd);
> +			dev_err(&pdev->dev, "failed to register sensor %d: %d\n",
> +				i, ret);
> +			goto remove_ts;
> +		}
> +	}
> +	priv->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, priv);
> +
> +	return 0;
> +
> +remove_ts:
> +	clk_disable_unprepare(priv->clk_gate);
> +	clk_disable_unprepare(priv->pclk);
> +	for (i--; i >= 0; i--)
> +		thermal_zone_of_sensor_unregister(&pdev->dev,
> +						  priv->sensors[i].tzd);
> +
> +	return ret;
> +}
> +
> +static int zx2967_thermal_exit(struct platform_device *pdev)
> +{
> +	struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
> +	int i;
> +
> +	for (i = 0; i < NUM_SENSORS; i++) {
> +		struct zx2967_thermal_sensor *sensor = &priv->sensors[i];
> +
> +		thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd);
> +	}
> +	clk_disable_unprepare(priv->pclk);
> +	clk_disable_unprepare(priv->clk_gate);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id zx2967_thermal_id_table[] = {
> +	{ .compatible = "zte,zx296718-thermal" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, zx2967_thermal_id_table);
> +
> +static SIMPLE_DEV_PM_OPS(zx2967_thermal_pm_ops,
> +			 zx2967_thermal_suspend, zx2967_thermal_resume);
> +
> +static struct platform_driver zx2967_thermal_driver = {
> +	.probe = zx2967_thermal_probe,
> +	.remove = zx2967_thermal_exit,
> +	.driver = {
> +		.name = "zx2967_thermal",
> +		.of_match_table = zx2967_thermal_id_table,
> +		.pm = &zx2967_thermal_pm_ops,
> +	},
> +};
> +module_platform_driver(zx2967_thermal_driver);
> +
> +MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
> +MODULE_DESCRIPTION("ZTE zx2967 thermal driver");
> +MODULE_LICENSE("GPL");

GPLv2?

> -- 
> 2.7.4
> 

^ permalink raw reply


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