Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: arm/arm64: Access CNTHCTL_EL2 bit fields correctly
From: Marc Zyngier @ 2016-11-29 10:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161129104753.GA15346@cbox>

On 29/11/16 10:47, Christoffer Dall wrote:
> On Tue, Nov 29, 2016 at 09:37:07AM +0000, Marc Zyngier wrote:
>> On 28/11/16 19:42, Christoffer Dall wrote:
>>> On Mon, Nov 28, 2016 at 06:39:04PM +0000, Marc Zyngier wrote:
>>>> On 28/11/16 17:43, Marc Zyngier wrote:
>>>>> Hi Jintack,
>>>>>
>>>>> On 28/11/16 16:46, Jintack Lim wrote:
>>>>>> Bit positions of CNTHCTL_EL2 are changing depending on HCR_EL2.E2H bit.
>>>>>> EL1PCEN and EL1PCTEN are 1st and 0th bits when E2H is not set, but they
>>>>>> are 11th and 10th bits respectively when E2H is set.  Current code is
>>>>>> unintentionally setting wrong bits to CNTHCTL_EL2 with E2H set, which
>>>>>> may allow guest OS to access physical timer. So, fix it.
>>>>>>
>>>>>> Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
>>>>>> ---
>>>>>>  arch/arm/include/asm/kvm_timer.h     | 33 +++++++++++++++++++
>>>>>>  arch/arm64/include/asm/kvm_timer.h   | 62 ++++++++++++++++++++++++++++++++++++
>>>>>>  include/clocksource/arm_arch_timer.h |  6 ++--
>>>>>>  virt/kvm/arm/hyp/timer-sr.c          |  8 ++---
>>>>>>  4 files changed, 103 insertions(+), 6 deletions(-)
>>>>>>  create mode 100644 arch/arm/include/asm/kvm_timer.h
>>>>>>  create mode 100644 arch/arm64/include/asm/kvm_timer.h
>>>>>>
>>>>
>>>> [...]
>>>>
>>>>> We could make it nicer (read "faster") by introducing a
>>>>> hyp_alternate_select construct that only returns a value instead
>>>>> of calling a function. I remember writing something like that
>>>>> at some point, and dropping it...
>>>>
>>>> So here's what this could look like (warning, wacky code ahead,
>>>> though I fixed a stupid bug that was present in the previous patch).
>>>> The generated code is quite nice (no branch, only an extra mov
>>>> instruction on the default path)... Of course, completely untested!
>>>
>>> Isn't this all about determining which bitmask to use, statically, once,
>>> after the system has booted?
>>>
>>> How about a good old fashioned static variable, or global struct like
>>> the global one we use for the VGIC, which sets the proper mit mask
>>> during kvm init, and the world-switch code just uses a variable?
>>
>> We could indeed do that (I've been carried away with my tendency for
>> weird and wonderful hacks).
>>
>> But as Jintack mentioned, there is a much better approach, which is to
>> do nothing at all on the VHE path (we can set the permission bits once
>> and for all). cntvoff_el2 also falls into the same category of things we
>> should be able to only restore and not bother resetting (as it doesn't
>> affect the EL2 virtual counter).
>>
>> Thoughts?
>>
> Yes, that sounds much better.
> 
> I have some patches to get rid of a lot of things, like cntvoff, during
> the world-switch for VHE, so if Jintack just wants to focus on the
> cnthctl I will catch cntvoff later.

Sound good to me.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH v2 2/2] ARM: dts: da850-lcdk: specify the maximum pixel clock rate for tilcdc
From: Sekhar Nori @ 2016-11-29 10:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480335328-4010-3-git-send-email-bgolaszewski@baylibre.com>

On Monday 28 November 2016 05:45 PM, Bartosz Golaszewski wrote:
> Due to memory throughput constraints any display mode for which the
> pixel clock rate exceeds the recommended value of 37500 KHz must be
> filtered out.

I think there might be more reasons than memory throughput constraints
for the reasoning behind 37.5Mhz cap on pixel clock. Why not just refer
to the datasheet section that places this constraint so we know its a
hardware restriction.

> 
> Specify the max-pixelclock property for the display node for
> da850-lcdk.
> 
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
>  arch/arm/boot/dts/da850-lcdk.dts | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
> index d864f11..1283263 100644
> --- a/arch/arm/boot/dts/da850-lcdk.dts
> +++ b/arch/arm/boot/dts/da850-lcdk.dts
> @@ -285,6 +285,7 @@
>  
>  &display {
>  	status = "okay";
> +	max-pixelclock = <37500>;

Should this not be in da850.dtsi since its an SoC imposed constraint? If
a board needs narrower constraint, it can override it. But I guess most
well designed boards will just hit the SoC constraint.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH V10 4/6] arm: arm64: pmu: Assign platform PMU CPU affinity
From: Will Deacon @ 2016-11-29 10:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478734793-6341-5-git-send-email-jeremy.linton@arm.com>

