Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm64: add missing printk newlines
From: Mark Rutland @ 2017-01-09 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

A few printk calls in arm64 omit a trailing newline, even though there
is no subsequent KERN_CONT printk associated with them, and we actually
want a newline.

This can result in unrelated lines being appended, rather than appearing
on a new line. Additionally, timestamp prefixes may appear in-line. This
makes the logs harder to read than necessary.

Avoid this by adding a trailing newline.

These were found with a shortlist generated by:

$ git grep 'pr\(intk\|_.*\)(.*)' -- arch/arm64 | grep -v pr_fmt | grep -v '\\n"'

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
CC: James Morse <james.morse@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/armv8_deprecated.c | 2 +-
 arch/arm64/kernel/hibernate.c        | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index ecf9298..86032a0 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -636,7 +636,7 @@ static int __init armv8_deprecated_init(void)
 		if(system_supports_mixed_endian_el0())
 			register_insn_emulation(&setend_ops);
 		else
-			pr_info("setend instruction emulation is not supported on the system");
+			pr_info("setend instruction emulation is not supported on this system\n");
 	}
 
 	cpuhp_setup_state_nocalls(CPUHP_AP_ARM64_ISNDEP_STARTING,
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index fe301cb..1b918aae 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -472,7 +472,7 @@ int swsusp_arch_resume(void)
 	 */
 	tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC);
 	if (!tmp_pg_dir) {
-		pr_err("Failed to allocate memory for temporary page tables.");
+		pr_err("Failed to allocate memory for temporary page tables.\n");
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -492,7 +492,7 @@ int swsusp_arch_resume(void)
 	 */
 	zero_page = (void *)get_safe_page(GFP_ATOMIC);
 	if (!zero_page) {
-		pr_err("Failed to allocate zero page.");
+		pr_err("Failed to allocate zero page.\n");
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -512,7 +512,7 @@ int swsusp_arch_resume(void)
 				   &phys_hibernate_exit,
 				   (void *)get_safe_page, GFP_ATOMIC);
 	if (rc) {
-		pr_err("Failed to create safe executable page for hibernate_exit code.");
+		pr_err("Failed to create safe executable page for hibernate_exit code.\n");
 		goto out;
 	}
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 1/4] dmaengine: pl330: remove pdata based initialization
From: Arnd Bergmann @ 2017-01-09 14:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483970598-6191-2-git-send-email-m.szyprowski@samsung.com>

On Monday, January 9, 2017 3:03:15 PM CET Marek Szyprowski wrote:
> -
> -extern bool pl330_filter(struct dma_chan *chan, void *param);
> 

One minor comment:
I think the function itself is now also unused and can be removed.

Aside from that, the series looks good to me.

	Arnd

^ permalink raw reply

* [PATCH v3 3/3] drm: zte: add overlay plane support
From: Shawn Guo @ 2017-01-09 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOw6vbLz0ueNsXXPuDtrHkL_Mac5w_jjD9nVUzy+9zbaR-iBmg@mail.gmail.com>

On Thu, Jan 05, 2017 at 02:26:30AM -0500, Sean Paul wrote:
> > +static u32 zx_vl_get_fmt(uint32_t format)
> > +{
> > +       u32 val = 0;
> > +
> > +       switch (format) {
> > +       case DRM_FORMAT_NV12:
> > +               val = VL_FMT_YUV420;
> > +               break;
> > +       case DRM_FORMAT_YUV420:
> > +               val = VL_YUV420_PLANAR | VL_FMT_YUV420;
> > +               break;
> > +       case DRM_FORMAT_YUYV:
> > +               val = VL_YUV422_YUYV | VL_FMT_YUV422;
> > +               break;
> > +       case DRM_FORMAT_YVYU:
> > +               val = VL_YUV422_YVYU | VL_FMT_YUV422;
> > +               break;
> > +       case DRM_FORMAT_UYVY:
> > +               val = VL_YUV422_UYVY | VL_FMT_YUV422;
> > +               break;
> > +       case DRM_FORMAT_VYUY:
> > +               val = VL_YUV422_VYUY | VL_FMT_YUV422;
> > +               break;
> > +       case DRM_FORMAT_YUV444:
> > +               val = VL_FMT_YUV444_8BIT;
> 
> Minor nit: You could have eliminated val and just returned directly
> from all of the cases. Seems like there are a few other functions this
> is also true for.

Okay.  I will change zx_vl_get_fmt() and zx_vl_rsz_get_fmt()
accordingly.

> 
> > +               break;
> > +       default:
> > +               WARN_ONCE(1, "invalid pixel format %d\n", format);
> > +       }
> > +
> > +       return val;
> > +}

<snip>

> > +static void zx_vl_rsz_setup(struct zx_plane *zplane, uint32_t format,
> > +                           u32 src_w, u32 src_h, u32 dst_w, u32 dst_h)
> > +{
> > +       void __iomem *rsz = zplane->rsz;
> > +       u32 src_chroma_w = src_w;
> > +       u32 src_chroma_h = src_h;
> > +       u32 fmt;
> > +
> > +       /* Set up source and destination resolution */
> > +       zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1));
> > +       zx_writel(rsz + RSZ_DEST_CFG, RSZ_VER(dst_h - 1) | RSZ_HOR(dst_w - 1));
> > +
> > +       /* Configure data format for VL RSZ */
> > +       fmt = zx_vl_rsz_get_fmt(format);
> > +       zx_writel_mask(rsz + RSZ_VL_CTRL_CFG, RSZ_VL_FMT_MASK, fmt);
> > +
> > +       /* Calculate Chroma heigth and width */
> 
> s/heigth/height/

Thanks for spotting it.

> 
> > +       if (fmt == RSZ_VL_FMT_YCBCR420) {
> > +               src_chroma_w = src_w >> 1;
> > +               src_chroma_h = src_h >> 1;
> > +       } else if (fmt == RSZ_VL_FMT_YCBCR422) {
> > +               src_chroma_w = src_w >> 1;
> > +       }
> > +
> > +       /* Set up Luma and Chroma step registers */
> > +       zx_writel(rsz + RSZ_VL_LUMA_HOR, rsz_step_value(src_w, dst_w));
> > +       zx_writel(rsz + RSZ_VL_LUMA_VER, rsz_step_value(src_h, dst_h));
> > +       zx_writel(rsz + RSZ_VL_CHROMA_HOR, rsz_step_value(src_chroma_w, dst_w));
> > +       zx_writel(rsz + RSZ_VL_CHROMA_VER, rsz_step_value(src_chroma_h, dst_h));
> > +
> > +       zx_vl_rsz_set_update(zplane);
> > +}

<snip>

> > diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
> > index 3fb4fc04e693..e832c2ec3156 100644
> > --- a/drivers/gpu/drm/zte/zx_vou.c
> > +++ b/drivers/gpu/drm/zte/zx_vou.c
> > @@ -84,6 +84,8 @@ struct zx_crtc_bits {
> >  struct zx_crtc {
> >         struct drm_crtc crtc;
> >         struct drm_plane *primary;
> > +       struct drm_plane *overlay_active[VL_NUM];
> > +       unsigned int overlay_active_num;
> 
> I don't think this belongs here. You can instead add an active (or
> enabled) bool to the zx_plane struct and keep track of it via
> atomic_plane_update/disable. This allows you to call
> zx_plane_set_update unconditionally in the vou irq handler and check
> active/enabled in zx_plane_set_update.

It's a truly great suggestion.  How did I not think of it :)  The v4 is
coming for that.

Thanks a lot for the review effort, Sean.

Shawn

^ permalink raw reply

* [PATCH 1/2] ARM: hyp-stub: improve ABI
From: Catalin Marinas @ 2017-01-09 14:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170109125431.GY14217@n2100.armlinux.org.uk>

On Mon, Jan 09, 2017 at 12:54:31PM +0000, Russell King - ARM Linux wrote:
> So, we need KVM's stub to be (a) better documented so this stuff is
> obvious, and (b) updated so that kdump stands a chance of working even
> if the KVM stub is still in place at the point the host kernel panics.
> 
> Another reason why documentation is important here is that we need to
> make it clear to alternative hypervisors that the host kernel may issue
> a HVC call at any moment due to a crash with particular arguments, and
> that the host kernel expects a certain behaviour in that case, and that
> the hypervisor does not crash.

The only hypervisor (apart from the hyp-stub) built and deployed
together with the kernel is KVM. On ARM, to be able to enable KVM, the
host kernel must be booted in Hyp mode and install the stub before
dropping to SVC.

With Xen (or a different Type-1 hypervisor), the "host" kernel (dom0 for
Xen, a.k.a. control domain) is booted in SVC mode directly, so hyp-stub
is not installed and is_hyp_mode_available() returns false.

> For example, how will Xen behave - is introducing these changes going
> to cause a regression with Xen?  Does anyone even know the answer to
> that?  From what I can see, it seems we'll end up calling Xen's
> hypervisor with a random r12 value (which it uses as a reason code)
> but without the 0xea1 immediate constant in the HVC instruction.
> Beyond that, I've no idea.

Any HVC calls from the control domain kernel must comply with the ABI
offered by the corresponding hypervisor and has nothing to do with the
hyp-stub ABI. Routing hyp-stub ABI HVC calls to an unaware hypervisor
like Xen as part of kdump/kexec is a kernel bug and would probably
result in the kernel being killed. I haven't tried but kexec in a host
kernel under Xen should work just like kexec in any other guest kernel.

-- 
Catalin

^ permalink raw reply

* [PATCH] arm64: head.S: fix up stale comments
From: Mark Rutland @ 2017-01-09 14:31 UTC (permalink / raw)
  To: linux-arm-kernel

In commit 23c8a500c24d02dd ("arm64: kernel: use ordinary return/argument
register for el2_setup()"), we stopped using w20 as a global stash of
the boot mode flag, and instead pass this around in w0 as a function
parameter.

Unfortunately, we missed a couple of comments, which still refer to the
old convention of using w20/x20.

This patch fixes up the comments to describe the code as it currently
works.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/head.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 4b1abac..9b0857a 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -483,7 +483,7 @@ ENTRY(kimage_vaddr)
  * If we're fortunate enough to boot at EL2, ensure that the world is
  * sane before dropping to EL1.
  *
- * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x20 if
+ * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in w0 if
  * booted in EL1 or EL2 respectively.
  */
 ENTRY(el2_setup)
@@ -628,7 +628,7 @@ ENDPROC(el2_setup)
 
 /*
  * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed
- * in x20. See arch/arm64/include/asm/virt.h for more info.
+ * in w0. See arch/arm64/include/asm/virt.h for more info.
  */
 set_cpu_boot_mode_flag:
 	adr_l	x1, __boot_cpu_mode
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 0/3] Add overlay plane support for ZTE drm driver
From: Shawn Guo @ 2017-01-09 14:35 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Changes for v4:
 - Instead of using val, return value directly for zx_vl_get_fmt() and
   zx_vl_rsz_get_fmt().
 - Fix typo of 'heigth'
 - Add 'enabled' in struct zx_plane to track layer enabling state, and
   check the state in zx_plane_set_update(), so that we can call
   zx_plane_set_update() unconditionally in the vou irq handler.

Changes for v3:
 - Let zx_plane be accessible from zx_vou driver, and so we can easily
   access all the data encoded in zx_plane with a drm_plane pointer.
   Thus, function zx_overlay_find_vl_idx() can be saved completely.
 - Refine the existing zx_plane driver a bit to support disable graphic
   layer, and make the support of overlay plane a bit easier, by sharing
   VOU layer setup and teardown functions between graphic and video
   layers.

Changes for v2:
 - Use clipped coordinates for overlay position calculation

Shawn Guo (3):
  drm: zte: make zx_plane accessible from zx_vou driver
  drm: zte: add .atomic_disable hook to disable graphic layer
  drm: zte: add overlay plane support

 drivers/gpu/drm/zte/zx_plane.c      | 328 +++++++++++++++++++++++++++++++-----
 drivers/gpu/drm/zte/zx_plane.h      |  13 +-
 drivers/gpu/drm/zte/zx_plane_regs.h |  51 ++++++
 drivers/gpu/drm/zte/zx_vou.c        | 185 +++++++++++++++-----
 drivers/gpu/drm/zte/zx_vou.h        |   3 +
 drivers/gpu/drm/zte/zx_vou_regs.h   |  18 ++
 6 files changed, 516 insertions(+), 82 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH v4 1/3] drm: zte: make zx_plane accessible from zx_vou driver
From: Shawn Guo @ 2017-01-09 14:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483972544-12731-1-git-send-email-shawnguo@kernel.org>

From: Shawn Guo <shawn.guo@linaro.org>

Move struct zx_plane from zx_plane.c to zx_plane.h, so that it can be
accessed from zx_vou driver, and we can save the use of struct
zx_layer_data completely.  More importantly, those additional data used
by VOU controller to enable/disable graphic and video layers can later
be added and accessed much more easily from zx_vou driver.

While at it, we make two changes to zx_plane_init() interface:

 - Encode struct device pointer in zx_plane, so that we do not need to
   pass it as a parameter.
 - Change return of zx_plane_init() from struct drm_plane pointer to
   error code, since we can get the pointer from zx_plane in zx_vou
   driver now.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/zte/zx_plane.c | 36 +++++++-----------------------------
 drivers/gpu/drm/zte/zx_plane.h | 11 +++++++----
 drivers/gpu/drm/zte/zx_vou.c   | 31 +++++++++++++++++++------------
 3 files changed, 33 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 546eb92a94e8..78d29b1db91c 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -21,16 +21,6 @@
 #include "zx_plane_regs.h"
 #include "zx_vou.h"
 
-struct zx_plane {
-	struct drm_plane plane;
-	void __iomem *layer;
-	void __iomem *csc;
-	void __iomem *hbsc;
-	void __iomem *rsz;
-};
-
-#define to_zx_plane(plane)	container_of(plane, struct zx_plane, plane)
-
 static const uint32_t gl_formats[] = {
 	DRM_FORMAT_ARGB8888,
 	DRM_FORMAT_XRGB8888,
@@ -248,28 +238,16 @@ static void zx_plane_hbsc_init(struct zx_plane *zplane)
 	zx_writel(hbsc + HBSC_THRESHOLD_COL3, (0x3c0 << 16) | 0x40);
 }
 
-struct drm_plane *zx_plane_init(struct drm_device *drm, struct device *dev,
-				struct zx_layer_data *data,
-				enum drm_plane_type type)
+int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
+		  enum drm_plane_type type)
 {
 	const struct drm_plane_helper_funcs *helper;
-	struct zx_plane *zplane;
-	struct drm_plane *plane;
+	struct drm_plane *plane = &zplane->plane;
+	struct device *dev = zplane->dev;
 	const uint32_t *formats;
 	unsigned int format_count;
 	int ret;
 
-	zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
-	if (!zplane)
-		return ERR_PTR(-ENOMEM);
-
-	plane = &zplane->plane;
-
-	zplane->layer = data->layer;
-	zplane->hbsc = data->hbsc;
-	zplane->csc = data->csc;
-	zplane->rsz = data->rsz;
-
 	zx_plane_hbsc_init(zplane);
 
 	switch (type) {
@@ -282,7 +260,7 @@ struct drm_plane *zx_plane_init(struct drm_device *drm, struct device *dev,
 		/* TODO: add video layer (vl) support */
 		break;
 	default:
-		return ERR_PTR(-ENODEV);
+		return -ENODEV;
 	}
 
 	ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK,
@@ -290,10 +268,10 @@ struct drm_plane *zx_plane_init(struct drm_device *drm, struct device *dev,
 				       type, NULL);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret);
-		return ERR_PTR(ret);
+		return ret;
 	}
 
 	drm_plane_helper_add(plane, helper);
 
-	return plane;
+	return 0;
 }
diff --git a/drivers/gpu/drm/zte/zx_plane.h b/drivers/gpu/drm/zte/zx_plane.h
index 2b82cd558d9d..264a92e0b532 100644
--- a/drivers/gpu/drm/zte/zx_plane.h
+++ b/drivers/gpu/drm/zte/zx_plane.h
@@ -11,16 +11,19 @@
 #ifndef __ZX_PLANE_H__
 #define __ZX_PLANE_H__
 
-struct zx_layer_data {
+struct zx_plane {
+	struct drm_plane plane;
+	struct device *dev;
 	void __iomem *layer;
 	void __iomem *csc;
 	void __iomem *hbsc;
 	void __iomem *rsz;
 };
 
-struct drm_plane *zx_plane_init(struct drm_device *drm, struct device *dev,
-				struct zx_layer_data *data,
-				enum drm_plane_type type);
+#define to_zx_plane(plane) container_of(plane, struct zx_plane, plane)
+
+int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
+		  enum drm_plane_type type);
 void zx_plane_set_update(struct drm_plane *plane);
 
 #endif /* __ZX_PLANE_H__ */
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index 73fe15c17c32..d5c801f6f97b 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -294,7 +294,7 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
 			enum vou_chn_type chn_type)
 {
 	struct device *dev = vou->dev;
-	struct zx_layer_data data;
+	struct zx_plane *zplane;
 	struct zx_crtc *zcrtc;
 	int ret;
 
@@ -305,19 +305,25 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
 	zcrtc->vou = vou;
 	zcrtc->chn_type = chn_type;
 
+	zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
+	if (!zplane)
+		return -ENOMEM;
+
+	zplane->dev = dev;
+
 	if (chn_type == VOU_CHN_MAIN) {
-		data.layer = vou->osd + MAIN_GL_OFFSET;
-		data.csc = vou->osd + MAIN_CSC_OFFSET;
-		data.hbsc = vou->osd + MAIN_HBSC_OFFSET;
-		data.rsz = vou->otfppu + MAIN_RSZ_OFFSET;
+		zplane->layer = vou->osd + MAIN_GL_OFFSET;
+		zplane->csc = vou->osd + MAIN_CSC_OFFSET;
+		zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
+		zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
 		zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
 		zcrtc->regs = &main_crtc_regs;
 		zcrtc->bits = &main_crtc_bits;
 	} else {
-		data.layer = vou->osd + AUX_GL_OFFSET;
-		data.csc = vou->osd + AUX_CSC_OFFSET;
-		data.hbsc = vou->osd + AUX_HBSC_OFFSET;
-		data.rsz = vou->otfppu + AUX_RSZ_OFFSET;
+		zplane->layer = vou->osd + AUX_GL_OFFSET;
+		zplane->csc = vou->osd + AUX_CSC_OFFSET;
+		zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
+		zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
 		zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
 		zcrtc->regs = &aux_crtc_regs;
 		zcrtc->bits = &aux_crtc_bits;
@@ -331,13 +337,14 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
 		return ret;
 	}
 
-	zcrtc->primary = zx_plane_init(drm, dev, &data, DRM_PLANE_TYPE_PRIMARY);
-	if (IS_ERR(zcrtc->primary)) {
-		ret = PTR_ERR(zcrtc->primary);
+	ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY);
+	if (ret) {
 		DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret);
 		return ret;
 	}
 
+	zcrtc->primary = &zplane->plane;
+
 	ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL,
 					&zx_crtc_funcs, NULL);
 	if (ret) {
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 2/3] drm: zte: add .atomic_disable hook to disable graphic layer
From: Shawn Guo @ 2017-01-09 14:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483972544-12731-1-git-send-email-shawnguo@kernel.org>

From: Shawn Guo <shawn.guo@linaro.org>

There are a few hardware bits for each graphic layer to control main/aux
channel and clock selection, as well as the layer enabling.  These bits
sit outside the layer block itself, but in VOU control glue block.  We
currently set these bits up at CRTC initialization for once, and do not
support disabling the layer.

This patch creates a pair of functions zx_vou_layer_enable[disable] to
be invoked from plane hooks .atomic_update and .atomic_disable to set up
and tear down the layer.  This is generic for both graphic and video
layers, so it will make the overlay plane support to be added later much
easier.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/zte/zx_plane.c | 15 +++++++++
 drivers/gpu/drm/zte/zx_plane.h |  1 +
 drivers/gpu/drm/zte/zx_vou.c   | 70 ++++++++++++++++++++++++++++++------------
 drivers/gpu/drm/zte/zx_vou.h   |  3 ++
 4 files changed, 69 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 78d29b1db91c..5445eebf830f 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -197,12 +197,27 @@ static void zx_gl_plane_atomic_update(struct drm_plane *plane,
 	/* Enable HBSC block */
 	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN);
 
+	zx_vou_layer_enable(plane);
+
 	zx_gl_set_update(zplane);
 }
 
+static void zx_plane_atomic_disable(struct drm_plane *plane,
+				    struct drm_plane_state *old_state)
+{
+	struct zx_plane *zplane = to_zx_plane(plane);
+	void __iomem *hbsc = zplane->hbsc;
+
+	zx_vou_layer_disable(plane);
+
+	/* Disable HBSC block */
+	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, 0);
+}
+
 static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = {
 	.atomic_check = zx_gl_plane_atomic_check,
 	.atomic_update = zx_gl_plane_atomic_update,
+	.atomic_disable = zx_plane_atomic_disable,
 };
 
 static void zx_plane_destroy(struct drm_plane *plane)
