* [PATCH v2] drm/atmel-hlcdc: check stride values in the first plane
From: Boris Brezillon @ 2018-06-17 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180617084826.31885-1-stefan@agner.ch>
On Sun, 17 Jun 2018 10:48:22 +0200
Stefan Agner <stefan@agner.ch> wrote:
> The statement always evaluates to true since the struct fields
> are arrays. This has shown up as a warning when compiling with
> clang:
> warning: address of array 'desc->layout.xstride' will always
> evaluate to 'true' [-Wpointer-bool-conversion]
>
> Check for values in the first plane instead.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
I'll add
Fixes: 1a396789f65a ("drm: add Atmel HLCDC Display Controller support")
Cc: stable at vger.kernel.org
when applying.
Thanks,
Boris
> ---
> Changes in v2:
> - Check for first value instead of dropping if statement
> (subject was: drm/atmel-hlcdc: remove unnecessary if statement)
>
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index 73c875db45f4..47e0992f3908 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -839,7 +839,7 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
> return ret;
> }
>
> - if (desc->layout.xstride && desc->layout.pstride) {
> + if (desc->layout.xstride[0] && desc->layout.pstride[0]) {
> int ret;
>
> ret = drm_plane_create_rotation_property(&plane->base,
^ permalink raw reply
* [PATCH] drm/exynos: ipp: use correct enum type
From: Stefan Agner @ 2018-06-17 8:55 UTC (permalink / raw)
To: linux-arm-kernel
The limit_id_fallback array uses enum drm_ipp_size_id to index its
content. The content itself is of type enum drm_exynos_ipp_limit_type.
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/gpu/drm/exynos/exynos_drm_ipp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 26374e58c557..04702e974e81 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -428,7 +428,7 @@ enum drm_ipp_size_id {
IPP_LIMIT_BUFFER, IPP_LIMIT_AREA, IPP_LIMIT_ROTATED, IPP_LIMIT_MAX
};
-static const enum drm_ipp_size_id limit_id_fallback[IPP_LIMIT_MAX][4] = {
+static const enum drm_exynos_ipp_limit_type limit_id_fallback[IPP_LIMIT_MAX][4] = {
[IPP_LIMIT_BUFFER] = { DRM_EXYNOS_IPP_LIMIT_SIZE_BUFFER },
[IPP_LIMIT_AREA] = { DRM_EXYNOS_IPP_LIMIT_SIZE_AREA,
DRM_EXYNOS_IPP_LIMIT_SIZE_BUFFER },
--
2.17.1
^ permalink raw reply related
* [PATCH v2] drm/atmel-hlcdc: check stride values in the first plane
From: Stefan Agner @ 2018-06-17 8:48 UTC (permalink / raw)
To: linux-arm-kernel
The statement always evaluates to true since the struct fields
are arrays. This has shown up as a warning when compiling with
clang:
warning: address of array 'desc->layout.xstride' will always
evaluate to 'true' [-Wpointer-bool-conversion]
Check for values in the first plane instead.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
Changes in v2:
- Check for first value instead of dropping if statement
(subject was: drm/atmel-hlcdc: remove unnecessary if statement)
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 73c875db45f4..47e0992f3908 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -839,7 +839,7 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
return ret;
}
- if (desc->layout.xstride && desc->layout.pstride) {
+ if (desc->layout.xstride[0] && desc->layout.pstride[0]) {
int ret;
ret = drm_plane_create_rotation_property(&plane->base,
--
2.17.1
^ permalink raw reply related
* [PATCH v2] mm: convert return type of handle_mm_fault() caller to vm_fault_t
From: Souptick Joarder @ 2018-06-17 8:48 UTC (permalink / raw)
To: linux-arm-kernel
Use new return type vm_fault_t for fault handler. For
now, this is just documenting that the function returns
a VM_FAULT value rather than an errno. Once all instances
are converted, vm_fault_t will become a distinct type.
Ref-> commit 1c8f422059ae ("mm: change return type to vm_fault_t")
In this patch all the caller of handle_mm_fault()
are changed to return vm_fault_t type.
Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
---
v2: Fixed kbuild error
arch/alpha/mm/fault.c | 3 ++-
arch/arc/mm/fault.c | 4 +++-
arch/arm/mm/fault.c | 7 ++++---
arch/arm64/mm/fault.c | 6 +++---
arch/hexagon/mm/vm_fault.c | 2 +-
arch/ia64/mm/fault.c | 2 +-
arch/m68k/mm/fault.c | 4 ++--
arch/microblaze/mm/fault.c | 2 +-
arch/mips/mm/fault.c | 2 +-
arch/nds32/mm/fault.c | 2 +-
arch/nios2/mm/fault.c | 2 +-
arch/openrisc/mm/fault.c | 2 +-
arch/parisc/mm/fault.c | 2 +-
arch/powerpc/include/asm/copro.h | 4 +++-
arch/powerpc/mm/copro_fault.c | 2 +-
arch/powerpc/mm/fault.c | 7 ++++---
arch/powerpc/platforms/cell/spufs/fault.c | 2 +-
arch/riscv/mm/fault.c | 3 ++-
arch/s390/mm/fault.c | 13 ++++++++-----
arch/sh/mm/fault.c | 4 ++--
arch/sparc/mm/fault_32.c | 3 ++-
arch/sparc/mm/fault_64.c | 3 ++-
arch/um/kernel/trap.c | 2 +-
arch/unicore32/mm/fault.c | 9 +++++----
arch/x86/mm/fault.c | 5 +++--
arch/xtensa/mm/fault.c | 2 +-
drivers/iommu/amd_iommu_v2.c | 2 +-
drivers/iommu/intel-svm.c | 4 +++-
drivers/misc/cxl/fault.c | 2 +-
drivers/misc/ocxl/link.c | 3 ++-
mm/hmm.c | 8 ++++----
mm/ksm.c | 2 +-
32 files changed, 69 insertions(+), 51 deletions(-)
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index cd3c572..2a979ee 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -87,7 +87,8 @@
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
const struct exception_table_entry *fixup;
- int fault, si_code = SEGV_MAPERR;
+ int si_code = SEGV_MAPERR;
+ vm_fault_t fault;
siginfo_t info;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index a0b7bd6..3a18d33 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -15,6 +15,7 @@
#include <linux/uaccess.h>
#include <linux/kdebug.h>
#include <linux/perf_event.h>
+#include <linux/mm_types.h>
#include <asm/pgalloc.h>
#include <asm/mmu.h>
@@ -66,7 +67,8 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
siginfo_t info;
- int fault, ret;
+ int ret;
+ vm_fault_t fault;
int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index b75eada..758abcb 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -219,12 +219,12 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
return vma->vm_flags & mask ? false : true;
}
-static int __kprobes
+static vm_fault_t __kprobes
__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
unsigned int flags, struct task_struct *tsk)
{
struct vm_area_struct *vma;
- int fault;
+ vm_fault_t fault;
vma = find_vma(mm, addr);
fault = VM_FAULT_BADMAP;
@@ -259,7 +259,8 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
{
struct task_struct *tsk;
struct mm_struct *mm;
- int fault, sig, code;
+ int sig, code;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
if (notify_page_fault(regs, fsr))
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 2af3dd8..8da263b 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -371,12 +371,12 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re
#define VM_FAULT_BADMAP 0x010000
#define VM_FAULT_BADACCESS 0x020000
-static int __do_page_fault(struct mm_struct *mm, unsigned long addr,
+static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr,
unsigned int mm_flags, unsigned long vm_flags,
struct task_struct *tsk)
{
struct vm_area_struct *vma;
- int fault;
+ vm_fault_t fault;
vma = find_vma(mm, addr);
fault = VM_FAULT_BADMAP;
@@ -419,7 +419,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
struct task_struct *tsk;
struct mm_struct *mm;
struct siginfo si;
- int fault, major = 0;
+ vm_fault_t fault, major = 0;
unsigned long vm_flags = VM_READ | VM_WRITE;
unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
index 3eec33c..5d1de6c 100644
--- a/arch/hexagon/mm/vm_fault.c
+++ b/arch/hexagon/mm/vm_fault.c
@@ -52,7 +52,7 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs)
struct mm_struct *mm = current->mm;
siginfo_t info;
int si_code = SEGV_MAPERR;
- int fault;
+ vm_fault_t fault;
const struct exception_table_entry *fixup;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index dfdc152..e085d89 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -87,7 +87,7 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
struct mm_struct *mm = current->mm;
struct siginfo si;
unsigned long mask;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
mask = ((((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index 03253c4..1fc7ac0 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -73,7 +73,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct * vma;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
pr_debug("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
@@ -139,7 +139,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
*/
fault = handle_mm_fault(vma, address, flags);
- pr_debug("handle_mm_fault returns %d\n", fault);
+ pr_debug("handle_mm_fault returns %x\n", fault);
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
return 0;
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index f91b30f..92a8682 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -91,7 +91,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
siginfo_t info;
int code = SEGV_MAPERR;
int is_write = error_code & ESR_S;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
regs->ear = address;
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 4f8f5bf..0bc5030 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -43,7 +43,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
struct mm_struct *mm = tsk->mm;
const int field = sizeof(unsigned long) * 2;
siginfo_t info;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c
index 3a246fb..96796d3 100644
--- a/arch/nds32/mm/fault.c
+++ b/arch/nds32/mm/fault.c
@@ -73,7 +73,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
struct mm_struct *mm;
struct vm_area_struct *vma;
siginfo_t info;
- int fault;
+ vm_fault_t fault;
unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c
index b804dd0..24fd84c 100644
--- a/arch/nios2/mm/fault.c
+++ b/arch/nios2/mm/fault.c
@@ -47,7 +47,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
int code = SEGV_MAPERR;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
cause >>= 2;
diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
index d0021df..21e8f16 100644
--- a/arch/openrisc/mm/fault.c
+++ b/arch/openrisc/mm/fault.c
@@ -53,7 +53,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
struct mm_struct *mm;
struct vm_area_struct *vma;
siginfo_t info;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
tsk = current;
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index e247edb..ff9e634 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -262,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
struct task_struct *tsk;
struct mm_struct *mm;
unsigned long acc_type;
- int fault = 0;
+ vm_fault_t fault = 0;
unsigned int flags;
if (faulthandler_disabled())
diff --git a/arch/powerpc/include/asm/copro.h b/arch/powerpc/include/asm/copro.h
index ce216df..48616fe 100644
--- a/arch/powerpc/include/asm/copro.h
+++ b/arch/powerpc/include/asm/copro.h
@@ -10,13 +10,15 @@
#ifndef _ASM_POWERPC_COPRO_H
#define _ASM_POWERPC_COPRO_H
+#include <linux/mm_types.h>
+
struct copro_slb
{
u64 esid, vsid;
};
int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
- unsigned long dsisr, unsigned *flt);
+ unsigned long dsisr, vm_fault_t *flt);
int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb);
diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c
index 7d0945b..c8da352 100644
--- a/arch/powerpc/mm/copro_fault.c
+++ b/arch/powerpc/mm/copro_fault.c
@@ -34,7 +34,7 @@
* to handle fortunately.
*/
int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
- unsigned long dsisr, unsigned *flt)
+ unsigned long dsisr, vm_fault_t *flt)
{
struct vm_area_struct *vma;
unsigned long is_write;
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index c01d627..17cce1b 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -159,7 +159,7 @@ static noinline int bad_access(struct pt_regs *regs, unsigned long address)
}
static int do_sigbus(struct pt_regs *regs, unsigned long address,
- unsigned int fault)
+ vm_fault_t fault)
{
siginfo_t info;
unsigned int lsb = 0;
@@ -189,7 +189,8 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address,
return 0;
}
-static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)
+static int mm_fault_error(struct pt_regs *regs, unsigned long addr,
+ vm_fault_t fault)
{
/*
* Kernel page fault interrupted by SIGKILL. We have no reason to
@@ -402,7 +403,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
int is_exec = TRAP(regs) == 0x400;
int is_user = user_mode(regs);
int is_write = page_fault_is_write(error_code);
- int fault, major = 0;
+ vm_fault_t fault, major = 0;
bool store_update_sp = false;
if (notify_page_fault(regs))
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 870c0a8..0195076 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -111,7 +111,7 @@ int spufs_handle_class1(struct spu_context *ctx)
{
u64 ea, dsisr, access;
unsigned long flags;
- unsigned flt = 0;
+ vm_fault_t flt = 0;
int ret;
/*
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 148c98c..88401d5 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -41,7 +41,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
struct mm_struct *mm;
unsigned long addr, cause;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
- int fault, code = SEGV_MAPERR;
+ int code = SEGV_MAPERR;
+ vm_fault_t fault;
cause = regs->scause;
addr = regs->sbadaddr;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 93faeca..8ea0855 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -350,7 +350,8 @@ static noinline int signal_return(struct pt_regs *regs)
return -EACCES;
}
-static noinline void do_fault_error(struct pt_regs *regs, int access, int fault)
+static noinline void do_fault_error(struct pt_regs *regs, int access,
+ vm_fault_t fault)
{
int si_code;
@@ -410,7 +411,7 @@ static noinline void do_fault_error(struct pt_regs *regs, int access, int fault)
* 11 Page translation -> Not present (nullification)
* 3b Region third trans. -> Not present (nullification)
*/
-static inline int do_exception(struct pt_regs *regs, int access)
+static inline vm_fault_t do_exception(struct pt_regs *regs, int access)
{
struct gmap *gmap;
struct task_struct *tsk;
@@ -420,7 +421,7 @@ static inline int do_exception(struct pt_regs *regs, int access)
unsigned long trans_exc_code;
unsigned long address;
unsigned int flags;
- int fault;
+ vm_fault_t fault;
tsk = current;
/*
@@ -571,7 +572,8 @@ static inline int do_exception(struct pt_regs *regs, int access)
void do_protection_exception(struct pt_regs *regs)
{
unsigned long trans_exc_code;
- int access, fault;
+ int access;
+ vm_fault_t fault;
trans_exc_code = regs->int_parm_long;
/*
@@ -606,7 +608,8 @@ void do_protection_exception(struct pt_regs *regs)
void do_dat_exception(struct pt_regs *regs)
{
- int access, fault;
+ int access;
+ vm_fault_t fault;
access = VM_READ | VM_EXEC | VM_WRITE;
fault = do_exception(regs, access);
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 6fd1bf7..474bf14 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -320,7 +320,7 @@ static noinline int vmalloc_fault(unsigned long address)
static noinline int
mm_fault_error(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, unsigned int fault)
+ unsigned long address, vm_fault_t fault)
{
/*
* Pagefault was interrupted by SIGKILL. We have no reason to
@@ -403,7 +403,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
struct task_struct *tsk;
struct mm_struct *mm;
struct vm_area_struct * vma;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
tsk = current;
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index a8103a8..1a44a4e 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -174,7 +174,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
unsigned int fixup;
unsigned long g2;
int from_user = !(regs->psr & PSR_PS);
- int fault, code;
+ int code;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
if (text_fault)
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 41363f4..2078bfe 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -284,7 +284,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned int insn = 0;
- int si_code, fault_code, fault;
+ int si_code, fault_code;
+ vm_fault_t fault;
unsigned long address, mm_rss;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index b2b02df..0afcd09 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -72,7 +72,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
}
do {
- int fault;
+ vm_fault_t fault;
fault = handle_mm_fault(vma, address, flags);
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c
index bbefcc4..2982140 100644
--- a/arch/unicore32/mm/fault.c
+++ b/arch/unicore32/mm/fault.c
@@ -167,11 +167,11 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
return vma->vm_flags & mask ? false : true;
}
-static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
- unsigned int flags, struct task_struct *tsk)
+static vm_fault_t __do_pf(struct mm_struct *mm, unsigned long addr,
+ unsigned int fsr, unsigned int flags, struct task_struct *tsk)
{
struct vm_area_struct *vma;
- int fault;
+ vm_fault_t fault;
vma = find_vma(mm, addr);
fault = VM_FAULT_BADMAP;
@@ -208,7 +208,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
struct task_struct *tsk;
struct mm_struct *mm;
- int fault, sig, code;
+ int sig, code;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
tsk = current;
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 73bd8c9..5171d60 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -16,6 +16,7 @@
#include <linux/prefetch.h> /* prefetchw */
#include <linux/context_tracking.h> /* exception_enter(), ... */
#include <linux/uaccess.h> /* faulthandler_disabled() */
+#include <linux/mm_types.h>
#include <asm/cpufeature.h> /* boot_cpu_has, ... */
#include <asm/traps.h> /* dotraplinkage, ... */
@@ -1004,7 +1005,7 @@ static inline bool bad_area_access_from_pkeys(unsigned long error_code,
static noinline void
mm_fault_error(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, u32 *pkey, unsigned int fault)
+ unsigned long address, u32 *pkey, vm_fault_t fault)
{
if (fatal_signal_pending(current) && !(error_code & X86_PF_USER)) {
no_context(regs, error_code, address, 0, 0);
@@ -1218,7 +1219,7 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
struct vm_area_struct *vma;
struct task_struct *tsk;
struct mm_struct *mm;
- int fault, major = 0;
+ vm_fault_t fault, major = 0;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
u32 pkey;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 8b9b6f4..203fade 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -42,7 +42,7 @@ void do_page_fault(struct pt_regs *regs)
siginfo_t info;
int is_write, is_exec;
- int fault;
+ vm_fault_t fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
info.si_code = SEGV_MAPERR;
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index 1d0b53a0..58da65d 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -508,7 +508,7 @@ static void do_fault(struct work_struct *work)
{
struct fault *fault = container_of(work, struct fault, work);
struct vm_area_struct *vma;
- int ret = VM_FAULT_ERROR;
+ vm_fault_t ret = VM_FAULT_ERROR;
unsigned int flags = 0;
struct mm_struct *mm;
u64 address;
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index e8cd984..75189c0 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -24,6 +24,7 @@
#include <linux/pci-ats.h>
#include <linux/dmar.h>
#include <linux/interrupt.h>
+#include <linux/mm_types.h>
#include <asm/page.h>
#define PASID_ENTRY_P BIT_ULL(0)
@@ -594,7 +595,8 @@ static irqreturn_t prq_event_thread(int irq, void *d)
struct vm_area_struct *vma;
struct page_req_dsc *req;
struct qi_desc resp;
- int ret, result;
+ int result;
+ vm_fault_t ret;
u64 address;
handled = 1;
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 70dbb6d..93ecc67 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -134,7 +134,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
int cxl_handle_mm_fault(struct mm_struct *mm, u64 dsisr, u64 dar)
{
- unsigned flt = 0;
+ vm_fault_t flt = 0;
int result;
unsigned long access, flags, inv_flags = 0;
diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c
index f307905..4e155fb 100644
--- a/drivers/misc/ocxl/link.c
+++ b/drivers/misc/ocxl/link.c
@@ -2,6 +2,7 @@
// Copyright 2017 IBM Corp.
#include <linux/sched/mm.h>
#include <linux/mutex.h>
+#include <linux/mm_types.h>
#include <linux/mmu_context.h>
#include <asm/copro.h>
#include <asm/pnv-ocxl.h>
@@ -126,7 +127,7 @@ static void ack_irq(struct spa *spa, enum xsl_response r)
static void xsl_fault_handler_bh(struct work_struct *fault_work)
{
- unsigned int flt = 0;
+ vm_fault_t flt = 0;
unsigned long access, flags, inv_flags = 0;
enum xsl_response r;
struct xsl_fault *fault = container_of(fault_work, struct xsl_fault,
diff --git a/mm/hmm.c b/mm/hmm.c
index 486dc39..d7919e5 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -308,14 +308,14 @@ static int hmm_vma_do_fault(struct mm_walk *walk, unsigned long addr,
struct hmm_vma_walk *hmm_vma_walk = walk->private;
struct hmm_range *range = hmm_vma_walk->range;
struct vm_area_struct *vma = walk->vma;
- int r;
+ vm_fault_t ret;
flags |= hmm_vma_walk->block ? 0 : FAULT_FLAG_ALLOW_RETRY;
flags |= write_fault ? FAULT_FLAG_WRITE : 0;
- r = handle_mm_fault(vma, addr, flags);
- if (r & VM_FAULT_RETRY)
+ ret = handle_mm_fault(vma, addr, flags);
+ if (ret & VM_FAULT_RETRY)
return -EBUSY;
- if (r & VM_FAULT_ERROR) {
+ if (ret & VM_FAULT_ERROR) {
*pfn = range->values[HMM_PFN_ERROR];
return -EFAULT;
}
diff --git a/mm/ksm.c b/mm/ksm.c
index e3cbf9a..cb4e6ed 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -451,7 +451,7 @@ static inline bool ksm_test_exit(struct mm_struct *mm)
static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
{
struct page *page;
- int ret = 0;
+ vm_fault_t ret = 0;
do {
cond_resched();
--
1.9.1
^ permalink raw reply related
* [PATCH V2] soc: imx: gpcv2: correct PGC offset
From: Shawn Guo @ 2018-06-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527643842-17643-1-git-send-email-Anson.Huang@nxp.com>
On Wed, May 30, 2018 at 09:30:42AM +0800, Anson Huang wrote:
> Correct MIPI/PCIe/USB_HSIC's PGC offset based on
> design RTL, the values in the Reference Manual
> (Rev. 1, 01/2018 and the older ones) are incorrect.
>
> The correct offset values should be as below:
>
> 0x800 ~ 0x83F: PGC for core0 of A7 platform;
> 0x840 ~ 0x87F: PGC for core1 of A7 platform;
> 0x880 ~ 0x8BF: PGC for SCU of A7 platform;
> 0xA00 ~ 0xA3F: PGC for fastmix/megamix;
> 0xC00 ~ 0xC3F: PGC for MIPI PHY;
> 0xC40 ~ 0xC7F: PGC for PCIe_PHY;
> 0xC80 ~ 0xCBF: PGC for USB OTG1 PHY;
> 0xCC0 ~ 0xCFF: PGC for USB OTG2 PHY;
> 0xD00 ~ 0xD3F: PGC for USB HSIC PHY;
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> Acked-by: Andrey Smirnov <andrew.smirnov@gmail.com>
I added the Fixes tag below and applied it as a fix.
Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
Shawn
^ permalink raw reply
* [PATCH v2 1/4] ARM: dts: imx6qdl-wandboard: remove regulators bus node
From: Shawn Guo @ 2018-06-17 7:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180529062021.3154-2-akurz@blala.de>
On Tue, May 29, 2018 at 06:20:18AM +0000, Alexander Kurz wrote:
> To match the convention, move all regulator-fixed nodes directly into
> the root node.
>
> Signed-off-by: Alexander Kurz <akurz@blala.de>
Applied all, thanks.
^ permalink raw reply
* [PATCH v3] ARM: DTS: imx53: Add support for imx53 HSC/DDC boards from K+P
From: Lukasz Majewski @ 2018-06-17 7:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180617065700.GK16091@dragon>
Hi Shawn,
> On Tue, Jun 12, 2018 at 03:32:08PM +0200, Lukasz Majewski wrote:
> > This commit provides support for HSC and DDC boards from
> > Kieback&Peter GmbH vendor.
> >
> > Signed-off-by: Lukasz Majewski <lukma@denx.de>
> > Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
>
> "ARM: dts: ..." for prefix. I fixed it up and applied the patch.
>
> Shawn
Thanks :-)
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180617/7b8e8d9a/attachment-0001.sig>
^ permalink raw reply
* [PATCH v2] ARM: dts: imx51-zii-rdu1: Make sure SD1_WP is low
From: Shawn Guo @ 2018-06-17 7:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180526021238.30753-1-andrew.smirnov@gmail.com>
On Fri, May 25, 2018 at 07:12:38PM -0700, Andrey Smirnov wrote:
> Make sure that MX51_PAD_GPIO1_1 does not remain configure as
> ALT0/SD1_WP (it is out of reset). This is needed because of external
> pull-up resistor attached to that pad that, when left unchanged, will
> drive SD1_WP high preventing eSDHC1/eMMC from working correctly.
>
> To fix that add a pinmux configuration line configureing the pad to
> function as a GPIO. While we are at it, add a corresponding
> output-high GPIO hog in an effort to minimize current consumption.
>
> Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Chris Healy <cphealy@gmail.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: devicetree at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Applied, thanks.
^ permalink raw reply
* [PATCH] ARM: dts: imx51-zii-rdu1: add rave-sp subdevices
From: Shawn Guo @ 2018-06-17 7:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180517191923.16212-1-nikita.yoush@cogentembedded.com>
On Thu, May 17, 2018 at 10:19:23PM +0300, Nikita Yushchenko wrote:
> This adds rave-sp powerbutton and backlight devices to RDU1 device tree.
>
> Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Applied, thanks.
^ permalink raw reply
* [PATCH v7 3/6] kernel/reboot.c: export pm_power_off_prepare
From: Shawn Guo @ 2018-06-17 7:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2307533.g32PyNi9fl@aspire.rjw.lan>
On Tue, Jun 12, 2018 at 04:33:05PM +0200, Rafael J. Wysocki wrote:
> On Tuesday, June 12, 2018 2:42:12 PM CEST Oleksij Rempel wrote:
> > This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
> > --Sj2PRcQlY7eZybdA0sq9wWzJEO8fKS924
> > Content-Type: multipart/mixed; boundary="d6BZYFRi4L3iCmOh3nm6wjii3dWC9QFDg";
> > protected-headers="v1"
> > From: Oleksij Rempel <o.rempel@pengutronix.de>
> > To: Shawn Guo <shawnguo@kernel.org>, Mark Brown <broonie@kernel.org>,
> > "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> > Cc: kernel at pengutronix.de, devicetree at vger.kernel.org,
> > linux-arm-kernel at lists.infradead.org, linux-clk at vger.kernel.org,
> > linux-kernel at vger.kernel.org, Andrew Morton <akpm@linux-foundation.org>,
> > Liam Girdwood <lgirdwood@gmail.com>,
> > Leonard Crestez <leonard.crestez@nxp.com>, Rob Herring <robh+dt@kernel.org>,
> > Mark Rutland <mark.rutland@arm.com>,
> > Michael Turquette <mturquette@baylibre.com>,
> > Stephen Boyd <sboyd@codeaurora.org>, Fabio Estevam <fabio.estevam@nxp.com>,
> > Russell King <linux@armlinux.org.uk>
> > Message-ID: <daba73df-037c-2583-3a08-f3f27c4129d1@pengutronix.de>
> > Subject: Re: [PATCH v7 3/6] kernel/reboot.c: export pm_power_off_prepare
> > References: <20180517055014.6607-1-o.rempel@pengutronix.de>
> > <20180517055014.6607-4-o.rempel@pengutronix.de>
> > In-Reply-To: <20180517055014.6607-4-o.rempel@pengutronix.de>
> >
> > --d6BZYFRi4L3iCmOh3nm6wjii3dWC9QFDg
> > Content-Type: text/plain; charset=utf-8
> > Content-Language: en-US
> > Content-Transfer-Encoding: quoted-printable
> >
> > Hi Rafael,
> >
> > Last version of this patch was send at 17.05.2018. No other comment was
> > provided and this patch is a blocker for other patches in this serie.
> > Can you please give some feedback on it.
>
> I would have done that had I not missed the patch.
>
> Which probably wouldn't have happened had you CCed it to linux-pm.
>
> Anyway, I have no particular problems with exporting pm_power_off_prepare via
> EXPORT_SYMBOL_GPL().
Rafael,
Can we have your explicit Acked-by tag on this patch? Thanks.
Shawn
^ permalink raw reply
* [PATCH v3] ARM: DTS: imx53: Add support for imx53 HSC/DDC boards from K+P
From: Shawn Guo @ 2018-06-17 6:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180612133208.22458-1-lukma@denx.de>
On Tue, Jun 12, 2018 at 03:32:08PM +0200, Lukasz Majewski wrote:
> This commit provides support for HSC and DDC boards from
> Kieback&Peter GmbH vendor.
>
> Signed-off-by: Lukasz Majewski <lukma@denx.de>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
"ARM: dts: ..." for prefix. I fixed it up and applied the patch.
Shawn
^ permalink raw reply
* [PATCH v1] ARM: imx: add imx7d-m4
From: Shawn Guo @ 2018-06-17 6:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180405115134.8036-1-o.rempel@pengutronix.de>
On Thu, Apr 05, 2018 at 01:51:34PM +0200, Oleksij Rempel wrote:
> Provide basic support for Cortex-M4 located on NXP iMX7D.
> This code was tested in combination with imx-rproc driver
> which will upload with specially formatted ELF image containing
> kernel, device and CPIO rootfs.
>
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Can we make the patch subject a bit more complete, at least like
"ARM: imx: add imx7d-m4 support" or something?
Shawn
^ permalink raw reply
* [PATCH v1] ARM: imx: add imx7d-m4
From: Shawn Guo @ 2018-06-17 6:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180405115134.8036-1-o.rempel@pengutronix.de>
On Thu, Apr 05, 2018 at 01:51:34PM +0200, Oleksij Rempel wrote:
> Provide basic support for Cortex-M4 located on NXP iMX7D.
> This code was tested in combination with imx-rproc driver
> which will upload with specially formatted ELF image containing
> kernel, device and CPIO rootfs.
>
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> ---
> arch/arm/boot/dts/Makefile | 2 +-
> arch/arm/mach-imx/Kconfig | 33 +++++++++++++++++++++------------
> arch/arm/mach-imx/Makefile | 3 ++-
> arch/arm/mach-imx/mach-imx7d-cm4.c | 21 +++++++++++++++++++++
> 4 files changed, 45 insertions(+), 14 deletions(-)
> create mode 100644 arch/arm/mach-imx/mach-imx7d-cm4.c
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 852452515bea..d49bb9a58aee 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -527,7 +527,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
> imx6ul-tx6ul-0011.dtb \
> imx6ul-tx6ul-mainboard.dtb \
> imx6ull-14x14-evk.dtb
> -dtb-$(CONFIG_SOC_IMX7D) += \
> +dtb-$(CONFIG_SOC_IMX7D_CA7) += \
I would keep this unchanged, and have future IMX7D_CM4 DTBs just
covered by CONFIG_SOC_IMX7D as well.
Shawn
> imx7d-cl-som-imx7.dtb \
> imx7d-colibri-emmc-eval-v3.dtb \
> imx7d-colibri-eval-v3.dtb \
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 782699e67600..101c8599d952 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -528,18 +528,6 @@ config SOC_IMX6UL
> help
> This enables support for Freescale i.MX6 UltraLite processor.
>
> -config SOC_IMX7D
> - bool "i.MX7 Dual support"
> - select PINCTRL_IMX7D
> - select ARM_GIC
> - select HAVE_ARM_ARCH_TIMER
> - select HAVE_IMX_ANATOP
> - select HAVE_IMX_MMDC
> - select HAVE_IMX_SRC
> - select IMX_GPCV2
> - help
> - This enables support for Freescale i.MX7 Dual processor.
> -
> config SOC_LS1021A
> bool "Freescale LS1021A support"
> select ARM_GIC
> @@ -554,6 +542,27 @@ comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms"
>
> if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
>
> +config SOC_IMX7D_CA7
> + bool
> + select ARM_GIC
> + select HAVE_ARM_ARCH_TIMER
> + select HAVE_IMX_ANATOP
> + select HAVE_IMX_MMDC
> + select HAVE_IMX_SRC
> + select IMX_GPCV2
> +
> +config SOC_IMX7D_CM4
> + bool
> + select ARMV7M_SYSTICK
> +
> +config SOC_IMX7D
> + bool "i.MX7 Dual support"
> + select PINCTRL_IMX7D
> + select SOC_IMX7D_CA7 if ARCH_MULTI_V7
> + select SOC_IMX7D_CM4 if ARM_SINGLE_ARMV7M
> + help
> + This enables support for Freescale i.MX7 Dual processor.
> +
> config SOC_VF610
> bool "Vybrid Family VF610 support"
> select ARM_GIC if ARCH_MULTI_V7
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index 8ff71058207d..68640f100ef3 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -80,7 +80,8 @@ obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
> obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
> obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
> obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
> -obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
> +obj-$(CONFIG_SOC_IMX7D_CA7) += mach-imx7d.o
> +obj-$(CONFIG_SOC_IMX7D_CM4) += mach-imx7d-cm4.o
>
> ifeq ($(CONFIG_SUSPEND),y)
> AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
> diff --git a/arch/arm/mach-imx/mach-imx7d-cm4.c b/arch/arm/mach-imx/mach-imx7d-cm4.c
> new file mode 100644
> index 000000000000..c36dea79aeb8
> --- /dev/null
> +++ b/arch/arm/mach-imx/mach-imx7d-cm4.c
> @@ -0,0 +1,21 @@
> +/*
> + * Copyright 2017 Pengutronix
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <asm/v7m.h>
> +#include <asm/mach/arch.h>
> +
> +static const char * const imx7d_cm4_dt_compat[] __initconst = {
> + "fsl,imx7d-cm4",
> + NULL,
> +};
> +
> +DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual Cortex-M4 (Device Tree)")
> + .dt_compat = imx7d_cm4_dt_compat,
> + .restart = armv7m_restart,
> +MACHINE_END
> --
> 2.16.1
>
^ permalink raw reply
* [RFC PATCH 03/10] devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.
From: Chanwoo Choi @ 2018-06-17 0:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAFqH_51jDy6hvwTtVQf52OZ2QFwAACzH8bh2bUZdxAnvKqM6=A@mail.gmail.com>
Hi Enric
2018-06-16 19:15 GMT+09:00 Enric Balletbo Serra <eballetbo@gmail.com>:
> Hi Chanwoo,
>
> I'll send a new version soon, just wanted to ask some questions here. See below.
>
> Missatge de Chanwoo Choi <cw00.choi@samsung.com> del dia dt., 15 de
> maig 2018 a les 0:21:
>>
>> Hi,
>>
>> On 2018? 05? 15? 06:16, Enric Balletbo i Serra wrote:
>> > Trusted Firmware-A (TF-A) for rk3399 implements a SiP call to get the
>> > on-die termination (ODT) and auto power down parameters from kernel,
>> > this patch adds the functionality to do this. Also, if DDR clock
>> > frequency is lower than the on-die termination (ODT) disable frequency
>> > this driver should disable the DDR ODT.
>>
>> I have a question.
>> 'disable frequency' is the same meaning of 'disable the DDR ODT'?
>>
>
> Yes, the DT defines an odt_dis_freq parameter, when the DDR frequency
> is less than the value in this parameter we disable the ODT on the
> DRAM.
>
>> >
>> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>> > ---
>> >
>> > drivers/devfreq/rk3399_dmc.c | 50 ++++++++++++++++++++++++++++-
>> > include/soc/rockchip/rockchip_sip.h | 1 +
>> > 2 files changed, 50 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
>> > index d5c03e5abe13..cc1bbca3fb15 100644
>> > --- a/drivers/devfreq/rk3399_dmc.c
>> > +++ b/drivers/devfreq/rk3399_dmc.c
>> > @@ -18,14 +18,17 @@
>> > #include <linux/devfreq.h>
>> > #include <linux/devfreq-event.h>
>> > #include <linux/interrupt.h>
>> > +#include <linux/mfd/syscon.h>
>> > #include <linux/module.h>
>> > #include <linux/of.h>
>> > #include <linux/platform_device.h>
>> > #include <linux/pm_opp.h>
>> > +#include <linux/regmap.h>
>> > #include <linux/regulator/consumer.h>
>> > #include <linux/rwsem.h>
>> > #include <linux/suspend.h>
>> >
>> > +#include <soc/rockchip/rk3399_grf.h>
>> > #include <soc/rockchip/rockchip_sip.h>
>> >
>> > struct dram_timing {
>> > @@ -69,8 +72,11 @@ struct rk3399_dmcfreq {
>> > struct mutex lock;
>> > struct dram_timing timing;
>> > struct regulator *vdd_center;
>> > + struct regmap *regmap_pmu;
>> > unsigned long rate, target_rate;
>> > unsigned long volt, target_volt;
>> > + unsigned int odt_dis_freq;
>> > + int odt_pd_arg0, odt_pd_arg1;
>> > };
>> >
>> > static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
>> > @@ -80,6 +86,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
>> > struct dev_pm_opp *opp;
>> > unsigned long old_clk_rate = dmcfreq->rate;
>> > unsigned long target_volt, target_rate;
>> > + struct arm_smccc_res res;
>> > + int dram_flag;
>> > int err;
>> >
>> > opp = devfreq_recommended_opp(dev, freq, flags);
>> > @@ -95,6 +103,15 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
>> >
>> > mutex_lock(&dmcfreq->lock);
>> >
>> > + dram_flag = 0;
>>
>> Also, if dram_flag is 0, it mean that disable ODT frequency?
>
> Yes, not a good name, maybe I should just rename it to odt_enable to
> be more clear.
>
>> If it's right, you better to define the precise variables as following
>> instead of just integer(0 or 1).
>> For example,
>> - ROCKCHIP_SIP_DRAM_FREQ_ENABLE
>> - ROCKCHIP_SIP_DRAM_FREQ_DISABLE
>>
>> > + if (target_rate >= dmcfreq->odt_dis_freq)
>> > + dram_flag = 1;
>> > +
>> > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
>> > + dmcfreq->odt_pd_arg1,
>> > + ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
>> > + dram_flag, 0, 0, 0, &res);
>> > +
>>
>> This operation is special for only rk3399_dmc. It is difficult
>> to understand what to do. I recommend you better to add the detailed comment
>> with code.
>
> Will do.
>
>>
>> > /*
>> > * If frequency scaling from low to high, adjust voltage first.
>> > * If frequency scaling from high to low, adjust frequency first.
>> > @@ -294,11 +311,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
>> > {
>> > struct arm_smccc_res res;
>> > struct device *dev = &pdev->dev;
>> > - struct device_node *np = pdev->dev.of_node;
>> > + struct device_node *np = pdev->dev.of_node, *node;
>> > struct rk3399_dmcfreq *data;
>> > int ret, index, size;
>> > uint32_t *timing;
>> > struct dev_pm_opp *opp;
>> > + u32 ddr_type;
>> > + u32 val;
>> >
>> > data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);
>> > if (!data)
>> > @@ -334,6 +353,29 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
>> > return ret;
>> > }
>> >
>> > + /* Try to find the optional reference to the pmu syscon */
>> > + node = of_parse_phandle(np, "rockchip,pmu", 0);
>> > + if (node) {
>> > + data->regmap_pmu = syscon_node_to_regmap(node);
>> > + if (IS_ERR(data->regmap_pmu))
>> > + return PTR_ERR(data->regmap_pmu);
>> > + }
>> > +
>> > + /* Get DDR type */
>> > + regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
>> > + ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
>> > + RK3399_PMUGRF_DDRTYPE_MASK;
>> > +
>> > + /* Get the odt_dis_freq parameter in function of the DDR type */
>> > + if (ddr_type == RK3399_PMUGRF_DDRTYPE_DDR3)
>> > + data->odt_dis_freq = data->timing.ddr3_odt_dis_freq;
>> > + else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
>> > + data->odt_dis_freq = data->timing.lpddr3_odt_dis_freq;
>> > + else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
>> > + data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq;
>> > + else
>> > + return -EINVAL;
>> > +
>>
>> how about using 'switch' statement?
>>
>
> Ok
>
>> > /*
>> > * Get dram timing and pass it to arm trust firmware,
>> > * the dram drvier in arm trust firmware will get these
>> > @@ -358,6 +400,12 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
>> > ROCKCHIP_SIP_CONFIG_DRAM_INIT,
>> > 0, 0, 0, 0, &res);
>> >
>> > + data->odt_pd_arg0 = (data->timing.sr_idle & 0xff) |
>> > + ((data->timing.sr_mc_gate_idle & 0xff) << 8) |
>> > + ((data->timing.standby_idle & 0xffff) << 16);
>> > + data->odt_pd_arg1 = (data->timing.pd_idle & 0xfff) |
>> > + ((data->timing.srpd_lite_idle & 0xfff) << 16);
>> > +
>>
>> odt_pd_arg0 and odt_pd_arg1 might be used for disabling/enabling the ODT frequency.
>> As I commented, it depend on only rk3399_dmc. You better to add detailed comment.
>>
>
> Ok
>
>> And I prefer to define the XXX_SHIFT/XXX_MASK definition instead of
>> using 8/16/0xff/0xffff for the readability.
>>
>
> I tried to add the XXX_SHIFT/XXX_MASK definitions and IMHO the
> readability is worst if I use a maximum line length of 80 characters.
> These masks are only used here, let me try to convince you by adding a
> good doc in the next version and if you still prefer I add the
> definition I'll do.
If you add the some description and it would be only used on here,
I don't force to add some definition such as _SHIFT, _MASK as you suggested.
>
>> > /*
>> > * We add a devfreq driver to our parent since it has a device tree node
>> > * with operating points.
>> > diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
>> > index 7e28092c4d3d..ad9482c56797 100644
>> > --- a/include/soc/rockchip/rockchip_sip.h
>> > +++ b/include/soc/rockchip/rockchip_sip.h
>> > @@ -23,5 +23,6 @@
>> > #define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05
>> > #define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
>> > #define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
>> > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08
>> >
>> > #endif
>> >
>>
>>
>> --
>> Best Regards,
>> Chanwoo Choi
>> Samsung Electronics
>>
>> _______________________________________________
>> Linux-rockchip mailing list
>> Linux-rockchip at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-rockchip
> Cheers,
> Enric
--
Best Regards,
Chanwoo Choi
Samsung Electronics
^ permalink raw reply
* [PATCH v3 3/5] crypto: arm/speck - add NEON-accelerated implementation of Speck-XTS
From: Stefan Agner @ 2018-06-16 22:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180214184223.254359-4-ebiggers@google.com>
Hi Eric,
On 14.02.2018 19:42, Eric Biggers wrote:
> Add an ARM NEON-accelerated implementation of Speck-XTS. It operates on
> 128-byte chunks at a time, i.e. 8 blocks for Speck128 or 16 blocks for
> Speck64. Each 128-byte chunk goes through XTS preprocessing, then is
> encrypted/decrypted (doing one cipher round for all the blocks, then the
> next round, etc.), then goes through XTS postprocessing.
>
> The performance depends on the processor but can be about 3 times faster
> than the generic code. For example, on an ARMv7 processor we observe
> the following performance with Speck128/256-XTS:
>
> xts-speck128-neon: Encryption 107.9 MB/s, Decryption 108.1 MB/s
> xts(speck128-generic): Encryption 32.1 MB/s, Decryption 36.6 MB/s
>
> In comparison to AES-256-XTS without the Cryptography Extensions:
>
> xts-aes-neonbs: Encryption 41.2 MB/s, Decryption 36.7 MB/s
> xts(aes-asm): Encryption 31.7 MB/s, Decryption 30.8 MB/s
> xts(aes-generic): Encryption 21.2 MB/s, Decryption 20.9 MB/s
>
> Speck64/128-XTS is even faster:
>
> xts-speck64-neon: Encryption 138.6 MB/s, Decryption 139.1 MB/s
>
> Note that as with the generic code, only the Speck128 and Speck64
> variants are supported. Also, for now only the XTS mode of operation is
> supported, to target the disk and file encryption use cases. The NEON
> code also only handles the portion of the data that is evenly divisible
> into 128-byte chunks, with any remainder handled by a C fallback. Of
> course, other modes of operation could be added later if needed, and/or
> the NEON code could be updated to handle other buffer sizes.
>
> The XTS specification is only defined for AES which has a 128-bit block
> size, so for the GF(2^64) math needed for Speck64-XTS we use the
> reducing polynomial 'x^64 + x^4 + x^3 + x + 1' given by the original XEX
> paper. Of course, when possible users should use Speck128-XTS, but even
> that may be too slow on some processors; Speck64-XTS can be faster.
>
> Signed-off-by: Eric Biggers <ebiggers@google.com>
> ---
> arch/arm/crypto/Kconfig | 6 +
> arch/arm/crypto/Makefile | 2 +
> arch/arm/crypto/speck-neon-core.S | 432 ++++++++++++++++++++++++++++++
> arch/arm/crypto/speck-neon-glue.c | 288 ++++++++++++++++++++
> 4 files changed, 728 insertions(+)
> create mode 100644 arch/arm/crypto/speck-neon-core.S
> create mode 100644 arch/arm/crypto/speck-neon-glue.c
>
> diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig
> index b8e69fe282b8..925d1364727a 100644
> --- a/arch/arm/crypto/Kconfig
> +++ b/arch/arm/crypto/Kconfig
> @@ -121,4 +121,10 @@ config CRYPTO_CHACHA20_NEON
> select CRYPTO_BLKCIPHER
> select CRYPTO_CHACHA20
>
> +config CRYPTO_SPECK_NEON
> + tristate "NEON accelerated Speck cipher algorithms"
> + depends on KERNEL_MODE_NEON
> + select CRYPTO_BLKCIPHER
> + select CRYPTO_SPECK
> +
> endif
> diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
> index 30ef8e291271..a758107c5525 100644
> --- a/arch/arm/crypto/Makefile
> +++ b/arch/arm/crypto/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
> obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
> obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o
> obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha20-neon.o
> +obj-$(CONFIG_CRYPTO_SPECK_NEON) += speck-neon.o
>
> ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
> ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
> @@ -53,6 +54,7 @@ ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o
> crct10dif-arm-ce-y := crct10dif-ce-core.o crct10dif-ce-glue.o
> crc32-arm-ce-y:= crc32-ce-core.o crc32-ce-glue.o
> chacha20-neon-y := chacha20-neon-core.o chacha20-neon-glue.o
> +speck-neon-y := speck-neon-core.o speck-neon-glue.o
>
> quiet_cmd_perl = PERL $@
> cmd_perl = $(PERL) $(<) > $(@)
> diff --git a/arch/arm/crypto/speck-neon-core.S
> b/arch/arm/crypto/speck-neon-core.S
> new file mode 100644
> index 000000000000..3c1e203e53b9
> --- /dev/null
> +++ b/arch/arm/crypto/speck-neon-core.S
> @@ -0,0 +1,432 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
> + *
> + * Copyright (c) 2018 Google, Inc
> + *
> + * Author: Eric Biggers <ebiggers@google.com>
> + */
> +
> +#include <linux/linkage.h>
> +
> + .text
> + .fpu neon
> +
> + // arguments
> + ROUND_KEYS .req r0 // const {u64,u32} *round_keys
> + NROUNDS .req r1 // int nrounds
> + DST .req r2 // void *dst
> + SRC .req r3 // const void *src
> + NBYTES .req r4 // unsigned int nbytes
> + TWEAK .req r5 // void *tweak
> +
> + // registers which hold the data being encrypted/decrypted
> + X0 .req q0
> + X0_L .req d0
> + X0_H .req d1
> + Y0 .req q1
> + Y0_H .req d3
> + X1 .req q2
> + X1_L .req d4
> + X1_H .req d5
> + Y1 .req q3
> + Y1_H .req d7
> + X2 .req q4
> + X2_L .req d8
> + X2_H .req d9
> + Y2 .req q5
> + Y2_H .req d11
> + X3 .req q6
> + X3_L .req d12
> + X3_H .req d13
> + Y3 .req q7
> + Y3_H .req d15
> +
> + // the round key, duplicated in all lanes
> + ROUND_KEY .req q8
> + ROUND_KEY_L .req d16
> + ROUND_KEY_H .req d17
> +
> + // index vector for vtbl-based 8-bit rotates
> + ROTATE_TABLE .req d18
> +
> + // multiplication table for updating XTS tweaks
> + GF128MUL_TABLE .req d19
> + GF64MUL_TABLE .req d19
> +
> + // current XTS tweak value(s)
> + TWEAKV .req q10
> + TWEAKV_L .req d20
> + TWEAKV_H .req d21
> +
> + TMP0 .req q12
> + TMP0_L .req d24
> + TMP0_H .req d25
> + TMP1 .req q13
> + TMP2 .req q14
> + TMP3 .req q15
> +
> + .align 4
> +.Lror64_8_table:
> + .byte 1, 2, 3, 4, 5, 6, 7, 0
> +.Lror32_8_table:
> + .byte 1, 2, 3, 0, 5, 6, 7, 4
> +.Lrol64_8_table:
> + .byte 7, 0, 1, 2, 3, 4, 5, 6
> +.Lrol32_8_table:
> + .byte 3, 0, 1, 2, 7, 4, 5, 6
> +.Lgf128mul_table:
> + .byte 0, 0x87
> + .fill 14
> +.Lgf64mul_table:
> + .byte 0, 0x1b, (0x1b << 1), (0x1b << 1) ^ 0x1b
> + .fill 12
> +
> +/*
> + * _speck_round_128bytes() - Speck encryption round on 128 bytes at a time
> + *
> + * Do one Speck encryption round on the 128 bytes (8 blocks for
> Speck128, 16 for
> + * Speck64) stored in X0-X3 and Y0-Y3, using the round key stored in all lanes
> + * of ROUND_KEY. 'n' is the lane size: 64 for Speck128, or 32 for Speck64.
> + *
> + * The 8-bit rotates are implemented using vtbl instead of vshr + vsli because
> + * the vtbl approach is faster on some processors and the same speed on others.
> + */
> +.macro _speck_round_128bytes n
> +
> + // x = ror(x, 8)
> + vtbl.8 X0_L, {X0_L}, ROTATE_TABLE
> + vtbl.8 X0_H, {X0_H}, ROTATE_TABLE
> + vtbl.8 X1_L, {X1_L}, ROTATE_TABLE
> + vtbl.8 X1_H, {X1_H}, ROTATE_TABLE
> + vtbl.8 X2_L, {X2_L}, ROTATE_TABLE
> + vtbl.8 X2_H, {X2_H}, ROTATE_TABLE
> + vtbl.8 X3_L, {X3_L}, ROTATE_TABLE
> + vtbl.8 X3_H, {X3_H}, ROTATE_TABLE
> +
> + // x += y
> + vadd.u\n X0, Y0
> + vadd.u\n X1, Y1
> + vadd.u\n X2, Y2
> + vadd.u\n X3, Y3
> +
> + // x ^= k
> + veor X0, ROUND_KEY
> + veor X1, ROUND_KEY
> + veor X2, ROUND_KEY
> + veor X3, ROUND_KEY
> +
> + // y = rol(y, 3)
> + vshl.u\n TMP0, Y0, #3
> + vshl.u\n TMP1, Y1, #3
> + vshl.u\n TMP2, Y2, #3
> + vshl.u\n TMP3, Y3, #3
> + vsri.u\n TMP0, Y0, #(\n - 3)
> + vsri.u\n TMP1, Y1, #(\n - 3)
> + vsri.u\n TMP2, Y2, #(\n - 3)
> + vsri.u\n TMP3, Y3, #(\n - 3)
> +
> + // y ^= x
> + veor Y0, TMP0, X0
> + veor Y1, TMP1, X1
> + veor Y2, TMP2, X2
> + veor Y3, TMP3, X3
> +.endm
> +
> +/*
> + * _speck_unround_128bytes() - Speck decryption round on 128 bytes at a time
> + *
> + * This is the inverse of _speck_round_128bytes().
> + */
> +.macro _speck_unround_128bytes n
> +
> + // y ^= x
> + veor TMP0, Y0, X0
> + veor TMP1, Y1, X1
> + veor TMP2, Y2, X2
> + veor TMP3, Y3, X3
> +
> + // y = ror(y, 3)
> + vshr.u\n Y0, TMP0, #3
> + vshr.u\n Y1, TMP1, #3
> + vshr.u\n Y2, TMP2, #3
> + vshr.u\n Y3, TMP3, #3
> + vsli.u\n Y0, TMP0, #(\n - 3)
> + vsli.u\n Y1, TMP1, #(\n - 3)
> + vsli.u\n Y2, TMP2, #(\n - 3)
> + vsli.u\n Y3, TMP3, #(\n - 3)
> +
> + // x ^= k
> + veor X0, ROUND_KEY
> + veor X1, ROUND_KEY
> + veor X2, ROUND_KEY
> + veor X3, ROUND_KEY
> +
> + // x -= y
> + vsub.u\n X0, Y0
> + vsub.u\n X1, Y1
> + vsub.u\n X2, Y2
> + vsub.u\n X3, Y3
> +
> + // x = rol(x, 8);
> + vtbl.8 X0_L, {X0_L}, ROTATE_TABLE
> + vtbl.8 X0_H, {X0_H}, ROTATE_TABLE
> + vtbl.8 X1_L, {X1_L}, ROTATE_TABLE
> + vtbl.8 X1_H, {X1_H}, ROTATE_TABLE
> + vtbl.8 X2_L, {X2_L}, ROTATE_TABLE
> + vtbl.8 X2_H, {X2_H}, ROTATE_TABLE
> + vtbl.8 X3_L, {X3_L}, ROTATE_TABLE
> + vtbl.8 X3_H, {X3_H}, ROTATE_TABLE
> +.endm
> +
> +.macro _xts128_precrypt_one dst_reg, tweak_buf, tmp
> +
> + // Load the next source block
> + vld1.8 {\dst_reg}, [SRC]!
> +
> + // Save the current tweak in the tweak buffer
> + vst1.8 {TWEAKV}, [\tweak_buf:128]!
> +
> + // XOR the next source block with the current tweak
> + veor \dst_reg, TWEAKV
> +
> + /*
> + * Calculate the next tweak by multiplying the current one by x,
> + * modulo p(x) = x^128 + x^7 + x^2 + x + 1.
> + */
> + vshr.u64 \tmp, TWEAKV, #63
> + vshl.u64 TWEAKV, #1
> + veor TWEAKV_H, \tmp\()_L
> + vtbl.8 \tmp\()_H, {GF128MUL_TABLE}, \tmp\()_H
> + veor TWEAKV_L, \tmp\()_H
> +.endm
> +
> +.macro _xts64_precrypt_two dst_reg, tweak_buf, tmp
> +
> + // Load the next two source blocks
> + vld1.8 {\dst_reg}, [SRC]!
> +
> + // Save the current two tweaks in the tweak buffer
> + vst1.8 {TWEAKV}, [\tweak_buf:128]!
> +
> + // XOR the next two source blocks with the current two tweaks
> + veor \dst_reg, TWEAKV
> +
> + /*
> + * Calculate the next two tweaks by multiplying the current ones by x^2,
> + * modulo p(x) = x^64 + x^4 + x^3 + x + 1.
> + */
> + vshr.u64 \tmp, TWEAKV, #62
> + vshl.u64 TWEAKV, #2
> + vtbl.8 \tmp\()_L, {GF64MUL_TABLE}, \tmp\()_L
> + vtbl.8 \tmp\()_H, {GF64MUL_TABLE}, \tmp\()_H
> + veor TWEAKV, \tmp
> +.endm
> +
> +/*
> + * _speck_xts_crypt() - Speck-XTS encryption/decryption
> + *
> + * Encrypt or decrypt NBYTES bytes of data from the SRC buffer to the
> DST buffer
> + * using Speck-XTS, specifically the variant with a block size of
> '2n' and round
> + * count given by NROUNDS. The expanded round keys are given in
> ROUND_KEYS, and
> + * the current XTS tweak value is given in TWEAK. It's assumed that
> NBYTES is a
> + * nonzero multiple of 128.
> + */
> +.macro _speck_xts_crypt n, decrypting
> + push {r4-r7}
> + mov r7, sp
> +
> + /*
> + * The first four parameters were passed in registers r0-r3. Load the
> + * additional parameters, which were passed on the stack.
> + */
> + ldr NBYTES, [sp, #16]
> + ldr TWEAK, [sp, #20]
> +
> + /*
> + * If decrypting, modify the ROUND_KEYS parameter to point to the last
> + * round key rather than the first, since for decryption the round keys
> + * are used in reverse order.
> + */
> +.if \decrypting
> +.if \n == 64
> + add ROUND_KEYS, ROUND_KEYS, NROUNDS, lsl #3
> + sub ROUND_KEYS, #8
> +.else
> + add ROUND_KEYS, ROUND_KEYS, NROUNDS, lsl #2
> + sub ROUND_KEYS, #4
> +.endif
> +.endif
> +
> + // Load the index vector for vtbl-based 8-bit rotates
> +.if \decrypting
> + ldr r12, =.Lrol\n\()_8_table
> +.else
> + ldr r12, =.Lror\n\()_8_table
> +.endif
> + vld1.8 {ROTATE_TABLE}, [r12:64]
> +
> + // One-time XTS preparation
> +
> + /*
> + * Allocate stack space to store 128 bytes worth of tweaks. For
> + * performance, this space is aligned to a 16-byte boundary so that we
> + * can use the load/store instructions that declare 16-byte alignment.
> + */
> + sub sp, #128
> + bic sp, #0xf
This fails here when building with CONFIG_THUMB2_KERNEL=y
AS arch/arm/crypto/speck-neon-core.o
arch/arm/crypto/speck-neon-core.S: Assembler messages:
arch/arm/crypto/speck-neon-core.S:419: Error: r13 not allowed here --
`bic sp,#0xf'
arch/arm/crypto/speck-neon-core.S:423: Error: r13 not allowed here --
`bic sp,#0xf'
arch/arm/crypto/speck-neon-core.S:427: Error: r13 not allowed here --
`bic sp,#0xf'
arch/arm/crypto/speck-neon-core.S:431: Error: r13 not allowed here --
`bic sp,#0xf'
In a quick hack this change seems to address it:
- sub sp, #128
- bic sp, #0xf
+ mov r6, sp
+ sub r6, #128
+ bic r6, #0xf
+ mov sp, r6
But there is probably a better solution to address this.
--
Stefan
> +
> +.if \n == 64
> + // Load first tweak
> + vld1.8 {TWEAKV}, [TWEAK]
> +
> + // Load GF(2^128) multiplication table
> + ldr r12, =.Lgf128mul_table
> + vld1.8 {GF128MUL_TABLE}, [r12:64]
> +.else
> + // Load first tweak
> + vld1.8 {TWEAKV_L}, [TWEAK]
> +
> + // Load GF(2^64) multiplication table
> + ldr r12, =.Lgf64mul_table
> + vld1.8 {GF64MUL_TABLE}, [r12:64]
> +
> + // Calculate second tweak, packing it together with the first
> + vshr.u64 TMP0_L, TWEAKV_L, #63
> + vtbl.u8 TMP0_L, {GF64MUL_TABLE}, TMP0_L
> + vshl.u64 TWEAKV_H, TWEAKV_L, #1
> + veor TWEAKV_H, TMP0_L
> +.endif
> +
> +.Lnext_128bytes_\@:
> +
> + /*
> + * Load the source blocks into {X,Y}[0-3], XOR them with their XTS tweak
> + * values, and save the tweaks on the stack for later. Then
> + * de-interleave the 'x' and 'y' elements of each block, i.e. make it so
> + * that the X[0-3] registers contain only the second halves of blocks,
> + * and the Y[0-3] registers contain only the first halves of blocks.
> + * (Speck uses the order (y, x) rather than the more intuitive (x, y).)
> + */
> + mov r12, sp
> +.if \n == 64
> + _xts128_precrypt_one X0, r12, TMP0
> + _xts128_precrypt_one Y0, r12, TMP0
> + _xts128_precrypt_one X1, r12, TMP0
> + _xts128_precrypt_one Y1, r12, TMP0
> + _xts128_precrypt_one X2, r12, TMP0
> + _xts128_precrypt_one Y2, r12, TMP0
> + _xts128_precrypt_one X3, r12, TMP0
> + _xts128_precrypt_one Y3, r12, TMP0
> + vswp X0_L, Y0_H
> + vswp X1_L, Y1_H
> + vswp X2_L, Y2_H
> + vswp X3_L, Y3_H
> +.else
> + _xts64_precrypt_two X0, r12, TMP0
> + _xts64_precrypt_two Y0, r12, TMP0
> + _xts64_precrypt_two X1, r12, TMP0
> + _xts64_precrypt_two Y1, r12, TMP0
> + _xts64_precrypt_two X2, r12, TMP0
> + _xts64_precrypt_two Y2, r12, TMP0
> + _xts64_precrypt_two X3, r12, TMP0
> + _xts64_precrypt_two Y3, r12, TMP0
> + vuzp.32 Y0, X0
> + vuzp.32 Y1, X1
> + vuzp.32 Y2, X2
> + vuzp.32 Y3, X3
> +.endif
> +
> + // Do the cipher rounds
> +
> + mov r12, ROUND_KEYS
> + mov r6, NROUNDS
> +
> +.Lnext_round_\@:
> +.if \decrypting
> +.if \n == 64
> + vld1.64 ROUND_KEY_L, [r12]
> + sub r12, #8
> + vmov ROUND_KEY_H, ROUND_KEY_L
> +.else
> + vld1.32 {ROUND_KEY_L[],ROUND_KEY_H[]}, [r12]
> + sub r12, #4
> +.endif
> + _speck_unround_128bytes \n
> +.else
> +.if \n == 64
> + vld1.64 ROUND_KEY_L, [r12]!
> + vmov ROUND_KEY_H, ROUND_KEY_L
> +.else
> + vld1.32 {ROUND_KEY_L[],ROUND_KEY_H[]}, [r12]!
> +.endif
> + _speck_round_128bytes \n
> +.endif
> + subs r6, r6, #1
> + bne .Lnext_round_\@
> +
> + // Re-interleave the 'x' and 'y' elements of each block
> +.if \n == 64
> + vswp X0_L, Y0_H
> + vswp X1_L, Y1_H
> + vswp X2_L, Y2_H
> + vswp X3_L, Y3_H
> +.else
> + vzip.32 Y0, X0
> + vzip.32 Y1, X1
> + vzip.32 Y2, X2
> + vzip.32 Y3, X3
> +.endif
> +
> + // XOR the encrypted/decrypted blocks with the tweaks we saved earlier
> + mov r12, sp
> + vld1.8 {TMP0, TMP1}, [r12:128]!
> + vld1.8 {TMP2, TMP3}, [r12:128]!
> + veor X0, TMP0
> + veor Y0, TMP1
> + veor X1, TMP2
> + veor Y1, TMP3
> + vld1.8 {TMP0, TMP1}, [r12:128]!
> + vld1.8 {TMP2, TMP3}, [r12:128]!
> + veor X2, TMP0
> + veor Y2, TMP1
> + veor X3, TMP2
> + veor Y3, TMP3
> +
> + // Store the ciphertext in the destination buffer
> + vst1.8 {X0, Y0}, [DST]!
> + vst1.8 {X1, Y1}, [DST]!
> + vst1.8 {X2, Y2}, [DST]!
> + vst1.8 {X3, Y3}, [DST]!
> +
> + // Continue if there are more 128-byte chunks remaining, else return
> + subs NBYTES, #128
> + bne .Lnext_128bytes_\@
> +
> + // Store the next tweak
> +.if \n == 64
> + vst1.8 {TWEAKV}, [TWEAK]
> +.else
> + vst1.8 {TWEAKV_L}, [TWEAK]
> +.endif
> +
> + mov sp, r7
> + pop {r4-r7}
> + bx lr
> +.endm
> +
> +ENTRY(speck128_xts_encrypt_neon)
> + _speck_xts_crypt n=64, decrypting=0
> +ENDPROC(speck128_xts_encrypt_neon)
> +
> +ENTRY(speck128_xts_decrypt_neon)
> + _speck_xts_crypt n=64, decrypting=1
> +ENDPROC(speck128_xts_decrypt_neon)
> +
> +ENTRY(speck64_xts_encrypt_neon)
> + _speck_xts_crypt n=32, decrypting=0
> +ENDPROC(speck64_xts_encrypt_neon)
> +
> +ENTRY(speck64_xts_decrypt_neon)
> + _speck_xts_crypt n=32, decrypting=1
> +ENDPROC(speck64_xts_decrypt_neon)
> diff --git a/arch/arm/crypto/speck-neon-glue.c
> b/arch/arm/crypto/speck-neon-glue.c
> new file mode 100644
> index 000000000000..f012c3ea998f
> --- /dev/null
> +++ b/arch/arm/crypto/speck-neon-glue.c
> @@ -0,0 +1,288 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
> + *
> + * Copyright (c) 2018 Google, Inc
> + *
> + * Note: the NIST recommendation for XTS only specifies a 128-bit block size,
> + * but a 64-bit version (needed for Speck64) is fairly
> straightforward; the math
> + * is just done in GF(2^64) instead of GF(2^128), with the reducing polynomial
> + * x^64 + x^4 + x^3 + x + 1 from the original XEX paper (Rogaway, 2004:
> + * "Efficient Instantiations of Tweakable Blockciphers and Refinements to Modes
> + * OCB and PMAC"), represented as 0x1B.
> + */
> +
> +#include <asm/hwcap.h>
> +#include <asm/neon.h>
> +#include <asm/simd.h>
> +#include <crypto/algapi.h>
> +#include <crypto/gf128mul.h>
> +#include <crypto/internal/skcipher.h>
> +#include <crypto/speck.h>
> +#include <crypto/xts.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +/* The assembly functions only handle multiples of 128 bytes */
> +#define SPECK_NEON_CHUNK_SIZE 128
> +
> +/* Speck128 */
> +
> +struct speck128_xts_tfm_ctx {
> + struct speck128_tfm_ctx main_key;
> + struct speck128_tfm_ctx tweak_key;
> +};
> +
> +asmlinkage void speck128_xts_encrypt_neon(const u64 *round_keys, int nrounds,
> + void *dst, const void *src,
> + unsigned int nbytes, void *tweak);
> +
> +asmlinkage void speck128_xts_decrypt_neon(const u64 *round_keys, int nrounds,
> + void *dst, const void *src,
> + unsigned int nbytes, void *tweak);
> +
> +typedef void (*speck128_crypt_one_t)(const struct speck128_tfm_ctx *,
> + u8 *, const u8 *);
> +typedef void (*speck128_xts_crypt_many_t)(const u64 *, int, void *,
> + const void *, unsigned int, void *);
> +
> +static __always_inline int
> +__speck128_xts_crypt(struct skcipher_request *req,
> + speck128_crypt_one_t crypt_one,
> + speck128_xts_crypt_many_t crypt_many)
> +{
> + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> + const struct speck128_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
> + struct skcipher_walk walk;
> + le128 tweak;
> + int err;
> +
> + err = skcipher_walk_virt(&walk, req, true);
> +
> + crypto_speck128_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
> +
> + while (walk.nbytes > 0) {
> + unsigned int nbytes = walk.nbytes;
> + u8 *dst = walk.dst.virt.addr;
> + const u8 *src = walk.src.virt.addr;
> +
> + if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
> + unsigned int count;
> +
> + count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
> + kernel_neon_begin();
> + (*crypt_many)(ctx->main_key.round_keys,
> + ctx->main_key.nrounds,
> + dst, src, count, &tweak);
> + kernel_neon_end();
> + dst += count;
> + src += count;
> + nbytes -= count;
> + }
> +
> + /* Handle any remainder with generic code */
> + while (nbytes >= sizeof(tweak)) {
> + le128_xor((le128 *)dst, (const le128 *)src, &tweak);
> + (*crypt_one)(&ctx->main_key, dst, dst);
> + le128_xor((le128 *)dst, (const le128 *)dst, &tweak);
> + gf128mul_x_ble(&tweak, &tweak);
> +
> + dst += sizeof(tweak);
> + src += sizeof(tweak);
> + nbytes -= sizeof(tweak);
> + }
> + err = skcipher_walk_done(&walk, nbytes);
> + }
> +
> + return err;
> +}
> +
> +static int speck128_xts_encrypt(struct skcipher_request *req)
> +{
> + return __speck128_xts_crypt(req, crypto_speck128_encrypt,
> + speck128_xts_encrypt_neon);
> +}
> +
> +static int speck128_xts_decrypt(struct skcipher_request *req)
> +{
> + return __speck128_xts_crypt(req, crypto_speck128_decrypt,
> + speck128_xts_decrypt_neon);
> +}
> +
> +static int speck128_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
> + unsigned int keylen)
> +{
> + struct speck128_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
> + int err;
> +
> + err = xts_verify_key(tfm, key, keylen);
> + if (err)
> + return err;
> +
> + keylen /= 2;
> +
> + err = crypto_speck128_setkey(&ctx->main_key, key, keylen);
> + if (err)
> + return err;
> +
> + return crypto_speck128_setkey(&ctx->tweak_key, key + keylen, keylen);
> +}
> +
> +/* Speck64 */
> +
> +struct speck64_xts_tfm_ctx {
> + struct speck64_tfm_ctx main_key;
> + struct speck64_tfm_ctx tweak_key;
> +};
> +
> +asmlinkage void speck64_xts_encrypt_neon(const u32 *round_keys, int nrounds,
> + void *dst, const void *src,
> + unsigned int nbytes, void *tweak);
> +
> +asmlinkage void speck64_xts_decrypt_neon(const u32 *round_keys, int nrounds,
> + void *dst, const void *src,
> + unsigned int nbytes, void *tweak);
> +
> +typedef void (*speck64_crypt_one_t)(const struct speck64_tfm_ctx *,
> + u8 *, const u8 *);
> +typedef void (*speck64_xts_crypt_many_t)(const u32 *, int, void *,
> + const void *, unsigned int, void *);
> +
> +static __always_inline int
> +__speck64_xts_crypt(struct skcipher_request *req, speck64_crypt_one_t
> crypt_one,
> + speck64_xts_crypt_many_t crypt_many)
> +{
> + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> + const struct speck64_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
> + struct skcipher_walk walk;
> + __le64 tweak;
> + int err;
> +
> + err = skcipher_walk_virt(&walk, req, true);
> +
> + crypto_speck64_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
> +
> + while (walk.nbytes > 0) {
> + unsigned int nbytes = walk.nbytes;
> + u8 *dst = walk.dst.virt.addr;
> + const u8 *src = walk.src.virt.addr;
> +
> + if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
> + unsigned int count;
> +
> + count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
> + kernel_neon_begin();
> + (*crypt_many)(ctx->main_key.round_keys,
> + ctx->main_key.nrounds,
> + dst, src, count, &tweak);
> + kernel_neon_end();
> + dst += count;
> + src += count;
> + nbytes -= count;
> + }
> +
> + /* Handle any remainder with generic code */
> + while (nbytes >= sizeof(tweak)) {
> + *(__le64 *)dst = *(__le64 *)src ^ tweak;
> + (*crypt_one)(&ctx->main_key, dst, dst);
> + *(__le64 *)dst ^= tweak;
> + tweak = cpu_to_le64((le64_to_cpu(tweak) << 1) ^
> + ((tweak & cpu_to_le64(1ULL << 63)) ?
> + 0x1B : 0));
> + dst += sizeof(tweak);
> + src += sizeof(tweak);
> + nbytes -= sizeof(tweak);
> + }
> + err = skcipher_walk_done(&walk, nbytes);
> + }
> +
> + return err;
> +}
> +
> +static int speck64_xts_encrypt(struct skcipher_request *req)
> +{
> + return __speck64_xts_crypt(req, crypto_speck64_encrypt,
> + speck64_xts_encrypt_neon);
> +}
> +
> +static int speck64_xts_decrypt(struct skcipher_request *req)
> +{
> + return __speck64_xts_crypt(req, crypto_speck64_decrypt,
> + speck64_xts_decrypt_neon);
> +}
> +
> +static int speck64_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
> + unsigned int keylen)
> +{
> + struct speck64_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
> + int err;
> +
> + err = xts_verify_key(tfm, key, keylen);
> + if (err)
> + return err;
> +
> + keylen /= 2;
> +
> + err = crypto_speck64_setkey(&ctx->main_key, key, keylen);
> + if (err)
> + return err;
> +
> + return crypto_speck64_setkey(&ctx->tweak_key, key + keylen, keylen);
> +}
> +
> +static struct skcipher_alg speck_algs[] = {
> + {
> + .base.cra_name = "xts(speck128)",
> + .base.cra_driver_name = "xts-speck128-neon",
> + .base.cra_priority = 300,
> + .base.cra_blocksize = SPECK128_BLOCK_SIZE,
> + .base.cra_ctxsize = sizeof(struct speck128_xts_tfm_ctx),
> + .base.cra_alignmask = 7,
> + .base.cra_module = THIS_MODULE,
> + .min_keysize = 2 * SPECK128_128_KEY_SIZE,
> + .max_keysize = 2 * SPECK128_256_KEY_SIZE,
> + .ivsize = SPECK128_BLOCK_SIZE,
> + .walksize = SPECK_NEON_CHUNK_SIZE,
> + .setkey = speck128_xts_setkey,
> + .encrypt = speck128_xts_encrypt,
> + .decrypt = speck128_xts_decrypt,
> + }, {
> + .base.cra_name = "xts(speck64)",
> + .base.cra_driver_name = "xts-speck64-neon",
> + .base.cra_priority = 300,
> + .base.cra_blocksize = SPECK64_BLOCK_SIZE,
> + .base.cra_ctxsize = sizeof(struct speck64_xts_tfm_ctx),
> + .base.cra_alignmask = 7,
> + .base.cra_module = THIS_MODULE,
> + .min_keysize = 2 * SPECK64_96_KEY_SIZE,
> + .max_keysize = 2 * SPECK64_128_KEY_SIZE,
> + .ivsize = SPECK64_BLOCK_SIZE,
> + .walksize = SPECK_NEON_CHUNK_SIZE,
> + .setkey = speck64_xts_setkey,
> + .encrypt = speck64_xts_encrypt,
> + .decrypt = speck64_xts_decrypt,
> + }
> +};
> +
> +static int __init speck_neon_module_init(void)
> +{
> + if (!(elf_hwcap & HWCAP_NEON))
> + return -ENODEV;
> + return crypto_register_skciphers(speck_algs, ARRAY_SIZE(speck_algs));
> +}
> +
> +static void __exit speck_neon_module_exit(void)
> +{
> + crypto_unregister_skciphers(speck_algs, ARRAY_SIZE(speck_algs));
> +}
> +
> +module_init(speck_neon_module_init);
> +module_exit(speck_neon_module_exit);
> +
> +MODULE_DESCRIPTION("Speck block cipher (NEON-accelerated)");
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
> +MODULE_ALIAS_CRYPTO("xts(speck128)");
> +MODULE_ALIAS_CRYPTO("xts-speck128-neon");
> +MODULE_ALIAS_CRYPTO("xts(speck64)");
> +MODULE_ALIAS_CRYPTO("xts-speck64-neon");
^ permalink raw reply
* [RFC PATCH] iio: adc: at91-sama5d2_adc: add support for oversampling resolution
From: Jonathan Cameron @ 2018-06-16 17:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528699954-2353-1-git-send-email-eugen.hristev@microchip.com>
On Mon, 11 Jun 2018 09:52:34 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> This is implements oversampling support for the SAMA5D2 ADC
> device.
> Enabling oversampling : OSR can improve resolution from 12 bits to
> 13 or 14 bits.
> To not modify the scan element of the buffer , from 12 bits to 13 or 14,
> I have added the extra bit(s) as MICRO values to the INT value from the
> conversion.
> Special care was required for the triggered buffer scenario (+ DMA).
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
> Hello Jonathan,
>
> I marked this patch as RFC because I am not confident in the best way to handle
> this oversampling support.
>
> I modified the return value of the channels to use IIO_VALUE_INT_PLUS_MICRO
> instead of IIO_VALUE_INT, so I can add an extra bit or two bits in there to the
> INT value (0/500000 or 0/250000/500000/7500000) .
> You know of a better way to add this support?
> Looks like the iio channel spec cannot be modified at
> runtime. Would be best if the real bits in the channel spec would be changed to
> 13 or 14, but then, the buffer would be confused, as the buffer spec is now
> le:u12/16>>0 so how can I change that to reflect oversampling, or,
> IIO_VALUE_INT_PLUS_MICRO ?
> And I am not sure how to handle this w.r.t ABI and userspace changes.
Hmm. Yes, that rigidity in buffer formatting is sometimes a pain. One day
we should look at relaxing it. I did look at it a long time ago but it looked
really fiddly to actually do.
>
> At this moment I added the micro values just to the software trigger readings,
> and triggered buffer + DMA does not provide the extra bits, but, I need
> to shift all values with 2 bits to the right . The code is rather ugly
> right now, but I can change it to look prettier if this is the proper way
> to do it.
So if we were doing this from scratch (i.e. new driver) then it would be easy.
you'd do the opposite - report it as a 14bit channel at all times and shift it
left (0 fill) if not supplying 14bits due to lower oversampling ratios.
Now the risk is some userspace code isn't actually reading the description
but is assuming the buffer entry is 12 bits. I would hope that no one
is doing that (as generic code would be checking correctly) so perhaps we
can get away with making that change? That would mean also adjusting
the scale value and sticking to integer output in sysfs (appropriately
scaled when only 12 bits etc actually there).
Given what you have here is an ABI change anyway, I'd just go for it
and declare it to always be 14bits. It would be valid if you want
to not rescale the sysfs values at all, but instead adjust the 'scale'
as the oversampling changes - either is valid under the ABI.
Btw nicely designed hw doing overscaling does the shift for you
(i.e. it's the least sig bits that are just 0 when no oversampling).
Makes the SW easy and means you've already gotten the placement right
before you get to implementing oversampling.
>
> Thanks for all the feedback,
> Eugen
>
>
> drivers/iio/adc/at91-sama5d2_adc.c | 198 ++++++++++++++++++++++++++++++++-----
> 1 file changed, 172 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 58c4c2b..f1a89b7 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -130,6 +130,15 @@
> #define AT91_SAMA5D2_OVER 0x3c
> /* Extended Mode Register */
> #define AT91_SAMA5D2_EMR 0x40
> +/* Extended Mode Register - Oversampling rate */
> +#define AT91_SAMA5D2_EMR_OSR(V) ((V) << 16)
> +#define AT91_SAMA5D2_EMR_OSR_MASK GENMASK(17, 16)
> +#define AT91_SAMA5D2_EMR_OSR_0SAMPLES 0
> +#define AT91_SAMA5D2_EMR_OSR_4SAMPLES 1
> +#define AT91_SAMA5D2_EMR_OSR_16SAMPLES 2
> +
> +/* Extended Mode Register - Averaging on single trigger event */
> +#define AT91_SAMA5D2_EMR_ASTE(V) ((V) << 20)
> /* Compare Window Register */
> #define AT91_SAMA5D2_CWR 0x44
> /* Channel Gain Register */
> @@ -248,6 +257,14 @@
> #define AT91_HWFIFO_MAX_SIZE_STR "128"
> #define AT91_HWFIFO_MAX_SIZE 128
>
> +/* Possible values for oversampling ratio, and the string equivalent */
> +#define AT91_OSR_0SAMPLES 0
> +#define AT91_OSR_0SAMPLES_STR "0"
> +#define AT91_OSR_4SAMPLES 4
> +#define AT91_OSR_4SAMPLES_STR "4"
> +#define AT91_OSR_16SAMPLES 16
> +#define AT91_OSR_16SAMPLES_STR "16"
> +
> #define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \
> { \
> .type = IIO_VOLTAGE, \
> @@ -261,7 +278,8 @@
> }, \
> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
> + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ)|\
> + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
> .datasheet_name = "CH"#num, \
> .indexed = 1, \
> }
> @@ -281,7 +299,8 @@
> }, \
> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
> + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ)|\
> + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
> .datasheet_name = "CH"#num"-CH"#num2, \
> .indexed = 1, \
> }
> @@ -299,7 +318,8 @@
> .storagebits = 16, \
> }, \
> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
> + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ)|\
> + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
> .datasheet_name = name, \
> }
> #define AT91_SAMA5D2_CHAN_PRESSURE(num, name) \
> @@ -313,7 +333,8 @@
> .storagebits = 16, \
> }, \
> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
> + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ)|\
> + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
> .datasheet_name = name, \
> }
>
> @@ -384,6 +405,7 @@ struct at91_adc_state {
> const struct iio_chan_spec *chan;
> bool conversion_done;
> u32 conversion_value;
> + unsigned int oversampling_ratio;
> struct at91_adc_soc_info soc_info;
> wait_queue_head_t wq_data_available;
> struct at91_adc_dma dma_st;
> @@ -475,6 +497,76 @@ static inline int at91_adc_of_xlate(struct iio_dev *indio_dev,
> return at91_adc_chan_xlate(indio_dev, iiospec->args[0]);
> }
>
> +static void at91_adc_config_emr(struct at91_adc_state *st)
> +{
> + /* configure the extended mode register */
> + unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
> +
> + /* select oversampling per single trigger event */
> + emr |= AT91_SAMA5D2_EMR_ASTE(1);
> +
> + /* delete leftover content if it's the case */
> + emr &= ~AT91_SAMA5D2_EMR_OSR_MASK;
> +
> + /* select oversampling ratio from configuration */
> + switch (st->oversampling_ratio) {
> + case AT91_OSR_0SAMPLES:
> + emr |= AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_0SAMPLES) &
> + AT91_SAMA5D2_EMR_OSR_MASK;
> + break;
> + case AT91_OSR_4SAMPLES:
> + emr |= AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_4SAMPLES) &
> + AT91_SAMA5D2_EMR_OSR_MASK;
> + break;
> + case AT91_OSR_16SAMPLES:
> + emr |= AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_16SAMPLES) &
> + AT91_SAMA5D2_EMR_OSR_MASK;
> + break;
> + };
> +
> + at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
> +}
> +
> +static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val,
> + int *val2)
> +{
> + u8 extra_bits;
> +
> + switch (st->oversampling_ratio) {
> + case AT91_OSR_4SAMPLES:
> + /* in this case we need to report 1 extra bit */
> + extra_bits = *val & 0x1;
> + if (extra_bits)
> + *val2 = 500000;
> + else
> + *val2 = 0;
> + *val >>= 1; /* keep just 12 bits */
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AT91_OSR_16SAMPLES:
> + /* in this case we need to report 2 extra bits */
> + extra_bits = *val & 0x3;
> + switch (extra_bits) {
> + case 0:
> + *val2 = 0;
> + break;
> + case 1:
> + *val2 = 250000;
> + break;
> + case 2:
> + *val2 = 500000;
> + break;
> + case 3:
> + *val2 = 750000;
> + break;
> + };
> + *val >>= 2; /* keep just 12 bits */
> + return IIO_VAL_INT_PLUS_MICRO;
> + };
> +
> + return IIO_VAL_INT;
> +}
> +
> static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> {
> u32 clk_khz = st->current_sample_rate / 1000;
> @@ -916,6 +1008,9 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> {
> struct at91_adc_state *st = iio_priv(indio_dev);
> int i = 0;
> + /* micro value for oversampling data */
> + int micro;
> + int val;
> u8 bit;
>
> for_each_set_bit(bit, indio_dev->active_scan_mask,
> @@ -936,7 +1031,9 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> * Thus, emit a warning.
> */
> if (chan->type == IIO_VOLTAGE) {
> - st->buffer[i] = at91_adc_readl(st, chan->address);
> + val = at91_adc_readl(st, chan->address);
> + at91_adc_adjust_val_osr(st, &val, µ);
> + st->buffer[i] = val;
> } else {
> st->buffer[i] = 0;
> WARN(true, "This trigger cannot handle this type of channel");
> @@ -954,6 +1051,9 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
> s64 ns = iio_get_time_ns(indio_dev);
> s64 interval;
> int sample_index = 0, sample_count, sample_size;
> + /* micro value for oversampling data */
> + int micro;
> + int val, j;
>
> u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> /* if we reached this point, we cannot sample faster */
> @@ -972,6 +1072,17 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
> interval = div_s64((ns - st->dma_st.dma_ts), sample_count);
>
> while (transferred_len >= sample_size) {
> + /*
> + * for all the values in the current sample,
> + * adjust the values inside the buffer for oversampling
> + */
> + for (j = 0; j < sample_size / 2; j++) {
> + /* buffer is byte-based. we need the whole value */
> + val = *((u16 *)&st->dma_st.rx_buf[st->dma_st.buf_idx + j * 2]);
> + at91_adc_adjust_val_osr(st, &val, µ);
> + *((u16 *)&st->dma_st.rx_buf[st->dma_st.buf_idx + j * 2]) = val;
> + }
> +
> iio_push_to_buffers_with_timestamp(indio_dev,
> (st->dma_st.rx_buf + st->dma_st.buf_idx),
> (st->dma_st.dma_ts + interval * sample_index));
> @@ -1190,8 +1301,10 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> return IRQ_HANDLED;
> }
>
> +
Tidy this up by not adding the line above.
> static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> - struct iio_chan_spec const *chan, int *val)
> + struct iio_chan_spec const *chan, int *val,
> + int *val2)
> {
> struct at91_adc_state *st = iio_priv(indio_dev);
> u32 cor = 0;
> @@ -1212,7 +1325,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> mutex_unlock(&st->lock);
> iio_device_release_direct_mode(indio_dev);
>
> - return ret;
> + return at91_adc_adjust_val_osr(st, val, val2);
> }
> if (chan->type == IIO_PRESSURE) {
> ret = iio_device_claim_direct_mode(indio_dev);
> @@ -1225,7 +1338,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> mutex_unlock(&st->lock);
> iio_device_release_direct_mode(indio_dev);
>
> - return ret;
> + return at91_adc_adjust_val_osr(st, val, val2);
> }
>
> /* in this case we have a voltage channel */
> @@ -1254,9 +1367,9 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>
> if (ret > 0) {
> *val = st->conversion_value;
> + ret = at91_adc_adjust_val_osr(st, val, val2);
> if (chan->scan_type.sign == 's')
> *val = sign_extend32(*val, 11);
> - ret = IIO_VAL_INT;
> st->conversion_done = false;
> }
>
> @@ -1280,7 +1393,7 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev,
>
> switch (mask) {
> case IIO_CHAN_INFO_RAW:
> - return at91_adc_read_info_raw(indio_dev, chan, val);
> + return at91_adc_read_info_raw(indio_dev, chan, val, val2);
> case IIO_CHAN_INFO_SCALE:
> *val = st->vref_uv / 1000;
> if (chan->differential)
> @@ -1292,6 +1405,10 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev,
> *val = at91_adc_get_sample_freq(st);
> return IIO_VAL_INT;
>
> + case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> + *val = st->oversampling_ratio;
> + return IIO_VAL_INT;
> +
> default:
> return -EINVAL;
> }
> @@ -1303,16 +1420,28 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev,
> {
> struct at91_adc_state *st = iio_priv(indio_dev);
>
> - if (mask != IIO_CHAN_INFO_SAMP_FREQ)
> - return -EINVAL;
> + switch (mask) {
> + case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> + if ((val != AT91_OSR_0SAMPLES) && (val != AT91_OSR_4SAMPLES) &&
> + (val != AT91_OSR_16SAMPLES))
> + return -EINVAL;
> + /* if no change, optimize out */
> + if (val == st->oversampling_ratio)
> + return 0;
> + st->oversampling_ratio = val;
> + /* update ratio */
> + at91_adc_config_emr(st);
> + return 0;
> + case IIO_CHAN_INFO_SAMP_FREQ:
> + if (val < st->soc_info.min_sample_rate ||
> + val > st->soc_info.max_sample_rate)
> + return -EINVAL;
>
> - if (val < st->soc_info.min_sample_rate ||
> - val > st->soc_info.max_sample_rate)
> + at91_adc_setup_samp_freq(st, val);
> + return 0;
> + default:
> return -EINVAL;
> -
> - at91_adc_setup_samp_freq(st, val);
> -
> - return 0;
> + };
> }
>
> static void at91_adc_dma_init(struct platform_device *pdev)
> @@ -1446,14 +1575,6 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
> return 0;
> }
>
> -static const struct iio_info at91_adc_info = {
> - .read_raw = &at91_adc_read_raw,
> - .write_raw = &at91_adc_write_raw,
> - .update_scan_mode = &at91_adc_update_scan_mode,
> - .of_xlate = &at91_adc_of_xlate,
> - .hwfifo_set_watermark = &at91_adc_set_watermark,
> -};
> -
> static void at91_adc_hw_init(struct at91_adc_state *st)
> {
> at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> @@ -1466,6 +1587,9 @@ static void at91_adc_hw_init(struct at91_adc_state *st)
> AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
>
> at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate);
> +
> + /* configure extended mode register */
> + at91_adc_config_emr(st);
> }
>
> static ssize_t at91_adc_get_fifo_state(struct device *dev,
> @@ -1496,6 +1620,19 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
> static IIO_CONST_ATTR(hwfifo_watermark_min, "2");
> static IIO_CONST_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR);
>
> +static IIO_CONST_ATTR(oversampling_ratio_available,
> + AT91_OSR_0SAMPLES_STR " " AT91_OSR_4SAMPLES_STR " "
> + AT91_OSR_16SAMPLES_STR);
Stringify macro?
> +
> +static struct attribute *at91_adc_attributes[] = {
> + &iio_const_attr_oversampling_ratio_available.dev_attr.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group at91_adc_attribute_group = {
> + .attrs = at91_adc_attributes,
> +};
> +
> static const struct attribute *at91_adc_fifo_attributes[] = {
> &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
> &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
> @@ -1504,6 +1641,15 @@ static const struct attribute *at91_adc_fifo_attributes[] = {
> NULL,
> };
>
> +static const struct iio_info at91_adc_info = {
> + .attrs = &at91_adc_attribute_group,
> + .read_raw = &at91_adc_read_raw,
> + .write_raw = &at91_adc_write_raw,
> + .update_scan_mode = &at91_adc_update_scan_mode,
> + .of_xlate = &at91_adc_of_xlate,
> + .hwfifo_set_watermark = &at91_adc_set_watermark,
> +};
> +
> static int at91_adc_probe(struct platform_device *pdev)
> {
> struct iio_dev *indio_dev;
^ permalink raw reply
* [PATCH v7 3/6] DTS: gta04: add uart2 child node for w2sg0004 GPS receiver
From: H. Nikolaus Schaller @ 2018-06-16 15:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180614194428.GA17808@amd>
Hi Pavel,
> Am 14.06.2018 um 21:44 schrieb Pavel Machek <pavel@ucw.cz>:
>
> On Thu 2018-05-03 11:35:48, H. Nikolaus Schaller wrote:
>> GTA04 has a W2SG0004 module connected to UART2 of the OMAP3
>> processor. A GPIO can pulse the on/off toggle switch.
>>
>> Note that there is no WAKEUP output from the W2SG0004,
>> hence we can't use the generic SirfStar binding.
>>
>> The VSIM regulator is used to power on/off the LNA of an
>> external active GPS antenna so that a driver can turn the
>> LNA off if GPS is not needed to save battery energy.
>
> This reads as if you did low->high->low to turn GPS on, then
> low->high->low to turn GPS off again. Is that correct?
Yes, it controls a toggle switch inside the gps module.
Data sheet (page 5, table 1):
http://download.goldelico.com/gta04-hardware/Datasheets/W2SG0004_Datasheet_Rev1.81.pdf
Well, it says it wants a "Low going pulse (two RTC ticks), for power save".
So this indicates "high->low->high" and the chip responds on an unspecified edge.
If I speculate about the logic behind this, I think there was the concept of a
push-button at the navigator's console of a vessel (button is connected through
a single long wire and grounded at the console) to turn the receiver on or off.
Now the question is which edge turns it on or of. Pushing or releasing the button?
high->low or low->high? There is no hint in the data sheet.
If we assume it has not been changed in the w2sg0084i, we can look at page 9, figure 3
https://www.mouser.com/ds/2/437/W2SG0084i_Datasheet_Rev1%2061-1114.pdf
to find that a rising edge changes the power state.
Experiments with manually controlling the w2sg0004 through /sys/class/gpio have
confirmed that that the rising edge is relevant.
Now on power-on there seems to be a special rule. If the on/off line is
permanently grounded (i.e. low), the module will turn on automatically at
power-on. So there is no need for any edge.
But since we don't want the module to be turned on at power-on (while U-Boot
is running) we have code there to initialize the gpio line to high.
Unfortunately you have not cited the code of the patch, so let me add it back:
> + /* GPIO_145: trigger for on/off-impulse for w2sg0004 */
> + enable-gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
So there it is described as GPIO_ACTIVE_HIGH.
This might seem to contradict the data sheet which talks about a low going pulse,
but better reflects the active low->high edge.
I hope this answers your question completely.
BR and thanks,
Nikolaus
^ permalink raw reply
* [PATCH 1/2] drm/rockchip: cnd-dp: adjust spdif register setting
From: Heiko Stübner @ 2018-06-16 13:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526979222-32478-1-git-send-email-hl@rock-chips.com>
Am Dienstag, 22. Mai 2018, 10:53:41 CEST schrieb Lin Huang:
> We use jitter bypass mode for spdif, so do not need to set jitter mode
> related bit in SPDIF_CTRL_ADDR register. Also, we need to enable
> SPDIF_ENABLE bit.
>
> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
> Signed-off-by: Lin Huang <hl@rock-chips.com>
applied to drm-misc-next after adapting the commit message
to make it clear that we need to keep the SPDIF_ENABLE bit.
Thanks
Heiko
^ permalink raw reply
* [PATCH 5/5] drm/rockchip: lvds: add missing of_node_put
From: Heiko Stübner @ 2018-06-16 12:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527102436-13447-6-git-send-email-Julia.Lawall@lip6.fr>
Hi Julia,
Am Mittwoch, 23. Mai 2018, 21:07:16 CEST schrieb Julia Lawall:
> The device node iterators perform an of_node_get on each iteration, so a
> jump out of the loop requires an of_node_put.
>
> The semantic patch that fixes this problem is as follows
> (http://coccinelle.lip6.fr):
>
> // <smpl>
> @@
> expression root,e;
> local idexpression child;
> iterator name for_each_child_of_node;
> @@
>
> for_each_child_of_node(root, child) {
> ... when != of_node_put(child)
> when != e = child
> + of_node_put(child);
> ? break;
> ...
> }
> ... when != child
> // </smpl>
>
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
thanks for catching this. I've added a "Fixes"-tag and
applied the patch to drm-misc-next
Thanks
Heiko
^ permalink raw reply
* [RFC PATCH 03/10] devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.
From: Enric Balletbo Serra @ 2018-06-16 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5AFA0B94.4000100@samsung.com>
Hi Chanwoo,
I'll send a new version soon, just wanted to ask some questions here. See below.
Missatge de Chanwoo Choi <cw00.choi@samsung.com> del dia dt., 15 de
maig 2018 a les 0:21:
>
> Hi,
>
> On 2018? 05? 15? 06:16, Enric Balletbo i Serra wrote:
> > Trusted Firmware-A (TF-A) for rk3399 implements a SiP call to get the
> > on-die termination (ODT) and auto power down parameters from kernel,
> > this patch adds the functionality to do this. Also, if DDR clock
> > frequency is lower than the on-die termination (ODT) disable frequency
> > this driver should disable the DDR ODT.
>
> I have a question.
> 'disable frequency' is the same meaning of 'disable the DDR ODT'?
>
Yes, the DT defines an odt_dis_freq parameter, when the DDR frequency
is less than the value in this parameter we disable the ODT on the
DRAM.
> >
> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> > ---
> >
> > drivers/devfreq/rk3399_dmc.c | 50 ++++++++++++++++++++++++++++-
> > include/soc/rockchip/rockchip_sip.h | 1 +
> > 2 files changed, 50 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
> > index d5c03e5abe13..cc1bbca3fb15 100644
> > --- a/drivers/devfreq/rk3399_dmc.c
> > +++ b/drivers/devfreq/rk3399_dmc.c
> > @@ -18,14 +18,17 @@
> > #include <linux/devfreq.h>
> > #include <linux/devfreq-event.h>
> > #include <linux/interrupt.h>
> > +#include <linux/mfd/syscon.h>
> > #include <linux/module.h>
> > #include <linux/of.h>
> > #include <linux/platform_device.h>
> > #include <linux/pm_opp.h>
> > +#include <linux/regmap.h>
> > #include <linux/regulator/consumer.h>
> > #include <linux/rwsem.h>
> > #include <linux/suspend.h>
> >
> > +#include <soc/rockchip/rk3399_grf.h>
> > #include <soc/rockchip/rockchip_sip.h>
> >
> > struct dram_timing {
> > @@ -69,8 +72,11 @@ struct rk3399_dmcfreq {
> > struct mutex lock;
> > struct dram_timing timing;
> > struct regulator *vdd_center;
> > + struct regmap *regmap_pmu;
> > unsigned long rate, target_rate;
> > unsigned long volt, target_volt;
> > + unsigned int odt_dis_freq;
> > + int odt_pd_arg0, odt_pd_arg1;
> > };
> >
> > static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
> > @@ -80,6 +86,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
> > struct dev_pm_opp *opp;
> > unsigned long old_clk_rate = dmcfreq->rate;
> > unsigned long target_volt, target_rate;
> > + struct arm_smccc_res res;
> > + int dram_flag;
> > int err;
> >
> > opp = devfreq_recommended_opp(dev, freq, flags);
> > @@ -95,6 +103,15 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
> >
> > mutex_lock(&dmcfreq->lock);
> >
> > + dram_flag = 0;
>
> Also, if dram_flag is 0, it mean that disable ODT frequency?
Yes, not a good name, maybe I should just rename it to odt_enable to
be more clear.
> If it's right, you better to define the precise variables as following
> instead of just integer(0 or 1).
> For example,
> - ROCKCHIP_SIP_DRAM_FREQ_ENABLE
> - ROCKCHIP_SIP_DRAM_FREQ_DISABLE
>
> > + if (target_rate >= dmcfreq->odt_dis_freq)
> > + dram_flag = 1;
> > +
> > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
> > + dmcfreq->odt_pd_arg1,
> > + ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
> > + dram_flag, 0, 0, 0, &res);
> > +
>
> This operation is special for only rk3399_dmc. It is difficult
> to understand what to do. I recommend you better to add the detailed comment
> with code.
Will do.
>
> > /*
> > * If frequency scaling from low to high, adjust voltage first.
> > * If frequency scaling from high to low, adjust frequency first.
> > @@ -294,11 +311,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
> > {
> > struct arm_smccc_res res;
> > struct device *dev = &pdev->dev;
> > - struct device_node *np = pdev->dev.of_node;
> > + struct device_node *np = pdev->dev.of_node, *node;
> > struct rk3399_dmcfreq *data;
> > int ret, index, size;
> > uint32_t *timing;
> > struct dev_pm_opp *opp;
> > + u32 ddr_type;
> > + u32 val;
> >
> > data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);
> > if (!data)
> > @@ -334,6 +353,29 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
> > return ret;
> > }
> >
> > + /* Try to find the optional reference to the pmu syscon */
> > + node = of_parse_phandle(np, "rockchip,pmu", 0);
> > + if (node) {
> > + data->regmap_pmu = syscon_node_to_regmap(node);
> > + if (IS_ERR(data->regmap_pmu))
> > + return PTR_ERR(data->regmap_pmu);
> > + }
> > +
> > + /* Get DDR type */
> > + regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
> > + ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
> > + RK3399_PMUGRF_DDRTYPE_MASK;
> > +
> > + /* Get the odt_dis_freq parameter in function of the DDR type */
> > + if (ddr_type == RK3399_PMUGRF_DDRTYPE_DDR3)
> > + data->odt_dis_freq = data->timing.ddr3_odt_dis_freq;
> > + else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
> > + data->odt_dis_freq = data->timing.lpddr3_odt_dis_freq;
> > + else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
> > + data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq;
> > + else
> > + return -EINVAL;
> > +
>
> how about using 'switch' statement?
>
Ok
> > /*
> > * Get dram timing and pass it to arm trust firmware,
> > * the dram drvier in arm trust firmware will get these
> > @@ -358,6 +400,12 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
> > ROCKCHIP_SIP_CONFIG_DRAM_INIT,
> > 0, 0, 0, 0, &res);
> >
> > + data->odt_pd_arg0 = (data->timing.sr_idle & 0xff) |
> > + ((data->timing.sr_mc_gate_idle & 0xff) << 8) |
> > + ((data->timing.standby_idle & 0xffff) << 16);
> > + data->odt_pd_arg1 = (data->timing.pd_idle & 0xfff) |
> > + ((data->timing.srpd_lite_idle & 0xfff) << 16);
> > +
>
> odt_pd_arg0 and odt_pd_arg1 might be used for disabling/enabling the ODT frequency.
> As I commented, it depend on only rk3399_dmc. You better to add detailed comment.
>
Ok
> And I prefer to define the XXX_SHIFT/XXX_MASK definition instead of
> using 8/16/0xff/0xffff for the readability.
>
I tried to add the XXX_SHIFT/XXX_MASK definitions and IMHO the
readability is worst if I use a maximum line length of 80 characters.
These masks are only used here, let me try to convince you by adding a
good doc in the next version and if you still prefer I add the
definition I'll do.
> > /*
> > * We add a devfreq driver to our parent since it has a device tree node
> > * with operating points.
> > diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
> > index 7e28092c4d3d..ad9482c56797 100644
> > --- a/include/soc/rockchip/rockchip_sip.h
> > +++ b/include/soc/rockchip/rockchip_sip.h
> > @@ -23,5 +23,6 @@
> > #define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05
> > #define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
> > #define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08
> >
> > #endif
> >
>
>
> --
> Best Regards,
> Chanwoo Choi
> Samsung Electronics
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
Cheers,
Enric
^ permalink raw reply
* [linux-sunxi] Re: [PATCH v2 11/27] drm/sun4i: tcon: Add support for tcon-top gate
From: Chen-Yu Tsai @ 2018-06-16 5:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3871160.F3Km1rQkUz@jernej-laptop>
On Sat, Jun 16, 2018 at 1:33 AM, Jernej ?krabec <jernej.skrabec@siol.net> wrote:
> Dne petek, 15. junij 2018 ob 19:13:17 CEST je Chen-Yu Tsai napisal(a):
>> On Sat, Jun 16, 2018 at 12:41 AM, Jernej ?krabec
>>
>> <jernej.skrabec@siol.net> wrote:
>> > Hi,
>> >
>> > Dne petek, 15. junij 2018 ob 10:31:10 CEST je Maxime Ripard napisal(a):
>> >> Hi,
>> >>
>> >> On Tue, Jun 12, 2018 at 10:00:20PM +0200, Jernej Skrabec wrote:
>> >> > TV TCONs connected to TCON TOP have to enable additional gate in order
>> >> > to work.
>> >> >
>> >> > Add support for such TCONs.
>> >> >
>> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> >> > ---
>> >> >
>> >> > drivers/gpu/drm/sun4i/sun4i_tcon.c | 11 +++++++++++
>> >> > drivers/gpu/drm/sun4i/sun4i_tcon.h | 4 ++++
>> >> > 2 files changed, 15 insertions(+)
>> >> >
>> >> > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 08747fc3ee71..0afb5a94a414
>> >> > 100644
>> >> > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> > @@ -688,6 +688,16 @@ static int sun4i_tcon_init_clocks(struct device
>> >> > *dev,
>> >> >
>> >> > dev_err(dev, "Couldn't get the TCON bus clock\n");
>> >> > return PTR_ERR(tcon->clk);
>> >> >
>> >> > }
>> >> >
>> >> > +
>> >> > + if (tcon->quirks->has_tcon_top_gate) {
>> >> > + tcon->top_clk = devm_clk_get(dev, "tcon-top");
>> >> > + if (IS_ERR(tcon->top_clk)) {
>> >> > + dev_err(dev, "Couldn't get the TCON TOP bus
>> >> > clock\n");
>> >> > + return PTR_ERR(tcon->top_clk);
>> >> > + }
>> >> > + clk_prepare_enable(tcon->top_clk);
>> >> > + }
>> >> > +
>> >>
>> >> Is it required for the TCON itself to operate, or does the TCON
>> >> requires the TCON TOP, which in turn requires that clock to be
>> >> functional?
>> >>
>> >> I find it quite odd to have a clock that isn't meant for a particular
>> >> device to actually be wired to another device. I'm not saying this
>> >> isn't the case, but it would be a first.
>> >
>> > Documentation doesn't say much about that gate. I did few tests and TCON
>> > registers can be read and written even if TCON TOP TV TCON gate is
>> > disabled. However, there is no image, as expected.
>>
>> The R40 manual does include it in the diagram, on page 504. There's also a
>> mux to select whether the clock comes directly from the CCU or the TV
>> encoder (a feedback mode?). I assume this is the gate you are referring to
>> here, in which case it is not a bus clock, but rather the TCON module or
>> channel clock, strangely routed.
>>
>> > More interestingly, I enabled test pattern directly in TCON to eliminate
>> > influence of the mixer. As soon as I disabled that gate, test pattern on
>> > HDMI screen was gone, which suggest that this gate influences something
>> > inside TCON.
>> >
>> > Another test I did was that I moved enable/disable gate code to
>> > sun4i_tcon_channel_set_status() and it worked just as well.
>> >
>> > I'll ask AW engineer what that gate actually does, but from what I saw, I
>> > would say that most appropriate location to enable/disable TCON TOP TV
>> > TCON
>> > gate is TCON driver. Alternatively, TCON TOP driver could check if any TV
>> > TCON is in use and enable appropriate gate. However, that doesn't sound
>> > right to me for some reason.
>>
>> If what I said above it true, then yes, the appropriate location to enable
>> it is the TCON driver, but moreover, the representation of the clock tree
>> should be fixed such that the TCON takes the clock from the TCON TOP as its
>> channel/ module clock instead. That way you don't need this patch, but
>> you'd add another for all the clock routing.
>
> Can you be more specific? I not sure what you mean here.
For clock related properties in the device tree:
&tcon_top {
clocks = <&ccu CLK_BUS_TCON_TOP>,
<&ccu CLK_TCON_TV0>,
<&tve0>,
<&ccu CLK_TCON_TV1>,
<&tve1>;
clock-names = "bus", "tcon-tv0", "tve0", "tcon-tv1", "tve1";
clock-output-names = "tcon-top-tv0", "tcon-top-tv1";
};
&tcon_tv0 {
clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>'
clock-names = "ahb", "tcon-ch1";
};
A diagram would look like:
| This part is TCON TOP |
v v
CCU CLK_TCON_TV0 --|----\ |
| mux ---- gate ----|-- TCON_TV0
TVE0 --------------|----/ |
And the same goes for TCON_TV1 and TVE1.
The user manual is a bit lacking on how TVE outputs a clock though.
ChenYu
^ permalink raw reply
* [PATCH 1/3] drm: mxsfb: Change driver.name to mxsfb-drm
From: Marek Vasut @ 2018-06-15 23:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b3fa74c5110b45e5992920485749869ab1f7ebce.camel@nxp.com>
On 06/16/2018 12:42 AM, Leonard Crestez wrote:
> On Fri, 2018-06-15 at 23:36 +0200, Marek Vasut wrote:
>> On 06/15/2018 10:58 PM, Leonard Crestez wrote:
>>> On Fri, 2018-06-15 at 16:47 -0300, Fabio Estevam wrote:
>>>> On Fri, Jun 15, 2018 at 4:43 PM, Leonard Crestez
>>>> <leonard.crestez@nxp.com> wrote:
>
>>>>> The FBDEV driver uses the same name and both can't be registered at the
>>>>> same time. Fix this by renaming the drm driver to mxsfb-drm
>>>>
>>>> Stefan sent the same patch a few days ago:
>>>
>>> In that thread there is a proposal for removing the old fbdev/mxsfb
>>> driver entirely.
>>>
>>> That would break old DTBs, isn't this generally considered bad? Also,
>>> are we sure the removal of fbdev/mxsfb wouldn't lose any features?
>>>
>>> What my series does is make both drivers work with the same kernel
>>> image and turns the choice into a board-level dtb decision. Supporting
>>> everything at once seems desirable to me and it allows for a very
>>> smooth upgrade path.
>>
>> Having two drivers in the kernel with different set of bugs is always bad.
>>
>>> The old driver could be removed later, after all users are converted.
>>
>> Both drivers were in for long enough already. And let's be realistic,
>> how many MX23/MX28 users of old DTs with new kernels are there who
>> cannot update the DT as well ?
>
> Grepping for "display =" in arch/arm/boot/dts/imx* I see that old
> bindings are also used by 3rd-party boards for imx6/7:
> * imx6sx-nitrogen6sx
> * imx6ul-geam
> * imx6ul-isiot
> * imx6ul-opos6uldev
> * imx6ul-pico-hobbit
> * imx6ul-tx6ul
> * imx7d-nitrogen7
Er, yes, a handful of boards which could be updated :)
> Converting everything might be quite a bit of work, and explicitly
> supporting old bindings is also work.
Does adding support for old bindings justify the effort invested ? I
doubt so, it only adds more code to maintain.
> It is very confusing that there is a whole set of displays for imx6/7
> which are supported by upstream but only with a non-default config.
> While it is extremely common in the embedded field to have custom
> configs the default one in the kernel should try to "just work".
>
> Couldn't this patch series be considered a bugfix? It was also
> surprisingly small.
I think it's just a workaround which allows you to postpone the real
fix, and I don't like that.
--
Best regards,
Marek Vasut
^ permalink raw reply
* [PATCH 1/3] drm: mxsfb: Change driver.name to mxsfb-drm
From: Marek Vasut @ 2018-06-15 23:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOMZO5DJju6oBRLakkTx4np7w9nMwPm6TMkGGYjbMLUPDUugYw@mail.gmail.com>
On 06/16/2018 12:22 AM, Fabio Estevam wrote:
> On Fri, Jun 15, 2018 at 6:36 PM, Marek Vasut <marex@denx.de> wrote:
>
>> Having two drivers in the kernel with different set of bugs is always bad.
>
> Sure, but breaking dtb's is also bad.
You picked only the first part of my argument, the less important one ;-)
> Can the mxsfb driver be modified to handle the old style bindings?
Maybe, but do we care ? Cfr my comment about the amount of users who
will be affected by this.
> The IPU drm driver is capable of handling both the old style where the
> display timing is passed in dts and the new drm style.
>
> For example:
>
> arch/arm/boot/dts/imx6qdl-sabresd.dtsi uses the drm style binding
> arch/arm/boot/dts/imx6qdl-sabreauto.dtsi uses the old style of passing
> the display timings in dts
>
> Both formats are accepted by the ipu drm driver.
>
> Can't mxsfb drm driver support both? Then we don't need to worry about
> breaking dtb's and could safely remove the mxs fbdev driver.
This might be a way forward, but again, does it justify the effort ?
We will be adding compatibility code which we will have to maintain for
maybe a handful of users I think.
--
Best regards,
Marek Vasut
^ permalink raw reply
* [PATCH 1/3] drm: mxsfb: Change driver.name to mxsfb-drm
From: Leonard Crestez @ 2018-06-15 22:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <638457fd-85da-8fec-d146-517c43f71813@denx.de>
On Fri, 2018-06-15 at 23:36 +0200, Marek Vasut wrote:
> On 06/15/2018 10:58 PM, Leonard Crestez wrote:
> > On Fri, 2018-06-15 at 16:47 -0300, Fabio Estevam wrote:
> > > On Fri, Jun 15, 2018 at 4:43 PM, Leonard Crestez
> > > <leonard.crestez@nxp.com> wrote:
> > > > The FBDEV driver uses the same name and both can't be registered at the
> > > > same time. Fix this by renaming the drm driver to mxsfb-drm
> > >
> > > Stefan sent the same patch a few days ago:
> >
> > In that thread there is a proposal for removing the old fbdev/mxsfb
> > driver entirely.
> >
> > That would break old DTBs, isn't this generally considered bad? Also,
> > are we sure the removal of fbdev/mxsfb wouldn't lose any features?
> >
> > What my series does is make both drivers work with the same kernel
> > image and turns the choice into a board-level dtb decision. Supporting
> > everything at once seems desirable to me and it allows for a very
> > smooth upgrade path.
>
> Having two drivers in the kernel with different set of bugs is always bad.
>
> > The old driver could be removed later, after all users are converted.
>
> Both drivers were in for long enough already. And let's be realistic,
> how many MX23/MX28 users of old DTs with new kernels are there who
> cannot update the DT as well ?
Grepping for "display =" in arch/arm/boot/dts/imx* I see that old
bindings are also used by 3rd-party boards for imx6/7:
* imx6sx-nitrogen6sx
* imx6ul-geam
* imx6ul-isiot
* imx6ul-opos6uldev
* imx6ul-pico-hobbit
* imx6ul-tx6ul
* imx7d-nitrogen7
Converting everything might be quite a bit of work, and explicitly
supporting old bindings is also work.
It is very confusing that there is a whole set of displays for imx6/7
which are supported by upstream but only with a non-default config.
While it is extremely common in the embedded field to have custom
configs the default one in the kernel should try to "just work".
Couldn't this patch series be considered a bugfix? It was also
surprisingly small.
--
Regards,
Leonard
^ permalink raw reply
* [PATCH 1/3] drm: mxsfb: Change driver.name to mxsfb-drm
From: Fabio Estevam @ 2018-06-15 22:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <638457fd-85da-8fec-d146-517c43f71813@denx.de>
On Fri, Jun 15, 2018 at 6:36 PM, Marek Vasut <marex@denx.de> wrote:
> Having two drivers in the kernel with different set of bugs is always bad.
Sure, but breaking dtb's is also bad.
Can the mxsfb driver be modified to handle the old style bindings?
The IPU drm driver is capable of handling both the old style where the
display timing is passed in dts and the new drm style.
For example:
arch/arm/boot/dts/imx6qdl-sabresd.dtsi uses the drm style binding
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi uses the old style of passing
the display timings in dts
Both formats are accepted by the ipu drm driver.
Can't mxsfb drm driver support both? Then we don't need to worry about
breaking dtb's and could safely remove the mxs fbdev driver.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox