* [PATCH 1/5] ARM: wire up HWCAP2 feature bits to the CPU modalias
From: Russell King - ARM Linux @ 2016-10-31 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_y7e=sJT+7FNj846NczgpNOdVx53SDC7dupmN-3ztNwA@mail.gmail.com>
On Sat, Oct 29, 2016 at 11:08:36AM +0100, Ard Biesheuvel wrote:
> On 18 October 2016 at 11:52, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> > Wire up the generic support for exposing CPU feature bits via the
> > modalias in /sys/device/system/cpu. This allows udev to automatically
> > load modules for things like crypto algorithms that are implemented
> > using optional instructions.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > ---
> > arch/arm/Kconfig | 1 +
> > arch/arm/include/asm/cpufeature.h | 32 ++++++++++++++++++++
> > 2 files changed, 33 insertions(+)
> >
>
> Russell,
>
> do you have any concerns regarding this patch? If not, I will drop it
> into the patch system.
It's still something I need to look at... I've been offline last week,
and sort-of offline the previous week, so I'm catching up.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH v5 1/2] drm: tilcdc: implement palette loading for rev1
From: Jyri Sarha @ 2016-10-31 16:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477923567-1610-2-git-send-email-bgolaszewski@baylibre.com>
On 10/31/16 16:19, Bartosz Golaszewski wrote:
> Revision 1 of the IP doesn't work if we don't load the palette (even
> if it's not used, which is the case for the RGB565 format).
>
> Add a function called from tilcdc_crtc_enable() which performs all
> required actions if we're dealing with a rev1 chip.
>
There is only one thing I do not like about this patch. The palette
loading is done so late that the frame buffer address are already placed
into DMA base and ceiling registers, and we need to read them from the
registers and restore them back after the palette loading.
Could you try if the palette loading function works without trouble when
called from tilcdc_pm_resume() before drm_atomic_helper_resume() call?
If it does it would be cleaner in the sense that you could get rid off
the old dma address restore code. You could reinit the completion always
there right before the palette loading.
If you can not get the above suggestion to work, then I can take this
patch.
BR,
Jyri
ps. There is one nit pick comment bellow.
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 88 +++++++++++++++++++++++++++++++++++-
> 1 file changed, 87 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index db2f538..937697d 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -21,11 +21,15 @@
> #include <drm/drm_flip_work.h>
> #include <drm/drm_plane_helper.h>
> #include <linux/workqueue.h>
> +#include <linux/completion.h>
> +#include <linux/dma-mapping.h>
>
> #include "tilcdc_drv.h"
> #include "tilcdc_regs.h"
>
> -#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000
> +#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000
> +#define TILCDC_REV1_PALETTE_SIZE 32
> +#define TILCDC_REV1_PALETTE_FIRST_ENTRY 0x4000
>
> struct tilcdc_crtc {
> struct drm_crtc base;
> @@ -53,6 +57,10 @@ struct tilcdc_crtc {
>
> int sync_lost_count;
> bool frame_intact;
> +
> + dma_addr_t palette_dma_handle;
> + void *palette_base;
> + struct completion palette_loaded;
> };
> #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
>
> @@ -98,6 +106,55 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
> tilcdc_crtc->curr_fb = fb;
> }
>
> +/*
> + * The driver currently only supports the RGB565 format for revision 1. For
> + * 16 bits-per-pixel the palette block is bypassed, but the first 32 bytes of
> + * the framebuffer are still considered palette. The first 16-bit entry must
> + * be 0x4000 while all other entries must be zeroed.
> + */
> +static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
> +{
> + u32 dma_fb_base, dma_fb_ceiling, raster_ctl;
> + struct tilcdc_crtc *tilcdc_crtc;
> + struct drm_device *dev;
> + u16 *first_entry;
> +
> + dev = crtc->dev;
> + tilcdc_crtc = to_tilcdc_crtc(crtc);
> + first_entry = tilcdc_crtc->palette_base;
> +
> + *first_entry = TILCDC_REV1_PALETTE_FIRST_ENTRY;
> +
> + dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG);
> + dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG);
> + raster_ctl = tilcdc_read(dev, LCDC_RASTER_CTRL_REG);
> +
> + /* Tell the LCDC where the palette is located. */
> + tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG,
> + tilcdc_crtc->palette_dma_handle);
> + tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG,
> + (u32)tilcdc_crtc->palette_dma_handle
Just a nit pick, but I would put the plus sign to the end of the line
above instead of the beginning of the line bellow. However,
check_patch.pl does not complain about this so I guess I can accept it too.
> + + TILCDC_REV1_PALETTE_SIZE - 1);
> +
> + /* Load it. */
> + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
> + LCDC_PALETTE_LOAD_MODE(DATA_ONLY));
> + tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
> + LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY));
> +
> + /* Enable the LCDC and wait for palette to be loaded. */
> + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
> + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
> +
> + wait_for_completion(&tilcdc_crtc->palette_loaded);
> +
> + /* Restore the registers. */
> + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
> + tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base);
> + tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling);
> + tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl);
> +}
> +
> static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
> {
> struct tilcdc_drm_private *priv = dev->dev_private;
> @@ -152,6 +209,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
> {
> struct drm_device *dev = crtc->dev;
> struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
> + struct tilcdc_drm_private *priv = dev->dev_private;
>
> WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
>
> @@ -162,6 +220,9 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
>
> reset(crtc);
>
> + if (priv->rev == 1 && !completion_done(&tilcdc_crtc->palette_loaded))
> + tilcdc_crtc_load_palette(crtc);
> +
> tilcdc_crtc_enable_irqs(dev);
>
> tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
> @@ -200,6 +261,13 @@ void tilcdc_crtc_disable(struct drm_crtc *crtc)
> __func__);
> }
>
> + /*
> + * LCDC will not retain the palette when reset. Make sure it gets
> + * reloaded on tilcdc_crtc_enable().
> + */
> + if (priv->rev == 1)
> + reinit_completion(&tilcdc_crtc->palette_loaded);
> +
> drm_crtc_vblank_off(crtc);
>
> tilcdc_crtc_disable_irqs(dev);
> @@ -802,6 +870,14 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
> dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow",
> __func__, stat);
>
> + if (priv->rev == 1) {
> + if (stat & LCDC_PL_LOAD_DONE) {
> + complete(&tilcdc_crtc->palette_loaded);
> + tilcdc_clear(dev,
> + LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
> + }
> + }
> +
> /* For revision 2 only */
> if (priv->rev == 2) {
> if (stat & LCDC_FRAME_DONE) {
> @@ -843,6 +919,16 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
> return NULL;
> }
>
> + if (priv->rev == 1) {
> + init_completion(&tilcdc_crtc->palette_loaded);
> + tilcdc_crtc->palette_base = dmam_alloc_coherent(dev->dev,
> + TILCDC_REV1_PALETTE_SIZE,
> + &tilcdc_crtc->palette_dma_handle,
> + GFP_KERNEL | __GFP_ZERO);
> + if (!tilcdc_crtc->palette_base)
> + return ERR_PTR(-ENOMEM);
> + }
> +
> crtc = &tilcdc_crtc->base;
>
> ret = tilcdc_plane_init(dev, &tilcdc_crtc->primary);
>
^ permalink raw reply
* [PATCH v2 3/3] arm64: Support systems without FP/ASIMD
From: Suzuki K Poulose @ 2016-10-31 16:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477929825-5907-1-git-send-email-suzuki.poulose@arm.com>
The arm64 kernel assumes that FP/ASIMD units are always present
and accesses the FP/ASIMD specific registers unconditionally. This
could cause problems when they are absent. This patch adds the
support for kernel handling systems without FP/ASIMD by skipping the
register access within the kernel. For kvm, we trap the accesses
to FP/ASIMD and inject an undefined instruction exception to the VM.
The callers of the exported kernel_neon_begin_parital() should
make sure that the FP/ASIMD is supported.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
Changes since V1:
- Dropped explicit FP/ASIMD check from Crypto modules.
---
arch/arm64/include/asm/cpufeature.h | 8 +++++++-
arch/arm64/include/asm/neon.h | 3 ++-
arch/arm64/kernel/cpufeature.c | 15 +++++++++++++++
arch/arm64/kernel/fpsimd.c | 14 ++++++++++++++
arch/arm64/kvm/handle_exit.c | 11 +++++++++++
arch/arm64/kvm/hyp/hyp-entry.S | 9 ++++++++-
arch/arm64/kvm/hyp/switch.c | 5 ++++-
7 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ae5e994..63d739c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -38,8 +38,9 @@
#define ARM64_HAS_32BIT_EL0 13
#define ARM64_HYP_OFFSET_LOW 14
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
+#define ARM64_HAS_NO_FPSIMD 16
-#define ARM64_NCAPS 16
+#define ARM64_NCAPS 17
#ifndef __ASSEMBLY__
@@ -236,6 +237,11 @@ static inline bool system_supports_mixed_endian_el0(void)
return id_aa64mmfr0_mixed_endian_el0(read_system_reg(SYS_ID_AA64MMFR0_EL1));
}
+static inline bool system_supports_fpsimd(void)
+{
+ return !cpus_have_const_cap(ARM64_HAS_NO_FPSIMD);
+}
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/include/asm/neon.h b/arch/arm64/include/asm/neon.h
index 13ce4cc..ad4cdc9 100644
--- a/arch/arm64/include/asm/neon.h
+++ b/arch/arm64/include/asm/neon.h
@@ -9,8 +9,9 @@
*/
#include <linux/types.h>
+#include <asm/fpsimd.h>
-#define cpu_has_neon() (1)
+#define cpu_has_neon() system_supports_fpsimd()
#define kernel_neon_begin() kernel_neon_begin_partial(32)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index d577f26..8f22544 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -744,6 +744,14 @@ static bool hyp_offset_low(const struct arm64_cpu_capabilities *entry,
return idmap_addr > GENMASK(VA_BITS - 2, 0) && !is_kernel_in_hyp_mode();
}
+static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unused)
+{
+ u64 pfr0 = read_system_reg(SYS_ID_AA64PFR0_EL1);
+
+ return cpuid_feature_extract_signed_field(pfr0,
+ ID_AA64PFR0_FP_SHIFT) < 0;
+}
+
static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "GIC system register CPU interface",
@@ -827,6 +835,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.def_scope = SCOPE_SYSTEM,
.matches = hyp_offset_low,
},
+ {
+ /* FP/SIMD is not implemented */
+ .capability = ARM64_HAS_NO_FPSIMD,
+ .def_scope = SCOPE_SYSTEM,
+ .min_field_value = 0,
+ .matches = has_no_fpsimd,
+ },
{},
};
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 975b274..80da5aa 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -127,6 +127,8 @@ void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs)
void fpsimd_thread_switch(struct task_struct *next)
{
+ if (!system_supports_fpsimd())
+ return;
/*
* Save the current FPSIMD state to memory, but only if whatever is in
* the registers is in fact the most recent userland FPSIMD state of
@@ -157,6 +159,8 @@ void fpsimd_thread_switch(struct task_struct *next)
void fpsimd_flush_thread(void)
{
+ if (!system_supports_fpsimd())
+ return;
memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
fpsimd_flush_task_state(current);
set_thread_flag(TIF_FOREIGN_FPSTATE);
@@ -168,6 +172,8 @@ void fpsimd_flush_thread(void)
*/
void fpsimd_preserve_current_state(void)
{
+ if (!system_supports_fpsimd())
+ return;
preempt_disable();
if (!test_thread_flag(TIF_FOREIGN_FPSTATE))
fpsimd_save_state(¤t->thread.fpsimd_state);
@@ -181,6 +187,8 @@ void fpsimd_preserve_current_state(void)
*/
void fpsimd_restore_current_state(void)
{
+ if (!system_supports_fpsimd())
+ return;
preempt_disable();
if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
struct fpsimd_state *st = ¤t->thread.fpsimd_state;
@@ -199,6 +207,8 @@ void fpsimd_restore_current_state(void)
*/
void fpsimd_update_current_state(struct fpsimd_state *state)
{
+ if (!system_supports_fpsimd())
+ return;
preempt_disable();
fpsimd_load_state(state);
if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
@@ -228,6 +238,8 @@ static DEFINE_PER_CPU(struct fpsimd_partial_state, softirq_fpsimdstate);
*/
void kernel_neon_begin_partial(u32 num_regs)
{
+ if (WARN_ON(!system_supports_fpsimd()))
+ return;
if (in_interrupt()) {
struct fpsimd_partial_state *s = this_cpu_ptr(
in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate);
@@ -252,6 +264,8 @@ EXPORT_SYMBOL(kernel_neon_begin_partial);
void kernel_neon_end(void)
{
+ if (!system_supports_fpsimd())
+ return;
if (in_interrupt()) {
struct fpsimd_partial_state *s = this_cpu_ptr(
in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate);
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index fa96fe2..39e055a 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -57,6 +57,16 @@ static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
return 1;
}
+/*
+ * Guest access to FP/ASIMD registers are routed to this handler only
+ * when the system doesn't support FP/ASIMD.
+ */
+static int handle_no_fpsimd(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
/**
* kvm_handle_wfx - handle a wait-for-interrupts or wait-for-event
* instruction executed by a guest
@@ -144,6 +154,7 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug,
[ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
[ESR_ELx_EC_BRK64] = kvm_handle_guest_debug,
+ [ESR_ELx_EC_FP_ASIMD] = handle_no_fpsimd,
};
static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index f6d9694..16167d7 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -117,9 +117,16 @@ el1_trap:
* x2: ESR_EC
*/
- /* Guest accessed VFP/SIMD registers, save host, restore Guest */
+ /*
+ * We trap the first access to the FP/SIMD to save the host context
+ * and restore the guest context lazily.
+ * If FP/SIMD is not implemented, handle the trap and inject an
+ * undefined instruction exception to the guest.
+ */
+alternative_if_not ARM64_HAS_NO_FPSIMD
cmp x2, #ESR_ELx_EC_FP_ASIMD
b.eq __fpsimd_guest_restore
+alternative_else_nop_endif
mrs x0, tpidr_el2
mov x1, #ARM_EXCEPTION_TRAP
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index ae7855f..f2d0c4f 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>
+#include <asm/fpsimd.h>
static bool __hyp_text __fpsimd_enabled_nvhe(void)
{
@@ -73,9 +74,11 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
* traps are only taken to EL2 if the operation would not otherwise
* trap to EL1. Therefore, always make sure that for 32-bit guests,
* we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit.
+ * If FP/ASIMD is not implemented, FPEXC is UNDEFINED and any access to
+ * it will cause an exception.
*/
val = vcpu->arch.hcr_el2;
- if (!(val & HCR_RW)) {
+ if (!(val & HCR_RW) && system_supports_fpsimd()) {
write_sysreg(1 << 30, fpexc32_el2);
isb();
}
--
2.7.4
^ permalink raw reply related
* [PATCH v2 2/3] arm64: Add hypervisor safe helper for checking constant capabilities
From: Suzuki K Poulose @ 2016-10-31 16:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477929825-5907-1-git-send-email-suzuki.poulose@arm.com>
The hypervisor may not have full access to the kernel data structures
and hence cannot safely use cpus_have_cap() helper for checking the
system capability. Add a safe helper for hypervisors to check a constant
system capability, which *doesn't* fall back to checking the bitmap
maintained by the kernel.
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 758d74f..ae5e994 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -9,8 +9,6 @@
#ifndef __ASM_CPUFEATURE_H
#define __ASM_CPUFEATURE_H
-#include <linux/jump_label.h>
-
#include <asm/hwcap.h>
#include <asm/sysreg.h>
@@ -45,6 +43,8 @@
#ifndef __ASSEMBLY__
+#include <linux/bug.h>
+#include <linux/jump_label.h>
#include <linux/kernel.h>
/* CPU feature register tracking */
@@ -122,6 +122,16 @@ static inline bool cpu_have_feature(unsigned int num)
return elf_hwcap & (1UL << num);
}
+/* System capability check for constant caps */
+static inline bool cpus_have_const_cap(int num)
+{
+ if (__builtin_constant_p(num))
+ return static_branch_unlikely(&cpu_hwcap_keys[num]);
+ BUILD_BUG();
+ /* unreachable */
+ return false;
+}
+
static inline bool cpus_have_cap(unsigned int num)
{
if (num >= ARM64_NCAPS)
@@ -218,7 +228,7 @@ static inline bool cpu_supports_mixed_endian_el0(void)
static inline bool system_supports_32bit_el0(void)
{
- return cpus_have_cap(ARM64_HAS_32BIT_EL0);
+ return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
}
static inline bool system_supports_mixed_endian_el0(void)
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/3] arm64: crypto/aes-ce-ccm: Cleanup hwcap check
From: Suzuki K Poulose @ 2016-10-31 16:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477929825-5907-1-git-send-email-suzuki.poulose@arm.com>
Use the module_cpu_feature_match to make sure the system has
HWCAP_AES to use the module.
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/crypto/aes-ce-ccm-glue.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
index f4bf2f2..fa82eaa 100644
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
@@ -14,6 +14,7 @@
#include <crypto/algapi.h>
#include <crypto/scatterwalk.h>
#include <crypto/internal/aead.h>
+#include <linux/cpufeature.h>
#include <linux/module.h>
#include "aes-ce-setkey.h"
@@ -296,8 +297,6 @@ static struct aead_alg ccm_aes_alg = {
static int __init aes_mod_init(void)
{
- if (!(elf_hwcap & HWCAP_AES))
- return -ENODEV;
return crypto_register_aead(&ccm_aes_alg);
}
@@ -306,7 +305,7 @@ static void __exit aes_mod_exit(void)
crypto_unregister_aead(&ccm_aes_alg);
}
-module_init(aes_mod_init);
+module_cpu_feature_match(AES, aes_mod_init);
module_exit(aes_mod_exit);
MODULE_DESCRIPTION("Synchronous AES in CCM mode using ARMv8 Crypto Extensions");
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/3] arm64: Support systems without FP/ASIMD
From: Suzuki K Poulose @ 2016-10-31 16:03 UTC (permalink / raw)
To: linux-arm-kernel
This series adds supports to the kernel and KVM hyp to handle
systems without FP/ASIMD properly. At the moment the kernel
doesn't check if the FP unit is available before accessing
the registers (e.g during context switch). Also for KVM,
we trap the FP/ASIMD accesses and handle it by injecting an
undefined instruction into the VM on systems without FP.
Tested on a FVP_Base-AEM-v8A model by disabling VFP on at
least one CPU ( -C clusterX.cpuY.vfp-present=0 ).
Applies on aarch64 : for-next/core
Suzuki K Poulose (3):
arm64: crypto/aes-ce-ccm: Cleanup hwcap check
arm64: Add hypervisor safe helper for checking constant capabilities
arm64: Support systems without FP/ASIMD
arch/arm64/crypto/aes-ce-ccm-glue.c | 5 ++---
arch/arm64/include/asm/cpufeature.h | 24 ++++++++++++++++++++----
arch/arm64/include/asm/neon.h | 3 ++-
arch/arm64/kernel/cpufeature.c | 15 +++++++++++++++
arch/arm64/kernel/fpsimd.c | 14 ++++++++++++++
arch/arm64/kvm/handle_exit.c | 11 +++++++++++
arch/arm64/kvm/hyp/hyp-entry.S | 9 ++++++++-
arch/arm64/kvm/hyp/switch.c | 5 ++++-
8 files changed, 76 insertions(+), 10 deletions(-)
--
2.7.4
^ permalink raw reply
* SMR masking and PCI
From: Diana Madalina Craciun @ 2016-10-31 15:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c39b785a-0f18-fc0a-ce08-7ebe3cfaf8c5@arm.com>
Hi Robin,
On 10/28/2016 07:16 PM, Robin Murphy wrote:
> Hi Stuart,
>
> On 27/10/16 18:10, Stuart Yoder wrote:
>> Hi Robin,
>>
>> A question about how the SMR masking defined in the arm,smmu binding
>> relates to the PCI iommu-map.
>>
>> The #iommu-cells property defines the number of cells an "IOMMU specifier"
>> takes and 2 is specified to be:
>>
>> SMMUs with stream matching support and complex masters
>> may use a value of 2, where the second cell represents
>> an SMR mask to combine with the ID in the first cell.
>>
>> An iommu-map entry is defined as:
>>
>> (rid-base,iommu,iommu-base,length)
>>
>> What seems to be currently missing in the iommu-map support is
>> the possibility the case where #iommu-cells=<2>.
> Indeed. The bindings have so far rather implicitly assumed the case of
> #{msi,iommu}-cells = 1, and the code has followed suit.
>
>> In this case iommu-base which is an IOMMU specifier should
>> occupy 2 cells. For example on an ls2085a we would want:
>>
>> iommu-map = <0x0 0x6 0x7 0x3ff 0x1
>> 0x100 0x6 0x8 0x3ff 0x1>;
>>
>> ...to mask our stream IDs to 10 bits.
>>
>> This should work in theory and comply with the bindings, no?
> In theory, but now consider:
>
> iommu-map = <0x0 0x6 0x7 0x3ff 0x2>;
>
> faced with ID 1. The input base is 0, the output base is the 2-cell
> value 0x7000003ff, so the final ID value should be 0x700000400, right?
>
>> of_pci_map_rid() seems to have a hardcoded assumption that
>> each field in the map is 4 bytes.
> It does. I guess we should explicitly check that #{msi,iommu}-cells = 1
> on the target node, and maybe clarify in the binding that that cell
> should represent a plain linear ID value (although that's pretty obvious
> from context IMO).
>
>> (Also, I guess that msi-map is not affected by this since it
>> is not related to the IOMMU...but we do have common code
>> handling both maps.)
> I'd say it's definitely affected, since #msi-cells can equally be more
> than 1, and encodes an equally opaque value.
>
> It seems pretty reasonable to me that we could extend the binding to
> accommodate #cells > 1 iff length == 1. Mark?
>
> That said, is there a concrete need for this, i.e. do you actually have
> one device with a single requester ID, which maps to multiple output IDs
> (which differ only in the upper bits) in a non-predictable manner?
>
Actually in the example presented by Stuart, the SMR mask should be
0x7C00 (as 0 means that the bit is relevant for matching). So, we have
the stream ID 7, but the SMMU 500 is appending the TBU bits which makes
the stream ID look like 0x1407 (TBU 5). In our platform the relationship
device-TBU is not exposed and documented. The SMMU-500 ref manual
describes this case:
"If the Stream ID presented to each TBU is already unique, and the TBU
ID addition is not required, then you must ensure that the TBU ID field
is masked in the SMR."
This is the reason that we need the SMR mask, to mask the TBU bits in
the SMR.
Thank you,
Diana
^ permalink raw reply
* [PATCH v2 1/8] drm/bridge: rgb-to-vga: Support an enable GPIO
From: Russell King - ARM Linux @ 2016-10-31 15:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161026221724.55yufeql6s5nd5gq@lukather>
On Thu, Oct 27, 2016 at 12:17:24AM +0200, Maxime Ripard wrote:
> Hi Rob,
>
> On Wed, Oct 26, 2016 at 05:13:46PM -0500, Rob Herring wrote:
> > On Thu, Oct 20, 2016 at 11:43:37AM +0800, Chen-Yu Tsai wrote:
> > > Some rgb-to-vga bridges have an enable GPIO, either directly tied to
> > > an enable pin on the bridge IC, or indirectly controlling a power
> > > switch.
> > >
> > > Add support for it.
> > >
> > > Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> > > ---
> > > .../bindings/display/bridge/dumb-vga-dac.txt | 2 ++
> > > drivers/gpu/drm/bridge/dumb-vga-dac.c | 28 ++++++++++++++++++++++
> > > 2 files changed, 30 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
> > > index 003bc246a270..d3484822bf77 100644
> > > --- a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
> > > +++ b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
> > > @@ -16,6 +16,8 @@ graph bindings specified in Documentation/devicetree/bindings/graph.txt.
> > > - Video port 0 for RGB input
> > > - Video port 1 for VGA output
> > >
> > > +Optional properties:
> > > +- enable-gpios: GPIO pin to enable or disable the bridge
> >
> > This should also define the active state.
> >
> > > +static void dumb_vga_enable(struct drm_bridge *bridge)
> > > +{
> > > + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
> > > +
> > > + if (vga->enable_gpio)
> > > + gpiod_set_value_cansleep(vga->enable_gpio, 1);
> >
> > So the driver should allow either active high or low.
>
> You mean like having a enable-active-high property? Isn't that
> redundant with the GPIO flags?
Correct - the gpiod APIs remove the need for drivers to know the
polarity of the signal, handling it inside the GPIO subsystem
instead, controlled either from the gpiod lookup tables in legacy
board files, or the DT specification for the GPIO.
So, in drivers, gpiod_set_value*(, 1) means "set gpio to active
level" and gpiod_set_value*(, 0) means "set gpio to inactive level".
Far nicer than all the bugs we've had with the legacy GPIO interfaces
with random different drivers implementing random different ways to
invert the signal, with all the pain that brings with it when a
platform comes along with a different inversion state.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* MAINTAINERS entry for ARM/CLKDEV SUPPORT
From: Russell King - ARM Linux @ 2016-10-31 15:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <663e5d47-c2b5-c76f-01b4-0fb9a792acf6@codeaurora.org>
On Wed, Oct 26, 2016 at 02:31:31PM -0700, Stephen Boyd wrote:
> On 10/26/2016 12:19 PM, Dan Carpenter wrote:
> > On Mon, Oct 10, 2016 at 03:18:19PM +0100, Russell King - ARM Linux wrote:
> >> On Mon, Oct 10, 2016 at 05:08:10PM +0300, Dan Carpenter wrote:
> >>> Hello Stephen Boyd,
> >> Okay, that's really not nice.
> >>
> >> This is _not_ a question for Stephen. Stephen does _not_ co-maintain
> >> clkdev or the clk API, but co-maintains CCF. I've no idea why you are
> >> addressing this to Stephen when this is clearly a question for me to
> >> answer.
> >>
> > Sorry, I didn't mean to offend. He's the one who deleted the clkdev.h
> > file though so I thought he might know if it should still be listed or
> > if it was gone for good.
> >
>
> Yes, the arm version isn't coming back. We should delete
> arch/arm/include/asm/clkdev.h from the maintainers file and perhaps
> replace it with the asm-generic one.
I disagree. See my reply to the original mail for the reasons.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* Applied "ASoC: sun4i-codec: return error code instead of NULL when create_card fails" to the asoc tree
From: Mark Brown @ 2016-10-31 15:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161031064209.12241-1-wens@csie.org>
The patch
ASoC: sun4i-codec: return error code instead of NULL when create_card fails
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 85915b63ad8b796848f431b66c9ba5e356e722e5 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Mon, 31 Oct 2016 14:42:09 +0800
Subject: [PATCH] ASoC: sun4i-codec: return error code instead of NULL when
create_card fails
When sun4i_codec_create_card fails, we do not assign a proper error
code to the return value. The return value would be 0 from the previous
function call, or we would have bailed out sooner. This would confuse
the driver core into thinking the device probe succeeded, when in fact
it didn't, leaving various devres based resources lingering.
Make the create_card function pass back a meaningful error code, and
assign it to the return value.
Fixes: 45fb6b6f2aa3 ("ASoC: sunxi: add support for the on-chip codec on
early Allwinner SoCs")
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/sunxi/sun4i-codec.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index e047ec06d538..a60707761abf 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -765,11 +765,11 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
if (!card)
- return NULL;
+ return ERR_PTR(-ENOMEM);
card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
if (!card->dai_link)
- return NULL;
+ return ERR_PTR(-ENOMEM);
card->dev = dev;
card->name = "sun4i-codec";
@@ -876,7 +876,8 @@ static int sun4i_codec_probe(struct platform_device *pdev)
}
card = sun4i_codec_create_card(&pdev->dev);
- if (!card) {
+ if (IS_ERR(card)) {
+ ret = PTR_ERR(card);
dev_err(&pdev->dev, "Failed to create our card\n");
goto err_unregister_codec;
}
--
2.10.1
^ permalink raw reply related
* [RESEND PATCH] arm: assabet_defconfig: disable IDE subsystem
From: Russell King - ARM Linux @ 2016-10-31 15:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1913139.FJW82OAuEF@amdc3058>
On Wed, Oct 26, 2016 at 07:01:12PM +0200, Bartlomiej Zolnierkiewicz wrote:
>
> Hi,
>
> On Wednesday, July 13, 2016 04:37:31 PM Arnd Bergmann wrote:
> > On Wednesday, July 13, 2016 12:59:23 PM CEST Bartlomiej Zolnierkiewicz wrote:
> > >
> > > On Friday, July 08, 2016 10:23:48 PM Arnd Bergmann wrote:
> > > > On Friday, July 8, 2016 5:24:41 PM CEST Bartlomiej Zolnierkiewicz wrote:
> > > > > This patch disables deprecated IDE subsystem in assabet_defconfig
> > > > > (no IDE host drivers are selected in this config so there is no
> > > > > valid reason to enable IDE subsystem itself).
> > > > >
> > > > > Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> > > > > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> > > >
> > > > I think the series makes a lot of sense. I have checked your assertions
> > > > in the changelogs and found no flaws in your logic, so I think we should
> > > > take them all through arm-soc unless there are other concerns.
> > >
> > > Thank you.
> > >
> > > Should I resend everything or just patches that were not reposted yet
> > > (the ones that were marked as RFT initially and got no feedback)?
> >
> > I'd be fine with just getting a pull request with all the patches that
> > had no negative feedback and that were not already applied (if any).
>
> Here it is (sorry for taking so long).
I've just been digging in the dmesg logs from when I was using the
Assabet+Neponset as my firewall, and it was having to use the IDE
ide-cs driver rather than the pata pcmcia driver.
I don't recall whether the pata pcmcia driver was a problem or not,
as the PCMCIA interface can't cope with _any_ 32-bit accesses. I
think PATA tries to use the "highest" possible access size by
default...
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH] arm64: mm: fix __page_to_voff definition
From: Catalin Marinas @ 2016-10-31 15:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161030143858.vhmnibvvwf5qjvqj@localhost>
On Sun, Oct 30, 2016 at 02:38:58PM +0000, Catalin Marinas wrote:
> On Fri, Oct 21, 2016 at 02:28:46PM +0530, Neeraj Upadhyay wrote:
> > Fix parameter name for __page_to_voff, to match its definition.
> > At present, we don't see any issue, as page_to_virt's caller
> > declares 'page'.
> >
> > Fixes: 9f2875912dac ("arm64: mm: restrict virt_to_page() to the linear mapping")
> > Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
>
> I'll queue this patch for 4.10. Thanks.
I didn't realise that Will sent it already for 4.9-rc3, so I dropped it
from the 4.10 queue.
--
Catalin
^ permalink raw reply
* [PATCHv2 1/4] dt-bindings: mfd: Add Altera Arria10 SR Monitor
From: Thor Thayer @ 2016-10-31 15:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161031053604.3rjbuk7maabzbwq7@rob-hp-laptop>
Hi Rob,
On 10/31/2016 12:36 AM, Rob Herring wrote:
> On Thu, Oct 27, 2016 at 03:00:23PM -0500, tthayer at opensource.altera.com wrote:
>> From: Thor Thayer <tthayer@opensource.altera.com>
>>
>> Add the Arria10 DevKit System Resource Chip register and state
>> monitoring module to the MFD.
>>
>> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
>> ---
>> Note: This needs to be applied to the bindings document that
>> was Acked & Applied but didn't reach the for-next branch.
>> See https://patchwork.ozlabs.org/patch/629397/
>> ---
>> v2 Change compatible string -mon to -monitor for clarity
>> ---
>> Documentation/devicetree/bindings/mfd/altera-a10sr.txt | 9 +++++++++
>> 1 file changed, 9 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/altera-a10sr.txt b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
>> index ea151f2..c47be28 100644
>> --- a/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
>> +++ b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
>> @@ -18,6 +18,7 @@ The A10SR consists of these sub-devices:
>> Device Description
>> ------ ----------
>> a10sr_gpio GPIO Controller
>
> This should be just "gpio" BTW.
I reason I preprend a10sr_ is to distinguish this GPIO from the other
GPIOs when binding to our LEDs (see below). I think the LEDs need a
unique node name (unless I'm not understanding something).
A less important reason I use a10sr_gpio on the node name is that I can
cat the /sys/class/gpio/gpioxxx/label and see that it is associated with
the a10sr instead of one of our other general GPIOs. Is there a better
way to distinguish these?
>
>> +a10sr_monitor Register and State Monitoring
>
> s/_/-/ or maybe just "monitor". Not really a generic node name to use
> for this.
>
The reason I use _ for the node name is that the DTC fails if I
reference a node name with "-" but works OK for "_". For instance, I get
an error if the LEDs reference "a10sr-gpio" but "a10sr_gpio" compiles ok.
Thanks for reviewing!
Thor
> Rob
>
^ permalink raw reply
* [RFC] fpga: Pull checks for supported operations into framework
From: Moritz Fischer @ 2016-10-31 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477851123-17686-1-git-send-email-moritz.fischer@ettus.com>
Found a couple of issues, will resubmit after cleaning up. Feel free to add
general feedback on the idea anyways in the meantime. Sorry for double post.
On Sun, Oct 30, 2016 at 11:12 AM, Moritz Fischer
<moritz.fischer@ettus.com> wrote:
> Most of the drivers only support a subset of {PARTIAL, FULL}
> reconfiguration.
> Pull duplicate checks in each driver into the framework.
>
> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
> Cc: Alan Tull <atull@opensource.altera.com>
> Cc: Michal Simek <michal.simek@xilinx.com>
> Cc: S?ren Brinkmann <soren.brinkmann@xilinx.com>
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> ---
> Hi all,
>
> with the new drivers (ice40, altera-ps-spi) being submitted I've noticed
> we're duplicating this check over and over again,
> so I figured we might as well pull it into the framework.
>
> I'm not sure if there are gonna be other 'flags' we need to support
> in the short term (we talked about byte-swapping ...)
>
> Note: This patch goes on top of greg's char-misc-testing that already
> contains Alan's latest changes to support the A10 and won't apply
> to master.
>
> Cheers,
>
> Moritz
>
> ---
> drivers/fpga/fpga-mgr.c | 12 ++++++++++++
> drivers/fpga/socfpga-a10.c | 4 +++-
> drivers/fpga/socfpga.c | 3 ++-
> drivers/fpga/zynq-fpga.c | 3 ++-
> include/linux/fpga/fpga-mgr.h | 9 +++++++--
> 5 files changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
> index c58b4c4..85f17d8 100644
> --- a/drivers/fpga/fpga-mgr.c
> +++ b/drivers/fpga/fpga-mgr.c
> @@ -49,6 +49,11 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
> struct device *dev = &mgr->dev;
> int ret;
>
> + if (!(mgr->supported_flags & info->flags)) {
> + dev_err(dev, "Unsupported flags passed\n");
> + return -ENOTSUPP;
> + }
That condition is obviously garbage ...
> +
> /*
> * Call the low level driver's write_init function. This will do the
> * device-specific things to get the FPGA into the state where it is
> @@ -252,6 +257,7 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
> */
> int fpga_mgr_register(struct device *dev, const char *name,
> const struct fpga_manager_ops *mops,
> + u32 supported_flags,
> void *priv)
> {
> struct fpga_manager *mgr;
> @@ -268,6 +274,11 @@ int fpga_mgr_register(struct device *dev, const char *name,
> return -EINVAL;
> }
>
> + if (!supported_flags) {
> + dev_err(dev, "Attempt to register with no supported flags\n");
> + return -EINVAL;
> + }
> +
> mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> if (!mgr)
> return -ENOMEM;
> @@ -282,6 +293,7 @@ int fpga_mgr_register(struct device *dev, const char *name,
>
> mgr->name = name;
> mgr->mops = mops;
> + mgr->supported_flags = supported_flags;
> mgr->priv = priv;
>
> /*
> diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
> index ccd9fb2..e7c82ff 100644
> --- a/drivers/fpga/socfpga-a10.c
> +++ b/drivers/fpga/socfpga-a10.c
> @@ -519,7 +519,9 @@ static int socfpga_a10_fpga_probe(struct platform_device *pdev)
> }
>
> return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
> - &socfpga_a10_fpga_mgr_ops, priv);
> + &socfpga_a10_fpga_mgr_ops,
> + FPGA_MGR_PARTIAL_RECONFIG,
> + priv);
> }
>
> static int socfpga_a10_fpga_remove(struct platform_device *pdev)
> diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
> index b6672e6..3285b7d 100644
> --- a/drivers/fpga/socfpga.c
> +++ b/drivers/fpga/socfpga.c
> @@ -582,7 +582,8 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
> return ret;
>
> return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
> - &socfpga_fpga_ops, priv);
> + &socfpga_fpga_ops, FPGA_MGR_FULL_RECONFIG,
> + priv);
> }
>
> static int socfpga_fpga_remove(struct platform_device *pdev)
> diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
> index 249682e..1dabd25 100644
> --- a/drivers/fpga/zynq-fpga.c
> +++ b/drivers/fpga/zynq-fpga.c
> @@ -413,6 +413,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
> struct zynq_fpga_priv *priv;
> struct resource *res;
> int err;
> + u32 flags = FPGA_MGR_FULL_RECONFIG | FPGA_MGR_PARTIAL_RECONFIG;
>
> priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> if (!priv)
> @@ -465,7 +466,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
> clk_disable(priv->clk);
>
> err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
> - &zynq_fpga_ops, priv);
> + &zynq_fpga_ops, flags, priv);
> if (err) {
> dev_err(dev, "unable to register FPGA manager");
> clk_unprepare(priv->clk);
> diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
> index 040b86d..4f4bcf2 100644
> --- a/include/linux/fpga/fpga-mgr.h
> +++ b/include/linux/fpga/fpga-mgr.h
> @@ -64,9 +64,12 @@ enum fpga_mgr_states {
>
> /*
> * FPGA Manager flags
> + * FPGA_MGR_FULL_RECONFIG: do full reconfiguration if supported
> * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
> */
> -#define FPGA_MGR_PARTIAL_RECONFIG BIT(0)
> +#define FPGA_MGR_FULL_RECONFIG BIT(0)
> +#define FPGA_MGR_PARTIAL_RECONFIG BIT(1)
> +#define FPGA_MGR_EXTERNAL_CONFIG BIT(2)
On second thought the FULL_RECONFIG is the same as !PARTIAL_RECONFIG,
so useless ..
>
> /**
> * struct fpga_image_info - information specific to a FPGA image
> @@ -119,6 +122,7 @@ struct fpga_manager {
> enum fpga_mgr_states state;
> const struct fpga_manager_ops *mops;
> void *priv;
> + u32 supported_flags;
> };
>
> #define to_fpga_manager(d) container_of(d, struct fpga_manager, dev)
> @@ -135,7 +139,8 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
> void fpga_mgr_put(struct fpga_manager *mgr);
>
> int fpga_mgr_register(struct device *dev, const char *name,
> - const struct fpga_manager_ops *mops, void *priv);
> + const struct fpga_manager_ops *mops, u32 supported_flags,
> + void *priv);
>
> void fpga_mgr_unregister(struct device *dev);
>
> --
> 2.4.11
>
Cheers,
Moritz
^ permalink raw reply
* [PATCH] ARM: davinci: da850: Fix pwm name matching
From: David Lechner @ 2016-10-31 14:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b4f6970b-5723-d1ed-088e-3c07129a005f@ti.com>
On 10/31/2016 05:18 AM, Sekhar Nori wrote:
> On Tuesday 25 October 2016 11:24 PM, David Lechner wrote:
>> This fixes pwm name matching for DA850 familiy devices. When using device
>> tree, the da850_auxdata_lookup[] table caused pwm devices to have the exact
>> same name, which caused errors when trying to register the devices.
>>
>> The names for clock matching in da850_clks[] also have to be updated to
>> to exactly match in order for the clock lookup to work correctly.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>>
>> Tested working on LEGO MINDSTORMS EV3.
>>
>>
>> arch/arm/mach-davinci/da850.c | 10 +++++++---
>> arch/arm/mach-davinci/da8xx-dt.c | 10 +++++-----
>> 2 files changed, 12 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
>> index ed3d0e9..6b78a8f 100644
>> --- a/arch/arm/mach-davinci/da850.c
>> +++ b/arch/arm/mach-davinci/da850.c
>> @@ -510,9 +510,13 @@ static struct clk_lookup da850_clks[] = {
>> CLK("vpif", NULL, &vpif_clk),
>> CLK("ahci_da850", NULL, &sata_clk),
>> CLK("davinci-rproc.0", NULL, &dsp_clk),
>> - CLK("ehrpwm", "fck", &ehrpwm_clk),
>> - CLK("ehrpwm", "tbclk", &ehrpwm_tbclk),
>> - CLK("ecap", "fck", &ecap_clk),
>> + CLK("ehrpwm.0", "fck", &ehrpwm_clk),
>> + CLK("ehrpwm.0", "tbclk", &ehrpwm_tbclk),
>> + CLK("ehrpwm.1", "fck", &ehrpwm_clk),
>> + CLK("ehrpwm.1", "tbclk", &ehrpwm_tbclk),
>> + CLK("ecap.0", "fck", &ecap_clk),
>> + CLK("ecap.1", "fck", &ecap_clk),
>> + CLK("ecap.2", "fck", &ecap_clk),
>
> This has exposed a limitation of DaVinci clock framework. The struct clk
> are stored as a linked list themselves. So a node repeating in the table
> above will create a loop in the linked list. This is easily seen on the
> LCDK board. davinci_clk_disable_unused() never returns. PWMs are unused
> on that board.
>
> There is no "simple" solution to this AFAICS. One solution is to
> separate the iterator from the clock hardware structure and use struct
> clk_hw available in struct clk_lookup.
>
> Or move DaVinci to common clock framework. This is of course preferred
> but much more involved as all 6 supported SoCs have to be moved together.
>
> Thanks,
> Sekhar
>
>
The simple solution for now could be to make child clocks for each of
these that simply enable the parent clock. e.g. ehrpwm0_clk and
ehpwm1_clk are children of ehrpwm_clk, etc.
Looking at da830.c, it looks like the solution was to make multiple
clocks that use the same LPSC, but this does not seem right to me.
^ permalink raw reply
* [PATCH v2 5/5] ARM: dts: da850-lcdk: add tilcdc panel node
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
The tilcdc driver is not yet ready for working together with the
dumb-vga-dac drm bridge. While the work on enabling drm_bridge
support in tilcdc continues, enable the VGA connector on da850-lcdk
with the following workaround: use the tilcdc-panel driver with
a set of common (and tested) resolutions.
Once the drm bridge support is complete, we'll remove the node added
by this patch and use the correct solution. This change will be
transparent for the user.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/boot/dts/da850-lcdk.dts | 63 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index b39796e..df582c6 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -62,6 +62,65 @@
regulator-max-microvolt = <5000000>;
};
+ /*
+ * Remove this node once the tilcdc driver gets support for
+ * drm bridge modules.
+ */
+ panel {
+ compatible = "ti,tilcdc,panel";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+ status = "okay";
+
+ panel-info {
+ ac-bias = <0>;
+ ac-bias-intrpt = <0>;
+ dma-burst-sz = <16>;
+ bpp = <16>;
+ fdd = <255>;
+ sync-edge = <0>;
+ sync-ctrl = <0>;
+ raster-order = <0>;
+ fifo-th = <5>;
+ };
+
+ display-timings {
+ native-mode = <&svga_timings>;
+ vga_timings: 640x480 at 60 {
+ clock-frequency = <27500000>;
+ hactive = <640>;
+ hback-porch = <90>;
+ hfront-porch = <40>;
+ hsync-len = <128>;
+ vactive = <480>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ vsync-len = <4>;
+ };
+ vga_timings_hf: 640x480 at 75 {
+ clock-frequency = <34000000>;
+ hactive = <640>;
+ hback-porch = <90>;
+ hfront-porch = <40>;
+ hsync-len = <128>;
+ vactive = <480>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ vsync-len = <4>;
+ };
+ svga_timings: 800x600 at 56 {
+ clock-frequency = <37500000>;
+ hactive = <800>;
+ hback-porch = <140>;
+ hfront-porch = <40>;
+ hsync-len = <128>;
+ vactive = <600>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ vsync-len = <4>;
+ };
+ };
+ };
};
&pmx_core {
@@ -251,3 +310,7 @@
&ddrctl {
status = "okay";
};
+
+&display {
+ status = "okay";
+};
--
2.9.3
^ permalink raw reply related
* [PATCH v2 4/5] ARM: dts: da850-lcdk: enable mstpri and ddrctl nodes
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Enable the MSTPRI configuration and DDR2/mDDR memory controller
nodes on da850-lcdk. This is needed in order to adjust the memory
throughput constraints for better tilcdc support.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/boot/dts/da850-lcdk.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 4747629..b39796e 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -243,3 +243,11 @@
};
};
};
+
+&mstpri {
+ status = "okay";
+};
+
+&ddrctl {
+ status = "okay";
+};
--
2.9.3
^ permalink raw reply related
* [PATCH v2 3/5] ARM: dts: da850: add the mstpri and ddrctl nodes
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Add the nodes for the MSTPRI configuration and DDR2/mDDR memory
controller drivers to da850.dtsi.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/boot/dts/da850.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 112c6d7..44bece3 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -454,6 +454,12 @@
interrupts = <52>;
status = "disabled";
};
+
+ mstpri: mstpri at 14110 {
+ compatible = "ti,da850-mstpri";
+ reg = <0x14110 0x0c>;
+ status = "disabled";
+ };
};
aemif: aemif at 68000000 {
compatible = "ti,da850-aemif";
@@ -465,4 +471,9 @@
1 0 0x68000000 0x00008000>;
status = "disabled";
};
+ ddrctl: ddrctl at b0000000 {
+ compatible = "ti,da850-ddr-controller";
+ reg = <0xb0000000 0xe8>;
+ status = "disabled";
+ };
};
--
2.9.3
^ permalink raw reply related
* [PATCH v2 2/5] ARM: bus: da8xx-mstpri: new driver
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Create the driver for the da8xx master peripheral priority
configuration and implement support for writing to the three
Master Priority registers on da850 SoCs.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
.../devicetree/bindings/bus/ti,da850-mstpri.txt | 20 ++
drivers/bus/Kconfig | 9 +
drivers/bus/Makefile | 2 +
drivers/bus/da8xx-mstpri.c | 269 +++++++++++++++++++++
4 files changed, 300 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
create mode 100644 drivers/bus/da8xx-mstpri.c
diff --git a/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
new file mode 100644
index 0000000..72daefc
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx master peripheral
+ priority driver
+
+DA8XX SoCs feature a set of registers allowing to change the priority of all
+peripherals classified as masters.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible: "ti,da850-mstpri" - for da850 based boards
+- reg: offset and length of the mstpri registers
+
+Example for da850-lcdk is shown below.
+
+mstpri {
+ compatible = "ti,da850-mstpri";
+ reg = <0x14110 0x0c>;
+};
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 7875105..f5db3a7 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -167,4 +167,13 @@ config VEXPRESS_CONFIG
help
Platform configuration infrastructure for the ARM Ltd.
Versatile Express.
+
+config DA8XX_MSTPRI
+ bool "TI da8xx master peripheral priority driver"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ Driver for Texas Instruments da8xx master peripheral priority
+ configuration. Allows to adjust the priorities of all master
+ peripherals.
+
endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index c6cfa6b..2adb540 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -21,3 +21,5 @@ obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
obj-$(CONFIG_TEGRA_ACONNECT) += tegra-aconnect.o
obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
+
+obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o
diff --git a/drivers/bus/da8xx-mstpri.c b/drivers/bus/da8xx-mstpri.c
new file mode 100644
index 0000000..85f0b53
--- /dev/null
+++ b/drivers/bus/da8xx-mstpri.c
@@ -0,0 +1,269 @@
+/*
+ * TI da8xx master peripheral priority driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com.com>
+ *
+ * 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/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/of_fdt.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+#define DA8XX_MSTPRI0_OFFSET 0
+#define DA8XX_MSTPRI1_OFFSET 4
+#define DA8XX_MSTPRI2_OFFSET 8
+
+enum {
+ DA8XX_MSTPRI_ARM_I = 0,
+ DA8XX_MSTPRI_ARM_D,
+ DA8XX_MSTPRI_UPP,
+ DA8XX_MSTPRI_SATA,
+ DA8XX_MSTPRI_PRU0,
+ DA8XX_MSTPRI_PRU1,
+ DA8XX_MSTPRI_EDMA30TC0,
+ DA8XX_MSTPRI_EDMA30TC1,
+ DA8XX_MSTPRI_EDMA31TC0,
+ DA8XX_MSTPRI_VPIF_DMA_0,
+ DA8XX_MSTPRI_VPIF_DMA_1,
+ DA8XX_MSTPRI_EMAC,
+ DA8XX_MSTPRI_USB0CFG,
+ DA8XX_MSTPRI_USB0CDMA,
+ DA8XX_MSTPRI_UHPI,
+ DA8XX_MSTPRI_USB1,
+ DA8XX_MSTPRI_LCDC,
+};
+
+struct da8xx_mstpri_descr {
+ int reg;
+ int shift;
+ int mask;
+};
+
+static const struct da8xx_mstpri_descr da8xx_mstpri_priority_list[] = {
+ [DA8XX_MSTPRI_ARM_I] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_ARM_D] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 4,
+ .mask = 0x000000f0,
+ },
+ [DA8XX_MSTPRI_UPP] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 16,
+ .mask = 0x000f0000,
+ },
+ [DA8XX_MSTPRI_SATA] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 20,
+ .mask = 0x00f00000,
+ },
+ [DA8XX_MSTPRI_PRU0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_PRU1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 4,
+ .mask = 0x000000f0,
+ },
+ [DA8XX_MSTPRI_EDMA30TC0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 8,
+ .mask = 0x00000f00,
+ },
+ [DA8XX_MSTPRI_EDMA30TC1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 12,
+ .mask = 0x0000f000,
+ },
+ [DA8XX_MSTPRI_EDMA31TC0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 16,
+ .mask = 0x000f0000,
+ },
+ [DA8XX_MSTPRI_VPIF_DMA_0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 24,
+ .mask = 0x0f000000,
+ },
+ [DA8XX_MSTPRI_VPIF_DMA_1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 28,
+ .mask = 0xf0000000,
+ },
+ [DA8XX_MSTPRI_EMAC] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_USB0CFG] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 8,
+ .mask = 0x00000f00,
+ },
+ [DA8XX_MSTPRI_USB0CDMA] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 12,
+ .mask = 0x0000f000,
+ },
+ [DA8XX_MSTPRI_UHPI] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 20,
+ .mask = 0x00f00000,
+ },
+ [DA8XX_MSTPRI_USB1] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 24,
+ .mask = 0x0f000000,
+ },
+ [DA8XX_MSTPRI_LCDC] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 28,
+ .mask = 0xf0000000,
+ },
+};
+
+struct da8xx_mstpri_priority {
+ int which;
+ u32 val;
+};
+
+struct da8xx_mstpri_board_priorities {
+ const char *board;
+ const struct da8xx_mstpri_priority *priorities;
+ size_t numprio;
+};
+
+/*
+ * Default memory settings of da850 do not meet the throughput/latency
+ * requirements of tilcdc. This results in the image displayed being
+ * incorrect and the following warning being displayed by the LCDC
+ * drm driver:
+ *
+ * tilcdc da8xx_lcdc.0: tilcdc_crtc_irq(0x00000020): FIFO underfow
+ */
+static const struct da8xx_mstpri_priority da850_lcdk_priorities[] = {
+ {
+ .which = DA8XX_MSTPRI_LCDC,
+ .val = 0,
+ },
+ {
+ .which = DA8XX_MSTPRI_EDMA30TC1,
+ .val = 0,
+ },
+ {
+ .which = DA8XX_MSTPRI_EDMA30TC0,
+ .val = 1,
+ },
+};
+
+static const struct da8xx_mstpri_board_priorities da8xx_mstpri_board_confs[] = {
+ {
+ .board = "ti,da850-lcdk",
+ .priorities = da850_lcdk_priorities,
+ .numprio = ARRAY_SIZE(da850_lcdk_priorities),
+ },
+};
+
+static const struct da8xx_mstpri_board_priorities *
+da8xx_mstpri_get_board_prio(void)
+{
+ const struct da8xx_mstpri_board_priorities *board_prio;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_mstpri_board_confs); i++) {
+ board_prio = &da8xx_mstpri_board_confs[i];
+
+ if (of_machine_is_compatible(board_prio->board))
+ return board_prio;
+ }
+
+ return NULL;
+}
+
+static int da8xx_mstpri_probe(struct platform_device *pdev)
+{
+ const struct da8xx_mstpri_board_priorities *prio_list;
+ const struct da8xx_mstpri_descr *prio_descr;
+ const struct da8xx_mstpri_priority *prio;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ void __iomem *mstpri;
+ u32 reg;
+ int i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mstpri = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mstpri)) {
+ dev_err(dev, "unable to map MSTPRI registers\n");
+ return PTR_ERR(mstpri);
+ }
+
+ prio_list = da8xx_mstpri_get_board_prio();
+ if (!prio_list) {
+ dev_err(dev, "no master priotities defined for board '%s'\n",
+ of_flat_dt_get_machine_name());
+ return -EINVAL;
+ }
+
+ for (i = 0; i < prio_list->numprio; i++) {
+ prio = &prio_list->priorities[i];
+ prio_descr = &da8xx_mstpri_priority_list[prio->which];
+
+ if (prio_descr->reg + sizeof(u32) > resource_size(res)) {
+ dev_warn(dev, "register offset out of range\n");
+ continue;
+ }
+
+ reg = readl(mstpri + prio_descr->reg);
+ reg &= ~prio_descr->mask;
+ reg |= prio->val << prio_descr->shift;
+
+ writel(reg, mstpri + prio_descr->reg);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id da8xx_mstpri_of_match[] = {
+ { .compatible = "ti,da850-mstpri", },
+ { },
+};
+
+static struct platform_driver da8xx_mstpri_driver = {
+ .probe = da8xx_mstpri_probe,
+ .driver = {
+ .name = "da8xx-mstpri",
+ .of_match_table = da8xx_mstpri_of_match,
+ },
+};
+module_platform_driver(da8xx_mstpri_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx master peripheral priority driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related
* [PATCH v2 1/5] ARM: memory: da8xx-ddrctl: new driver
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Create a new driver for the da8xx DDR2/mDDR controller and implement
support for writing to the Peripheral Bus Burst Priority Register.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
.../memory-controllers/ti-da8xx-ddrctl.txt | 20 +++
drivers/memory/Kconfig | 8 +
drivers/memory/Makefile | 1 +
drivers/memory/da8xx-ddrctl.c | 175 +++++++++++++++++++++
4 files changed, 204 insertions(+)
create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
create mode 100644 drivers/memory/da8xx-ddrctl.c
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
new file mode 100644
index 0000000..ec1dd40
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx DDR2/mDDR memory controller
+
+The DDR2/mDDR memory controller present on Texas Instruments da8xx SoCs features
+a set of registers which allow to tweak the controller's behavior.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible: "ti,da850-ddr-controller" - for da850 SoC based boards
+- reg: a tuple containing the base address of the memory
+ controller and the size of the memory area to map
+
+Example for da850 shown below.
+
+ddrctl {
+ compatible = "ti,da850-ddr-controller";
+ reg = <0xb0000000 0xe8>;
+};
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 4b4c0c3..ec80e35 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -134,6 +134,14 @@ config MTK_SMI
mainly help enable/disable iommu and control the power domain and
clocks for each local arbiter.
+config DA8XX_DDRCTL
+ bool "Texas Instruments da8xx DDR2/mDDR driver"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ This driver is for the DDR2/mDDR Memory Controller present on
+ Texas Instruments da8xx SoCs. It's used to tweak various memory
+ controller configuration options.
+
source "drivers/memory/samsung/Kconfig"
source "drivers/memory/tegra/Kconfig"
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index b20ae38..e88097fb 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
obj-$(CONFIG_MTK_SMI) += mtk-smi.o
+obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
obj-$(CONFIG_SAMSUNG_MC) += samsung/
obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/da8xx-ddrctl.c b/drivers/memory/da8xx-ddrctl.c
new file mode 100644
index 0000000..a20e7bb
--- /dev/null
+++ b/drivers/memory/da8xx-ddrctl.c
@@ -0,0 +1,175 @@
+/*
+ * TI da8xx DDR2/mDDR controller driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ *
+ * 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/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+struct da8xx_ddrctl_config_knob {
+ const char *name;
+ u32 reg;
+ u32 mask;
+ u32 shift;
+};
+
+static const struct da8xx_ddrctl_config_knob da8xx_ddrctl_knobs[] = {
+ {
+ .name = "da850-pbbpr",
+ .reg = 0x20,
+ .mask = 0xffffff00,
+ .shift = 0,
+ },
+};
+
+struct da8xx_ddrctl_setting {
+ const char *name;
+ u32 val;
+};
+
+struct da8xx_ddrctl_board_settings {
+ const char *board;
+ const struct da8xx_ddrctl_setting *settings;
+};
+
+static const struct da8xx_ddrctl_setting da850_lcdk_ddrctl_settings[] = {
+ {
+ .name = "da850-pbbpr",
+ .val = 0x20,
+ },
+ { }
+};
+
+static const struct da8xx_ddrctl_board_settings da8xx_ddrctl_board_confs[] = {
+ {
+ .board = "ti,da850-lcdk",
+ .settings = da850_lcdk_ddrctl_settings,
+ },
+};
+
+static const struct da8xx_ddrctl_config_knob *
+da8xx_ddrctl_match_knob(const struct da8xx_ddrctl_setting *setting)
+{
+ const struct da8xx_ddrctl_config_knob *knob;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_knobs); i++) {
+ knob = &da8xx_ddrctl_knobs[i];
+
+ if (strcmp(knob->name, setting->name) == 0)
+ return knob;
+ }
+
+ return NULL;
+}
+
+static const struct da8xx_ddrctl_setting *da8xx_ddrctl_get_board_settings(void)
+{
+ const struct da8xx_ddrctl_board_settings *board_settings;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_board_confs); i++) {
+ board_settings = &da8xx_ddrctl_board_confs[i];
+
+ if (of_machine_is_compatible(board_settings->board))
+ return board_settings->settings;
+ }
+
+ return NULL;
+}
+
+static int da8xx_ddrctl_probe(struct platform_device *pdev)
+{
+ const struct da8xx_ddrctl_config_knob *knob;
+ const struct da8xx_ddrctl_setting *setting;
+ struct device_node *node;
+ struct resource *res;
+ void __iomem *ddrctl;
+ struct device *dev;
+ u32 reg;
+
+ dev = &pdev->dev;
+ node = dev->of_node;
+
+ setting = da8xx_ddrctl_get_board_settings();
+ if (!setting) {
+ dev_err(dev, "no settings for board '%s'\n",
+ of_flat_dt_get_machine_name());
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ddrctl = devm_ioremap_resource(dev, res);
+ if (IS_ERR(ddrctl)) {
+ dev_err(dev, "unable to map memory controller registers\n");
+ return PTR_ERR(ddrctl);
+ }
+
+ for (; setting->name; setting++) {
+ knob = da8xx_ddrctl_match_knob(setting);
+ if (!knob) {
+ dev_warn(dev,
+ "no such config option: %s\n", setting->name);
+ continue;
+ }
+
+ if (knob->reg + sizeof(u32) > resource_size(res)) {
+ dev_warn(dev,
+ "register offset of '%s' exceeds mapped memory size\n",
+ knob->name);
+ continue;
+ }
+
+ reg = readl(ddrctl + knob->reg);
+ reg &= knob->mask;
+ reg |= setting->val << knob->shift;
+
+ dev_dbg(dev, "writing 0x%08x to %s\n", reg, setting->name);
+
+ writel(reg, ddrctl + knob->reg);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id da8xx_ddrctl_of_match[] = {
+ { .compatible = "ti,da850-ddr-controller", },
+ { },
+};
+
+static struct platform_driver da8xx_ddrctl_driver = {
+ .probe = da8xx_ddrctl_probe,
+ .driver = {
+ .name = "da850-ddr-controller",
+ .of_match_table = da8xx_ddrctl_of_match,
+ },
+};
+module_platform_driver(da8xx_ddrctl_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx DDR2/mDDR controller driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related
* [PATCH v2 0/5] ARM: da850: new drivers for better LCDC support
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
This series adds two new drivers in order to better support the LCDC
rev1 present on the da850 boards.
The first patch adds a new memory driver which allows to write to the
DDR2/mDDR memory controller present on the da8xx SoCs.
The second patch adds a new bus driver which allows to interact with
the MSTPRI registers of the SYSCFG0 module
As is mentioned in the comments: we don't want to commit to supporting
stable interfaces (DT bindings or sysfs attributes) so we hardcode the
settings required by some boards (for now only da850-lcdk) with the
hope that linux gets an appropriate framework for performance knobs
in the future.
Potential extensions of these drivers should be straightforward in the
future.
Subsequent patches add DT nodes for the new drivers: disabled nodes
in da850.dtsi and enabled in da850-lcdk.dts.
The last patch adds a workaround for current lack of support for drm
bridges in tilcdc.
Tested on a da850-lcdk with a display connected over VGA and two
additional patches for tilcdc (sent to linux-drm): ran simple modetest
for supported resolutions, used X.org and fluxbox as graphical
environment, played video with mplayer.
v1 -> v2:
- used regular readl()/writel() instead of __raw_** versions
- used resource_size() instead of calculating the size by hand
- used ioremap instead of syscon in patch [2/5]
- added the DT nodes in patches [3/5]-[5/5]
Bartosz Golaszewski (5):
ARM: memory: da8xx-ddrctl: new driver
ARM: bus: da8xx-mstpri: new driver
ARM: dts: da850: add the mstpri and ddrctl nodes
ARM: dts: da850-lcdk: enable mstpri and ddrctl nodes
ARM: dts: da850-lcdk: add tilcdc panel node
.../devicetree/bindings/bus/ti,da850-mstpri.txt | 20 ++
.../memory-controllers/ti-da8xx-ddrctl.txt | 20 ++
arch/arm/boot/dts/da850-lcdk.dts | 71 ++++++
arch/arm/boot/dts/da850.dtsi | 11 +
drivers/bus/Kconfig | 9 +
drivers/bus/Makefile | 2 +
drivers/bus/da8xx-mstpri.c | 269 +++++++++++++++++++++
drivers/memory/Kconfig | 8 +
drivers/memory/Makefile | 1 +
drivers/memory/da8xx-ddrctl.c | 175 ++++++++++++++
10 files changed, 586 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
create mode 100644 drivers/bus/da8xx-mstpri.c
create mode 100644 drivers/memory/da8xx-ddrctl.c
--
2.9.3
^ permalink raw reply
* [PATCH 0/3] ARM: dts: oxnas: Update support for OX820 and use dt-bindings
From: Neil Armstrong @ 2016-10-31 14:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMjsjYPKyH2CD4siZmB3F64h+c7vndfjFdniTDLB4Eh4Pw@mail.gmail.com>
Hi Olof,
On 10/31/2016 03:24 PM, Olof Johansson wrote:
> Hi,
>>
>> Hi,
>>
>> I'm ready to send a pull request for arm-soc-dt, but I need to understand how this dependency
>> should be worked out.
>>
>> Should this be sent as a late pull request ?
>
>
> The need for dt-include changes is one of my pet peeves these days,
> since they require coordination between trees.
>
> There's two ways to solve this:
>
> 1) Make sure that the branches you sent to other maintainers are
> stable, that they merge them as-is and don't rebase. This is a
> three-way handshake (we want to be cc:d on it). Then base your branch
> on top of those two branches.
It may be possible, at least from the clock tree.
Anyway, it's good to know, if I had a single tree to synchronize with,
I'll eventually select this option...
>
> or:
>
> 2) Avoid using the includes now, using numerical constants instead.
> Then, after next merge window, follow up with a patch that converts to
> symbols.
I will select this option for now, my ultimate goal is to have something booting
for 4.10, cleanup can really wait 4.11...
>
> -Olof
>
Thanks,
Neil
^ permalink raw reply
* [RFC PATCH 09/13] net: phy: Add Meson GXL Internal PHY driver
From: Neil Armstrong @ 2016-10-31 14:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0ea5a7a8-3913-0e6a-6ff2-9f34015ea071@gmail.com>
On 10/21/2016 10:56 PM, Florian Fainelli wrote:
> On 10/21/2016 07:40 AM, Neil Armstrong wrote:
>> Add driver for the Internal RMII PHY found in the Amlogic Meson GXL SoCs.
>>
>> This PHY seems to only implement some standard registers and need some
>> workarounds to provide autoneg values from vendor registers.
>>
>> Some magic values are currently used to configure the PHY, and this a
>> temporary setup until clarification about these registers names and
>> registers fields are provided by Amlogic.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>> +
>> +static int meson_gxl_config_init(struct phy_device *phydev)
>> +{
>> + int val;
>> + u32 features;
>> +
>> + meson_gxl_phy_config(phydev);
>> +
>> + features = SUPPORTED_MII;
>
> This does not really belong in the PHY driver, and this is statically
> assigned, I would just drop this.
>
Ok
>> +
>> + /* Do we support autonegotiation? */
>> + val = phy_read(phydev, MII_BMSR);
>> + if (val < 0)
>> + return val;
>> +
>> + if (val & BMSR_ANEGCAPABLE)
>> + features |= SUPPORTED_Autoneg;
>> + if (val & BMSR_100FULL)
>> + features |= SUPPORTED_100baseT_Full;
>> + if (val & BMSR_100HALF)
>> + features |= SUPPORTED_100baseT_Half;
>> + if (val & BMSR_10FULL)
>> + features |= SUPPORTED_10baseT_Full;
>> + if (val & BMSR_10HALF)
>> + features |= SUPPORTED_10baseT_Half;
>> +
>> + phydev->supported = features;
>> + phydev->advertising = features;
>
> This is redundant with what PHYLIB will determine for the PHY.
>
ok
>> +
>> + return 0;
>> +}
>> +
>> +static int meson_gxl_phy_read_status(struct phy_device *phydev)
>> +{
>> + int err;
>> +
>> + /* Update the link, but return if there was an error */
>> + err = genphy_update_link(phydev);
>> + if (err)
>> + return err;
>> +
>> + phydev->lp_advertising = 0;
>> + phydev->pause = 0;
>> + phydev->asym_pause = 0;
>> +
>> + if (phydev->autoneg == AUTONEG_ENABLE) {
>> + unsigned int speed;
>> + int reg = phy_read(phydev, GXL_REG_ANEG);
>
> Is all of this really necessary? This should all be reflected in the
> standard BMSR register, is not this the case here that we have to read
> this non-standard register?
>
This is what I understood from the original driver code, but I will make some further tests
and see if the BMSR returns some good data.
> You use genphy_config_aneg(), so surely, the standard auto-negotiation
> part works somehow?
Yes, and the BMSR is also used in the config_init here...
>
>> +
>> + if (reg < 0)
>> + return reg;
>> +
>> + speed = reg & REG_ANEG_SPEED_MASK;
>> +
>> + if (reg & REG_ANEG_FDUPLEX)
>> + phydev->duplex = DUPLEX_FULL;
>> + else
>> + phydev->duplex = DUPLEX_HALF;
>> +
>> + if ((reg & REG_ANEG_SPEED_MASK) == REG_ANEG_SPEED10)
>> + phydev->speed = SPEED_10;
>> + else if ((reg & REG_ANEG_SPEED_MASK) == REG_ANEG_SPEED100)
>> + phydev->speed = SPEED_100;
>> + } else {
>> + int bmcr = phy_read(phydev, MII_BMCR);
>> +
>> + if (bmcr < 0)
>> + return bmcr;
>> +
>> + if (bmcr & BMCR_FULLDPLX)
>> + phydev->duplex = DUPLEX_FULL;
>> + else
>> + phydev->duplex = DUPLEX_HALF;
>> +
>> + if (bmcr & BMCR_SPEED1000)
>> + phydev->speed = SPEED_1000;
>> + else if (bmcr & BMCR_SPEED100)
>> + phydev->speed = SPEED_100;
>> + else
>> + phydev->speed = SPEED_10;
>> + }
>
>> +
>> + return 0;
>> +}
>> +
>> +static struct phy_driver meson_gxl_phy = {
>> + .phy_id = 0x01814400,
>> + .name = "Meson GXL Internal PHY",
>> + .phy_id_mask = 0x0fffffff,
>
> Usually the last 4 bits are 0, since that's where the revision part is
> located.
>
Fixed
>> + .features = 0,
>
> You should set PHY_GBIT_FEATURES and set .flags to PHY_IS_INTERNAL since
> this is an internal PHY?
>
Ok
Thanks,
Neil
^ permalink raw reply
* [PATCH 0/3] ARM: dts: oxnas: Update support for OX820 and use dt-bindings
From: Olof Johansson @ 2016-10-31 14:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <fce063fd-6aaa-8d30-1588-e656e93bdebc@baylibre.com>
Hi,
On Mon, Oct 31, 2016 at 2:58 AM, Neil Armstrong <narmstrong@baylibre.com> wrote:
> On 10/21/2016 05:10 PM, Neil Armstrong wrote:
>> This patchset updates the ARM DTS for the Oxnas platform by :
>> - Add support for the Oxford Semicondutor OX820 and the PogoPlug V3
>> - Update the OX810SE to use the dt-bindings includes files introduced in [1] and [2]
>> - Fix the MAINTAINERS entry and add the PogoPlug V3 file maintainance
>>
>> This patchset depends on dt-bindings include headers posted at [1] and [2],
>> that were accepted/merged in the subsystem trees.
>>
>> How could I manage this dependency for 4.10 ?
>>
>> [1] https://listengine.tuxfamily.org/lists.tuxfamily.org/linux-oxnas/2016/10/msg00008.html
>> [2] https://listengine.tuxfamily.org/lists.tuxfamily.org/linux-oxnas/2016/10/msg00007.html
>>
>> Neil Armstrong (3):
>> ARM: dts: Add support for OX820 and Pogoplug V3
>> ARM: dts: OX810: Update with dt-bindings includes
>> MAINTAINERS: oxnas: Add new files definitions
>>
>> Documentation/devicetree/bindings/arm/oxnas.txt | 5 +
>> MAINTAINERS | 3 +-
>> arch/arm/boot/dts/Makefile | 3 +-
>> .../boot/dts/cloudengines-pogoplug-series-3.dts | 94 +++++++
>> arch/arm/boot/dts/ox810se.dtsi | 10 +-
>> arch/arm/boot/dts/ox820.dtsi | 298 +++++++++++++++++++++
>> 6 files changed, 407 insertions(+), 6 deletions(-)
>> create mode 100644 arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
>> create mode 100644 arch/arm/boot/dts/ox820.dtsi
>>
>
> Hi,
>
> I'm ready to send a pull request for arm-soc-dt, but I need to understand how this dependency
> should be worked out.
>
> Should this be sent as a late pull request ?
The need for dt-include changes is one of my pet peeves these days,
since they require coordination between trees.
There's two ways to solve this:
1) Make sure that the branches you sent to other maintainers are
stable, that they merge them as-is and don't rebase. This is a
three-way handshake (we want to be cc:d on it). Then base your branch
on top of those two branches.
or:
2) Avoid using the includes now, using numerical constants instead.
Then, after next merge window, follow up with a patch that converts to
symbols.
-Olof
^ permalink raw reply
* [RFC PATCH 08/13] dwmac-meson8b: add support for phy selection
From: Neil Armstrong @ 2016-10-31 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161021160807.GT16974@lunn.ch>
On 10/21/2016 06:08 PM, Andrew Lunn wrote:
> Hi Neil
>
>> Yes this would be a good idea if we were able to scan the internal
>> and external PHYs at the same time, but with our limited knowledge
>> the values we write in the register seems to switch a mux for the
>> whole RMII and MDIO signals to either interface.
>
> Ah, O.K. So you need something like:
>
> drivers/net/phy/mdio-mux-mmioreg.c
>
> This seems to be limited to a single byte for the mux register, so you
> might need to make some extensions.
>
> Andrew
>
Thanks for the hint, I will try to make use of this !
Neil
^ 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