diff --git a/drivers/gpu/drm/zte/zx_plane.h b/drivers/gpu/drm/zte/zx_plane.h
index 264a92e0b532..933611ddffd0 100644
--- a/drivers/gpu/drm/zte/zx_plane.h
+++ b/drivers/gpu/drm/zte/zx_plane.h
@@ -18,6 +18,7 @@ struct zx_plane {
 	void __iomem *csc;
 	void __iomem *hbsc;
 	void __iomem *rsz;
+	const struct vou_layer_bits *bits;
 };
 
 #define to_zx_plane(plane) container_of(plane, struct zx_plane, plane)
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index d5c801f6f97b..3fb4fc04e693 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -65,7 +65,6 @@ struct zx_crtc_bits {
 	u32 polarity_shift;
 	u32 int_frame_mask;
 	u32 tc_enable;
-	u32 gl_enable;
 };
 
 static const struct zx_crtc_bits main_crtc_bits = {
@@ -73,7 +72,6 @@ struct zx_crtc_bits {
 	.polarity_shift = MAIN_POL_SHIFT,
 	.int_frame_mask = TIMING_INT_MAIN_FRAME,
 	.tc_enable = MAIN_TC_EN,
-	.gl_enable = OSD_CTRL0_GL0_EN,
 };
 
 static const struct zx_crtc_bits aux_crtc_bits = {
@@ -81,7 +79,6 @@ struct zx_crtc_bits {
 	.polarity_shift = AUX_POL_SHIFT,
 	.int_frame_mask = TIMING_INT_AUX_FRAME,
 	.tc_enable = AUX_TC_EN,
-	.gl_enable = OSD_CTRL0_GL1_EN,
 };
 
 struct zx_crtc {
@@ -97,6 +94,24 @@ struct zx_crtc {
 
 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
 
+struct vou_layer_bits {
+	u32 enable;
+	u32 chnsel;
+	u32 clksel;
+};
+
+static const struct vou_layer_bits zx_gl_bits[GL_NUM] = {
+	{
+		.enable = OSD_CTRL0_GL0_EN,
+		.chnsel = OSD_CTRL0_GL0_SEL,
+		.clksel = VOU_CLK_GL0_SEL,
+	}, {
+		.enable = OSD_CTRL0_GL1_EN,
+		.chnsel = OSD_CTRL0_GL1_SEL,
+		.clksel = VOU_CLK_GL1_SEL,
+	},
+};
+
 struct zx_vou_hw {
 	struct device *dev;
 	void __iomem *osd;
@@ -220,10 +235,6 @@ static void zx_crtc_enable(struct drm_crtc *crtc)
 	/* Enable channel */
 	zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);
 
-	/* Enable Graphic Layer */
-	zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable,
-		       bits->gl_enable);
-
 	drm_crtc_vblank_on(crtc);
 
 	ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
@@ -247,9 +258,6 @@ static void zx_crtc_disable(struct drm_crtc *crtc)
 
 	drm_crtc_vblank_off(crtc);
 
-	/* Disable Graphic Layer */
-	zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable, 0);
-
 	/* Disable channel */
 	zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);
 
@@ -316,6 +324,7 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
 		zplane->csc = vou->osd + MAIN_CSC_OFFSET;
 		zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
 		zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
+		zplane->bits = &zx_gl_bits[0];
 		zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
 		zcrtc->regs = &main_crtc_regs;
 		zcrtc->bits = &main_crtc_bits;
@@ -324,6 +333,7 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
 		zplane->csc = vou->osd + AUX_CSC_OFFSET;
 		zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
 		zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
+		zplane->bits = &zx_gl_bits[1];
 		zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
 		zcrtc->regs = &aux_crtc_regs;
 		zcrtc->bits = &aux_crtc_bits;
@@ -411,6 +421,36 @@ void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe)
 		       zcrtc->bits->int_frame_mask, 0);
 }
 
+void zx_vou_layer_enable(struct drm_plane *plane)
+{
+	struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc);
+	struct zx_vou_hw *vou = zcrtc->vou;
+	struct zx_plane *zplane = to_zx_plane(plane);
+	const struct vou_layer_bits *bits = zplane->bits;
+
+	if (zcrtc->chn_type == VOU_CHN_MAIN) {
+		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0);
+		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0);
+	} else {
+		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
+			       bits->chnsel);
+		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
+			       bits->clksel);
+	}
+
+	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
+}
+
+void zx_vou_layer_disable(struct drm_plane *plane)
+{
+	struct zx_crtc *zcrtc = to_zx_crtc(plane->crtc);
+	struct zx_vou_hw *vou = zcrtc->vou;
+	struct zx_plane *zplane = to_zx_plane(plane);
+	const struct vou_layer_bits *bits = zplane->bits;
+
+	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
+}
+
 static irqreturn_t vou_irq_handler(int irq, void *dev_id)
 {
 	struct zx_vou_hw *vou = dev_id;
@@ -469,19 +509,9 @@ static void vou_dtrc_init(struct zx_vou_hw *vou)
 
 static void vou_hw_init(struct zx_vou_hw *vou)
 {
-	/* Set GL0 to main channel and GL1 to aux channel */
-	zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL0_SEL, 0);
-	zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL1_SEL,
-		       OSD_CTRL0_GL1_SEL);
-
 	/* Release reset for all VOU modules */
 	zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
 
-	/* Select main clock for GL0 and aux clock for GL1 module */
-	zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL0_SEL, 0);
-	zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL1_SEL,
-		       VOU_CLK_GL1_SEL);
-
 	/* Enable clock auto-gating for all VOU modules */
 	zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0);
 
diff --git a/drivers/gpu/drm/zte/zx_vou.h b/drivers/gpu/drm/zte/zx_vou.h
index 349e06cd86f4..4b4339be641b 100644
--- a/drivers/gpu/drm/zte/zx_vou.h
+++ b/drivers/gpu/drm/zte/zx_vou.h
@@ -43,4 +43,7 @@ struct vou_inf {
 int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe);
 void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe);
 
+void zx_vou_layer_enable(struct drm_plane *plane);
+void zx_vou_layer_disable(struct drm_plane *plane);
+
 #endif /* __ZX_VOU_H__ */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 3/3] drm: zte: add overlay plane support
From: Shawn Guo @ 2017-01-09 14:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483972544-12731-1-git-send-email-shawnguo@kernel.org>

From: Shawn Guo <shawn.guo@linaro.org>

It enables VOU VL (Video Layer) to support overlay plane with scaling
function.  VL0 has some quirks on scaling support.  We choose to skip it
and only adds VL1 and VL2 into DRM core for now.

Function zx_plane_atomic_disable() gets moved around with no changes to
save a forward declaration.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 drivers/gpu/drm/zte/zx_plane.c      | 301 +++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/zte/zx_plane.h      |   1 +
 drivers/gpu/drm/zte/zx_plane_regs.h |  51 ++++++
 drivers/gpu/drm/zte/zx_vou.c        |  84 +++++++++-
 drivers/gpu/drm/zte/zx_vou_regs.h   |  18 +++
 5 files changed, 426 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 5445eebf830f..24426c2b4b8f 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -30,6 +30,261 @@
 	DRM_FORMAT_ARGB4444,
 };
 
+static const uint32_t vl_formats[] = {
+	DRM_FORMAT_NV12,	/* Semi-planar YUV420 */
+	DRM_FORMAT_YUV420,	/* Planar YUV420 */
+	DRM_FORMAT_YUYV,	/* Packed YUV422 */
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+	DRM_FORMAT_YUV444,	/* YUV444 8bit */
+	/*
+	 * TODO: add formats below that HW supports:
+	 *  - YUV420 P010
+	 *  - YUV420 Hantro
+	 *  - YUV444 10bit
+	 */
+};
+
+#define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
+
+static int zx_vl_plane_atomic_check(struct drm_plane *plane,
+				    struct drm_plane_state *plane_state)
+{
+	struct drm_framebuffer *fb = plane_state->fb;
+	struct drm_crtc *crtc = plane_state->crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_rect clip;
+	int min_scale = FRAC_16_16(1, 8);
+	int max_scale = FRAC_16_16(8, 1);
+
+	if (!crtc || !fb)
+		return 0;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state,
+							crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	/* nothing to check when disabling or disabled */
+	if (!crtc_state->enable)
+		return 0;
+
+	/* plane must be enabled */
+	if (!plane_state->crtc)
+		return -EINVAL;
+
+	clip.x1 = 0;
+	clip.y1 = 0;
+	clip.x2 = crtc_state->adjusted_mode.hdisplay;
+	clip.y2 = crtc_state->adjusted_mode.vdisplay;
+
+	return drm_plane_helper_check_state(plane_state, &clip,
+					    min_scale, max_scale,
+					    true, true);
+}
+
+static int zx_vl_get_fmt(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_NV12:
+		return VL_FMT_YUV420;
+	case DRM_FORMAT_YUV420:
+		return VL_YUV420_PLANAR | VL_FMT_YUV420;
+	case DRM_FORMAT_YUYV:
+		return VL_YUV422_YUYV | VL_FMT_YUV422;
+	case DRM_FORMAT_YVYU:
+		return VL_YUV422_YVYU | VL_FMT_YUV422;
+	case DRM_FORMAT_UYVY:
+		return VL_YUV422_UYVY | VL_FMT_YUV422;
+	case DRM_FORMAT_VYUY:
+		return VL_YUV422_VYUY | VL_FMT_YUV422;
+	case DRM_FORMAT_YUV444:
+		return VL_FMT_YUV444_8BIT;
+	default:
+		WARN_ONCE(1, "invalid pixel format %d\n", format);
+		return -EINVAL;
+	}
+}
+
+static inline void zx_vl_set_update(struct zx_plane *zplane)
+{
+	void __iomem *layer = zplane->layer;
+
+	zx_writel_mask(layer + VL_CTRL0, VL_UPDATE, VL_UPDATE);
+}
+
+static inline void zx_vl_rsz_set_update(struct zx_plane *zplane)
+{
+	zx_writel(zplane->rsz + RSZ_VL_ENABLE_CFG, 1);
+}
+
+static int zx_vl_rsz_get_fmt(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_YUV420:
+		return RSZ_VL_FMT_YCBCR420;
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_YVYU:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+		return RSZ_VL_FMT_YCBCR422;
+	case DRM_FORMAT_YUV444:
+		return RSZ_VL_FMT_YCBCR444;
+	default:
+		WARN_ONCE(1, "invalid pixel format %d\n", format);
+		return -EINVAL;
+	}
+}
+
+static inline u32 rsz_step_value(u32 src, u32 dst)
+{
+	u32 val = 0;
+
+	if (src == dst)
+		val = 0;
+	else if (src < dst)
+		val = RSZ_PARA_STEP((src << 16) / dst);
+	else if (src > dst)
+		val = RSZ_DATA_STEP(src / dst) |
+		      RSZ_PARA_STEP(((src << 16) / dst) & 0xffff);
+
+	return val;
+}
+
+static void zx_vl_rsz_setup(struct zx_plane *zplane, uint32_t format,
+			    u32 src_w, u32 src_h, u32 dst_w, u32 dst_h)
+{
+	void __iomem *rsz = zplane->rsz;
+	u32 src_chroma_w = src_w;
+	u32 src_chroma_h = src_h;
+	u32 fmt;
+
+	/* Set up source and destination resolution */
+	zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1));
+	zx_writel(rsz + RSZ_DEST_CFG, RSZ_VER(dst_h - 1) | RSZ_HOR(dst_w - 1));
+
+	/* Configure data format for VL RSZ */
+	fmt = zx_vl_rsz_get_fmt(format);
+	if (fmt >= 0)
+		zx_writel_mask(rsz + RSZ_VL_CTRL_CFG, RSZ_VL_FMT_MASK, fmt);
+
+	/* Calculate Chroma height and width */
+	if (fmt == RSZ_VL_FMT_YCBCR420) {
+		src_chroma_w = src_w >> 1;
+		src_chroma_h = src_h >> 1;
+	} else if (fmt == RSZ_VL_FMT_YCBCR422) {
+		src_chroma_w = src_w >> 1;
+	}
+
+	/* Set up Luma and Chroma step registers */
+	zx_writel(rsz + RSZ_VL_LUMA_HOR, rsz_step_value(src_w, dst_w));
+	zx_writel(rsz + RSZ_VL_LUMA_VER, rsz_step_value(src_h, dst_h));
+	zx_writel(rsz + RSZ_VL_CHROMA_HOR, rsz_step_value(src_chroma_w, dst_w));
+	zx_writel(rsz + RSZ_VL_CHROMA_VER, rsz_step_value(src_chroma_h, dst_h));
+
+	zx_vl_rsz_set_update(zplane);
+}
+
+static void zx_vl_plane_atomic_update(struct drm_plane *plane,
+				      struct drm_plane_state *old_state)
+{
+	struct zx_plane *zplane = to_zx_plane(plane);
+	struct drm_plane_state *state = plane->state;
+	struct drm_framebuffer *fb = state->fb;
+	struct drm_rect *src = &state->src;
+	struct drm_rect *dst = &state->dst;
+	struct drm_gem_cma_object *cma_obj;
+	void __iomem *layer = zplane->layer;
+	void __iomem *hbsc = zplane->hbsc;
+	void __iomem *paddr_reg;
+	dma_addr_t paddr;
+	u32 src_x, src_y, src_w, src_h;
+	u32 dst_x, dst_y, dst_w, dst_h;
+	uint32_t format;
+	u32 fmt;
+	int num_planes;
+	int i;
+
+	if (!fb)
+		return;
+
+	format = fb->pixel_format;
+
+	src_x = src->x1 >> 16;
+	src_y = src->y1 >> 16;
+	src_w = drm_rect_width(src) >> 16;
+	src_h = drm_rect_height(src) >> 16;
+
+	dst_x = dst->x1;
+	dst_y = dst->y1;
+	dst_w = drm_rect_width(dst);
+	dst_h = drm_rect_height(dst);
+
+	/* Set up data address registers for Y, Cb and Cr planes */
+	num_planes = drm_format_num_planes(format);
+	paddr_reg = layer + VL_Y;
+	for (i = 0; i < num_planes; i++) {
+		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
+		paddr = cma_obj->paddr + fb->offsets[i];
+		paddr += src_y * fb->pitches[i];
+		paddr += src_x * drm_format_plane_cpp(format, i);
+		zx_writel(paddr_reg, paddr);
+		paddr_reg += 4;
+	}
+
+	/* Set up source height/width register */
+	zx_writel(layer + VL_SRC_SIZE, GL_SRC_W(src_w) | GL_SRC_H(src_h));
+
+	/* Set up start position register */
+	zx_writel(layer + VL_POS_START, GL_POS_X(dst_x) | GL_POS_Y(dst_y));
+
+	/* Set up end position register */
+	zx_writel(layer + VL_POS_END,
+		  GL_POS_X(dst_x + dst_w) | GL_POS_Y(dst_y + dst_h));
+
+	/* Strides of Cb and Cr planes should be identical */
+	zx_writel(layer + VL_STRIDE, LUMA_STRIDE(fb->pitches[0]) |
+		  CHROMA_STRIDE(fb->pitches[1]));
+
+	/* Set up video layer data format */
+	fmt = zx_vl_get_fmt(format);
+	if (fmt >= 0)
+		zx_writel(layer + VL_CTRL1, fmt);
+
+	/* Always use scaler since it exists (set for not bypass) */
+	zx_writel_mask(layer + VL_CTRL2, VL_SCALER_BYPASS_MODE,
+		       VL_SCALER_BYPASS_MODE);
+
+	zx_vl_rsz_setup(zplane, format, src_w, src_h, dst_w, dst_h);
+
+	/* Enable HBSC block */
+	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN);
+
+	zx_vou_layer_enable(plane);
+
+	zx_vl_set_update(zplane);
+}
+
+static void zx_plane_atomic_disable(struct drm_plane *plane,
+				    struct drm_plane_state *old_state)
+{
+	struct zx_plane *zplane = to_zx_plane(plane);
+	void __iomem *hbsc = zplane->hbsc;
+
+	zx_vou_layer_disable(plane);
+
+	/* Disable HBSC block */
+	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, 0);
+}
+
+static const struct drm_plane_helper_funcs zx_vl_plane_helper_funcs = {
+	.atomic_check = zx_vl_plane_atomic_check,
+	.atomic_update = zx_vl_plane_atomic_update,
+	.atomic_disable = zx_plane_atomic_disable,
+};
+
 static int zx_gl_plane_atomic_check(struct drm_plane *plane,
 				    struct drm_plane_state *plane_state)
 {
@@ -97,14 +352,6 @@ static inline void zx_gl_rsz_set_update(struct zx_plane *zplane)
 	zx_writel(zplane->rsz + RSZ_ENABLE_CFG, 1);
 }
 