On Wed, Nov 09, 2016 at 05:39:51PM -0600, Jeremy Linton wrote:
> On systems with multiple PMU types the PMU to CPU affinity
> needs to be detected and set. The CPU to interrupt affinity
> should also be set.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>  drivers/perf/arm_pmu.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 53 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index b37b572..6008be9 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -11,6 +11,7 @@
>   */
>  #define pr_fmt(fmt) "hw perfevents: " fmt
>  
> +#include <linux/acpi.h>
>  #include <linux/bitmap.h>
>  #include <linux/cpumask.h>
>  #include <linux/cpu_pm.h>
> @@ -24,6 +25,7 @@
>  #include <linux/irq.h>
>  #include <linux/irqdesc.h>
>  
> +#include <asm/cpu.h>
>  #include <asm/cputype.h>
>  #include <asm/irq_regs.h>
>  
> @@ -889,25 +891,67 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu)
>  }
>  
>  /*
> - * CPU PMU identification and probing.
> + * CPU PMU identification and probing. Its possible to have
> + * multiple CPU types in an ARM machine. Assure that we are
> + * picking the right PMU types based on the CPU in question
>   */
> -static int probe_current_pmu(struct arm_pmu *pmu,
> -			     const struct pmu_probe_info *info)
> +static int probe_plat_pmu(struct arm_pmu *pmu,
> +			     const struct pmu_probe_info *info,
> +			     unsigned int pmuid)
>  {
> -	int cpu = get_cpu();
> -	unsigned int cpuid = read_cpuid_id();
>  	int ret = -ENODEV;
> +	int cpu;
> +	int aff_ctr = 0;
> +	static int duplicate_pmus;
> +	struct platform_device *pdev = pmu->plat_device;
> +	int irq = platform_get_irq(pdev, 0);
>  
> -	pr_info("probing PMU on CPU %d\n", cpu);
> +	if (irq >= 0 && !irq_is_percpu(irq)) {
> +		pmu->irq_affinity = kcalloc(pdev->num_resources, sizeof(int),
> +					    GFP_KERNEL);
> +		if (!pmu->irq_affinity)
> +			return -ENOMEM;
> +	}
>  
> +	for_each_possible_cpu(cpu) {
> +		unsigned int cpuid = read_specific_cpuid(cpu);
> +
> +		if (cpuid == pmuid) {
> +			cpumask_set_cpu(cpu, &pmu->supported_cpus);
> +			if (pmu->irq_affinity) {
> +				pmu->irq_affinity[aff_ctr] = cpu;
> +				aff_ctr++;
> +			}
> +		}
> +	}
> +
> +	/* find the type of PMU given the CPU */
>  	for (; info->init != NULL; info++) {
> -		if ((cpuid & info->mask) != info->cpuid)
> +		if ((pmuid & info->mask) != info->cpuid)
>  			continue;
>  		ret = info->init(pmu);
> +		/*
> +		 * if this pmu declaration is unspecified and we have
> +		 * previously found a PMU on this platform then append
> +		 * a PMU number to the pmu name. This avoids changing
> +		 * the names of PMUs that are specific to a class of CPUs.
> +		 * The assumption is that if we match a specific PMU in the
> +		 * provided pmu_probe_info then it's unique, and another PMU
> +		 * in the system will match a different entry rather than
> +		 * needing the _number to assure its unique.
> +		 */
> +		if ((!info->cpuid) && (duplicate_pmus)) {

This is a bit grim: if you had a PMU with a non-zero info->cpuid, then you
later found a PMU with a zeroed info->cpuid, the latter would get a
redundant suffix. This doesn't happen in reality, because the ACPI case
always has info->cpuid == 0, but if somebody extends armv8_pmu_probe_table
then we'd get this and probably not realise.

I think the duplicate_pmus counter needs to be tied explicitly to the
"default type" (i.e. when info->cpuid == 0, but see my next comment).

> +			pmu->name = kasprintf(GFP_KERNEL, "%s_%d",
> +					    pmu->name, duplicate_pmus);
> +			if (!pmu->name) {
> +				kfree(pmu->irq_affinity);
> +				ret = -ENOMEM;
> +			}
> +		}

This code doesn't run for the device-tree probing case, but I think it would
be useful to do the same numbering trick for e.g. systems with multiple PMUs
that all end up matching on armv8_pmuv3.

Will

^ permalink raw reply

* [PATCH v9 06/11] arm/arm64: vgic: Implement VGICv3 CPU interface access
From: Christoffer Dall @ 2016-11-29 10:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CALicx6uK9kQ5fuW=SGnny7oerPbhGbVDw=MMi0Tna_B4XdJqeg@mail.gmail.com>

On Tue, Nov 29, 2016 at 03:31:44PM +0530, Vijay Kilari wrote:
> On Tue, Nov 29, 2016 at 2:07 PM, Christoffer Dall
> <christoffer.dall@linaro.org> wrote:
> > On Tue, Nov 29, 2016 at 01:08:26PM +0530, Vijay Kilari wrote:
> >> On Tue, Nov 29, 2016 at 1:09 AM, Christoffer Dall
> >> <christoffer.dall@linaro.org> wrote:
> >> > On Wed, Nov 23, 2016 at 06:31:53PM +0530, vijay.kilari at gmail.com wrote:
> >> >> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >> >>
> >> >> VGICv3 CPU interface registers are accessed using
> >> >> KVM_DEV_ARM_VGIC_CPU_SYSREGS ioctl. These registers are accessed
> >> >> as 64-bit. The cpu MPIDR value is passed along with register id.
> >> >> is used to identify the cpu for registers access.
> >> >>
> >> >> The VM that supports SEIs expect it on destination machine to handle
> >> >> guest aborts and hence checked for ICC_CTLR_EL1.SEIS compatibility.
> >> >> Similarly, VM that supports Affinity Level 3 that is required for AArch64
> >> >> mode, is required to be supported on destination machine. Hence checked
> >> >> for ICC_CTLR_EL1.A3V compatibility.
> >> >>
> >> >> The CPU system register handling is spitted into two files
> >> >
> >> > spitted?  Did you mean 'split into' ?
> >> >
> >> >> vgic-sys-reg-common.c and vgic-sys-reg-v3.c.
> >> >> The vgic-sys-reg-common.c handles read and write of VGIC CPU registers
> >> >
> >> > So this is weird because everything in virt/kvm/arm/ is exactly supposed
> >> > to be common between arm and arm64 already.
> >> >
> >> > I would rather that you had a copy of vgic-sys-reg-v3.c in arch/arm/kvm/
> >> > and in arch/arm64/kvm/ each taking care of its own architecture.
> >> >
> >> > But note that I didn't actually require that you implemented support for
> >> > GICv3 migration on AArch32 hosts for these patches, I just didn't want
> >> > thigns to silently break.
> >> >
> >> > If we cannot test the AArch32 implementation, we should potentially just
> >> > make sure that is not supported yet, return a proper error to userspace
> >> > and get the AArch64 host implementation correct.
> >> >
> >> > I suggest you move your:
> >> >   virt/kvm/arm/vgic/vgic-sys-reg-v3.c to
> >> >   arch/arm64/kvm/vgic-sys-reg-v3.c
> >> >
> >> > and rename
> >> >   virt/kvm/arm/vgic/vgic-sys-reg-common.c to
> >> >   virt/kvm/arm/vgic/vgic-sys-reg-v3.c
> >> >
> >> > And then wait with the AArch32 host side for now, but just make sure it
> >> > compiles and returns an error as opposed to crashing the system if
> >> > someone tries to excercise this interface on an AArch32 host.
> >>
> >> I will add arch/arm/kvm/vgic-coproc-v3.c (pls check if file name is ok or not?)
> >
> > I would call it vgic-v3-coproc.c
> >
> >> and return -ENXIO as shown below and update document accordingly.
> >>
> >> int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> >>                                u64 *reg)
> >> {
> >>        /*
> >>         * TODO: Implement for AArch32
> >>         */
> >>        return -ENXIO;
> >> }
> >>
> >> int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> >>                                u64 *reg)
> >> {
> >>        /*
> >>         * TODO: Implement for AArch32
> >>         */
> >>        return -ENXIO;
> >> }
> >
> >
> >>
> >> >
> >> >> for both AArch64 and AArch32 mode. The vgic-sys-reg-v3.c handles AArch64
> >> >> mode and is compiled only for AArch64 mode.
> >> >>
> >> >> Updated arch/arm/include/uapi/asm/kvm.h with new definitions
> >> >> required to compile for AArch32.
> >> >>
> >> >> The version of VGIC v3 specification is define here
> >> >> Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> >> >>
> >> >> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
> >> >> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >> >> ---
> >> [...]
> >> >> +static bool access_gic_aprn(struct kvm_vcpu *vcpu, bool is_write, u8 apr,
> >> >> +                         u8 idx, unsigned long *reg)
> >> >> +{
> >> >> +     struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
> >> >> +
> >> >> +     /* num_pri_bits are initialized with HW supported values.
> >> >> +      * We can rely safely on num_pri_bits even if VM has not
> >> >> +      * restored ICC_CTLR_EL1 before restoring APnR registers.
> >> >> +      */
> >> >
> >> > nit: commenting style
> >> ok
> >> >
> >> >> +     switch (vgic_v3_cpu->num_pri_bits) {
> >> >> +     case 7:
> >> >> +             vgic_v3_access_apr_reg(vcpu, is_write, apr, idx, reg);
> >> >> +             break;
> >> >> +     case 6:
> >> >> +             if (idx > 1)
> >> >> +                     goto err;
> >> >> +             vgic_v3_access_apr_reg(vcpu, is_write, apr, idx, reg);
> >> >> +             break;
> >> >> +     default:
> >> >> +             if (idx > 0)
> >> >> +                     goto err;
> >> >> +             vgic_v3_access_apr_reg(vcpu, is_write, apr, idx, reg);
> >> >> +     }
> >> >
> >> > It looks to me like userspace can then program active priorities with
> >> > higher numbers than what it will program num_pri_bits to later.  Is that
> >> > not weird, or am I missing something?
> >>
> >> As long as it is within HW supported priorities it is safe.
> >
> > I know that it is safe on the hardware, but it is weird to define a VM
> > with some max priority and still be able to set a higher active priority
> > is it not?
> 
> In that case, we need to cache the highest active priorities updated
> by a VM in a variable
> when APnR is restored and later check against num_pri_bits when
> ICC_CTLR_EL1 is updated.
> If the value cached is greater than num_pri_bits restored then reject
> ICC_CTLR_EL1 restore.
> 
> This variable should be initialized with value 5 ( min priority)
> 
> >
> > On the other hand, if we cannot enforce this at runtime, it may not
> > matter?
> 
> At VM runtime irrespective of VM's num_pri_bits all the APnR registers that
> HW supports are saved and restored.
> 

Yes, never mind my comment.  Since we cannot enforce this constraint
once the VM runs, I don't think there's any concern here.

> >> >
> >> >> +
> >> >> +     return true;
> >> >> +err:
> >> >> +     if (!is_write)
> >> >> +             *reg = 0;
> >> >> +
> >> >> +     return false;
> >> >> +}
> >> >> +
> >> >> +bool access_gic_ap0r_reg(struct kvm_vcpu *vcpu, bool is_write, u8 idx,
> >> >> +                      unsigned long *reg)
> >> >> +{
> >> >> +     return access_gic_aprn(vcpu, is_write, 0, idx, reg);
> >> >> +}
> >> >> +
> >> >> +bool access_gic_ap1r_reg(struct kvm_vcpu *vcpu, bool is_write, u8 idx,
> >> >> +                      unsigned long *reg)
> >> >> +{
> >> >> +     return access_gic_aprn(vcpu, is_write, 1, idx, reg);
> >> >> +}
> >> >> +
> >> >> +bool access_gic_sre_reg(struct kvm_vcpu *vcpu, bool is_write,
> >> >> +                     unsigned long *reg)
> >> >> +{
> >> >> +     struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
> >> >> +
> >> >> +     /* Validate SRE bit */
> >> >> +     if (is_write) {
> >> >> +             if (!(*reg & ICC_SRE_EL1_SRE))
> >> >> +                     return false;
> >> >> +     } else {
> >> >> +             *reg = vgicv3->vgic_sre;
> >> >> +     }
> >> >> +
> >> >> +     return true;
> >> >> +}
> >> >> diff --git a/virt/kvm/arm/vgic/vgic-sys-reg-v3.c b/virt/kvm/arm/vgic/vgic-sys-reg-v3.c
> >> >> new file mode 100644
> >> >> index 0000000..82c2f02
> >> >> --- /dev/null
> >> >> +++ b/virt/kvm/arm/vgic/vgic-sys-reg-v3.c
> >> >> @@ -0,0 +1,142 @@
> >> >> +/*
> >> >> + * VGIC system registers handling functions
> >> >> + *
> >> >> + * 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.
> >> >> + *
> >> >> + * This program is distributed in the hope that it will be useful,
> >> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> >> + * GNU General Public License for more details.
> >> >> + */
> >> >> +
> >> >> +#include <linux/kvm.h>
> >> >> +#include <linux/kvm_host.h>
> >> >> +#include <asm/kvm_emulate.h>
> >> >> +#include "vgic.h"
> >> >> +#include "sys_regs.h"
> >> >> +
> >> >> +#define ACCESS_SYS_REG(REG)                                          \
> >> >> +static bool access_gic_##REG##_sys_reg(struct kvm_vcpu *vcpu,                \
> >> >> +                                 struct sys_reg_params *p,           \
> >> >> +                                 const struct sys_reg_desc *r)       \
> >> >> +{                                                                    \
> >> >> +     unsigned long tmp;                                              \
> >> >> +     bool ret;                                                       \
> >> >> +                                                                     \
> >> >> +     if (p->is_write)                                                \
> >> >> +             tmp = p->regval;                                        \
> >> >> +     ret = access_gic_##REG##_reg(vcpu, p->is_write, &tmp);          \
> >> >> +     if (!p->is_write)                                               \
> >> >> +             p->regval = tmp;                                        \
> >> >> +                                                                     \
> >> >> +     return ret;                                                     \
> >> >> +}
> >> >> +
> >> >> +ACCESS_SYS_REG(ctlr)
> >> >> +ACCESS_SYS_REG(pmr)
> >> >> +ACCESS_SYS_REG(bpr0)
> >> >> +ACCESS_SYS_REG(bpr1)
> >> >> +ACCESS_SYS_REG(sre)
> >> >> +ACCESS_SYS_REG(grpen0)
> >> >> +ACCESS_SYS_REG(grpen1)
> >> >> +
> >> >> +#define ACCESS_APNR_SYS_REG(REG)                                     \
> >> >> +static bool access_gic_##REG##_sys_reg(struct kvm_vcpu *vcpu,                \
> >> >> +                                 struct sys_reg_params *p,           \
> >> >> +                                 const struct sys_reg_desc *r)       \
> >> >> +{                                                                    \
> >> >> +     unsigned long tmp;                                              \
> >> >> +     u8 idx = p->Op2 & 3;                                            \
> >> >> +     bool ret;                                                       \
> >> >> +                                                                     \
> >> >> +     if (p->is_write)                                                \
> >> >> +             tmp = p->regval;                                        \
> >> >> +     ret = access_gic_##REG##_reg(vcpu, p->is_write, idx, &tmp);     \
> >> >> +     if (!p->is_write)                                               \
> >> >> +             p->regval = tmp;                                        \
> >> >> +                                                                     \
> >> >> +     return ret;                                                     \
> >> >> +}
> >> >> +
> >> >> +ACCESS_APNR_SYS_REG(ap0r)
> >> >> +ACCESS_APNR_SYS_REG(ap1r)
> >> >
> >> > I don't get these indirections.  Why can't you call the functions
> >> > directly?
> >>
> >> The code is same for accessing the registers hence added this indirection.
> >>
> >
> > That's not answering my question.
> >
> > What is the benefit of adding this indirection as opposed to having the
> > functions called directly?
> 
> In sys_reg_desc the access function is of type
> 
>         bool (*access)(struct kvm_vcpu *,
>                        struct sys_reg_params *,
>                        const struct sys_reg_desc *);
> 
> Where as the each register access function is of type below to support
> access to AArch32(later if not now).
> 
> bool access_gic_xxx(struct kvm_vcpu *vcpu, bool is_write, unsigned long *reg);
> 
> I can drop this macro and make function calls for each reg access.
> 

Please don't worry about the 32-bit side until we actually implement
that.  And once we do, we can move things around in patches to support
the 32-bit side so that it makes sense to the reader.

So, for now, just have this one file, moved to arch/arm64/kvm/ where all
the access functions are static in this file and called directly from
the single dispatch function.

Thanks,
-Christoffer

^ permalink raw reply

* [PATCH V2 fix 5/6] mm: hugetlb: add a new function to allocate a new gigantic page
From: Vlastimil Babka @ 2016-11-29 10:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161129090322.GB16569@sha-win-210.asiapac.arm.com>

On 11/29/2016 10:03 AM, Huang Shijie wrote:
> On Mon, Nov 28, 2016 at 03:17:28PM +0100, Vlastimil Babka wrote:
>> On 11/16/2016 07:55 AM, Huang Shijie wrote:
>> > +static struct page *__hugetlb_alloc_gigantic_page(struct hstate *h,
>> > +		struct vm_area_struct *vma, unsigned long addr, int nid)
>> > +{
>> > +	NODEMASK_ALLOC(nodemask_t, nodes_allowed, GFP_KERNEL | __GFP_NORETRY);
>>
>> What if the allocation fails and nodes_allowed is NULL?
>> It might work fine now, but it's rather fragile, so I'd rather see an
> Yes.
>
>> explicit check.
> See the comment below.
>
>>
>> BTW same thing applies to __nr_hugepages_store_common().
>>
>> > +	struct page *page = NULL;
>> > +
>> > +	/* Not NUMA */
>> > +	if (!IS_ENABLED(CONFIG_NUMA)) {
>> > +		if (nid == NUMA_NO_NODE)
>> > +			nid = numa_mem_id();
>> > +
>> > +		page = alloc_gigantic_page(nid, huge_page_order(h));
>> > +		if (page)
>> > +			prep_compound_gigantic_page(page, huge_page_order(h));
>> > +
>> > +		NODEMASK_FREE(nodes_allowed);
>> > +		return page;
>> > +	}
>> > +
>> > +	/* NUMA && !vma */
>> > +	if (!vma) {
>> > +		if (nid == NUMA_NO_NODE) {
>> > +			if (!init_nodemask_of_mempolicy(nodes_allowed)) {
>> > +				NODEMASK_FREE(nodes_allowed);
>> > +				nodes_allowed = &node_states[N_MEMORY];
>> > +			}
>> > +		} else if (nodes_allowed) {
> The check is here.

It's below a possible usage of nodes_allowed as an argument of 
init_nodemask_of_mempolicy(mask). Which does

         if (!(mask && current->mempolicy))
                 return false;

which itself looks like an error at first sight :)

> Do we really need to re-arrange the code here for the explicit check? :)

We don't need it *now* to be correct, but I still find it fragile. Also it
mixes up the semantic of NULL as a conscious "default" value, and NULL as
a side-effect of memory allocation failure. Nothing good can come from that in 
the long term :)