-void zx_plane_set_update(struct drm_plane *plane)
-{
-	struct zx_plane *zplane = to_zx_plane(plane);
-
-	zx_gl_rsz_set_update(zplane);
-	zx_gl_set_update(zplane);
-}
-
 static void zx_gl_rsz_setup(struct zx_plane *zplane, u32 src_w, u32 src_h,
 			    u32 dst_w, u32 dst_h)
 {
@@ -202,18 +449,6 @@ static void zx_gl_plane_atomic_update(struct drm_plane *plane,
 	zx_gl_set_update(zplane);
 }
 
-static void zx_plane_atomic_disable(struct drm_plane *plane,
-				    struct drm_plane_state *old_state)
-{
-	struct zx_plane *zplane = to_zx_plane(plane);
-	void __iomem *hbsc = zplane->hbsc;
-
-	zx_vou_layer_disable(plane);
-
-	/* Disable HBSC block */
-	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, 0);
-}
-
 static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = {
 	.atomic_check = zx_gl_plane_atomic_check,
 	.atomic_update = zx_gl_plane_atomic_update,
@@ -235,6 +470,28 @@ static void zx_plane_destroy(struct drm_plane *plane)
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
 
+void zx_plane_set_update(struct drm_plane *plane)
+{
+	struct zx_plane *zplane = to_zx_plane(plane);
+
+	/* Do nothing if the layer is not enabled */
+	if (!zplane->enabled)
+		return;
+
+	switch (plane->type) {
+	case DRM_PLANE_TYPE_PRIMARY:
+		zx_gl_rsz_set_update(zplane);
+		zx_gl_set_update(zplane);
+		break;
+	case DRM_PLANE_TYPE_OVERLAY:
+		zx_vl_rsz_set_update(zplane);
+		zx_vl_set_update(zplane);
+		break;
+	default:
+		WARN_ONCE(1, "unsupported plane type %d\n", plane->type);
+	}
+}
+
 static void zx_plane_hbsc_init(struct zx_plane *zplane)
 {
 	void __iomem *hbsc = zplane->hbsc;
@@ -272,7 +529,9 @@ int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
 		format_count = ARRAY_SIZE(gl_formats);
 		break;
 	case DRM_PLANE_TYPE_OVERLAY:
-		/* TODO: add video layer (vl) support */
+		helper = &zx_vl_plane_helper_funcs;
+		formats = vl_formats;
+		format_count = ARRAY_SIZE(vl_formats);
 		break;
 	default:
 		return -ENODEV;
diff --git a/drivers/gpu/drm/zte/zx_plane.h b/drivers/gpu/drm/zte/zx_plane.h
index 933611ddffd0..e8f9b138114d 100644
--- a/drivers/gpu/drm/zte/zx_plane.h
+++ b/drivers/gpu/drm/zte/zx_plane.h
@@ -19,6 +19,7 @@ struct zx_plane {
 	void __iomem *hbsc;
 	void __iomem *rsz;
 	const struct vou_layer_bits *bits;
+	bool enabled;
 };
 
 #define to_zx_plane(plane) container_of(plane, struct zx_plane, plane)
diff --git a/drivers/gpu/drm/zte/zx_plane_regs.h b/drivers/gpu/drm/zte/zx_plane_regs.h
index 3dde6716a558..65f271aeabed 100644
--- a/drivers/gpu/drm/zte/zx_plane_regs.h
+++ b/drivers/gpu/drm/zte/zx_plane_regs.h
@@ -46,6 +46,37 @@
 #define GL_POS_X(x)	(((x) << GL_POS_X_SHIFT) & GL_POS_X_MASK)
 #define GL_POS_Y(x)	(((x) << GL_POS_Y_SHIFT) & GL_POS_Y_MASK)
 
+/* VL registers */
+#define VL_CTRL0			0x00
+#define VL_UPDATE			BIT(3)
+#define VL_CTRL1			0x04
+#define VL_YUV420_PLANAR		BIT(5)
+#define VL_YUV422_SHIFT			3
+#define VL_YUV422_YUYV			(0 << VL_YUV422_SHIFT)
+#define VL_YUV422_YVYU			(1 << VL_YUV422_SHIFT)
+#define VL_YUV422_UYVY			(2 << VL_YUV422_SHIFT)
+#define VL_YUV422_VYUY			(3 << VL_YUV422_SHIFT)
+#define VL_FMT_YUV420			0
+#define VL_FMT_YUV422			1
+#define VL_FMT_YUV420_P010		2
+#define VL_FMT_YUV420_HANTRO		3
+#define VL_FMT_YUV444_8BIT		4
+#define VL_FMT_YUV444_10BIT		5
+#define VL_CTRL2			0x08
+#define VL_SCALER_BYPASS_MODE		BIT(0)
+#define VL_STRIDE			0x0c
+#define LUMA_STRIDE_SHIFT		16
+#define LUMA_STRIDE_MASK		(0xffff << LUMA_STRIDE_SHIFT)
+#define CHROMA_STRIDE_SHIFT		0
+#define CHROMA_STRIDE_MASK		(0xffff << CHROMA_STRIDE_SHIFT)
+#define VL_SRC_SIZE			0x10
+#define VL_Y				0x14
+#define VL_POS_START			0x30
+#define VL_POS_END			0x34
+
+#define LUMA_STRIDE(x)	 (((x) << LUMA_STRIDE_SHIFT) & LUMA_STRIDE_MASK)
+#define CHROMA_STRIDE(x) (((x) << CHROMA_STRIDE_SHIFT) & CHROMA_STRIDE_MASK)
+
 /* CSC registers */
 #define CSC_CTRL0			0x30
 #define CSC_COV_MODE_SHIFT		16
@@ -69,6 +100,18 @@
 #define RSZ_DEST_CFG			0x04
 #define RSZ_ENABLE_CFG			0x14
 
+#define RSZ_VL_LUMA_HOR			0x08
+#define RSZ_VL_LUMA_VER			0x0c
+#define RSZ_VL_CHROMA_HOR		0x10
+#define RSZ_VL_CHROMA_VER		0x14
+#define RSZ_VL_CTRL_CFG			0x18
+#define RSZ_VL_FMT_SHIFT		3
+#define RSZ_VL_FMT_MASK			(0x3 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_FMT_YCBCR420		(0x0 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_FMT_YCBCR422		(0x1 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_FMT_YCBCR444		(0x2 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_ENABLE_CFG		0x1c
+
 #define RSZ_VER_SHIFT			16
 #define RSZ_VER_MASK			(0xffff << RSZ_VER_SHIFT)
 #define RSZ_HOR_SHIFT			0
@@ -77,6 +120,14 @@
 #define RSZ_VER(x)	(((x) << RSZ_VER_SHIFT) & RSZ_VER_MASK)
 #define RSZ_HOR(x)	(((x) << RSZ_HOR_SHIFT) & RSZ_HOR_MASK)
 
+#define RSZ_DATA_STEP_SHIFT		16
+#define RSZ_DATA_STEP_MASK		(0xffff << RSZ_DATA_STEP_SHIFT)
+#define RSZ_PARA_STEP_SHIFT		0
+#define RSZ_PARA_STEP_MASK		(0xffff << RSZ_PARA_STEP_SHIFT)
+
+#define RSZ_DATA_STEP(x) (((x) << RSZ_DATA_STEP_SHIFT) & RSZ_DATA_STEP_MASK)
+#define RSZ_PARA_STEP(x) (((x) << RSZ_PARA_STEP_SHIFT) & RSZ_PARA_STEP_MASK)
+
 /* HBSC registers */
 #define HBSC_SATURATION			0x00
 #define HBSC_HUE			0x04
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index 3fb4fc04e693..8e7edda184d0 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -112,6 +112,22 @@ struct vou_layer_bits {
 	},
 };
 
+static const struct vou_layer_bits zx_vl_bits[VL_NUM] = {
+	{
+		.enable = OSD_CTRL0_VL0_EN,
+		.chnsel = OSD_CTRL0_VL0_SEL,
+		.clksel = VOU_CLK_VL0_SEL,
+	}, {
+		.enable = OSD_CTRL0_VL1_EN,
+		.chnsel = OSD_CTRL0_VL1_SEL,
+		.clksel = VOU_CLK_VL1_SEL,
+	}, {
+		.enable = OSD_CTRL0_VL2_EN,
+		.chnsel = OSD_CTRL0_VL2_SEL,
+		.clksel = VOU_CLK_VL2_SEL,
+	},
+};
+
 struct zx_vou_hw {
 	struct device *dev;
 	void __iomem *osd;
@@ -125,6 +141,7 @@ struct zx_vou_hw {
 	struct clk *aux_clk;
 	struct zx_crtc *main_crtc;
 	struct zx_crtc *aux_crtc;
+	struct drm_plane *overlays[VL_NUM];
 };
 
 static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
@@ -439,6 +456,8 @@ void zx_vou_layer_enable(struct drm_plane *plane)
 	}
 
 	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
+
+	zplane->enabled = true;
 }
 
 void zx_vou_layer_disable(struct drm_plane *plane)