> Thanks
> Huang Shijie
>> > +			init_nodemask_of_node(nodes_allowed, nid);
>> > +		} else {
>> > +			nodes_allowed = &node_states[N_MEMORY];
>> > +		}
>> > +
>> > +		page = alloc_fresh_gigantic_page(h, nodes_allowed, true);
>> > +
>

^ permalink raw reply

* [PATCH] ARM: davinci: da8xx: Fix sleeping function called from invalid context
From: Sekhar Nori @ 2016-11-29 10:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480350566-26225-1-git-send-email-abailon@baylibre.com>

On Monday 28 November 2016 09:59 PM, Alexandre Bailon wrote:
> Everytime the usb20 phy is enabled, there is a
> "sleeping function called from invalid context" BUG.

Who calls PHY clk_enable() from non-preemptible context? Can you provide
the call stack?

> usb20_phy_clk_enable(), called with the irq disabled uses
> clk_get() and clk_enable_prepapre() which may sleep.
> Move clk_get() to da8xx_register_usb20_phy_clk() and
> replace clk_prepare_enable() by clk_enable().
> 
> Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
> ---
>  arch/arm/mach-davinci/usb-da8xx.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
> index b010e5f..c9b5cd4 100644
> --- a/arch/arm/mach-davinci/usb-da8xx.c
> +++ b/arch/arm/mach-davinci/usb-da8xx.c
> @@ -156,23 +156,23 @@ int __init da8xx_register_usb_refclkin(int rate)
>  	return 0;
>  }
>  
> +static struct clk *usb20_clk;
> +
>  static void usb20_phy_clk_enable(struct clk *clk)
>  {
> -	struct clk *usb20_clk;
>  	int err;
>  	u32 val;
>  	u32 timeout = 500000; /* 500 msec */
>  
>  	val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
>  
> -	usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
> -	if (IS_ERR(usb20_clk)) {
> +	if (!usb20_clk || IS_ERR(usb20_clk)) {

NULL is a valid clock handle. There is no way clock enable of
usb20_phy_clk can be invoked if its not registered. So, you can assume
that usb20_clk is valid if you get here.

>  		pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk));
>  		return;
>  	}
>  
>  	/* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
> -	err = clk_prepare_enable(usb20_clk);
> +	err = clk_enable(usb20_clk);
>  	if (err) {
>  		pr_err("failed to enable usb20 clk: %d\n", err);
>  		clk_put(usb20_clk);
> @@ -197,8 +197,7 @@ static void usb20_phy_clk_enable(struct clk *clk)
>  
>  	pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
>  done:
> -	clk_disable_unprepare(usb20_clk);
> -	clk_put(usb20_clk);
> +	clk_disable(usb20_clk);


I noticed that we are missing clk_disable(usb20_clk) in
usb20_phy_clk_disable(). It will now be easier to do that after this
patch. Can you add that in a separate patch?

>  }
>  
>  static void usb20_phy_clk_disable(struct clk *clk)
> @@ -287,6 +286,10 @@ int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
>  	struct clk *parent;
>  	int ret = 0;
>  
> +	usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
> +	if (IS_ERR(usb20_clk))
> +		return PTR_ERR(parent);
> +
>  	parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
>  	if (IS_ERR(parent))
>  		return PTR_ERR(parent);

clk_put(usb20_clk) should be called here on failure path.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH] KVM: arm/arm64: Access CNTHCTL_EL2 bit fields correctly
From: Christoffer Dall @ 2016-11-29 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c75fe6ae-8ae0-285d-6f47-3e28c7e8f431@arm.com>

On Tue, Nov 29, 2016 at 09:37:07AM +0000, Marc Zyngier wrote:
> On 28/11/16 19:42, Christoffer Dall wrote:
> > On Mon, Nov 28, 2016 at 06:39:04PM +0000, Marc Zyngier wrote:
> >> On 28/11/16 17:43, Marc Zyngier wrote:
> >>> Hi Jintack,
> >>>
> >>> On 28/11/16 16:46, Jintack Lim wrote:
> >>>> Bit positions of CNTHCTL_EL2 are changing depending on HCR_EL2.E2H bit.
> >>>> EL1PCEN and EL1PCTEN are 1st and 0th bits when E2H is not set, but they
> >>>> are 11th and 10th bits respectively when E2H is set.  Current code is
> >>>> unintentionally setting wrong bits to CNTHCTL_EL2 with E2H set, which
> >>>> may allow guest OS to access physical timer. So, fix it.
> >>>>
> >>>> Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
> >>>> ---
> >>>>  arch/arm/include/asm/kvm_timer.h     | 33 +++++++++++++++++++
> >>>>  arch/arm64/include/asm/kvm_timer.h   | 62 ++++++++++++++++++++++++++++++++++++
> >>>>  include/clocksource/arm_arch_timer.h |  6 ++--
> >>>>  virt/kvm/arm/hyp/timer-sr.c          |  8 ++---
> >>>>  4 files changed, 103 insertions(+), 6 deletions(-)
> >>>>  create mode 100644 arch/arm/include/asm/kvm_timer.h
> >>>>  create mode 100644 arch/arm64/include/asm/kvm_timer.h
> >>>>
> >>
> >> [...]
> >>
> >>> We could make it nicer (read "faster") by introducing a
> >>> hyp_alternate_select construct that only returns a value instead
> >>> of calling a function. I remember writing something like that
> >>> at some point, and dropping it...
> >>
> >> So here's what this could look like (warning, wacky code ahead,
> >> though I fixed a stupid bug that was present in the previous patch).
> >> The generated code is quite nice (no branch, only an extra mov
> >> instruction on the default path)... Of course, completely untested!
> > 
> > Isn't this all about determining which bitmask to use, statically, once,
> > after the system has booted?
> > 
> > How about a good old fashioned static variable, or global struct like
> > the global one we use for the VGIC, which sets the proper mit mask
> > during kvm init, and the world-switch code just uses a variable?
> 
> We could indeed do that (I've been carried away with my tendency for
> weird and wonderful hacks).
> 
> But as Jintack mentioned, there is a much better approach, which is to
> do nothing at all on the VHE path (we can set the permission bits once
> and for all). cntvoff_el2 also falls into the same category of things we
> should be able to only restore and not bother resetting (as it doesn't
> affect the EL2 virtual counter).
> 
> Thoughts?
> 
Yes, that sounds much better.

I have some patches to get rid of a lot of things, like cntvoff, during
the world-switch for VHE, so if Jintack just wants to focus on the
cnthctl I will catch cntvoff later.

-Christoffer

^ permalink raw reply

* [PATCH 4/4] MAINTAINERS: add entry for Amlogic DRM drivers
From: Neil Armstrong @ 2016-11-29 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480416469-9655-1-git-send-email-narmstrong@baylibre.com>

Add myself as maintainer for Amlogic DRM drivers.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9cab85a..b6e80c5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4085,6 +4085,15 @@ S:	Supported
 F:	drivers/gpu/drm/sun4i/
 F:	Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
 
+DRM DRIVERS FOR AMLOGIC SOCS
+M:	Neil Armstrong <narmstrong@baylibre.com>
+L:	dri-devel at lists.freedesktop.org
+L:	linux-amlogic at lists.infradead.org
+W:	http://linux-meson.com/
+S:	Supported
+F:	drivers/gpu/drm/meson/
+F:	Documentation/devicetree/bindings/display/meson/meson-drm.txt
+
 DRM DRIVERS FOR EXYNOS
 M:	Inki Dae <inki.dae@samsung.com>
 M:	Joonyoung Shim <jy0922.shim@samsung.com>
-- 
1.9.1

^ permalink raw reply related

* [PATCH 3/4] dt-bindings: display: add Amlogic Meson DRM Bindings
From: Neil Armstrong @ 2016-11-29 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480416469-9655-1-git-send-email-narmstrong@baylibre.com>

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 .../bindings/display/meson/meson-drm.txt           | 134 +++++++++++++++++++++
 1 file changed, 134 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/meson/meson-drm.txt

diff --git a/Documentation/devicetree/bindings/display/meson/meson-drm.txt b/Documentation/devicetree/bindings/display/meson/meson-drm.txt
new file mode 100644
index 0000000..cf241be
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/meson/meson-drm.txt
@@ -0,0 +1,134 @@
+Amlogic Meson Display Controller
+================================
+
+The Amlogic Meson Display controller is composed of several components
+that are going to be documented below:
+
+DMC|---------------VPU (Video Processing Unit)----------------|------HHI------|
+   | vd1   _______     _____________    _________________     |               |
+D  |-------|      |----|            |   |                |    |   HDMI PLL    |
+D  | vd2   | VIU  |    | Video Post |   | Video Encoders |<---|-----VCLK      |
+R  |-------|      |----| Processing |   |                |    |               |
+   | osd2  |      |    |            |---| Enci ----------|----|-----VDAC------|
+R  |-------| CSC  |----| Scalers    |   | Encp ----------|----|----HDMI-TX----|
+A  | osd1  |      |    | Blenders   |   | Encl ----------|----|---------------|
+M  |-------|______|----|____________|   |________________|    |               |
+___|__________________________________________________________|_______________|
+
+
+VIU: Video Input Unit
+---------------------
+
+The Video Input Unit is in charge of the pixel scanout from the DDR memory.
+It fetches the frames addresses, stride and parameters from the "Canvas" memory.
+This part is also in charge of the CSC (Colorspace Conversion).
+It can handle 2 OSD Planes and 2 Video Planes.
+
+VPP: Video Post Processing
+--------------------------
+
+The Video Post Processing is in charge of the scaling and blending of the
+various planes into a single pixel stream.
+There is a special "pre-blending" used by the video planes with a dedicated
+scaler and a "post-blending" to merge with the OSD Planes.
+The OSD planes also have a dedicated scaler for one of the OSD.
+
+VENC: Video Encoders
+--------------------
+
+The VENC is composed of the multiple pixel encoders :
+ - ENCI : Interlace Video encoder for CVBS and Interlace HDMI
+ - ENCP : Progressive Video Encoder for HDMI
+ - ENCL : LCD LVDS Encoder
+The VENC Unit gets a Pixel Clocks (VCLK) from a dedicated HDMI PLL and clock
+tree and provides the scanout clock to the VPP and VIU.
+The ENCI is connected to a single VDAC for Composite Output.
+The ENCI and ENCP are connected to an on-chip HDMI Transceiver.
+
+Device Tree Bindings:
+---------------------
+
+VPU: Video Processing Unit
+--------------------------
+
+Required properties:
+- compatible: value should be different for each SoC family as :
+	- GXBB (S905) : "amlogic,meson-gxbb-vpu"
+	- GXL (S905X, S905D) : "amlogic,meson-gxl-vpu"
+	- GXM (S912) : "amlogic,meson-gxm-vpu"
+	followed by the common "amlogic,meson-gx-vpu"
+- reg: base address and size of he following memory-mapped regions :
+	- vpu
+	- hhi
+	- dmc
+- reg-names: should contain the names of the previous memory regions
+- interrupts: should contain the VENC Vsync interrupt number
+
+- ports: A ports node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt. The
+  second port should be the output endpoints for VENC connectors.
+
+CBVS Output
+-----------
+
+The VENC can output Composite/CVBS output via a dedicated VDAC, usage of such
+Composite output is optional.
+
+Required properties:
+- compatible: value should be different for each SoC family as :
+ 	- GXBB (S905) : "amlogic,meson-gxbb-cvbs"
+ 	- GXL (S905X, S905D) : "amlogic,meson-gxl-cvbs"
+ 	- GXM (S912) : "amlogic,meson-gxm-cvbs"
+	followed by the common "amlogic,meson-gx-cvbs"
+
+- ports: A ports node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt. The
+  first port should be the input endpoints, connected ot the VPU node.
+
+Example:
+
+venc_cvbs: venc-cvbs {
+	compatible = "amlogic,meson-gxbb-cvbs";
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		enc_cvbs_in: port at 0 {
+			 #address-cells = <1>;
+			 #size-cells = <0>;
+			 reg = <0>;
+
+			 venc_cvbs_in_vpu: endpoint at 0 {
+				 reg = <0>;
+				 remote-endpoint = <&vpu_out_venc_cvbs>;
+			};
+		};
+	};
+};
+
+vpu: vpu at d0100000 {
+	compatible = "amlogic,meson-gxbb-vpu";
+	reg = <0x0 0xd0100000 0x0 0x100000>,
+	      <0x0 0xc883c000 0x0 0x1000>,
+	      <0x0 0xc8838000 0x0 0x1000>;
+	reg-names = "base", "hhi", "dmc";
+	interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		vpu_out: port at 1 {
+			 #address-cells = <1>;
+			 #size-cells = <0>;
+			 reg = <1>;
+
+			 vpu_out_venc_cvbs: endpoint at 0 {
+				 reg = <0>;
+				 remote-endpoint = <&venc_cvbs_in_vpu>;
+			 };
+		 };
+	};
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/4] ARM64: dts: meson-gx: Add Graphic Controller nodes
From: Neil Armstrong @ 2016-11-29 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480416469-9655-1-git-send-email-narmstrong@baylibre.com>

Add Video Processing Unit and CVBS Output nodes, and enable CVBS on selected
boards.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi          | 46 ++++++++++++++++++++++
 .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts    |  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi   |  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi        |  8 ++++
 .../boot/dts/amlogic/meson-gxl-nexbox-a95x.dts     |  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi         |  8 ++++
 .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts |  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxm.dtsi         |  8 ++++
 8 files changed, 86 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index fc033c0..644d5f6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -153,6 +153,27 @@
 		};
 	};
 
+	venc_cvbs: venc-cvbs {
+		compatible = "amlogic,meson-gx-cvbs";
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			venc_cvbs_in: port at 0 {
+				 #address-cells = <1>;
+				 #size-cells = <0>;
+				 reg = <0>;
+
+				 venc_cvbs_in_vpu: endpoint at 0 {
+					 reg = <0>;
+					 remote-endpoint = <&vpu_out_venc_cvbs>;
+				};
+			};
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -356,5 +377,30 @@
 				status = "disabled";
 			};
 		};
+
+		vpu: vpu at d0100000 {
+			compatible = "amlogic,meson-gx-vpu";
+			reg = <0x0 0xd0100000 0x0 0x100000>,
+			      <0x0 0xc883c000 0x0 0x1000>,
+			      <0x0 0xc8838000 0x0 0x1000>;
+			reg-names = "base", "hhi", "dmc";
+			interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				vpu_out: port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					vpu_out_venc_cvbs: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&venc_cvbs_in_vpu>;
+					};
+				};
+			};
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
index 9696820..a55d1cf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -229,3 +229,7 @@
 	clocks = <&clkc CLKID_FCLK_DIV4>;
 	clock-names = "clkin0";
 };
+
+&venc_cvbs {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 5e5e2de..3c09bd1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -266,3 +266,7 @@
 	clocks = <&clkc CLKID_FCLK_DIV4>;
 	clock-names = "clkin0";
 };
+
+&venc_cvbs {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index ac5ad3b..1a321c8f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -506,3 +506,11 @@
 		 <&clkc CLKID_FCLK_DIV2>;
 	clock-names = "core", "clkin0", "clkin1";
 };
+
+&venc_cvbs {
+	compatible = "amlogic,meson-gxbb-cvbs", "amlogic,meson-gx-cvbs";
+};
+
+&vpu {
+	compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
index e99101a..2a9b46f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
@@ -203,3 +203,7 @@
 	clocks = <&clkc CLKID_FCLK_DIV4>;
 	clock-names = "clkin0";
 };
+
+&venc_cvbs {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 3af54dc..b60c5ce 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -299,3 +299,11 @@
 		 <&clkc CLKID_FCLK_DIV2>;
 	clock-names = "core", "clkin0", "clkin1";
 };
+
+&venc_cvbs {
+	compatible = "amlogic,meson-gxl-cvbs", "amlogic,meson-gx-cvbs";
+};
+
+&vpu {
+	compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
index d320727..1ae2451 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
@@ -167,3 +167,7 @@
 		max-speed = <1000>;
 	};
 };
+
+&venc_cvbs {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
index c1974bb..fecd8c2 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
@@ -112,3 +112,11 @@
 		};
 	};
 };
+
+&venc_cvbs {
+	compatible = "amlogic,meson-gxm-cvbs", "amlogic,meson-gx-cvbs";
+};
+
+&vpu {
+	compatible = "amlogic,meson-gxm-vpu", "amlogic,meson-gx-vpu";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/4] drm: Add support for the Amlogic Video Processing Unit
From: Neil Armstrong @ 2016-11-29 10:47 UTC (permalink / raw)
  To: linux-arm-kernel

This a repost of the previous RFC at [1] with fixes, the following patches will
be sent via a PULL Request once the Amlogic maintainer acks and takes the DT
patches to avoid merges conflicts.

The Amlogic Meson SoCs embeds a Video Processing Unit able to output at least
a Composite/CVBS Video with embedded VDAC and an HDMI Link with Embedded HDMI
Transceiver.

Thus, the current driver does not support HDMI yet.

The Video Processig Unit is composed of multiple modules like the Video
Input Unit and the Video Post Processing that can be associated to a
CRTC with Planes management.
The last Unit is the Venc that embeds at least 3 Encoders, ENCI for Interlace
Video used by CVBS or HDMI, ENCP for Progressive Video used by the HDMI
Transceiver and ENCL for LCD Display.

The LCD Display is not planned to be supported on the Meson GX Family.

This driver is a DRM/KMS driver using the following DRM components :
 - GEM-CMA
 - PRIME-CMA
 - Atomic Modesetting
 - FBDev-CMA

For the following SoCs :
 - GXBB Family (S905)
 - GXL Family (S905X, S905D)
 - GXM Family (S912)

The current driver only supports the CVBS PAL/NTSC output modes, but the
CRTC/Planes management should support bigger modes.
But Advanced Colorspace Conversion, Scaling and HDMI Modes will be added in
a second time.

The Device Tree bindings makes use of the endpoints video interface definitions
to connect to the optional CVBS and in the future the HDMI Connector nodes.

The driver has been tested with Xorg modesetting driver and Weston DRM backend.

Changes since RFC at [1] :
 - Add maintainers entry
 - Move all Plane and CRTC code from backend to corresponding DRM code
 - Keep only init and common code in backend source files
 - Move the CVBS encoder out of the CVBS DT node, only keep the connector
 - Various cleanups using DRM helpers
 - Cleanup of copyright headers
 - Fixup of bindings documentation

[1] http://lkml.kernel.org/r/1480089791-12517-1-git-send-email-narmstrong at baylibre.com

Neil Armstrong (4):
  drm: Add support for Amlogic Meson Graphic Controller
  ARM64: dts: meson-gx: Add Graphic Controller nodes
  dt-bindings: display: add Amlogic Meson DRM Bindings
  MAINTAINERS: add entry for Amlogic DRM drivers

 .../bindings/display/meson/meson-drm.txt           |  134 ++
 MAINTAINERS                                        |    9 +
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi          |   46 +
 .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts    |    4 +
 arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi   |    4 +
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi        |    8 +
 .../boot/dts/amlogic/meson-gxl-nexbox-a95x.dts     |    4 +
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi         |    8 +
 .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts |    4 +
 arch/arm64/boot/dts/amlogic/meson-gxm.dtsi         |    8 +
 drivers/gpu/drm/Kconfig                            |    2 +
 drivers/gpu/drm/Makefile                           |    1 +
 drivers/gpu/drm/meson/Kconfig                      |    9 +
 drivers/gpu/drm/meson/Makefile                     |    5 +
 drivers/gpu/drm/meson/meson_canvas.c               |   68 +
 drivers/gpu/drm/meson/meson_canvas.h               |   42 +
 drivers/gpu/drm/meson/meson_crtc.c                 |  208 +++
 drivers/gpu/drm/meson/meson_crtc.h                 |   32 +
 drivers/gpu/drm/meson/meson_cvbs.c                 |  177 +++
 drivers/gpu/drm/meson/meson_drv.c                  |  385 ++++++
 drivers/gpu/drm/meson/meson_drv.h                  |   61 +
 drivers/gpu/drm/meson/meson_plane.c                |  230 ++++
 drivers/gpu/drm/meson/meson_plane.h                |   30 +
 drivers/gpu/drm/meson/meson_registers.h            | 1395 ++++++++++++++++++++
 drivers/gpu/drm/meson/meson_vclk.c                 |  167 +++
 drivers/gpu/drm/meson/meson_vclk.h                 |   34 +
 drivers/gpu/drm/meson/meson_venc.c                 |  254 ++++
 drivers/gpu/drm/meson/meson_venc.h                 |   72 +
 drivers/gpu/drm/meson/meson_venc_cvbs.c            |  187 +++
 drivers/gpu/drm/meson/meson_venc_cvbs.h            |   41 +
 drivers/gpu/drm/meson/meson_viu.c                  |  331 +++++
 drivers/gpu/drm/meson/meson_viu.h                  |   64 +
 drivers/gpu/drm/meson/meson_vpp.c                  |  162 +++
 drivers/gpu/drm/meson/meson_vpp.h                  |   35 +
 34 files changed, 4221 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/meson/meson-drm.txt
 create mode 100644 drivers/gpu/drm/meson/Kconfig
 create mode 100644 drivers/gpu/drm/meson/Makefile
 create mode 100644 drivers/gpu/drm/meson/meson_canvas.c
 create mode 100644 drivers/gpu/drm/meson/meson_canvas.h
 create mode 100644 drivers/gpu/drm/meson/meson_crtc.c
 create mode 100644 drivers/gpu/drm/meson/meson_crtc.h
 create mode 100644 drivers/gpu/drm/meson/meson_cvbs.c
 create mode 100644 drivers/gpu/drm/meson/meson_drv.c
 create mode 100644 drivers/gpu/drm/meson/meson_drv.h
 create mode 100644 drivers/gpu/drm/meson/meson_plane.c
 create mode 100644 drivers/gpu/drm/meson/meson_plane.h
 create mode 100644 drivers/gpu/drm/meson/meson_registers.h
 create mode 100644 drivers/gpu/drm/meson/meson_vclk.c
 create mode 100644 drivers/gpu/drm/meson/meson_vclk.h
 create mode 100644 drivers/gpu/drm/meson/meson_venc.c
 create mode 100644 drivers/gpu/drm/meson/meson_venc.h
 create mode 100644 drivers/gpu/drm/meson/meson_venc_cvbs.c
 create mode 100644 drivers/gpu/drm/meson/meson_venc_cvbs.h
 create mode 100644 drivers/gpu/drm/meson/meson_viu.c
 create mode 100644 drivers/gpu/drm/meson/meson_viu.h
 create mode 100644 drivers/gpu/drm/meson/meson_vpp.c
 create mode 100644 drivers/gpu/drm/meson/meson_vpp.h

-- 
1.9.1

^ permalink raw reply

* [PATCH V10 2/6] arm: arm64: Add routine to determine cpuid of other cpus
From: Russell King - ARM Linux @ 2016-11-29 10:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161129103112.GC30283@arm.com>

On Tue, Nov 29, 2016 at 10:31:12AM +0000, Will Deacon wrote:
> [adding Russell]
> 
> On Wed, Nov 09, 2016 at 05:39:49PM -0600, Jeremy Linton wrote:
> > It is helpful if we can read the cpuid/midr of other CPUs
> > in the system independent of arm/arm64.
> > 
> > Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> > ---
> >  arch/arm/include/asm/cputype.h   | 2 ++
> >  arch/arm64/include/asm/cputype.h | 3 +++
> >  2 files changed, 5 insertions(+)
> > 
> > diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
> > index 522b5fe..31fb273 100644
> > --- a/arch/arm/include/asm/cputype.h
> > +++ b/arch/arm/include/asm/cputype.h
> > @@ -235,6 +235,8 @@ static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
> >  #define cpu_is_sa1100() (read_cpuid_part() == ARM_CPU_PART_SA1100)
> >  #define cpu_is_sa1110() (read_cpuid_part() == ARM_CPU_PART_SA1110)
> >  
> > +#define read_specific_cpuid(cpu_num) per_cpu_ptr(&cpu_data, cpu_num)->cpuid
> > +
> >  /*
> >   * Intel's XScale3 core supports some v6 features (supersections, L2)
> >   * but advertises itself as v5 as it does not support the v6 ISA.  For
> 
> Russell -- are you ok with adding this macro to arch/arm/? It will get used
> by the CPU PMU driver, which needs a portable (i.e. between arm and arm64)
> way to convert a logical CPU ID into the MIDR register for that CPU.

No, because we don't set the cpuid member in uniprocessor configurations,
so it's going to be a fragile macro - it'll return zero for kernels
configured without SMP support.

I'd ideally like cpuid for the boot CPU to be set early, so that we can
get rid of many ifdefs in this area, but haven't convinced myself that
it's safe to do so in all configurations with the percpu stuff not being
up and running in setup_arch().

-- 
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 v2 1/6] mm: hugetlb: rename some allocation functions
From: Vlastimil Babka @ 2016-11-29 10:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161129085349.GA16569@sha-win-210.asiapac.arm.com>

On 11/29/2016 09:53 AM, Huang Shijie wrote:
> On Mon, Nov 28, 2016 at 02:29:03PM +0100, Vlastimil Babka wrote:
>> On 11/14/2016 08:07 AM, Huang Shijie wrote:
>> >  static inline bool gigantic_page_supported(void) { return true; }
>> >  #else
>> > +static inline struct page *alloc_gigantic_page(int nid, unsigned int order)
>> > +{
>> > +	return NULL;
>> > +}
>>
>> This hunk is not explained by the description. Could belong to a later
>> patch?
>>
>
> Okay, I can create an extra patch to add the description for the
> alloc_gigantic_page().

Not sure about extra patch, just move it to an existing later patch that relies 
on it?

Vlastimil

> Thanks
> Huang Shijie
>

^ permalink raw reply

* [PATCH v3 net-next 2/6] net: mvneta: Use cacheable memory to store the rx buffer virtual address
From: Gregory CLEMENT @ 2016-11-29 10:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPv3WKetQf_tqva2jaF1y79EWxDo3=yuvbK3jp2uFOqQSGweyA@mail.gmail.com>

Hi Marcin,
 
 On mar., nov. 29 2016, Marcin Wojtas <mw@semihalf.com> wrote:

> Gregory,
>
> 2016-11-29 11:19 GMT+01:00 Gregory CLEMENT <gregory.clement@free-electrons.com>:
>> Hi Marcin,
>>
>>  On mar., nov. 29 2016, Marcin Wojtas <mw@semihalf.com> wrote:
>>
>>> Hi Gregory,
>>>
>>> Another remark below, sorry for noise.
>>>
>>> 2016-11-29 10:37 GMT+01:00 Gregory CLEMENT <gregory.clement@free-electrons.com>:
>>>> Until now the virtual address of the received buffer were stored in the
>>>> cookie field of the rx descriptor. However, this field is 32-bits only
>>>> which prevents to use the driver on a 64-bits architecture.
>>>>
>>>> With this patch the virtual address is stored in an array not shared with
>>>> the hardware (no more need to use the DMA API). Thanks to this, it is
>>>> possible to use cache contrary to the access of the rx descriptor member.
>>>>
>>>> The change is done in the swbm path only because the hwbm uses the cookie
>>>> field, this also means that currently the hwbm is not usable in 64-bits.
>>>>
>>>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>>>> ---
>>>>  drivers/net/ethernet/marvell/mvneta.c | 93 ++++++++++++++++++++++++----
>>>>  1 file changed, 81 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
>>>> index 1b84f746d748..32b142d0e44e 100644
>>>> --- a/drivers/net/ethernet/marvell/mvneta.c
>>>> +++ b/drivers/net/ethernet/marvell/mvneta.c
>>>> @@ -561,6 +561,9 @@ struct mvneta_rx_queue {
>>>>         u32 pkts_coal;
>>>>         u32 time_coal;
>>>>
>>>> +       /* Virtual address of the RX buffer */
>>>> +       void  **buf_virt_addr;
>>>> +
>>>>         /* Virtual address of the RX DMA descriptors array */
>>>>         struct mvneta_rx_desc *descs;
>>>>
>>>> @@ -1573,10 +1576,14 @@ static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
>>>>
>>>>  /* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
>>>>  static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
>>>> -                               u32 phys_addr, u32 cookie)
>>>> +                               u32 phys_addr, void *virt_addr,
>>>> +                               struct mvneta_rx_queue *rxq)
>>>>  {
>>>> -       rx_desc->buf_cookie = cookie;
>>>> +       int i;
>>>> +
>>>>         rx_desc->buf_phys_addr = phys_addr;
>>>> +       i = rx_desc - rxq->descs;
>>>> +       rxq->buf_virt_addr[i] = virt_addr;
>>>>  }
>>>>
>>>>  /* Decrement sent descriptors counter */
>>>> @@ -1781,7 +1788,8 @@ EXPORT_SYMBOL_GPL(mvneta_frag_free);
>>>>
>>>>  /* Refill processing for SW buffer management */
>>>>  static int mvneta_rx_refill(struct mvneta_port *pp,
>>>> -                           struct mvneta_rx_desc *rx_desc)
>>>> +                           struct mvneta_rx_desc *rx_desc,
>>>> +                           struct mvneta_rx_queue *rxq)
>>>>
>>>>  {
>>>>         dma_addr_t phys_addr;
>>>> @@ -1799,7 +1807,7 @@ static int mvneta_rx_refill(struct mvneta_port *pp,
>>>>                 return -ENOMEM;
>>>>         }
>>>>
>>>> -       mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)data);
>>>> +       mvneta_rx_desc_fill(rx_desc, phys_addr, data, rxq);
>>>>         return 0;
>>>>  }
>>>>
>>>> @@ -1861,7 +1869,12 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
>>>>
>>>>         for (i = 0; i < rxq->size; i++) {
>>>>                 struct mvneta_rx_desc *rx_desc = rxq->descs + i;
>>>> -               void *data = (void *)rx_desc->buf_cookie;
>>>> +               void *data;
>>>> +
>>>> +               if (!pp->bm_priv)
>>>> +                       data = rxq->buf_virt_addr[i];
>>>> +               else
>>>> +                       data = (void *)(uintptr_t)rx_desc->buf_cookie;
>>>
>>> Dropping packets for HWBM (in fact returning dropped buffers to the
>>> pool) is done a couple of lines above. This point will never be
>>
>> indeed I changed the code at every place the buf_cookie was used and
>> missed the fact that for HWBM this code was never reached.
>>
>>> reached with HWBM enabled (and it's also incorrect).
>>
>> What is incorrect?
>>
>
> Possible dma_unmapping + mvneta_frag_free for buffers in HWBM, when
> dropping packets.

Yes sure, but as you mentioned this code is never reached when HWBM is
enabled. I thought there was other part of the code to fix.

Thanks,

Gregory

>
> Thanks,
> Marcin

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

^ permalink raw reply

* [PATCH v3 net-next 2/6] net: mvneta: Use cacheable memory to store the rx buffer virtual address
From: Marcin Wojtas @ 2016-11-29 10:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87shqafv07.fsf@free-electrons.com>

Gregory,

2016-11-29 11:19 GMT+01:00 Gregory CLEMENT <gregory.clement@free-electrons.com>:
> Hi Marcin,
>
>  On mar., nov. 29 2016, Marcin Wojtas <mw@semihalf.com> wrote:
>
>> Hi Gregory,
>>
>> Another remark below, sorry for noise.
>>
>> 2016-11-29 10:37 GMT+01:00 Gregory CLEMENT <gregory.clement@free-electrons.com>:
>>> Until now the virtual address of the received buffer were stored in the
>>> cookie field of the rx descriptor. However, this field is 32-bits only
>>> which prevents to use the driver on a 64-bits architecture.
>>>
>>> With this patch the virtual address is stored in an array not shared with
>>> the hardware (no more need to use the DMA API). Thanks to this, it is
>>> possible to use cache contrary to the access of the rx descriptor member.
>>>
>>> The change is done in the swbm path only because the hwbm uses the cookie
>>> field, this also means that currently the hwbm is not usable in 64-bits.
>>>
>>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>>> ---
>>>  drivers/net/ethernet/marvell/mvneta.c | 93 ++++++++++++++++++++++++----
>>>  1 file changed, 81 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
>>> index 1b84f746d748..32b142d0e44e 100644
>>> --- a/drivers/net/ethernet/marvell/mvneta.c
>>> +++ b/drivers/net/ethernet/marvell/mvneta.c
>>> @@ -561,6 +561,9 @@ struct mvneta_rx_queue {
>>>         u32 pkts_coal;
>>>         u32 time_coal;
>>>
>>> +       /* Virtual address of the RX buffer */
>>> +       void  **buf_virt_addr;
>>> +
>>>         /* Virtual address of the RX DMA descriptors array */
>>>         struct mvneta_rx_desc *descs;
>>>
>>> @@ -1573,10 +1576,14 @@ static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
>>>
>>>  /* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
>>>  static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
>>> -                               u32 phys_addr, u32 cookie)
>>> +                               u32 phys_addr, void *virt_addr,
>>> +                               struct mvneta_rx_queue *rxq)
>>>  {
>>> -       rx_desc->buf_cookie = cookie;
>>> +       int i;
>>> +
>>>         rx_desc->buf_phys_addr = phys_addr;
>>> +       i = rx_desc - rxq->descs;
>>> +       rxq->buf_virt_addr[i] = virt_addr;
>>>  }
>>>
>>>  /* Decrement sent descriptors counter */
>>> @@ -1781,7 +1788,8 @@ EXPORT_SYMBOL_GPL(mvneta_frag_free);
>>>
>>>  /* Refill processing for SW buffer management */
>>>  static int mvneta_rx_refill(struct mvneta_port *pp,
>>> -                           struct mvneta_rx_desc *rx_desc)
>>> +                           struct mvneta_rx_desc *rx_desc,
>>> +                           struct mvneta_rx_queue *rxq)
>>>
>>>  {
>>>         dma_addr_t phys_addr;
>>> @@ -1799,7 +1807,7 @@ static int mvneta_rx_refill(struct mvneta_port *pp,
>>>                 return -ENOMEM;
>>>         }
>>>
>>> -       mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)data);
>>> +       mvneta_rx_desc_fill(rx_desc, phys_addr, data, rxq);
>>>         return 0;
>>>  }
>>>
>>> @@ -1861,7 +1869,12 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
>>>
>>>         for (i = 0; i < rxq->size; i++) {
>>>                 struct mvneta_rx_desc *rx_desc = rxq->descs + i;
>>> -               void *data = (void *)rx_desc->buf_cookie;
>>> +               void *data;
>>> +
>>> +               if (!pp->bm_priv)
>>> +                       data = rxq->buf_virt_addr[i];
>>> +               else
>>> +                       data = (void *)(uintptr_t)rx_desc->buf_cookie;
>>
>> Dropping packets for HWBM (in fact returning dropped buffers to the
>> pool) is done a couple of lines above. This point will never be
>
> indeed I changed the code at every place the buf_cookie was used and
> missed the fact that for HWBM this code was never reached.
>
>> reached with HWBM enabled (and it's also incorrect).
>
> What is incorrect?
>

Possible dma_unmapping + mvneta_frag_free for buffers in HWBM, when
dropping packets.

Thanks,
Marcin

^ permalink raw reply

* [PATCH 7/10] mmc: sdhci-xenon: Add support to PHYs of Marvell Xenon SDHC
From: Ziji Hu @ 2016-11-29 10:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPDyKFqjNy2oJiHHt+8CkTaiiExFKaR0i4GXGKdOMMRX-swPRg@mail.gmail.com>

Hi Ulf,

On 2016/11/29 15:49, Ulf Hansson wrote:
> On 29 November 2016 at 03:53, Ziji Hu <huziji@marvell.com> wrote:
>> Hi Ulf,
>>
>> On 2016/11/28 23:16, Ulf Hansson wrote:
>>> On 28 November 2016 at 12:38, Ziji Hu <huziji@marvell.com> wrote:
>>>> Hi Ulf,
>>>>
>>>> On 2016/11/28 19:13, Ulf Hansson wrote:
>>>>>>
>>>>>>     As you suggest, I replace mmc_wait_for_cmd() with mmc_send_tuning(), to
>>>>>>     send commands for testing current sampling point set in our host PHY.
>>>>>>
>>>>>>     According to my test result, it shows that mmc_send_tuning() can only support
>>>>>>     tuning command (CMD21/CMD19).
>>>>>>     As a result, we cannot use mmc_send_tuning() when card is in the speed modes
>>>>>>     which doesn't support tuning, such as eMMC HS SDR, eMMC HS DRR and
>>>>>>     SD SDR 12/SDR25/DDR50. Card will not response to tuning commands in those
>>>>>>     speed modes.
>>>>>>
>>>>>>     Could you please provide suggestions for the speed mode in which tuning is
>>>>>>     not available?
>>>>>>
>>>>>
>>>>> Normally the mmc host driver shouldn't have to care about what the
>>>>> card supports, as that is the responsibility of the mmc core to
>>>>> manage.
>>>>>
>>>>> The host should only need to implement the ->execute_tuning() ops,
>>>>> which gets called when the card supports tuning (CMD19/21). Does it
>>>>> make sense?
>>>>>
>>>>    I think it is irrelevant to tuning procedure.
>>>>
>>>>    Our host requires to adjust PHY setting after each time ios setting
>>>>    (SDCLK/bus width/speed mode) is changed.
>>>>    The simplified sequence is:
>>>>    mmc change ios --> mmc_set_ios() --> ->set_ios() --> after sdhci_set_ios(),
>>>>    adjust PHY setting.
>>>>    During PHY setting adjustment, out host driver has to send commands to
>>>>    test current sampling point. Tuning is another independent step.
>>>
>>> For those speed modes (or other ios changes) that *don't* requires
>>> tuning, then what will you do when you send the command to confirm the
>>> change of PHY setting and it fails?
>>>
>>> My assumption is that you will fail anyway, by propagating the error
>>> to the mmc core. At least that what was my understanding from your
>>> earlier replies, right!?
>>>
>>> Then, I think there are no point having the host driver sending a
>>> command to confirm the PHY settings, as the mmc core will anyway
>>> discover if something goes wrong when the next command is sent.
>>>
>>> Please correct me if I am wrong!
>>>
>>
>>    Sorry that I didn't make myself clear.
>>
>>    Our host PHY delay line consists of hundreds of sampling points.
>>    Each sampling point represents a different phase shift.
>>
>>    In lower speed mode, our host driver will scan the delay line.
>>    It will select and test multiple sampling points, other than testing
>>    only single sampling point.
>>
>>    If a sampling point fails to transfer cmd/data, our host driver will
>>    move to test next sampling point, until we find out a group of successful
>>    sampling points which can transfer cmd/data. At last we will select
>>    a perfect one from them.
> 
> Ahh, I see. Unfortunate, this is going to be very hard to implement properly.
> 
> The main problem is that the host driver has *no* knowledge about the
> internal state of the card, as that is the responsibility of the mmc
> core to keep track of.
> 
> If the host driver would send a command during every update of the
> "ios" setting, from ->set_ios(), for sure it would lead to commands
> being sent that are "forbidden" in the current internal state of the
> card.
> This would lead to that the card initialization sequence fails,
> because the card may move to an unknown internal state and the mmc
> core would have no knowledge about what happened.
> 

   Yes. In theory, host layer should not initiate a command by itself.

   We assume that bus is idle and card is stable in Tran state, when core layer
   asks host to switch "ios".
   Besides, we only select the commands which is valid in the whole procedure,
   such as CMD8 for eMMC.
   Those test commands are actually like read operations to card registers.
   The card will return to Tran state even if transfer fails. It is also easy
   for host to recover.  

> Hmm..
> 
> Can you specify, *exactly*, under which "ios updates" you need to
> verify updated PHY setting changes by sending a cmd/data? Also, please
> specify if it's enough to only test the CMD line or also DATA lines.
> 

   When one of the three parameters in below changes, our host driver needs
   to adjust PHY in lower speed mode.
   1. Speed Mode (timing): like legacy mode --> HS DDR
   2. Bus Clock: like 400KHz --> 50MHz
   3. Bus Width: like 1-bit --> 4-bit/8-bit

   For eMMC, we use CMD8 to test sampling point.
   For SD, we use CMD13.
   For SDIO, currently CMD52 is used to read a register from CCCR.
   Those commands in above are all valid during the whole procedure to switch
   to high speed mode from legacy mode.

   It is the best case if the test command can transfer both on CMD and DAT lines.
   CMD8 for eMMC can test both CMD line and DAT lines. CMD13 and CMD52 only test
   CMD line. We might use ACMD51 for SD and CMD53 for SDIO later thus DAT lines
   are also under test.

> Kind regards
> Uffe
> 

^ permalink raw reply

* [PATCH V10 2/6] arm: arm64: Add routine to determine cpuid of other cpus
From: Will Deacon @ 2016-11-29 10:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478734793-6341-3-git-send-email-jeremy.linton@arm.com>

[adding Russell]

On Wed, Nov 09, 2016 at 05:39:49PM -0600, Jeremy Linton wrote:
> It is helpful if we can read the cpuid/midr of other CPUs
> in the system independent of arm/arm64.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>  arch/arm/include/asm/cputype.h   | 2 ++
>  arch/arm64/include/asm/cputype.h | 3 +++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
> index 522b5fe..31fb273 100644
> --- a/arch/arm/include/asm/cputype.h
> +++ b/arch/arm/include/asm/cputype.h
> @@ -235,6 +235,8 @@ static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
>  #define cpu_is_sa1100() (read_cpuid_part() == ARM_CPU_PART_SA1100)
>  #define cpu_is_sa1110() (read_cpuid_part() == ARM_CPU_PART_SA1110)
>  
> +#define read_specific_cpuid(cpu_num) per_cpu_ptr(&cpu_data, cpu_num)->cpuid
> +
>  /*
>   * Intel's XScale3 core supports some v6 features (supersections, L2)
>   * but advertises itself as v5 as it does not support the v6 ISA.  For

Russell -- are you ok with adding this macro to arch/arm/? It will get used
by the CPU PMU driver, which needs a portable (i.e. between arm and arm64)
way to convert a logical CPU ID into the MIDR register for that CPU.

Thanks,

Will

^ permalink raw reply

* [PATCH V10 5/6] arm64: pmu: Detect and enable multiple PMUs in an ACPI system
From: Will Deacon @ 2016-11-29 10:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478734793-6341-6-git-send-email-jeremy.linton@arm.com>

On Wed, Nov 09, 2016 at 05:39:52PM -0600, Jeremy Linton wrote:
> Its possible that an ACPI system has multiple CPU types in it
> with differing PMU counters. Iterate the CPU's and make a determination
> about how many of each type exist in the system. Then take and create
> a PMU platform device for each type, and assign it the interrupts parsed
> from the MADT. Creating a platform device is necessary because the PMUs
> are not described as devices in the DSDT table.
> 
> This code is loosely based on earlier work by Mark Salter.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>  drivers/perf/arm_pmu.c      |   8 +-
>  drivers/perf/arm_pmu_acpi.c | 234 +++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 240 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 6008be9..07e1404 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -1087,7 +1087,13 @@ int arm_pmu_device_probe(struct platform_device *pdev,
>  		if (!ret)
>  			ret = init_fn(pmu);
>  	} else if (probe_table) {
> -		ret = probe_plat_pmu(pmu, probe_table, read_cpuid_id());
> +		if (acpi_disabled) {
> +			/* use the current cpu. */
> +			ret = probe_plat_pmu(pmu, probe_table,
> +					     read_cpuid_id());
> +		} else {
> +			ret = probe_plat_pmu(pmu, probe_table, pdev->id);
> +		}
>  	}
>  
>  	if (ret) {
> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c
> index 135851c..eecf1c1 100644
> --- a/drivers/perf/arm_pmu_acpi.c
> +++ b/drivers/perf/arm_pmu_acpi.c
> @@ -2,13 +2,17 @@
>   * ARM ACPI PMU support
>   *
>   * Copyright (C) 2015 Red Hat Inc.
> + * Copyright (C) 2016 ARM Ltd.
>   * Author: Mark Salter <msalter@redhat.com>
> + *	   Jeremy Linton <jeremy.linton@arm.com>
>   *
>   * This work is licensed under the terms of the GNU GPL, version 2.  See
>   * the COPYING file in the top-level directory.
>   *
>   */
>  
> +#define pr_fmt(fmt) "ACPI-PMU: " fmt
> +
>  #include <asm/cpu.h>
>  #include <linux/acpi.h>
>  #include <linux/irq.h>
> @@ -20,7 +24,14 @@
>  struct pmu_irq {
>  	int  gsi;
>  	int  trigger;
> -	bool registered;
> +	int  irq;
> +	bool used;
> +};
> +
> +struct pmu_types {
> +	struct list_head list;
> +	int		 cpu_type;
> +	int		 cpu_count;
>  };
>  
>  static struct pmu_irq pmu_irqs[NR_CPUS];
> @@ -38,3 +49,224 @@ void __init arm_pmu_parse_acpi(int cpu, struct acpi_madt_generic_interrupt *gic)
>  	else
>  		pmu_irqs[cpu].trigger = ACPI_LEVEL_SENSITIVE;
>  }
> +
> +static void __init arm_pmu_acpi_handle_alloc_failure(struct list_head *pmus)
> +{
> +	int i;
> +	struct pmu_types *pmu, *safe_temp;
> +
> +	list_for_each_entry_safe(pmu, safe_temp, pmus, list) {
> +		list_del(&pmu->list);
> +		kfree(pmu);
> +	}
> +
> +	for_each_possible_cpu(i)
> +		if (pmu_irqs[i].irq > 0)
> +			acpi_unregister_gsi(pmu_irqs[i].gsi);
> +}
> +
> +/*
> + * Count number and type of CPU cores in the system. Returns the number
> + * of "unused" MADT entries we could not associate with a PMU. This can
> + * be the result of CPU's not being online,  or errors in the MADT.
> + * Under normal circumstances this will be 0.
> + */
> +static int __init arm_pmu_acpi_determine_cpu_types(struct list_head *pmus)
> +{
> +	int i;
> +	int unused_madt_entries = 0;
> +
> +	for_each_possible_cpu(i) {
> +		struct cpuinfo_arm64 *cinfo = per_cpu_ptr(&cpu_data, i);
> +		struct pmu_types *pmu;
> +
> +		/*
> +		 * Ignore GSI registration failure for now, as
> +		 * some of the MADT entries may not be used.
> +		 */
> +		pmu_irqs[i].irq = acpi_register_gsi(NULL, pmu_irqs[i].gsi,
> +						    pmu_irqs[i].trigger,
> +						    ACPI_ACTIVE_HIGH);
> +		/* likely not online */
> +		if (cinfo->reg_midr == 0) {

I appreciate that this code only gets built for arm64 at the moment, but
given that you've introduced the read_specific_cpuid macro, it seems like
it would be better to use it here too and avoid the reference to struct
cpuinfo_arm64 altogether. Similarly for the other references in this file.

Will

^ permalink raw reply

* [PATCH v3 net-next 2/6] net: mvneta: Use cacheable memory to store the rx buffer virtual address
From: Gregory CLEMENT @ 2016-11-29 10:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPv3WKeFXJA1RjFZ5VoRfBtU+QGUx+AT3LYuoMHamQtNWCCMVA@mail.gmail.com>

Hi Marcin,
 
 On mar., nov. 29 2016, Marcin Wojtas <mw@semihalf.com> wrote:

> Hi Gregory,
>
> Another remark below, sorry for noise.
>
> 2016-11-29 10:37 GMT+01:00 Gregory CLEMENT <gregory.clement@free-electrons.com>:
>> Until now the virtual address of the received buffer were stored in the
>> cookie field of the rx descriptor. However, this field is 32-bits only
>> which prevents to use the driver on a 64-bits architecture.
>>
>> With this patch the virtual address is stored in an array not shared with
>> the hardware (no more need to use the DMA API). Thanks to this, it is
>> possible to use cache contrary to the access of the rx descriptor member.
>>
>> The change is done in the swbm path only because the hwbm uses the cookie
>> field, this also means that currently the hwbm is not usable in 64-bits.
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  drivers/net/ethernet/marvell/mvneta.c | 93 ++++++++++++++++++++++++----
>>  1 file changed, 81 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
>> index 1b84f746d748..32b142d0e44e 100644
>> --- a/drivers/net/ethernet/marvell/mvneta.c
>> +++ b/drivers/net/ethernet/marvell/mvneta.c
>> @@ -561,6 +561,9 @@ struct mvneta_rx_queue {
>>         u32 pkts_coal;
>>         u32 time_coal;
>>
>> +       /* Virtual address of the RX buffer */
>> +       void  **buf_virt_addr;
>> +
>>         /* Virtual address of the RX DMA descriptors array */
>>         struct mvneta_rx_desc *descs;
>>
>> @@ -1573,10 +1576,14 @@ static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
>>
>>  /* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
>>  static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
>> -                               u32 phys_addr, u32 cookie)
>> +                               u32 phys_addr, void *virt_addr,
>> +                               struct mvneta_rx_queue *rxq)
>>  {
>> -       rx_desc->buf_cookie = cookie;
>> +       int i;
>> +
>>         rx_desc->buf_phys_addr = phys_addr;
>> +       i = rx_desc - rxq->descs;
>> +       rxq->buf_virt_addr[i] = virt_addr;
>>  }
>>
>>  /* Decrement sent descriptors counter */
>> @@ -1781,7 +1788,8 @@ EXPORT_SYMBOL_GPL(mvneta_frag_free);
>>
>>  /* Refill processing for SW buffer management */
>>  static int mvneta_rx_refill(struct mvneta_port *pp,
>> -                           struct mvneta_rx_desc *rx_desc)
>> +                           struct mvneta_rx_desc *rx_desc,
>> +                           struct mvneta_rx_queue *rxq)
>>
>>  {
>>         dma_addr_t phys_addr;
>> @@ -1799,7 +1807,7 @@ static int mvneta_rx_refill(struct mvneta_port *pp,
>>                 return -ENOMEM;
>>         }
>>
>> -       mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)data);
>> +       mvneta_rx_desc_fill(rx_desc, phys_addr, data, rxq);
>>         return 0;
>>  }
>>
>> @@ -1861,7 +1869,12 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
>>
>>         for (i = 0; i < rxq->size; i++) {
>>                 struct mvneta_rx_desc *rx_desc = rxq->descs + i;
>> -               void *data = (void *)rx_desc->buf_cookie;
>> +               void *data;
>> +
>> +               if (!pp->bm_priv)
>> +                       data = rxq->buf_virt_addr[i];
>> +               else
>> +                       data = (void *)(uintptr_t)rx_desc->buf_cookie;
>
> Dropping packets for HWBM (in fact returning dropped buffers to the
> pool) is done a couple of lines above. This point will never be

indeed I changed the code at every place the buf_cookie was used and
missed the fact that for HWBM this code was never reached.

> reached with HWBM enabled (and it's also incorrect).

What is incorrect?

Gregory


>
> Best regards,
> Marcin

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

^ permalink raw reply

* [PATCH v7 0/8] drm: sun8i: Add DE2 HDMI video support
From: Jean-Francois Moine @ 2016-11-29 10:18 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset series adds HDMI video support to the Allwinner
sun8i SoCs which include the display engine 2 (DE2).
The driver contains the code for the A83T and H3 SoCs, and
some H3 boards, but it could be used/extended for other SoCs
(A64, H2, H5) and boards (Banana PIs, Orange PIs).

v7:
	- more explanations about the DE2 in the DT documentation
	- separate patches for DT documentation (Rob Herring)
	- show all properties in DT examples (Rob Herring)
	- use drm_of_component_probe()
	- use the index of the DE 'ports' in the DT as
	  the DE mixer number (no alias needed anymore)
	- change some 'lcd' to 'tcon' in the DT
	- add HDMI module parameter for DVI mode when screen overscan
	  problems
	- fall back to some CEA modes in case of EDID read failure
	- fix some settings (interlace) and simplify code
	- fix bug in start of A83T HDMI
	- fix lack of CLK_PLL_DE definition in the DT include
	  (Icenowy Zheng)
v6:
	- remove audio support (other patchset to come)
	- use DRM modeset data for HDMI configuration
		(thanks to Jernej ??krabec)
	- more meaningfull register names
	- use a mutex for DE I/O protection
	- merge DE and plane into one file
	- don't activate the video hardware when video not started
		(Maxime Ripard)
	- remove 'type = "video" in DT graph ports
		(Rob Herring)
	- change the I/O accesses by #define instead of struct
		(Maxime Ripard, Andr?? Przywara)
	- remove pm functions (Maxime Ripard)
	- set the pll-de/de clocks in the DT (Maxime Ripard)
	- use platform_get_irq instead of irq_of_parse_and_map
		(Maxime Ripard)
	- rename sunxi to sun8i (Maxime Ripard)
	- fix coding style errors (Maxime Ripard)
	- subclass the drm structure in private data (Daniel Vetter)
	- move drm_dev_register at end of init (Daniel Vetter)
v5:
	- add overlay plane
	- add audio support
	- add support for the A83T
	- add back the HDMI driver
	- many bug fixes
v4: 
	- drivers/clk/sunxi/Makefile was missing (Emil Velikov)
v3:
	- add the hardware cursor
	- simplify and fix the DE2 init sequences
	- generation for all SUNXI SoCs (Andre Przywara)
v2:
	- remove the HDMI driver
	- remarks from Chen-Yu Tsai and Russell King
	- DT documentation added

Jean-Francois Moine (8):
  drm: sun8i: Add a basic DRM driver for Allwinner DE2
  drm/sun8i: Add DT bindings documentation of Allwinner DE2
  drm: sun8i: add HDMI video support to A83T and H3
  drm/sunxi: Add DT bindings documentation of Allwinner HDMI
  clk: sunxi-ng: define the PLL DE clock
  ARM: dts: sun8i-h3: add HDMI video nodes
  ARM: dts: sun8i-h3: Add HDMI video to the Banana Pi M2+
  ARM: dts: sun8i-h3: Add HDMI video to the Orange PI 2

 .../devicetree/bindings/display/sunxi/hdmi.txt     |  56 ++
 .../bindings/display/sunxi/sun8i-de2.txt           | 121 +++
 arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts    |  12 +
 arch/arm/boot/dts/sun8i-h3-orangepi-2.dts          |  12 +
 arch/arm/boot/dts/sun8i-h3.dtsi                    |  65 ++
 drivers/gpu/drm/Kconfig                            |   2 +
 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/sun8i/Kconfig                      |  26 +
 drivers/gpu/drm/sun8i/Makefile                     |   9 +
 drivers/gpu/drm/sun8i/de2_crtc.c                   | 449 +++++++++++
 drivers/gpu/drm/sun8i/de2_crtc.h                   |  52 ++
 drivers/gpu/drm/sun8i/de2_drv.c                    | 317 ++++++++
 drivers/gpu/drm/sun8i/de2_drv.h                    |  48 ++
 drivers/gpu/drm/sun8i/de2_hdmi.c                   | 440 +++++++++++
 drivers/gpu/drm/sun8i/de2_hdmi.h                   |  51 ++
 drivers/gpu/drm/sun8i/de2_hdmi_io.c                | 842 +++++++++++++++++++++
 drivers/gpu/drm/sun8i/de2_plane.c                  | 734 ++++++++++++++++++
 include/dt-bindings/clock/sun8i-h3-ccu.h           |   1 +
 18 files changed, 3238 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/sunxi/hdmi.txt
 create mode 100644 Documentation/devicetree/bindings/display/sunxi/sun8i-de2.txt
 create mode 100644 drivers/gpu/drm/sun8i/Kconfig
 create mode 100644 drivers/gpu/drm/sun8i/Makefile
 create mode 100644 drivers/gpu/drm/sun8i/de2_crtc.c
 create mode 100644 drivers/gpu/drm/sun8i/de2_crtc.h
 create mode 100644 drivers/gpu/drm/sun8i/de2_drv.c
 create mode 100644 drivers/gpu/drm/sun8i/de2_drv.h
 create mode 100644 drivers/gpu/drm/sun8i/de2_hdmi.c
 create mode 100644 drivers/gpu/drm/sun8i/de2_hdmi.h
 create mode 100644 drivers/gpu/drm/sun8i/de2_hdmi_io.c
 create mode 100644 drivers/gpu/drm/sun8i/de2_plane.c

-- 
2.10.2

^ permalink raw reply

* [PATCH v3 net-next 2/6] net: mvneta: Use cacheable memory to store the rx buffer virtual address
From: Gregory CLEMENT @ 2016-11-29 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPv3WKcn27QsqLamzS2QV-RF1GD3bgsYCYD-2q9tpTtqF+eiWQ@mail.gmail.com>

Hi Marcin,
 
 On mar., nov. 29 2016, Marcin Wojtas <mw@semihalf.com> wrote:

> Hi Gregory,
>
> Apparently HWBM had a mistake in implementation, please see below.
>
> 2016-11-29 10:37 GMT+01:00 Gregory CLEMENT <gregory.clement@free-electrons.com>:
>> Until now the virtual address of the received buffer were stored in the
>> cookie field of the rx descriptor. However, this field is 32-bits only
>> which prevents to use the driver on a 64-bits architecture.
>>
>> With this patch the virtual address is stored in an array not shared with
>> the hardware (no more need to use the DMA API). Thanks to this, it is
>> possible to use cache contrary to the access of the rx descriptor member.
>>
>> The change is done in the swbm path only because the hwbm uses the cookie
>> field, this also means that currently the hwbm is not usable in 64-bits.
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  drivers/net/ethernet/marvell/mvneta.c | 93 ++++++++++++++++++++++++----
>>  1 file changed, 81 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
>> index 1b84f746d748..32b142d0e44e 100644
>> --- a/drivers/net/ethernet/marvell/mvneta.c
>> +++ b/drivers/net/ethernet/marvell/mvneta.c
>> @@ -561,6 +561,9 @@ struct mvneta_rx_queue {
>>         u32 pkts_coal;
>>         u32 time_coal;
>>
>> +       /* Virtual address of the RX buffer */
>> +       void  **buf_virt_addr;
>> +
>>         /* Virtual address of the RX DMA descriptors array */
>>         struct mvneta_rx_desc *descs;
>>
>> @@ -1573,10 +1576,14 @@ static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
>>
>>  /* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
>>  static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
>> -                               u32 phys_addr, u32 cookie)
>> +                               u32 phys_addr, void *virt_addr,
>> +                               struct mvneta_rx_queue *rxq)
>>  {
>> -       rx_desc->buf_cookie = cookie;
>> +       int i;
>> +
>>         rx_desc->buf_phys_addr = phys_addr;
>> +       i = rx_desc - rxq->descs;
>> +       rxq->buf_virt_addr[i] = virt_addr;
>>  }
>>
>>  /* Decrement sent descriptors counter */
>> @@ -1781,7 +1788,8 @@ EXPORT_SYMBOL_GPL(mvneta_frag_free);
>>
>>  /* Refill processing for SW buffer management */
>>  static int mvneta_rx_refill(struct mvneta_port *pp,
>> -                           struct mvneta_rx_desc *rx_desc)
>> +                           struct mvneta_rx_desc *rx_desc,
>> +                           struct mvneta_rx_queue *rxq)
>>
>>  {
>>         dma_addr_t phys_addr;
>> @@ -1799,7 +1807,7 @@ static int mvneta_rx_refill(struct mvneta_port *pp,
>>                 return -ENOMEM;
>>         }
>>
>> -       mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)data);
>> +       mvneta_rx_desc_fill(rx_desc, phys_addr, data, rxq);
>>         return 0;
>>  }
>>
>> @@ -1861,7 +1869,12 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
>>
>>         for (i = 0; i < rxq->size; i++) {
>>                 struct mvneta_rx_desc *rx_desc = rxq->descs + i;
>> -               void *data = (void *)rx_desc->buf_cookie;
>> +               void *data;
>> +
>> +               if (!pp->bm_priv)
>> +                       data = rxq->buf_virt_addr[i];
>> +               else
>> +                       data = (void *)(uintptr_t)rx_desc->buf_cookie;
>>
>>                 dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
>>                                  MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
>> @@ -1894,12 +1907,13 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo,
>>                 unsigned char *data;
>>                 dma_addr_t phys_addr;
>>                 u32 rx_status, frag_size;
>> -               int rx_bytes, err;
>> +               int rx_bytes, err, index;
>>
>>                 rx_done++;
>>                 rx_status = rx_desc->status;
>>                 rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
>> -               data = (unsigned char *)rx_desc->buf_cookie;
>> +               index = rx_desc - rxq->descs;
>> +               data = (unsigned char *)rxq->buf_virt_addr[index];
>>                 phys_addr = rx_desc->buf_phys_addr;
>>
>>                 if (!mvneta_rxq_desc_is_first_last(rx_status) ||
>> @@ -1938,7 +1952,7 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo,
>>                 }
>>
>>                 /* Refill processing */
>> -               err = mvneta_rx_refill(pp, rx_desc);
>> +               err = mvneta_rx_refill(pp, rx_desc, rxq);
>>                 if (err) {
>>                         netdev_err(dev, "Linux processing - Can't refill\n");
>>                         rxq->missed++;
>> @@ -2020,7 +2034,7 @@ static int mvneta_rx_hwbm(struct mvneta_port *pp, int rx_todo,
>>                 rx_done++;
>>                 rx_status = rx_desc->status;
>>                 rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
>> -               data = (unsigned char *)rx_desc->buf_cookie;
>> +               data = (u8 *)(uintptr_t)rx_desc->buf_cookie;
>>                 phys_addr = rx_desc->buf_phys_addr;
>>                 pool_id = MVNETA_RX_GET_BM_POOL_ID(rx_desc);
>>                 bm_pool = &pp->bm_priv->bm_pools[pool_id];
>> @@ -2708,6 +2722,56 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
>>         return rx_done;
>>  }
>>
>> +/* Refill processing for HW buffer management */
>> +static int mvneta_rx_hwbm_refill(struct mvneta_port *pp,
>> +                                struct mvneta_rx_desc *rx_desc)
>> +
>> +{
>> +       dma_addr_t phys_addr;
>> +       void *data;
>> +
>> +       data = mvneta_frag_alloc(pp->frag_size);
>> +       if (!data)
>> +               return -ENOMEM;
>> +
>> +       phys_addr = dma_map_single(pp->dev->dev.parent, data,
>> +                                  MVNETA_RX_BUF_SIZE(pp->pkt_size),
>> +                                  DMA_FROM_DEVICE);
>> +       if (unlikely(dma_mapping_error(pp->dev->dev.parent, phys_addr))) {
>> +               mvneta_frag_free(pp->frag_size, data);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       rx_desc->buf_phys_addr = phys_addr;
>> +       rx_desc->buf_cookie = (uintptr_t)data;
>> +
>> +       return 0;
>> +}
>> +
>> +/* Handle rxq fill: allocates rxq skbs; called when initializing a port */
>> +static int mvneta_rxq_bm_fill(struct mvneta_port *pp,
>> +                             struct mvneta_rx_queue *rxq,
>> +                             int num)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < num; i++) {
>> +               memset(rxq->descs + i, 0, sizeof(struct mvneta_rx_desc));
>> +               if (mvneta_rx_hwbm_refill(pp, rxq->descs + i) != 0) {
>> +                       netdev_err(pp->dev, "%s:rxq %d, %d of %d buffs  filled\n",
>> +                                  __func__, rxq->id, i, num);
>> +                       break;
>> +               }
>> +       }
>> +
>> +       /* Add this number of RX descriptors as non occupied (ready to
>> +        * get packets)
>> +        */
>> +       mvneta_rxq_non_occup_desc_add(pp, rxq, i);
>> +
>> +       return i;
>> +}
>> +
>>  /* Handle rxq fill: allocates rxq skbs; called when initializing a port */
>>  static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
>>                            int num)
>> @@ -2716,7 +2780,7 @@ static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
>>
>>         for (i = 0; i < num; i++) {
>>                 memset(rxq->descs + i, 0, sizeof(struct mvneta_rx_desc));
>> -               if (mvneta_rx_refill(pp, rxq->descs + i) != 0) {
>> +               if (mvneta_rx_refill(pp, rxq->descs + i, rxq) != 0) {
>>                         netdev_err(pp->dev, "%s:rxq %d, %d of %d buffs  filled\n",
>>                                 __func__, rxq->id, i, num);
>>                         break;
>> @@ -2784,14 +2848,14 @@ static int mvneta_rxq_init(struct mvneta_port *pp,
>>                 mvneta_rxq_buf_size_set(pp, rxq,
>>                                         MVNETA_RX_BUF_SIZE(pp->pkt_size));
>>                 mvneta_rxq_bm_disable(pp, rxq);
>> +               mvneta_rxq_fill(pp, rxq, rxq->size);
>>         } else {
>>                 mvneta_rxq_bm_enable(pp, rxq);
>>                 mvneta_rxq_long_pool_set(pp, rxq);
>>                 mvneta_rxq_short_pool_set(pp, rxq);
>> +               mvneta_rxq_bm_fill(pp, rxq, rxq->size);
>
> Manual filling descriptors with new buffers is redundant. For HWBM,
> all buffers are allocated in mvneta_bm_construct() and in runtime they
> are put into descriptors by hardware. I think it's enough to add here:
> mvneta_rxq_non_occup_desc_add(pp, rxq, rxq->size);
>
> And remove mvneta_rxq_bm_fill and mvneta_rx_hwbm_refill.

You're right. I will do it it will simplify the code.

Thanks,

Gregory

>
> Best regards,
> Marcin

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

^ permalink raw reply

* [PATCH v7 8/8] ARM: dts: sun8i-h3: Add HDMI video to the Orange PI 2
From: Jean-Francois Moine @ 2016-11-29 10:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1480414715.git.moinejf@free.fr>

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 arch/arm/boot/dts/sun8i-h3-orangepi-2.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
index 047e9e1..7712972 100644
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
@@ -105,16 +105,28 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci1 {
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
 	status = "okay";
 };
 
+&tcon0 {
+	status = "okay";
+};
+
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
-- 
2.10.2

^ permalink raw reply related

* [PATCH v7 7/8] ARM: dts: sun8i-h3: Add HDMI video to the Banana Pi M2+
From: Jean-Francois Moine @ 2016-11-29 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1480414715.git.moinejf@free.fr>

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts
index c0c49dd..9f3e2f8 100644
--- a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts
+++ b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts
@@ -93,6 +93,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci1 {
 	status = "okay";
 };
@@ -101,12 +105,20 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
 	status = "okay";
 };
 
+&tcon0 {
+	status = "okay";
+};
+
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
-- 
2.10.2

^ permalink raw reply related

* [PATCH v7 6/8] ARM: dts: sun8i-h3: add HDMI video nodes
From: Jean-Francois Moine @ 2016-11-29 10:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1480414715.git.moinejf@free.fr>

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
Note 1:
 The DE clock is not set in the driver. Instead, it is set at system
 startup time by 'assigned-clocks', but there is a problem in sunxi-ng
 which uses readl_relaxed_poll_timeout(), and, as noticed by
 Ond??ej Jirman, this function is not available at startup time.
 The fix of this problem is not part of this patchset series.
Note 2:
 The DE clock is set to a high enough rate (432MHz). It seems that
 this is needed to handle 4K video.
 But, as the proposed DE driver does not treat yet 4K video, the clock
 could be set to a lower rate. For example, the default rate for the A83T
 is 250MHz (no 4K video).
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 65 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index fca66bf..1aa087d 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -140,6 +140,16 @@
 		#size-cells = <1>;
 		ranges;
 
+		de: de-controller at 01000000 {
+			compatible = "allwinner,sun8i-h3-display-engine";
+			reg = <0x01000000 0x400000>;
+			clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>;
+			clock-names = "bus", "clock";
+			resets = <&ccu RST_BUS_DE>;
+			ports = <&tcon0_p>, <&tcon1_p>;
+			status = "disabled";
+		};
+
 		dma: dma-controller at 01c02000 {
 			compatible = "allwinner,sun8i-h3-dma";
 			reg = <0x01c02000 0x1000>;
@@ -149,6 +159,37 @@
 			#dma-cells = <1>;
 		};
 
+		tcon0: lcd-controller at 01c0c000 {
+			compatible = "allwinner,sun8i-a83t-tcon";
+			reg = <0x01c0c000 0x400>;
+			clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
+			clock-names = "bus", "clock";
+			resets = <&ccu RST_BUS_TCON0>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			tcon0_p: port {
+				tcon0_hdmi: endpoint {
+					remote-endpoint = <&hdmi_tcon0>;
+				};
+			};
+		};
+
+		/* not used */
+		tcon1: lcd-controller at 01c0d000 {
+			compatible = "allwinner,sun8i-h3-tcon";
+			reg = <0x01c0d000 0x400>;
+			clocks = <&ccu CLK_BUS_TCON1>,
+				 <&ccu CLK_TCON0>;	/* no clock */
+			clock-names = "bus", "clock";
+			interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			tcon1_p: port {
+				endpoint {
+					/* empty */
+				};
+			};
+		};
+
 		mmc0: mmc at 01c0f000 {
 			compatible = "allwinner,sun7i-a20-mmc";
 			reg = <0x01c0f000 0x1000>;
@@ -314,6 +355,11 @@
 			clock-names = "hosc", "losc";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
+
+			assigned-clocks = <&ccu CLK_PLL_DE>,
+					  <&ccu CLK_DE>;
+			assigned-clock-rates =  <864000000>,
+						<432000000>;
 		};
 
 		pio: pinctrl at 01c20800 {
@@ -567,6 +613,25 @@
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		hdmi: hdmi at 01ee0000 {
+			compatible = "allwinner,sun8i-h3-hdmi";
+			reg = <0x01ee0000 0x20000>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI>,
+				 <&ccu CLK_HDMI_DDC>;
+			clock-names = "bus", "clock", "ddc-clock";
+			resets = <&ccu RST_BUS_HDMI0>, <&ccu RST_BUS_HDMI1>;
+			reset-names = "hdmi0", "hdmi1";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port at 0 {			/* video */
+				reg = <0>;
+				hdmi_tcon0: endpoint {
+					remote-endpoint = <&tcon0_hdmi>;
+				};
+			};
+		};
+
 		rtc: rtc at 01f00000 {
 			compatible = "allwinner,sun6i-a31-rtc";
 			reg = <0x01f00000 0x54>;
-- 
2.10.2

^ permalink raw reply related

* [PATCH] extcon: Split out the extcon APIs for extcon provider driver
From: Charles Keepax @ 2016-11-29 10:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480413743-13037-1-git-send-email-cw00.choi@samsung.com>

On Tue, Nov 29, 2016 at 07:02:23PM +0900, Chanwoo Choi wrote:
> This patchs split out the extcon APIs of extcon provider driver in order to
> prevent the direct access of struct extcon_dev by extcon consumer driver.
> The extcon consumer driver don't need to handle the extcon provider APIs.
> 
> The extcon subsystem has two type of extcon drivers as following:
> - extcon provider driver
> : Detect the external connector and identify the state/property of
>   each external connector. And it send the notification to synchronize
>   the information between provider and consumer driver.
> - extcon consumer driver
> : Receive the notifcation from extcon provider driver. When receving the noti,
>   it can get the both state and property of specific external connector.
> 
> Cc: Myungjoo Ham <myungjoo.ham@samsung.com>
> Cc: Chen-Yu Tsai <wens@csie.org>
> Cc: Krzysztof Kozlowski <krzk@kernel.org>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
> Cc: Felipe Balbi <balbi@kernel.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Chris Zhong <zyw@rock-chips.com>
> Cc: Roger Quadros <rogerq@ti.com>
> Cc: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> Cc: patches at opensource.wolfsonmicro.com
> Cc: linux-renesas-soc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-usb at vger.kernel.org
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
>  drivers/extcon/devres.c                |   2 +-
>  drivers/extcon/extcon-adc-jack.c       |   2 +-
>  drivers/extcon/extcon-arizona.c        |   2 +-

For the Arizona bit:

Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>

Thanks,
Charles

^ permalink raw reply


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