@@ -449,6 +468,57 @@ void zx_vou_layer_disable(struct drm_plane *plane)
 	const struct vou_layer_bits *bits = zplane->bits;
 
 	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
+
+	zplane->enabled = false;
+}
+
+static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou)
+{
+	struct device *dev = vou->dev;
+	struct zx_plane *zplane;
+	int i;
+	int ret;
+
+	/*
+	 * VL0 has some quirks on scaling support which need special handling.
+	 * Let's leave it out for now.
+	 */
+	for (i = 1; i < VL_NUM; i++) {
+		zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
+		if (!zplane) {
+			DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i);
+			return;
+		}
+
+		zplane->layer = vou->osd + OSD_VL_OFFSET(i);
+		zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i);
+		zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i);
+		zplane->bits = &zx_vl_bits[i];
+
+		ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY);
+		if (ret) {
+			DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i);
+			continue;
+		}
+
+		vou->overlays[i] = &zplane->plane;
+	}
+}
+
+static inline void zx_osd_int_update(struct zx_crtc *zcrtc)
+{
+	struct zx_vou_hw *vou = zcrtc->vou;
+	int i;
+
+	vou_chn_set_update(zcrtc);
+	zx_plane_set_update(zcrtc->primary);
+
+	for (i = 0; i < VL_NUM; i++) {
+		struct drm_plane *overlay = vou->overlays[i];
+
+		if (overlay)
+			zx_plane_set_update(overlay);
+	}
 }
 
 static irqreturn_t vou_irq_handler(int irq, void *dev_id)
@@ -470,15 +540,11 @@ static irqreturn_t vou_irq_handler(int irq, void *dev_id)
 	state = zx_readl(vou->osd + OSD_INT_STA);
 	zx_writel(vou->osd + OSD_INT_CLRSTA, state);
 
-	if (state & OSD_INT_MAIN_UPT) {
-		vou_chn_set_update(vou->main_crtc);
-		zx_plane_set_update(vou->main_crtc->primary);
-	}
+	if (state & OSD_INT_MAIN_UPT)
+		zx_osd_int_update(vou->main_crtc);
 
-	if (state & OSD_INT_AUX_UPT) {
-		vou_chn_set_update(vou->aux_crtc);
-		zx_plane_set_update(vou->aux_crtc->primary);
-	}
+	if (state & OSD_INT_AUX_UPT)
+		zx_osd_int_update(vou->aux_crtc);
 
 	if (state & OSD_INT_ERROR)
 		DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);
@@ -648,6 +714,8 @@ static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
 		goto disable_ppu_clk;
 	}
 
+	zx_overlay_init(drm, vou);
+
 	return 0;
 
 disable_ppu_clk:
diff --git a/drivers/gpu/drm/zte/zx_vou_regs.h b/drivers/gpu/drm/zte/zx_vou_regs.h
index f44e7a4ae441..193c1ce01fe7 100644
--- a/drivers/gpu/drm/zte/zx_vou_regs.h
+++ b/drivers/gpu/drm/zte/zx_vou_regs.h
@@ -22,6 +22,15 @@
 #define AUX_HBSC_OFFSET			0x860
 #define AUX_RSZ_OFFSET			0x800
 
+#define OSD_VL0_OFFSET			0x040
+#define OSD_VL_OFFSET(i)		(OSD_VL0_OFFSET + 0x050 * (i))
+
+#define HBSC_VL0_OFFSET			0x760
+#define HBSC_VL_OFFSET(i)		(HBSC_VL0_OFFSET + 0x040 * (i))
+
+#define RSZ_VL1_U0			0xa00
+#define RSZ_VL_OFFSET(i)		(RSZ_VL1_U0 + 0x200 * (i))
+
 /* OSD (GPC_GLOBAL) registers */
 #define OSD_INT_STA			0x04
 #define OSD_INT_CLRSTA			0x08
@@ -42,6 +51,12 @@
 )
 #define OSD_INT_ENABLE (OSD_INT_ERROR | OSD_INT_AUX_UPT | OSD_INT_MAIN_UPT)
 #define OSD_CTRL0			0x10
+#define OSD_CTRL0_VL0_EN		BIT(13)
+#define OSD_CTRL0_VL0_SEL		BIT(12)
+#define OSD_CTRL0_VL1_EN		BIT(11)
+#define OSD_CTRL0_VL1_SEL		BIT(10)
+#define OSD_CTRL0_VL2_EN		BIT(9)
+#define OSD_CTRL0_VL2_SEL		BIT(8)
 #define OSD_CTRL0_GL0_EN		BIT(7)
 #define OSD_CTRL0_GL0_SEL		BIT(6)
 #define OSD_CTRL0_GL1_EN		BIT(5)
@@ -146,6 +161,9 @@
 #define VOU_INF_DATA_SEL		0x08
 #define VOU_SOFT_RST			0x14
 #define VOU_CLK_SEL			0x18
+#define VOU_CLK_VL2_SEL			BIT(8)
+#define VOU_CLK_VL1_SEL			BIT(7)
+#define VOU_CLK_VL0_SEL			BIT(6)
 #define VOU_CLK_GL1_SEL			BIT(5)
 #define VOU_CLK_GL0_SEL			BIT(4)
 #define VOU_CLK_REQEN			0x20
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/3] pinctrl: sunxi: Add pinctrl variants
From: Linus Walleij @ 2017-01-09 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e664022c7ea8177305c5c62676bd64f949caf7ab.1483911013.git-series.maxime.ripard@free-electrons.com>

On Sun, Jan 8, 2017 at 10:31 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:

> Some SoCs are either supposed to be pin compatible (A10 and A20 for
> example), or are just repackaged versions of the same die (A10s, A13, GR8).
>
> In those case, having a full blown pinctrl driver just introduces
> duplication in both data size and maintainance effort.
>
> Add a variant option to both pins and functions to be able to limit the
> pins and functions described only to a subset of the SoC we support with a
> given driver.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 1/2] ARM: hyp-stub: improve ABI
From: Russell King - ARM Linux @ 2017-01-09 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170109140500.GA14217@n2100.armlinux.org.uk>

On Mon, Jan 09, 2017 at 02:05:00PM +0000, Russell King - ARM Linux wrote:
> So, although Marc produced a patch which updates the KVM hypervisor for
> the GET_VECTORS change, through reading the code today, it's become clear
> that much more is needed, so I'm yet again banging on about documentation.
> It's only become clear to me today that the KVM stub calling convention
> for the host kernel is:
> 
> entry:
> 	r0 = function pointer
> 	r1 = 32-bit function argument 0
> 	r2 = 32-bit function argument 1
> 	r3 = 32-bit function argument 2
> 	no further arguments are supported
> 	--- or ---
> 	r0 = -1 (or 0 post Marc's patch) for get_vectors
> exit:
> 	r0 = vectors (if get_vectors call was made)
> 	otherwise, who knows...

Hang on, even this is nowhere near the full picture.

static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
                                       unsigned long hyp_stack_ptr,
                                       unsigned long vector_ptr)
{
        /*
         * Call initialization code, and switch to the full blown HYP
         * code. The init code doesn't need to preserve these
         * registers as r0-r3 are already callee saved according to
         * the AAPCS.
         * Note that we slightly misuse the prototype by casting the
         * stack pointer to a void *.

         * The PGDs are always passed as the third argument, in order
         * to be passed into r2-r3 to the init code (yes, this is
         * compliant with the PCS!).
         */

        kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
}

This results in a completely different calling convention -

	r0 = hyp_stack_ptr
	r1 = vector_ptr
	r2,r3 = pgd_ptr

Which clearly doesn't fit the KVM hypervisor's calling requirements...
and, looking deeper at this:

        /* Switch from the HYP stub to our own HYP init vector */
        __hyp_set_vectors(kvm_get_idmap_vector());

        pgd_ptr = kvm_mmu_get_httbr();
        stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
        hyp_stack_ptr = stack_page + PAGE_SIZE;
        vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);

        __cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);

So we actually have _another_ hypervisor stub to care about - should
anything go wrong between __hyp_set_vectors() and __cpu_init_hyp_mode(),
we will be hitting the __do_hyp_init assembly code with maybe a get
vectors or soft reboot call, which, reading the code, would be bad
news.

Since this code is run at several different times - CPU hotplug (when
the system will be quiescent) and also cpuidle PM (when the system is
not quiescent).  With kdump/kexec, I think this could be racy.
Certainly if anything were to go wrong between the two with a kdump
kernel in place, we'd be making HVC calls to the KVM init stub and
expecting them to work.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [PATCH 2/3] pinctrl: sunxi: Add common sun5i pinctrl driver
From: Linus Walleij @ 2017-01-09 14:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <fd94b0b46841a455b1f1f68c2da801957d0748ac.1483911013.git-series.maxime.ripard@free-electrons.com>

On Sun, Jan 8, 2017 at 10:31 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:

> The sun5i SoCs (A10s, A13, GR8) are all based on the same die fit in
> different packages. Hence, the pins and functions available are just the
> based on the same set, each SoC having a different subset.
>
> Introduce a common pinctrl driver that supports multiple variants to allow
> to put as much as we can in common.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 3/3] pinctrl: sunxi: Remove old sun5i pinctrl drivers
From: Linus Walleij @ 2017-01-09 14:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c0bbab85a23bf441669f80634d1534536a4b7666.1483911013.git-series.maxime.ripard@free-electrons.com>

On Sun, Jan 8, 2017 at 10:31 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:

> Now that we have a common pinctrl driver for all the sun5i SoCs, we can
> remove the old, separate drivers.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 1/3] ARM: configs: stm32: enable ADC driver
From: Alexandre Torgue @ 2017-01-09 14:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480687022-12851-2-git-send-email-fabrice.gasnier@st.com>

Hi Fabrice

On 12/02/2016 02:57 PM, Fabrice GASNIER wrote:
> ADC driver depends on REGULATOR and IIO that are not yet selected.
> Current hardware boards (like stm32f429i-eval) is using fixed
> regulators.
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> ---
>  arch/arm/configs/stm32_defconfig | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
> index a60b5cb..92ccc3c 100644
> --- a/arch/arm/configs/stm32_defconfig
> +++ b/arch/arm/configs/stm32_defconfig
> @@ -49,6 +49,8 @@ CONFIG_SERIAL_STM32=y
>  CONFIG_SERIAL_STM32_CONSOLE=y
>  # CONFIG_HW_RANDOM is not set
>  # CONFIG_HWMON is not set
> +CONFIG_REGULATOR=y
> +CONFIG_REGULATOR_FIXED_VOLTAGE=y
>  # CONFIG_USB_SUPPORT is not set
>  CONFIG_NEW_LEDS=y
>  CONFIG_LEDS_CLASS=y
> @@ -57,6 +59,9 @@ CONFIG_LEDS_TRIGGERS=y
>  CONFIG_LEDS_TRIGGER_HEARTBEAT=y
>  CONFIG_DMADEVICES=y
>  CONFIG_STM32_DMA=y
> +CONFIG_IIO=y
> +CONFIG_STM32_ADC_CORE=y
> +CONFIG_STM32_ADC=y
>  # CONFIG_FILE_LOCKING is not set
>  # CONFIG_DNOTIFY is not set
>  # CONFIG_INOTIFY_USER is not set
>

Applied on stm32-defconfig-for-v4.11

Thanks.

Alex

^ permalink raw reply

* [PATCH 2/3] ARM: dts: stm32: Add ADC support to stm32f429
From: Alexandre Torgue @ 2017-01-09 14:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480687022-12851-3-git-send-email-fabrice.gasnier@st.com>

Hi Fabrice

On 12/02/2016 02:57 PM, Fabrice GASNIER wrote:
> Add ADC support & pinctrl analog phandle (adc3_in8) to stm32f429.
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> ---
>  arch/arm/boot/dts/stm32f429.dtsi | 49 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
>
> diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
> index 3dd47eb..be1d970 100644
> --- a/arch/arm/boot/dts/stm32f429.dtsi
> +++ b/arch/arm/boot/dts/stm32f429.dtsi
> @@ -172,6 +172,49 @@
>  			status = "disabled";
>  		};
>
> +		adc: adc at 40012000 {
> +			compatible = "st,stm32f4-adc-core";
> +			reg = <0x40012000 0x400>;
> +			interrupts = <18>;
> +			clocks = <&rcc 0 168>;
> +			clock-names = "adc";
> +			interrupt-controller;
> +			#interrupt-cells = <1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			status = "disabled";
> +
> +			adc1: adc at 0 {
> +				compatible = "st,stm32f4-adc";
> +				#io-channel-cells = <1>;
> +				reg = <0x0>;
> +				clocks = <&rcc 0 168>;
> +				interrupt-parent = <&adc>;
> +				interrupts = <0>;
> +				status = "disabled";
> +			};
> +
> +			adc2: adc at 100 {
> +				compatible = "st,stm32f4-adc";
> +				#io-channel-cells = <1>;
> +				reg = <0x100>;
> +				clocks = <&rcc 0 169>;
> +				interrupt-parent = <&adc>;
> +				interrupts = <1>;
> +				status = "disabled";
> +			};
> +
> +			adc3: adc at 200 {
> +				compatible = "st,stm32f4-adc";
> +				#io-channel-cells = <1>;
> +				reg = <0x200>;
> +				clocks = <&rcc 0 170>;
> +				interrupt-parent = <&adc>;
> +				interrupts = <2>;
> +				status = "disabled";
> +			};
> +		};
> +
>  		syscfg: system-config at 40013800 {
>  			compatible = "syscon";
>  			reg = <0x40013800 0x400>;
> @@ -334,6 +377,12 @@
>  					slew-rate = <2>;
>  				};
>  			};
> +
> +			adc3_in8_pin: adc at 200 {
> +				pins {
> +					pinmux = <STM32F429_PF10_FUNC_ANALOG>;
> +				};
> +			};
>  		};
>
>  		rcc: rcc at 40023810 {
>

Applied on stm32-dt-for-v4.11

Thanks
Alex

^ permalink raw reply

* [PATCH 1/6] drivers: pinctrl: add driver for Allwinner H5 SoC
From: Linus Walleij @ 2017-01-09 14:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170105220823.5ai4yvcblmzmaey2@lukather>

On Thu, Jan 5, 2017 at 11:08 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Tue, Dec 27, 2016 at 12:25:13AM +0800, Icenowy Zheng wrote:

>> +builtin_platform_driver(sun50i_h5_pinctrl_driver);
>
> This also looks very much like the H3. I'll post a patchset during the
> weekend to avoid duplicating those drivers. This was initially done
> for the sun5i, but it very much applies here.

I have applied Maxime's patch set from today.

Icenowy, please investigate the direction taken by Maxime
here for future revisions if needed.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 3/3] ARM: dts: stm32: enable ADC on stm32f429i-eval board
From: Alexandre Torgue @ 2017-01-09 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480687022-12851-4-git-send-email-fabrice.gasnier@st.com>

Hi Fabrice

On 12/02/2016 02:57 PM, Fabrice GASNIER wrote:
> Enable analog to digital converter on stm32f429i-eval board.
> It has on-board potentimeter wired to ADC3 in8 analog pin and
> uses fixed regulator to provide reference voltage.
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> ---
>  arch/arm/boot/dts/stm32429i-eval.dts | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>
> diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
> index 13c7cd2..6be0a24 100644
> --- a/arch/arm/boot/dts/stm32429i-eval.dts
> +++ b/arch/arm/boot/dts/stm32429i-eval.dts
> @@ -65,6 +65,20 @@
>  		serial0 = &usart1;
>  	};
>
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		reg_vref: regulator at 0 {
> +			compatible = "regulator-fixed";
> +			reg = <0>;
> +			regulator-name = "vref";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3300000>;
> +		};
> +	};
> +
>  	leds {
>  		compatible = "gpio-leds";
>  		green {
> @@ -123,3 +137,14 @@
>  	pinctrl-names = "default";
>  	status = "okay";
>  };
> +
> +&adc {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&adc3_in8_pin>;
> +	vref-supply = <&reg_vref>;
> +	status = "okay";
> +	adc3: adc at 200 {
> +		st,adc-channels = <8>;
> +		status = "okay";
> +	};
> +};
>
After node reordering:

Applied on stm32-dt-for-v4.11

Thanks
Alex

^ permalink raw reply

* [linux-sunxi] [PATCH] clk: sunxi-ng: fix PLL_CPUX adjusting on H3
From: Ondřej Jirman @ 2017-01-09 14:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170109095946.6esbfx6pafega5cd@lukather>



Dne 9.1.2017 v 10:59 Maxime Ripard napsal(a):
> On Sat, Jan 07, 2017 at 04:49:18PM +0100, Ond?ej Jirman wrote:
>> Maxime,
>>
>> Dne 25.11.2016 v 01:28 megous at megous.com napsal(a):
>>> From: Ondrej Jirman <megous@megous.com>
>>>
>>> When adjusting PLL_CPUX on H3, the PLL is temporarily driven
>>> too high, and the system becomes unstable (oopses or hangs).
>>>
>>> Add a notifier to avoid this situation by temporarily switching
>>> to a known stable 24 MHz oscillator.
>>
>> I have done more thorough testing on H3 and this approach with switching
>> to 24MHz oscillator does not work. Motivation being that my Orange Pi
>> One still gets lockups even with this patch under certain circumstances.
>>
>> So I have created a small test program for CPUS (additional OpenRISC CPU
>> on the SoC) which randomly changes PLL_CPUX settings while main CPU is
>> running a loop that sends messages to CPUS via msgbox.
>>
>> Assumption being that while CPUS is successfully receiving messages via
>> msgbox, the main CPU didn't lock up, yet.
>>
>> With this I am able to quickly and thoroughly test various PLL_CPUX
>> change and factor selection algorithms.
>>
>> Results are that bypassing CPUX clock by switching to 24 MHz oscillator
>> does not work at all. Main CPU locks up in about 1 second into the test.
>> Don't ask me why.
> 
> You mean that you are changing the frequency behind Linux' back? That
> won't work. There's more to cpufreq than just changing the frequency,
> but also adusting the number of loops per jiffy for the new frequency
> for example. I don't really expect that setup to work even on a
> perfectly stable system. CPUFreq *has* to be involved, otherwise, that
> alone might introduce bugs, and you cannot draw any conclusions
> anymore.

No, this has nothing to do with linux. I'm not running linux for this
test. I'm running a small program on CPUS (Open RISC CPU) on the SoC
loaded using FEL from USB.

The main cpu is just pushing messages into msgbox in a loop, so that
CPUS can determine that the main CPU is still running ok and give
feedback to me over UART. Not even DRAM is involved. The programs are
running from SRAM.

This is the most direct test of PLL change stability that can be done on
this SoC regardless of the OS. Not even CPU voltage switching is
involved. I just set the maximum voltage and fiddle with CPU_PLL
frequencies randomly, while waiting for the main CPU to lock up.

It does lock up quickly with mainline ccu_nkmp_find_best algorithm for
finding factors.

Even with linux kernel, it breaks. It's just more difficult to hit the
right conditions. I got oops only right after boot when running cpuburn
to trigger thermal_zone issued OPP change, if I first run some cpupower
commands. That's why I wrote this program to stress test various CPU_PLL
change/factor selection algorithms independently of everything else, to
get more predictable and quicker testing results.

>> What works is selecting NKMP factors so that M is always 1 and P is
>> anything other than /1 only for frequencies under 288MHz. As mandated by
>> the H3 datasheet. Mainline ccu_nkmp_find_best doesn't respect these
>> conditions. With that I can change CPUX frequencies randomly 20x a
>> second so far indefinitely without the main CPU ever locking up.
>>
>> Please drop or revert this patch. It is not a correct approach to the
>> problem. I'd suggest dropping the entire clock notifier mechanism, too,
>> unless it can be proven to work reliably.
> 
> It has been proven to work reliably on a number of other SoCs.

Unless it was stress tested like this with randomy changed settings, I
doubt you can call it reliable. It may just be very hard to hit the
issue on linux with particular OPP/thermal zone configuration. That's
because the issue is dependent on before and after NKMP values. People
may have just been lucky so far.

regards,
  o.

> Thanks!
> Maxime
> 

^ permalink raw reply

* [RFC PATCH] vring: Force use of DMA API for ARM-based systems
From: Will Deacon @ 2017-01-09 14:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <fbf1a09a-bdb2-504a-f4a7-56fa54b6292b@arm.com>

On Mon, Jan 09, 2017 at 11:24:04AM +0000, Robin Murphy wrote:
> On 06/01/17 21:51, Andy Lutomirski wrote:
> > On Fri, Jan 6, 2017 at 10:32 AM, Robin Murphy <robin.murphy@arm.com> wrote:
> >> On 06/01/17 17:48, Jean-Philippe Brucker wrote:
> >>> It used to work with 4.9, but since 9491ae4 ("mm: don't cap request size
> >>> based on read-ahead setting") unlocked read-ahead, we quickly run into
> >>> the limit of swiotlb and panic:
> >>>
> >>> [    5.382359] virtio-mmio 1c130000.virtio_block: swiotlb buffer is full
> >>> (sz: 491520 bytes)
> >>> [    5.382452] virtio-mmio 1c130000.virtio_block: DMA: Out of SW-IOMMU
> >>> space for 491520 bytes
> >>> [    5.382531] Kernel panic - not syncing: DMA: Random memory could be
> >>> DMA written
> >>> ...
> >>> [    5.383148] [<ffff0000083ad754>] swiotlb_map_page+0x194/0x1a0
> >>> [    5.383226] [<ffff000008096bb8>] __swiotlb_map_page+0x20/0x88
> >>> [    5.383320] [<ffff0000084bf738>] vring_map_one_sg.isra.1+0x70/0x88
> >>> [    5.383417] [<ffff0000084c04fc>] virtqueue_add_sgs+0x2ec/0x4e8
> >>> [    5.383505] [<ffff00000856d99c>] __virtblk_add_req+0x9c/0x1a8
> >>> ...
> >>> [    5.384449] [<ffff0000081829c4>] ondemand_readahead+0xfc/0x2b8
> >>>
> >>> Commit 9491ae4 caps the read-ahead request to a limit set by the backing
> >>> device. For virtio-blk, it is infinite (as set by the call to
> >>> blk_queue_max_hw_sectors in virtblk_probe).
> >>>
> >>> I'm not sure how to fix this. Setting an arbitrary sector limit in the
> >>> virtio-blk driver seems unfair to other users. Maybe we should check if
> >>> the device is behind a hardware IOMMU before using the DMA API?
> >>
> >> Hmm, this looks more like the virtio_block device simply has the wrong
> >> DMA mask to begin with. For virtio-pci we set the streaming DMA mask to
> >> 64 bits - should a platform device not be similarly capable?
> > 
> > If it's not, then turning off DMA API will cause random corruption.
> > ISTM one way or another the bug is in either the DMA ops or in the
> > driver initialization.
> 
> OK, having looked a little deeper, I reckon virtio_mmio_probe() is
> indeed missing a dma_set_mask() call compared to its PCI friends. The
> only question then is where does virtio-mmio stand with respect to
> legacy/modern/44-bit/64-bit etc.?

Legacy virtio-mmio has a variable page granule (GuestPageSize), so the
44-bit limitation shouldn't apply. The legacy spec doesn't actually
initialise GuestPageSize in the example initialisation sequence, but
Linux does. Non-legacy uses absolute, 64-bit addresses regardless of
transport, so yes, it might be as simple as adding:

	dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));

to virtio_mmio_probe. Jean-Philippe -- does that fix things for you?

Will

^ permalink raw reply

* [PATCH] arm64: head.S: fix up stale comments
From: Ard Biesheuvel @ 2017-01-09 14:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483972315-12782-1-git-send-email-mark.rutland@arm.com>

On 9 January 2017 at 14:31, Mark Rutland <mark.rutland@arm.com> wrote:
> In commit 23c8a500c24d02dd ("arm64: kernel: use ordinary return/argument
> register for el2_setup()"), we stopped using w20 as a global stash of
> the boot mode flag, and instead pass this around in w0 as a function
> parameter.
>
> Unfortunately, we missed a couple of comments, which still refer to the
> old convention of using w20/x20.
>
> This patch fixes up the comments to describe the code as it currently
> works.
>

Ah yes, apologies for the sloppiness

Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/kernel/head.S | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 4b1abac..9b0857a 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -483,7 +483,7 @@ ENTRY(kimage_vaddr)
>   * If we're fortunate enough to boot at EL2, ensure that the world is
>   * sane before dropping to EL1.
>   *
> - * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x20 if
> + * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in w0 if
>   * booted in EL1 or EL2 respectively.
>   */
>  ENTRY(el2_setup)
> @@ -628,7 +628,7 @@ ENDPROC(el2_setup)
>
>  /*
>   * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed
> - * in x20. See arch/arm64/include/asm/virt.h for more info.
> + * in w0. See arch/arm64/include/asm/virt.h for more info.
>   */
>  set_cpu_boot_mode_flag:
>         adr_l   x1, __boot_cpu_mode
> --
> 1.9.1
>

^ permalink raw reply

* [PATCH] arm64: head.S: fix up stale comments
From: Mark Rutland @ 2017-01-09 14:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_t7n8PUAeAYe2kkFpPciC0eJ+Qg7sHu_tTfux=3LwyTg@mail.gmail.com>

On Mon, Jan 09, 2017 at 02:55:51PM +0000, Ard Biesheuvel wrote:
> On 9 January 2017 at 14:31, Mark Rutland <mark.rutland@arm.com> wrote:
> > In commit 23c8a500c24d02dd ("arm64: kernel: use ordinary return/argument
> > register for el2_setup()"), we stopped using w20 as a global stash of
> > the boot mode flag, and instead pass this around in w0 as a function
> > parameter.
> >
> > Unfortunately, we missed a couple of comments, which still refer to the
> > old convention of using w20/x20.
> >
> > This patch fixes up the comments to describe the code as it currently
> > works.
> >
> 
> Ah yes, apologies for the sloppiness

No worries; I missed this in review, too...

> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Cheers!

Mark.

> > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Will Deacon <will.deacon@arm.com>
> > ---
> >  arch/arm64/kernel/head.S | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> > index 4b1abac..9b0857a 100644
> > --- a/arch/arm64/kernel/head.S
> > +++ b/arch/arm64/kernel/head.S
> > @@ -483,7 +483,7 @@ ENTRY(kimage_vaddr)
> >   * If we're fortunate enough to boot at EL2, ensure that the world is
> >   * sane before dropping to EL1.
> >   *
> > - * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x20 if
> > + * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in w0 if
> >   * booted in EL1 or EL2 respectively.
> >   */
> >  ENTRY(el2_setup)
> > @@ -628,7 +628,7 @@ ENDPROC(el2_setup)
> >
> >  /*
> >   * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed
> > - * in x20. See arch/arm64/include/asm/virt.h for more info.
> > + * in w0. See arch/arm64/include/asm/virt.h for more info.
> >   */
> >  set_cpu_boot_mode_flag:
> >         adr_l   x1, __boot_cpu_mode
> > --
> > 1.9.1
> >

^ permalink raw reply

* [PATCH 1/2] ARM: hyp-stub: improve ABI
From: Christoffer Dall @ 2017-01-09 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170109144235.GC14217@n2100.armlinux.org.uk>

On Mon, Jan 09, 2017 at 02:42:35PM +0000, Russell King - ARM Linux wrote:
> On Mon, Jan 09, 2017 at 02:05:00PM +0000, Russell King - ARM Linux wrote:
> > So, although Marc produced a patch which updates the KVM hypervisor for
> > the GET_VECTORS change, through reading the code today, it's become clear
> > that much more is needed, so I'm yet again banging on about documentation.
> > It's only become clear to me today that the KVM stub calling convention
> > for the host kernel is:
> > 
> > entry:
> > 	r0 = function pointer
> > 	r1 = 32-bit function argument 0
> > 	r2 = 32-bit function argument 1
> > 	r3 = 32-bit function argument 2
> > 	no further arguments are supported
> > 	--- or ---
> > 	r0 = -1 (or 0 post Marc's patch) for get_vectors
> > exit:
> > 	r0 = vectors (if get_vectors call was made)
> > 	otherwise, who knows...
> 
> Hang on, even this is nowhere near the full picture.
> 
> static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
>                                        unsigned long hyp_stack_ptr,
>                                        unsigned long vector_ptr)
> {
>         /*
>          * Call initialization code, and switch to the full blown HYP
>          * code. The init code doesn't need to preserve these
>          * registers as r0-r3 are already callee saved according to
>          * the AAPCS.
>          * Note that we slightly misuse the prototype by casting the
>          * stack pointer to a void *.
> 
>          * The PGDs are always passed as the third argument, in order
>          * to be passed into r2-r3 to the init code (yes, this is
>          * compliant with the PCS!).
>          */
> 
>         kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
> }
> 
> This results in a completely different calling convention -
> 
> 	r0 = hyp_stack_ptr
> 	r1 = vector_ptr
> 	r2,r3 = pgd_ptr
> 
> Which clearly doesn't fit the KVM hypervisor's calling requirements...
> and, looking deeper at this:
> 
>         /* Switch from the HYP stub to our own HYP init vector */
>         __hyp_set_vectors(kvm_get_idmap_vector());
> 
>         pgd_ptr = kvm_mmu_get_httbr();
>         stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
>         hyp_stack_ptr = stack_page + PAGE_SIZE;
>         vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
> 
>         __cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
> 
> So we actually have _another_ hypervisor stub to care about - should
> anything go wrong between __hyp_set_vectors() and __cpu_init_hyp_mode(),
> we will be hitting the __do_hyp_init assembly code with maybe a get
> vectors or soft reboot call, which, reading the code, would be bad
> news.
> 
> Since this code is run at several different times - CPU hotplug (when
> the system will be quiescent) and also cpuidle PM (when the system is
> not quiescent).  With kdump/kexec, I think this could be racy.
> Certainly if anything were to go wrong between the two with a kdump
> kernel in place, we'd be making HVC calls to the KVM init stub and
> expecting them to work.
> 
Indeed it looks like interrupts are enabled during cpu_init_hyp_mode,
and if it's possible to be preempted there or if kdump can be initiated
from interrupt context, this could go wrong, so you're probably right
that we need to support a common hyp-ABI for the kernel hyp stub, the
KVM stub (a.k.a. the trampoline code), and KVM's hyp layer itself.

Thanks,
-Christoffer

^ permalink raw reply

* [PATCH 1/2] ARM: hyp-stub: improve ABI
From: Christoffer Dall @ 2017-01-09 15:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170109140500.GA14217@n2100.armlinux.org.uk>

On Mon, Jan 09, 2017 at 02:05:00PM +0000, Russell King - ARM Linux wrote:
> On Mon, Jan 09, 2017 at 02:26:36PM +0100, Christoffer Dall wrote:
> > On Mon, Jan 09, 2017 at 12:26:39PM +0000, Russell King - ARM Linux wrote:
> > > On Tue, Jan 03, 2017 at 10:51:49AM +0100, Christoffer Dall wrote:
> > > > Hi Russell,
> > > > 
> > > > On Thu, Dec 15, 2016 at 06:57:18PM +0000, Russell King - ARM Linux wrote:
> > > > > What's also coming clear is that there's very few people who understand
> > > > > all the interactions here, and the whole thing seems to be an undocumented
> > > > > mess.  
> > > > 
> > > > I think the hyp stub has just served a very limited purpose so far, and
> > > > therefore is a somewhat immature implementation.  Now we've discovered a
> > > > need to clean it up, and we're all for that.  Again, I don't think the
> > > > problem is any larger than that, we just need to fix it, and it seems to
> > > > me everyone is willing to work on that.
> > > 
> > > What I want to see is some documentation of the hyp-stub, so that there
> > > can be some element of confidence that changes there are properly
> > > coordinated.  As I said in a follow up email:
> > > 
> > > | Either we need more people to have an understanding (so if one of them
> > > | gets run over by a bus, we're not left floundering around) or we need
> > > | it to be documented - even if it's just a simple comment "the ABI in
> > > | this file is shared with XYZ, if you change the ABI here, also update
> > > | XYZ too."
> > > 
> > > > Marc even offered to work on your suggestion to support the general
> > > > hyp ABI commands in KVM.
> > > 
> > > ... which is pointless, because it's a duplication of the effort I've
> > > already put in.  My patches already do the:
> > > 
> > > #define HVC_GET_VECTORS 0
> > > #define HVC_SET_VECTORS 1
> > > #define HVC_SOFT_RESTART 2
> > > 
> > > thing which ARM64 does, passing the arguments in via the appropriate
> > > registers.  However, such a change is a major revision of hyp-stub's
> > > ABI, which completely changes the way it works.
> > 
> > Sorry, I'm afraid I might have been unclear.  What I meant with "general
> > hyp ABI commands in KVM" was, that if there's a need for KVM to support
> > the operations (using a unified and documented ABI) that the hyp stub
> > supports, then we could add that in KVM as well.  I thought your patches
> > added the functionality for the hyp stub, and Marc would add whichever
> > remaining pieces in the KVM side.
> 
> The view over Christmas was "we only need to ensure the GET_VECTORS call
> continues to work", which is what Marc's patch does.  I've come to
> realise (through no help of the documentation situation) that that is
> far from the full story, because of the way kdump works.
> 
> Let me refresh...
> 
> In normal kexec(), kernel_restart_prepare() is called, which calls the
> reboot_notifier_list.  KVM uses this via kvm_reboot() and
> kvm_arch_hardware_disable() to call cpu_hyp_reset(), and in turn
> __kvm_hyp_reset in HYP mode.  That sets the stub vectors back to the
> hyp-stub implementation.  So, normal kexec should work fine.
> 
> However, kernel_restart_prepare() is _not_ called in the kdump case.

Thanks for this, it was slightly unclear to me in which way kdump
different from the other cases, but makes sense now.

> So, with my two patches in place, we will issue a HVC call with the
> arguments that I've given to whatever hypervisor is in place at the
> time, and as I've pointed out, with the KVM hypervisor, we will try to
> branch to address 2 or 3 - who knows what effect that'll have.
> 
> So, although Marc produced a patch which updates the KVM hypervisor for
> the GET_VECTORS change, through reading the code today, it's become clear
> that much more is needed, so I'm yet again banging on about documentation.
> It's only become clear to me today that the KVM stub calling convention
> for the host kernel is:

Just for clarity: I understood that Marc said he was willing to write
the code to support the common ABI that we agree on in KVM.  The fact
that he sent another small patch was a separate contribution, but that's
how I understood. it.

> 
> entry:
> 	r0 = function pointer
> 	r1 = 32-bit function argument 0
> 	r2 = 32-bit function argument 1
> 	r3 = 32-bit function argument 2
> 	no further arguments are supported
> 	--- or ---
> 	r0 = -1 (or 0 post Marc's patch) for get_vectors
> exit:
> 	r0 = vectors (if get_vectors call was made)
> 	otherwise, who knows...
> 
> I specify "32-bit" there because they're shifted by one register, which,
> if a 64-bit argument is passed with EABI, the arguments will no longer be
> appropriately aligned... so it's an important detail to be aware of with
> the current KVM hypervisor interface.
> 
> What I want to do here is to fix this kexec issue completely, not in a
> piecemeal fashion - I'm not interested in fixing one small problem, then
> coming back to it in a few months time to fix another problem.  That's a
> waste of time (well, unless you're into job creation.)  I've always been
> for "if you're going to do the job, damn well do the job properly".  So
> I'm not going to accept anything short of fixing _both_ kexec and kdump
> together.
> 
> So, given that the hyp-stub has this ABI after my patches:
> 
> entry:
> 	r0 = argument (0 = get vectors, 1 = set vectors, 2 = call function)
> 	r1 = vectors for r0 = 1
> 	r3 = function pointer (with bit 0 already set for thumb functions)
> 	     for r0 = 2
> exit:
> 	r0 = -1 for invalid calls
> 	r0 = current vectors address (for r0 = 0 on entry)
> 	is not expected to return for r0 = 2 on entry
> 	otherwise registers preserved preserved
> 
> which is clearly incompatible with the current KVM stub, can we come up
> with a common ABI that is satisfactory to both.
> 
> The above are probably the very first time anyone has written out the
> ABI of these things, and as can be seen, it's still something of a mess.
> 
> > > Longer term, I'd like to see the existing hypervisor documentation in
> > > Documentation/virtual/kvm/hypercalls.txt updated with the ARM details.
> > > According to that document, KVM effectively only exists on PPC and x86
> > > at the present time...
> > > 
> > 
> > I'm afraid I don't think this is right place to document this behavior.
> > 
> > There's a difference between an internal ABI between code running in two
> > CPU modes but both part of the same kernel, and a hypervisor running
> > a guest OS on top.
> > 
> > I believe that Documentation/virtual/kvm/hypercalls.txt documents the
> > latter case (i.e. guest hypercalls supported by the KVM host
> > hypervisor), not the former case, and these things should not be
> > combined.
> > 
> > I would suggest adding something like
> > Documentation/virtual/kvm/arm/hyp-abi.txt instead.
> 
> I'm fine with that - I just want there to be some documentation so we can
> stop poking around in the dark, with people stating random different and
> incorrect opinions about the code when problems like broken kexec/kdump
> come up.
> 
> The only way to make me shut up about the documentation thing is to do
> something about it...
> 

Nobody is arguing with the need for documentation, and I think I
understan the reason for needing to support a common ABI with a common
set of functions regardless of the logic in place in Hyp mode.

We just have to agree on a sane ABI and I'll be happy to help
write/review the API docs and clean things up.

Thanks,
-Christoffer

^ permalink raw reply

* [RFC 00/55] Nested Virtualization on KVM/ARM
From: David Hildenbrand @ 2017-01-09 15:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483943091-1364-1-git-send-email-jintack@cs.columbia.edu>


> Even though this work is not complete (see limitations below), I'd appreciate
> early feedback on this RFC. Specifically, I'm interested in:
> - Is it better to have a kernel config or to make it configurable at runtime?

x86 and s390x have a kernel module parameter (nested) that can only be
changed when loading the module and should default to false. So the
admin explicitly has to enable it. Maybe going the same path makes
sense.

-- 

David

^ permalink raw reply

* mmc: sdhci-of-at91: Internal clock never stabilised
From: Alex Gershgorin @ 2017-01-09 15:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170109135855.dquiysi5wnilujgp@rfolt0960.corp.atmel.com>

Thanks for your help, I will replace the chip with Rev B so I can
indeed start working on my board normally J

Regards,
Alex

On Mon, Jan 9, 2017 at 3:58 PM, Ludovic Desroches
<ludovic.desroches@atmel.com> wrote:
> On Mon, Jan 09, 2017 at 12:44:42PM +0200, Alex Gershgorin wrote:
>> Hi Ludovic,
>> As we read the chip ID from CHIPID_CIDR register we get 0x8a5c08c0 (we
>> use ATSAMA5D27A-CU).
>>
>
> It seems the device you have is a rev A device, this issue should be fixed in
> the revision B.
>
> I say should, because the bug was identified and I provided a workaround with
> the use of our own set_clock function has been done. Unfortunately, even
> if it happens less frequently, it seems the bug is still here.
>
> The hardware part has been reworked on the revision B. I don't recall facing
> this issue again but I can't guarantee that it won't happen anymore
> since the root cause was not properly identified on rev A.
>
> Regards
>
> Ludovic
>
>>
>> Thanks,
>> Alex
>>
>> On Mon, Jan 9, 2017 at 9:19 AM, Ludovic Desroches
>> <ludovic.desroches@atmel.com> wrote:
>> > Hi Alex,
>> >
>> > Which revision of SoC are you using?
>> >
>> > Regards
>> >
>> > Ludovic
>> >
>> > On Sun, Jan 08, 2017 at 01:53:44PM +0100, Alexandre Belloni wrote:
>> >> Hi,
>> >>
>> >> I think Cyrille worked on that a few month ago, maybe he has a comment.
>> >>
>> >> On 08/01/2017 at 14:07:53 +0200, Alex Gershgorin wrote :
>> >> > Hi All,
>> >> > We have two different HW platforms based on SAMA5D2 SoC (SAMA5D2 Xplained
>> >> > Board and our own HW).
>> >> > On both of them we are facing stabilization of the internal
>> >> > clock problem, it does not happen all the time but quite often.
>> >> > Please see below my Kernel boot messages:
>> >> >
>> >> > sdhci: Copyright(c) Pierre Ossman
>> >> > sdhci-pltfm: SDHCI platform and OF driver helper
>> >> > sdhci-at91 a0000000.sdio-host: update clk mul to 39 as gck rate is
>> >> > 480000000 Hz
>> >> > mmc0: Internal clock never stabilised.
>> >> > mmc0: Internal clock never stabilised.
>> >> > mmc0: SDHCI controller on a0000000.sdio-host [a0000000.sdio-host] using ADMA
>> >> >
>> >> > snip
>> >> >
>> >> > snip
>> >> >
>> >> > Waiting for root device /dev/mmcblk0p2...
>> >> > mmc0: Internal clock never stabilised.
>> >> > mmc0: Timeout waiting for hardware cmd interrupt.
>> >> > sdhci: =========== REGISTER DUMP (mmc0)===========
>> >> > sdhci: Sys addr: 0x00000000 | Version:  0x00001502
>> >> > sdhci: Blk size: 0x00000000 | Blk cnt:  0x00000000
>> >> > sdhci: Argument: 0x00000000 | Trn mode: 0x00000000
>> >> > sdhci: Present: 0x01ff0001 | Host ctl: 0x00000001
>> >> > sdhci: Power: 0x0000000f | Blk gap:  0x00000000
>> >> > sdhci: Wake-up: 0x00000000 | Clock:    0x0000ffe1
>> >> > sdhci: Timeout: 0x00000000 | Int stat: 0x00000000
>> >> > sdhci: Int enab: 0x00ff0003 | Sig enab: 0x00ff0003
>> >> > sdhci: AC12 err: 0x00000000 | Slot int: 0x00000000
>> >> > sdhci: Caps: 0x27ec0c8c | Caps_1: 0x00270f77
>> >> > sdhci: Cmd: 0x00000000 | Max curr: 0x00000000
>> >> > sdhci: Host ctl2: 0x00000000
>> >> > sdhci: ADMA Err: 0x00000000 | ADMA Ptr: 0x00000000
>> >> > sdhci: ===========================================
>> >> >
>> >> > Any direction to solve this problem?
>> >> >
>> >> > Thanks,
>> >> > Alex Gershgorin
>> >>
>> >> --
>> >> Alexandre Belloni, Free Electrons
>> >> Embedded Linux and Kernel engineering
>> >> http://free-electrons.com
>> >>
>> >> _______________________________________________
>> >> linux-arm-kernel mailing list
>> >> linux-arm-kernel at lists.infradead.org
>> >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ 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