Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [xlnx:2017.3_video_ea 6589/6607] warning: (RAPIDIO_DMA_ENGINE && ..) selects DMA_ENGINE which has unmet direct dependencies (DMADEVICES)
From: kbuild test robot @ 2017-12-13 19:14 UTC (permalink / raw)
  To: linux-arm-kernel

tree:   https://github.com/Xilinx/linux-xlnx 2017.3_video_ea
head:   af045f9682c65a0c26afb2f638603d3c01079222
commit: 62a7ed2f02d28f73f2c09d61ecbe1f289aecc6e5 [6589/6607] staging: xilinx: mixer: Initial commit of Xilinx Video Mixer IP DRM driver
config: i386-randconfig-x002-12131628 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        git checkout 62a7ed2f02d28f73f2c09d61ecbe1f289aecc6e5
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

warning: (RAPIDIO_DMA_ENGINE && DRM_XILINX && SND_SOC_SH4_SIU && XILINX_DMA_APF && DRM_XILINX_XVMIXER && CRYPTO_DEV_CCP_DD) selects DMA_ENGINE which has unmet direct dependencies (DMADEVICES)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 26870 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20171214/c4c96865/attachment-0001.gz>

^ permalink raw reply

* [PATCH] phy: rockchip-typec: Try to turn the PHY on several times
From: Doug Anderson @ 2017-12-13 19:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAFqH_52coxz73waki18JicDsndG9bzEw6Zbq6TCOST0J3N+NXQ@mail.gmail.com>

Hi,

On Wed, Dec 13, 2017 at 4:41 AM, Enric Balletbo Serra
<eballetbo@gmail.com> wrote:
> Hi Doug,
>
> 2017-12-11 22:45 GMT+01:00 Douglas Anderson <dianders@chromium.org>:
>> Bind / unbind stress testing of the USB controller on rk3399 found
>> that we'd often end up with lots of failures that looked like this:
>>
>>   phy phy-ff800000.phy.9: phy poweron failed --> -110
>>   dwc3 fe900000.dwc3: failed to initialize core
>>   dwc3: probe of fe900000.dwc3 failed with error -110
>>
>> Those errors were sometimes seen at bootup too, in which case USB
>> peripherals wouldn't work until unplugged and re-plugged in.
>>
>> I spent some time trying to figure out why the PHY was failing to
>> power on but I wasn't able to.  Possibly this has to do with the fact
>> that the PHY docs say that the USB controller "needs to be held in
>> reset to hold pipe power state in P2 before initializing the Type C
>> PHY" but that doesn't appear to be easy to do with the dwc3 driver
>> today.  Messing around with the ordering of the reset vs. the PHY
>> initialization in the dwc3 driver didn't seem to fix things.
>>
>> I did, however, find that if I simply retry the power on it seems to
>> have a good chance of working.  So let's add some retries.  I ran a
>> pretty tight bind/unbind loop overnight.  When I did so, I found that
>> I need to retry between 1% and 2% of the time.  Overnight I found only
>> a small handful of times where I needed 2 retries.  I never found a
>> case where I needed 3 retries.
>>
>> I'm completely aware of the fact that this is quite an ugly hack and I
>> wish I didn't have to resort to it, but I have no other real idea how
>> to make this hardware reliable.  If Rockchip in the future can come up
>> with a solution we can always revert this hack.  Until then, let's at
>> least have something that works.
>>
>> This patch is tested atop Enric's latest dwc3 patch series ending at:
>>   https://patchwork.kernel.org/patch/10095527/
>> ...but it could be applied independently of that series without any
>> bad effects.
>>
>> For some more details on this bug, you can refer to:
>>   https://bugs.chromium.org/p/chromium/issues/detail?id=783464
>>
>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>> ---
>>
>>  drivers/phy/rockchip/phy-rockchip-typec.c | 24 ++++++++++++++++++++++--
>>  1 file changed, 22 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
>> index ee85fa0ca4b0..5c2157156ce1 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
>> @@ -349,6 +349,8 @@
>>  #define MODE_DFP_USB                   BIT(1)
>>  #define MODE_DFP_DP                    BIT(2)
>>
>> +#define POWER_ON_TRIES                 5
>> +
>
> I did the test of increase the number of tries to 100 because
> unfortunately, even with this patch applied, I can see the problem on
> my kevin with current mainline.
>
> [  244.309094] rockchip-typec-phy ff800000.phy: Turn on failed after 100 loops
>
> That's an extra debug print ^
>
> [  244.317019] phy phy-ff800000.phy.8: phy poweron failed --> -110
> [  244.323824] dwc3 fe900000.dwc3: failed to initialize core
> [  244.330057] dwc3: probe of fe900000.dwc3 failed with error -110
>
> So I'm wondering if there is something else that I need to apply to
> really fix this as you didn't reproduce the issue doing lots of tests
> and I can reproduce the issue very easily.

Ah!  I added that message to the top of my upstream series and,
indeed, I sometimes see the PHY fail to turn on.  Doh.

OK, so here's what I've done:

* The place where I ran the overnight loops was actually the Chrome OS
4.4 kernel.  In that kernel I had a message very similar to yours and
I didn't hit it.  I just re-ran this for 20 minutes now and I can
re-confirm.  In the Chrome OS kernel I never see it needing more than
a 1 (or 2) loops and it doesn't ever get into the "totally failed"
case.

* Previously I ran ~10 minutes with the upstream kernel, but at the
time I didn't have your printout.  After 10 minutes I checked my logs
and I definitely saw the "Needed 1 loops to turn on", so I knew my
patch was doing something useful.  It didn't occur to me to re-confirm
that I didn't get the "totally failed" upstream, though now that I say
it out loud it's stupid that I didn't think to do this.

* Previously when playing with patches on the upstream kernel I saw
lots of problems powering on the PHY and I thought my patch was
helping, but that was all very non-scientific.


So to say it shortly:

* For me, my patch makes things a slightly better even on the upstream
kernel (I do sometimes see the "turned on after 1 tries")

* I can confirm that my patch doesn't fix everything upstream, so
there's something different about the Chrome OS tree still.

---

I also picked all the local patches from the Chrome OS kernel to the
PHY driver and now my PHY driver in the upstream and downstream trees
match.  I can still reproduce problems.  So the issue is somewhere at
a higher level...


So basically something outside the PHY driver is causing it to fail
unexpectedly upstream.  I guess the hacky retry won't work well enough
there after all.  :(

One question: if you get the "failed after 100 loops" and then you do
another unbind / bind, does it work after that?  The original reason I
got the idea to retry was because if I simply tried an unbind / bind
again then things worked OK...


-Doug

^ permalink raw reply

* arm64 crashkernel fails to boot on acpi-only machines due to ACPI regions being no longer mapped as NOMAP
From: Bhupesh SHARMA @ 2017-12-13 19:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_G8kBEAdAznVauZVAdJOFkr1vmu0Gf6tOwJfH2CgdufA@mail.gmail.com>

Hi Ard, Akashi,

On Wed, Dec 13, 2017 at 5:47 PM, Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
> On 13 December 2017 at 12:16, AKASHI Takahiro
> <takahiro.akashi@linaro.org> wrote:
>> On Wed, Dec 13, 2017 at 10:49:27AM +0000, Ard Biesheuvel wrote:
>>> On 13 December 2017 at 10:26, AKASHI Takahiro
>>> <takahiro.akashi@linaro.org> wrote:
>>> > Bhupesh, Ard,
>>> >
>>> > On Wed, Dec 13, 2017 at 03:21:59AM +0530, Bhupesh Sharma wrote:
>>> >> Hi Ard, Akashi
>>> >>
>>> > (snip)
>>> >
>>> >> Looking deeper into the issue, since the arm64 kexec-tools uses the
>>> >> 'linux,usable-memory-range' dt property to allow crash dump kernel to
>>> >> identify its own usable memory and exclude, at its boot time, any
>>> >> other memory areas that are part of the panicked kernel's memory.
>>> >> (see https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt
>>> >> , for details)
>>> >
>>> > Right.
>>> >
>>> >> 1). Now when 'kexec -p' is executed, this node is patched up only
>>> >> with the crashkernel memory range:
>>> >>
>>> >>                 /* add linux,usable-memory-range */
>>> >>                 nodeoffset = fdt_path_offset(new_buf, "/chosen");
>>> >>                 result = fdt_setprop_range(new_buf, nodeoffset,
>>> >>                                 PROP_USABLE_MEM_RANGE, &crash_reserved_mem,
>>> >>                                 address_cells, size_cells);
>>> >>
>>> >> (see https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/tree/kexec/arch/arm64/kexec-arm64.c#n465
>>> >> , for details)
>>> >>
>>> >> 2). This excludes the ACPI reclaim regions irrespective of whether
>>> >> they are marked as System RAM or as RESERVED. As,
>>> >> 'linux,usable-memory-range' dt node is patched up only with
>>> >> 'crash_reserved_mem' and not 'system_memory_ranges'
>>> >>
>>> >> 3). As a result when the crashkernel boots up it doesn't find this
>>> >> ACPI memory and crashes while trying to access the same:
>>> >>
>>> >> # kexec -p /boot/vmlinuz-`uname -r` --initrd=/boot/initramfs-`uname
>>> >> -r`.img --reuse-cmdline -d
>>> >>
>>> >> [snip..]
>>> >>
>>> >> Reserved memory range
>>> >> 000000000e800000-000000002e7fffff (0)
>>> >>
>>> >> Coredump memory ranges
>>> >> 0000000000000000-000000000e7fffff (0)
>>> >> 000000002e800000-000000003961ffff (0)
>>> >> 0000000039d40000-000000003ed2ffff (0)
>>> >> 000000003ed60000-000000003fbfffff (0)
>>> >> 0000001040000000-0000001ffbffffff (0)
>>> >> 0000002000000000-0000002ffbffffff (0)
>>> >> 0000009000000000-0000009ffbffffff (0)
>>> >> 000000a000000000-000000affbffffff (0)
>>> >>
>>> >> 4). So if we revert Ard's patch or just comment the fixing up of the
>>> >> memory cap'ing passed to the crash kernel inside
>>> >> 'arch/arm64/mm/init.c' (see below):
>>> >>
>>> >> static void __init fdt_enforce_memory_region(void)
>>> >> {
>>> >>         struct memblock_region reg = {
>>> >>                 .size = 0,
>>> >>         };
>>> >>
>>> >>         of_scan_flat_dt(early_init_dt_scan_usablemem, &reg);
>>> >>
>>> >>         if (reg.size)
>>> >>                 //memblock_cap_memory_range(reg.base, reg.size); /*
>>> >> comment this out */
>>> >> }
>>> >
>>> > Please just don't do that. It can cause a fatal damage on
>>> > memory contents of the *crashed* kernel.
>>> >
>>> >> 5). Both the above temporary solutions fix the problem.
>>> >>
>>> >> 6). However exposing all System RAM regions to the crashkernel is not
>>> >> advisable and may cause the crashkernel or some crashkernel drivers to
>>> >> fail.
>>> >>
>>> >> 6a). I am trying an approach now, where the ACPI reclaim regions are
>>> >> added to '/proc/iomem' separately as ACPI reclaim regions by the
>>> >> kernel code and on the other hand the user-space 'kexec-tools' will
>>> >> pick up the ACPI reclaim regions from '/proc/iomem' and add it to the
>>> >> dt node 'linux,usable-memory-range'
>>> >
>>> > I still don't understand why we need to carry over the information
>>> > about "ACPI Reclaim memory" to crash dump kernel. In my understandings,
>>> > such regions are free to be reused by the kernel after some point of
>>> > initialization. Why does crash dump kernel need to know about them?
>>> >
>>>
>>> Not really. According to the UEFI spec, they can be reclaimed after
>>> the OS has initialized, i.e., when it has consumed the ACPI tables and
>>> no longer needs them. Of course, in order to be able to boot a kexec
>>> kernel, those regions needs to be preserved, which is why they are
>>> memblock_reserve()'d now.
>>
>> For my better understandings, who is actually accessing such regions
>> during boot time, uefi itself or efistub?
>>
>
> No, only the kernel. This is where the ACPI tables are stored. For
> instance, on QEMU we have
>
>  ACPI: RSDP 0x0000000078980000 000024 (v02 BOCHS )
>  ACPI: XSDT 0x0000000078970000 000054 (v01 BOCHS  BXPCFACP 00000001
>   01000013)
>  ACPI: FACP 0x0000000078930000 00010C (v05 BOCHS  BXPCFACP 00000001
> BXPC 00000001)
>  ACPI: DSDT 0x0000000078940000 0011DA (v02 BOCHS  BXPCDSDT 00000001
> BXPC 00000001)
>  ACPI: APIC 0x0000000078920000 000140 (v03 BOCHS  BXPCAPIC 00000001
> BXPC 00000001)
>  ACPI: GTDT 0x0000000078910000 000060 (v02 BOCHS  BXPCGTDT 00000001
> BXPC 00000001)
>  ACPI: MCFG 0x0000000078900000 00003C (v01 BOCHS  BXPCMCFG 00000001
> BXPC 00000001)
>  ACPI: SPCR 0x00000000788F0000 000050 (v02 BOCHS  BXPCSPCR 00000001
> BXPC 00000001)
>  ACPI: IORT 0x00000000788E0000 00007C (v00 BOCHS  BXPCIORT 00000001
> BXPC 00000001)
>
> covered by
>
>  efi:   0x0000788e0000-0x00007894ffff [ACPI Reclaim Memory ...]
>  ...
>  efi:   0x000078970000-0x00007898ffff [ACPI Reclaim Memory ...]
>
>
>>> So it seems that kexec does not honour the memblock_reserve() table
>>> when booting the next kernel.
>>
>> not really.
>>
>>> > (In other words, can or should we skip some part of ACPI-related init code
>>> > on crash dump kernel?)
>>> >
>>>
>>> I don't think so. And the change to the handling of ACPI reclaim
>>> regions only revealed the bug, not created it (given that other
>>> memblock_reserve regions may be affected as well)
>>
>> As whether we should honor such reserved regions over kexec'ing
>> depends on each one's specific nature, we will have to take care one-by-one.
>> As a matter of fact, no information about "reserved" memblocks is
>> exposed to user space (via proc/iomem).
>>
>
> That is why I suggested (somewhere in this thread?) to not expose them
> as 'System RAM'. Do you think that could solve this?

I agree. So how about my proposal (please see my last reply) - to
expose these regions as "ACPI reclaim regions" in /proc/iomem.

Please note that we already have several instances where the driver
regions are already explicitly labelled by different concise names
across /proc/iomem, for e.g.:

# cat /proc/iomem | grep -i serial

  1c021000-1c02101f : serial

If we expose only the ACPI reclaim regions to the crashkernel (along
with the normal crash kernel memory range), we avoid exposing all
System RAM or reserved regions to the crashkernel which may cause
issues with crashkernel boot or crash coredump save operations.

And we can also accordingly modify the 'kexec-tools' to pick these
regions along with the normal crash kernel memory range and append
them to the 'linux,usable-memory-range' dt node, so that the crash
kernel can operate on them.

If you think this ok, I can try to send a RFC patch later this week.

Please let me know.

Regards,
Bhupesh


>>>
>>> >> 6b). The kernel code currently looks like the following:
>>> >>
>>> >> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>>> >> index 30ad2f085d1f..867bdec7c692 100644
>>> >> --- a/arch/arm64/kernel/setup.c
>>> >> +++ b/arch/arm64/kernel/setup.c
>>> >> @@ -206,6 +206,7 @@ static void __init request_standard_resources(void)
>>> >>  {
>>> >>      struct memblock_region *region;
>>> >>      struct resource *res;
>>> >> +    phys_addr_t addr_start, addr_end;
>>> >>
>>> >>      kernel_code.start   = __pa_symbol(_text);
>>> >>      kernel_code.end     = __pa_symbol(__init_begin - 1);
>>> >> @@ -218,9 +219,17 @@ static void __init request_standard_resources(void)
>>> >>              res->name  = "reserved";
>>> >>              res->flags = IORESOURCE_MEM;
>>> >>          } else {
>>> >> -            res->name  = "System RAM";
>>> >> -            res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
>>> >> +            addr_start =
>>> >> __pfn_to_phys(memblock_region_reserved_base_pfn(region));
>>> >> +            addr_end =
>>> >> __pfn_to_phys(memblock_region_reserved_end_pfn(region)) - 1;
>>> >> +            if ((efi_mem_type(addr_start) == EFI_ACPI_RECLAIM_MEMORY)
>>> >> || (efi_mem_type(addr_end) == EFI_ACPI_RECLAIM_MEMORY)) {
>>> >> +                res->name  = "ACPI reclaim region";
>>> >> +                res->flags = IORESOURCE_MEM;
>>> >> +            } else {
>>> >> +                res->name  = "System RAM";
>>> >> +                res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
>>> >> +            }
>>> >>          }
>>> >> +
>>> >>          res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
>>> >>          res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
>>> >>
>>> >> @@ -292,6 +301,7 @@ void __init setup_arch(char **cmdline_p)
>>> >>
>>> >>      request_standard_resources();
>>> >>
>>> >> +    efi_memmap_unmap();
>>> >>      early_ioremap_reset();
>>> >>
>>> >>      if (acpi_disabled)
>>> >> diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
>>> >> index 80d1a885def5..a7c522eac640 100644
>>> >> --- a/drivers/firmware/efi/arm-init.c
>>> >> +++ b/drivers/firmware/efi/arm-init.c
>>> >> @@ -259,7 +259,6 @@ void __init efi_init(void)
>>> >>
>>> >>      reserve_regions();
>>> >>      efi_esrt_init();
>>> >> -    efi_memmap_unmap();
>>> >>
>>> >>      memblock_reserve(params.mmap & PAGE_MASK,
>>> >>               PAGE_ALIGN(params.mmap_size +
>>> >>
>>> >>
>>> >> After this change the ACPI reclaim regions are properly recognized in
>>> >> '/proc/iomem':
>>> >>
>>> >> # cat /proc/iomem | grep -i ACPI
>>> >> 396c0000-3975ffff : ACPI reclaim region
>>> >> 39770000-397affff : ACPI reclaim region
>>> >> 398a0000-398bffff : ACPI reclaim region
>>> >>
>>> >> 6c). I am currently changing the 'kexec-tools' and will finish the
>>> >> testing over the next few days.
>>> >>
>>> >> I just wanted to know your opinion on this issue, so that I will be
>>> >> able to propose a fix on the above lines.
>>> >>
>>> >> Also Cc'ing kexec mailing list for more inputs on changes proposed to
>>> >> kexec-tools.
>>> >>
>>> >> Thanks,
>>> >> Bhupesh

^ permalink raw reply

* [PATCH 1/2] arm: dts: sun8i: a83t: remove leading zero from cpucfg node address
From: Corentin Labbe @ 2017-12-13 19:37 UTC (permalink / raw)
  To: linux-arm-kernel

This will fix the following warning:
Warning (simple_bus_reg): Node /soc/cpucfg at 01700000 simple-bus unit address format error, expected "1700000"

Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 7b372acf4bf6..715719f9ea2e 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -377,7 +377,7 @@
 			#reset-cells = <1>;
 		};
 
-		cpucfg at 01700000 {
+		cpucfg at 1700000 {
 			compatible = "allwinner,sun9i-a80-cpucfg";
 			reg = <0x01700000 0x100>;
 		};
-- 
2.13.6

^ permalink raw reply related

* [PATCH 2/2] arm: dts: sun8i: a83t: Add an unit address to the memory node
From: Corentin Labbe @ 2017-12-13 19:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213193715.31039-1-clabbe.montjoie@gmail.com>

This will fix the following warning:
Warning (unit_address_vs_reg): Node /memory has a reg or ranges property, but no unit name

Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 715719f9ea2e..bddde0141f24 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -160,7 +160,7 @@
 		};
 	};
 
-	memory {
+	memory at 40000000 {
 		reg = <0x40000000 0x80000000>;
 		device_type = "memory";
 	};
-- 
2.13.6

^ permalink raw reply related

* [PATCH v8 3/9] KVM: arm/arm64: Don't cache the timer IRQ level
From: Marc Zyngier @ 2017-12-13 19:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213104602.16383-4-christoffer.dall@linaro.org>

On Wed, 13 Dec 2017 10:45:56 +0000,
Christoffer Dall wrote:
> 
> The timer was modeled after a strict idea of modelling an interrupt line
> level in software, meaning that only transitions in the level needed to
> be reported to the VGIC.  This works well for the timer, because the
> arch timer code is in complete control of the device and can track the
> transitions of the line.
> 
> However, as we are about to support using the HW bit in the VGIC not
> just for the timer, but also for VFIO which cannot track transitions of
> the interrupt line, we have to decide on an interface for level
> triggered mapped interrupts to the GIC, which both the timer and VFIO
> can use.
> 
> VFIO only sees an asserting transition of the physical interrupt line,
> and tells the VGIC when that happens.  That means that part of the
> interrupt flow is offloaded to the hardware.
> 
> To use the same interface for VFIO devices and the timer, we therefore
> have to change the timer (we cannot change VFIO because it doesn't know
> the details of the device it is assigning to a VM).
> 
> Luckily, changing the timer is simple, we just need to stop 'caching'
> the line level, but instead let the VGIC know the state of the timer
> every time there is a potential change in the line level, and when the
> line level should be asserted from the timer ISR.  The VGIC can ignore
> extra notifications using its validate mechanism.
> 
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.

^ permalink raw reply

* [PATCH v8 7/9] KVM: arm/arm64: Provide a get_input_level for the arch timer
From: Marc Zyngier @ 2017-12-13 19:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213104602.16383-8-christoffer.dall@linaro.org>

On Wed, 13 Dec 2017 10:46:00 +0000,
Christoffer Dall wrote:
> 
> The VGIC can now support the life-cycle of mapped level-triggered
> interrupts, and we no longer have to read back the timer state on every
> exit from the VM if we had an asserted timer interrupt signal, because
> the VGIC already knows if we hit the unlikely case where the guest
> disables the timer without ACKing the virtual timer interrupt.
> 
> This means we rework a bit of the code to factor out the functionality
> to snapshot the timer state from vtimer_save_state(), and we can reuse
> this functionality in the sync path when we have an irqchip in
> userspace, and also to support our implementation of the
> get_input_level() function for the timer.
> 
> This change also means that we can no longer rely on the timer's view of
> the interrupt line to set the active state, because we no longer
> maintain this state for mapped interrupts when exiting from the guest.
> Instead, we only set the active state if the virtual interrupt is
> active, and otherwise we simply let the timer fire again and raise the
> virtual interrupt from the ISR.
> 
> Reviewed-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.

^ permalink raw reply

* [linux-sunxi] [PATCH v2 3/6] ARM: sun4i: Convert to CCU
From: Kevin Hilman @ 2017-12-13 19:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213171358.oocp24c2mdon45o5@plaes.org>

On Wed, Dec 13, 2017 at 9:13 AM, Priit Laes <plaes@plaes.org> wrote:
> On Wed, Dec 13, 2017 at 05:09:33PM +0000, Priit Laes wrote:
>> On Tue, Dec 12, 2017 at 01:24:52PM -0800, Kevin Hilman wrote:
>> > On Tue, Dec 12, 2017 at 9:26 AM, Priit Laes <plaes@plaes.org> wrote:
>> > > On Mon, Dec 11, 2017 at 02:22:30PM -0800, Kevin Hilman wrote:
>> > >> On Sun, Mar 26, 2017 at 10:20 AM, Priit Laes <plaes@plaes.org> wrote:
>> > >> > Convert sun4i-a10.dtsi to new CCU driver.
>> > >> >
>> > >> > Signed-off-by: Priit Laes <plaes@plaes.org>
>> > >>
>> > >> I finally got around to bisecting a mainline boot failure on
>> > >> sun4i-a10-cubieboard that's been happening for quite a while.  Based
>> > >> on on kernelci.org, it showed up sometime during the v4.15 merge
>> > >> window[1].  It bisected down to this commit (in mainline as commit
>> > >> 41193869f2bdb585ce09bfdd16d9482aadd560ad).
>> > >>
>> > >> When it fails, there is no output on the serial console, so I don't
>> > >> know exactly how it's failing, just that it no longer boots.
>> > >
>> > > We tried out latest 4.15 with various compilers and it works:
>> > > - gcc version 7.1.1 20170622 (Red Hat Cross 7.1.1-3) (GCC) - A10 Gemei G9 tablet
>> > > - gcc 7.2.0-debian - A10 Cubieboard
>> >
>> > And you can reproduce the bug with gcc5 or gcc6?
>>
>> Tried following commits on Gemei G9 (A10 tablet):
>> * 4.15.0-rc3-00037-gd39a01eff9af - latest master
>> * 4.14.0-rc1-00002-g41193869f2bd - the exact commit, causing the issue.
>>
>> With the same Linaro toolchain:
>> (gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05))
>
> And I also tried the same dtb and zImage from kernelci page [1] and it works with
> that too...
>
> https://storage.kernelci.org/mainline/master/v4.15-rc3/arm/sunxi_defconfig/

Can you share a full boot-log (including all the u-boot output etc.)
so I can see exactly how the kernel is being loaded?    Especially the
u-boot version?

As $SUBJECT patch seems to be changing clocks around, perhaps this is
an issue where some u-boot dependency is uncovered, and older versions
of u-boot don't play well with this change.

Kevin

^ permalink raw reply

* [PATCH 1/2] net: dsa: allow XAUI phy interface mode
From: David Miller @ 2017-12-13 19:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1eOgsk-0001AU-5z@rmk-PC.armlinux.org.uk>

From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 12 Dec 2017 09:29:46 +0000

> XGMII is a 32-bit bus plus two clock signals per direction.  XAUI is
> four serial lanes per direction.  The 88e6190 supports XAUI but not
> XGMII as it doesn't have enough pins.  The same is true of 88e6176.
> 
> Match on PHY_INTERFACE_MODE_XAUI for the XAUI port type, but keep
> accepting XGMII for backwards compatibility.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Applied.

^ permalink raw reply

* [PATCH 2/2] ARM: dts: vf610-zii-dev: use XAUI for DSA link ports
From: David Miller @ 2017-12-13 19:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1eOgsp-0001Ab-9x@rmk-PC.armlinux.org.uk>

From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 12 Dec 2017 09:29:51 +0000

> Use XAUI rather than XGMII for DSA link ports, as this is the interface
> mode that the switches actually use. XAUI is the 4 lane bus with clock
> per direction, whereas XGMII is a 32 bit bus with clock.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
> This must be applied along with patch 1 to avoid breakage.

Applied.

^ permalink raw reply

* [PATCH][next] net: phy: meson-gxl: make function meson_gxl_read_status static
From: David Miller @ 2017-12-13 20:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171212130311.17185-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Tue, 12 Dec 2017 13:03:11 +0000

> From: Colin Ian King <colin.king@canonical.com>
> 
> The function meson_gxl_read_status is local to the source and does
> not need to be in global scope, so make it static.
> 
> Cleans up sparse warning:
> symbol 'meson_gxl_read_status' was not declared. Should it be static?
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* [PATCH v8 8/9] KVM: arm/arm64: Avoid work when userspace iqchips are not used
From: Marc Zyngier @ 2017-12-13 20:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213104602.16383-9-christoffer.dall@linaro.org>

On Wed, 13 Dec 2017 10:46:01 +0000,
Christoffer Dall wrote:
> 
> We currently check if the VM has a userspace irqchip on every exit from
> the VCPU, and if so, we do some work to ensure correct timer behavior.
> This is unfortunate, as we could avoid doing any work entirely, if we
> didn't have to support irqchip in userspace.
> 
> Realizing the userspace irqchip on ARM is mostly a developer or hobby
> feature, and is unlikely to be used in servers or other scenarios where
> performance is a priority, we can use a refcounted static key to only
> check the irqchip configuration when we have at least one VM that uses
> an irqchip in userspace.
> 
> Reviewed-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>

On its own, this doesn't seem to be that useful. As far as I can see,
it saves us a load from the kvm structure before giving up. I think it
is more the cumulative effect of this load that could have an impact,
but you're only dealing with it at a single location.

How about making this a first class helper and redefine
irqchip_in_kernel as such:

static inline bool irqchip_in_kernel(struct kvm *kvm)
{
	if (static_branch_unlikely(&userspace_irqchip_in_use) &&
	    unlikely(!irqchip_in_kernel(kvm)))
		return true;

	return false;
}

and move that static key to a more central location?

> ---
>  virt/kvm/arm/arch_timer.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> index f8d09665ddce..73d262c4712b 100644
> --- a/virt/kvm/arm/arch_timer.c
> +++ b/virt/kvm/arm/arch_timer.c
> @@ -51,6 +51,8 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
>  				 struct arch_timer_context *timer_ctx);
>  static bool kvm_timer_should_fire(struct arch_timer_context *timer_ctx);
>  
> +static DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
> +
>  u64 kvm_phys_timer_read(void)
>  {
>  	return timecounter->cc->read(timecounter->cc);
> @@ -562,7 +564,8 @@ static void unmask_vtimer_irq_user(struct kvm_vcpu *vcpu)
>  
>  void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
>  {
> -	unmask_vtimer_irq_user(vcpu);
> +	if (static_branch_unlikely(&userspace_irqchip_in_use))
> +		unmask_vtimer_irq_user(vcpu);
>  }
>  
>  int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
> @@ -767,6 +770,8 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
>  	soft_timer_cancel(&timer->bg_timer, &timer->expired);
>  	soft_timer_cancel(&timer->phys_timer, NULL);
>  	kvm_vgic_unmap_phys_irq(vcpu, vtimer->irq.irq);
> +	if (timer->enabled && !irqchip_in_kernel(vcpu->kvm))
> +		static_branch_dec(&userspace_irqchip_in_use);
>  }
>  
>  static bool timer_irqs_are_valid(struct kvm_vcpu *vcpu)
> @@ -819,8 +824,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>  		return 0;
>  
>  	/* Without a VGIC we do not map virtual IRQs to physical IRQs */
> -	if (!irqchip_in_kernel(vcpu->kvm))
> +	if (!irqchip_in_kernel(vcpu->kvm)) {
> +		static_branch_inc(&userspace_irqchip_in_use);
>  		goto no_vgic;
> +	}
>  
>  	if (!vgic_initialized(vcpu->kvm))
>  		return -ENODEV;
> -- 
> 2.14.2
> 

Thanks,

	M.

^ permalink raw reply

* [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
From: Sakari Ailus @ 2017-12-13 20:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171211013146.2497-3-wenyou.yang@microchip.com>

Hi Wenyou,

Wenyou Yang wrote:
...
> +static int ov7740_start_streaming(struct ov7740 *ov7740)
> +{
> +	int ret;
> +
> +	if (ov7740->fmt) {
> +		ret = regmap_multi_reg_write(ov7740->regmap,
> +					     ov7740->fmt->regs,
> +					     ov7740->fmt->reg_num);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if (ov7740->frmsize) {
> +		ret = regmap_multi_reg_write(ov7740->regmap,
> +					     ov7740->frmsize->regs,
> +					     ov7740->frmsize->reg_num);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);

I believe you're still setting the controls after starting streaming.

-- 
Sakari Ailus
sakari.ailus at iki.fi

^ permalink raw reply

* [PATCH v8 9/9] KVM: arm/arm64: Update timer and forwarded irq documentation
From: Marc Zyngier @ 2017-12-13 20:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213104602.16383-10-christoffer.dall@linaro.org>

On Wed, 13 Dec 2017 10:46:02 +0000,
Christoffer Dall wrote:
> 
> Now when we've reworked how mapped level-triggered interrupts are
> processed for the timer interrupts, we update the documentation
> correspondingly.

Seems like the documentation is more out of date than we thought, see
below.

> 
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt | 50 ++++++++++------------
>  1 file changed, 23 insertions(+), 27 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt b/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
> index 38bca2835278..f68c7d95a341 100644
> --- a/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
> +++ b/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
> @@ -7,9 +7,10 @@ allowing software to inject virtual interrupts to a VM, which the guest
>  OS sees as regular interrupts.  The code is famously known as the VGIC.
>  
>  Some of these virtual interrupts, however, correspond to physical
> -interrupts from real physical devices.  One example could be the
> -architected timer, which itself supports virtualization, and therefore
> -lets a guest OS program the hardware device directly to raise an
> +interrupts from real physical devices.  One example could be the ARM
> +Generic Timers (also known as the "architected timers"), which are
> +directly assigned to a VM while it's running, and therefore
> +makes it possible for guest OSes to program the timers directly to raise an
>  interrupt at some point in time.  When such an interrupt is raised, the
>  host OS initially handles the interrupt and must somehow signal this
>  event as a virtual interrupt to the guest.  Another example could be a
> @@ -37,7 +38,7 @@ inactive.
>  
>  The LRs include an extra bit, called the HW bit.  When this bit is set,
>  KVM must also program an additional field in the LR, the physical IRQ
> -number, to link the virtual with the physical IRQ.
> +number, to link the virtual and physical IRQs together.
>  
>  When the HW bit is set, KVM must EITHER set the Pending OR the Active
>  bit, never both at the same time.
> @@ -59,21 +60,21 @@ The state of forwarded physical interrupts is managed in the following way:
>    - LR.Pending will stay set as long as the guest has not acked the interrupt.
>    - LR.Pending transitions to LR.Active on the guest read of the IAR, as
>      expected.
> -  - On guest EOI, the *physical distributor* active bit gets cleared,
> +  - On guest deactivate, the *physical distributor* active bit gets cleared,
>      but the LR.Active is left untouched (set).

Is this true? I seem to remember that we established it wasn't (back
when we redesigned the vgic). Certainly, the current code relies on
the Active bit being cleared in the LR as well as in the physical
distributor.

>    - KVM clears the LR on VM exits when the physical distributor
>      active state has been cleared.

And this isn't either, if my above assertion stands.

>  
>  (*): The host handling is slightly more complicated.  For some forwarded
> -interrupts (shared), KVM directly sets the active state on the physical
> -distributor before entering the guest, because the interrupt is never actually
> -handled on the host (see details on the timer as an example below).  For other
> -forwarded interrupts (non-shared) the host does not deactivate the interrupt
> -when the host ISR completes, but leaves the interrupt active until the guest
> -deactivates it.  Leaving the interrupt active is allowed, because Linux
> -configures the physical GIC with EOIMode=1, which causes EOI operations to
> -perform a priority drop allowing the GIC to receive other interrupts of the
> -default priority.
> +interrupts (shared), in some cases, KVM directly sets the active state
> +on the physical distributor before entering the guest, because the
> +interrupt is never actually handled on the host (see details on the
> +timer as an example below).  In other cases, the host does not

This isn't true either. We now handle the timer interrupt on the host.

> +deactivate the interrupt when the host ISR completes, but leaves the
> +interrupt active until the guest deactivates it.  Leaving the interrupt
> +active is allowed, because Linux configures the physical GIC with
> +EOIMode=1, which causes EOI operations to perform a priority drop
> +allowing the GIC to receive other interrupts of the default priority.
>  
>  
>  Forwarded Edge and Level Triggered PPIs and SPIs
> @@ -170,18 +171,13 @@ instead:
>  
>  1.  KVM runs the VCPU
>  2.  The guest programs the time to fire in T+100
> -4.  At T+100 the timer fires and a physical IRQ causes the VM to exit
> +3.  At T+100 the timer fires and a physical IRQ causes the VM to exit
>      (note that this initially only traps to EL2 and does not run the host ISR
>      until KVM has returned to the host).
> -5.  With interrupts still disabled on the CPU coming back from the guest, KVM
> -    stores the virtual timer state to memory and disables the virtual hw timer.
> -6.  KVM looks at the timer state (in memory) and injects a forwarded physical
> -    interrupt because it concludes the timer has expired.
> -7.  KVM marks the timer interrupt as active on the physical distributor
> -7.  KVM enables the timer, enables interrupts, and runs the VCPU
> -
> -Notice that again the forwarded physical interrupt is injected to the
> -guest without having actually been handled on the host.  In this case it
> -is because the physical interrupt is never actually seen by the host because the
> -timer is disabled upon guest return, and the virtual forwarded interrupt is
> -injected on the KVM guest entry path.
> +4.  When KVM returns to EL1 and enables interrupts, the timer interrupt
> +    fires again, and the kvm arch timer ISR runs and injects a virtual
> +    interrupt to the guest.
> +5.  Because the timer interrupt has the vcpu affinity set, as the ISR
> +    completes, the physical interrupt stays active on the physical
> +    distributor.
> +6.  KVM enables the timer, enables interrupts, and runs the VCPU
> -- 
> 2.14.2
> 

Thanks,

	M.

^ permalink raw reply

* [PATCH 0/4] PM / OPP: Introduce ti-opp-supply driver
From: Dave Gerlach @ 2017-12-13 20:33 UTC (permalink / raw)
  To: linux-arm-kernel

Some SoCs, such as Texas Instruments DRA7 family, have complex requirements for
scaling voltages and supplies when doing things like DVFS. For example, for
cpufreq on dra7xx, the cpu-supply must be scaled as is normally done however
there is also an Adaptive Body Bias (ABB) regulator that should be scaled at
the same time as the main supply in sequence depending on the transition,
explained earlier by Nishanth Menon here [1]. In addition to this, each
possible operating point has a corresponding optimized voltage value stored in
a register (Adaptive Voltage Scaling Class 0) that can be used instead of the
nominal value.

The OPP framework is now able to to handle DVFS transitions through the
provided dev_pm_opp_set_rate API and cpufreq-dt is doing this. Viresh Kumar
extended this to allow platforms to register a transition helper through the
use of dev_pm_opp_register_set_opp_helper and has also extended the OPP core to
support registering multiple regulators. By providing a TI platform specific
opp_helper function and registering the proepr regulators with the OPP core we
can meet the above requirements for properly changing DVFS state of the cpu
device.

This series introduces a ti-opp-supply driver that overrides the standard
single regulator DVFS transition handler to handle scaling the ABB regulator in
sequence with the normal supply and programing AVS voltages through a custom
opp_helper that is registered. The ti-cpufreq driver is extended to allow
registering the proper regulators needed for the CPU if the platform supports
multi regulators and is also changed to a regular driver so that it can defer
probe if needed as it now may have to if the regulators are not ready.

This series only contains driver changes and binding docs, DT patches will be
sent later but I have pushed them all here for anyone curious [2].

This series is required to enable the highest 1.5GHz OPP on dra7/am57 platforms
that support it but all dra7/am57 platforms will make use of this for all OPPs.

Regards,
Dave

[1] https://marc.info/?l=linux-pm&m=145684495832764&w=2
[2] https://github.com/dgerlach/linux-pm/tree/upstream/v4.15/ti-multireg-support

Dave Gerlach (4):
  cpufreq: ti-cpufreq: Convert to module_platform_driver
  cpufreq: ti-cpufreq: Add support for multiple regulators
  dt-bindings: opp: Introduce ti-opp-supply bindings
  PM / OPP: Add ti-opp-supply driver

 .../bindings/opp/ti-omap5-opp-supply.txt           |  63 +++
 drivers/cpufreq/ti-cpufreq.c                       |  51 ++-
 drivers/opp/Makefile                               |   1 +
 drivers/opp/ti-opp-supply.c                        | 428 +++++++++++++++++++++
 4 files changed, 537 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
 create mode 100644 drivers/opp/ti-opp-supply.c

-- 
2.15.1

^ permalink raw reply

* [PATCH 1/4] cpufreq: ti-cpufreq: Convert to module_platform_driver
From: Dave Gerlach @ 2017-12-13 20:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213203358.20839-1-d-gerlach@ti.com>

ti-cpufreq will be responsible for calling dev_pm_opp_set_regulators on
platforms that require AVS and ABB regulator support so we must be
able to defer probe if regulators are not yet available, so change
ti-cpufreq to be a module_platform_driver to allow for probe defer.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 drivers/cpufreq/ti-cpufreq.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
index 923317f03b4b..b1c230a1e2aa 100644
--- a/drivers/cpufreq/ti-cpufreq.c
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -17,6 +17,7 @@
 #include <linux/cpu.h>
 #include <linux/io.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -195,7 +196,7 @@ static const struct of_device_id ti_cpufreq_of_match[] = {
 	{},
 };
 
-static int ti_cpufreq_init(void)
+static int ti_cpufreq_probe(struct platform_device *pdev)
 {
 	u32 version[VERSION_COUNT];
 	struct device_node *np;
@@ -269,4 +270,22 @@ static int ti_cpufreq_init(void)
 
 	return ret;
 }
-device_initcall(ti_cpufreq_init);
+
+static int ti_cpufreq_init(void)
+{
+	platform_device_register_simple("ti-cpufreq", -1, NULL, 0);
+	return 0;
+}
+module_init(ti_cpufreq_init);
+
+static struct platform_driver ti_cpufreq_driver = {
+	.probe = ti_cpufreq_probe,
+	.driver = {
+		.name = "ti-cpufreq",
+	},
+};
+module_platform_driver(ti_cpufreq_driver);
+
+MODULE_DESCRIPTION("TI CPUFreq/OPP hw-supported driver");
+MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.15.1

^ permalink raw reply related

* [PATCH 2/4] cpufreq: ti-cpufreq: Add support for multiple regulators
From: Dave Gerlach @ 2017-12-13 20:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213203358.20839-1-d-gerlach@ti.com>

Some platforms, like those in the DRA7 and AM57 families, require the
scaling of multiple regulators in order to properly support higher OPPs.
Let the ti-cpufreq driver determine when this is required and pass the
appropriate regulator names to the OPP core so that they can be properly
managed.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 drivers/cpufreq/ti-cpufreq.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
index b1c230a1e2aa..a099b7bf74cd 100644
--- a/drivers/cpufreq/ti-cpufreq.c
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -51,6 +51,7 @@ struct ti_cpufreq_soc_data {
 	unsigned long efuse_mask;
 	unsigned long efuse_shift;
 	unsigned long rev_offset;
+	bool multi_regulator;
 };
 
 struct ti_cpufreq_data {
@@ -58,6 +59,7 @@ struct ti_cpufreq_data {
 	struct device_node *opp_node;
 	struct regmap *syscon;
 	const struct ti_cpufreq_soc_data *soc_data;
+	struct opp_table *opp_table;
 };
 
 static unsigned long amx3_efuse_xlate(struct ti_cpufreq_data *opp_data,
@@ -96,6 +98,7 @@ static struct ti_cpufreq_soc_data am3x_soc_data = {
 	.efuse_offset = 0x07fc,
 	.efuse_mask = 0x1fff,
 	.rev_offset = 0x600,
+	.multi_regulator = false,
 };
 
 static struct ti_cpufreq_soc_data am4x_soc_data = {
@@ -104,6 +107,7 @@ static struct ti_cpufreq_soc_data am4x_soc_data = {
 	.efuse_offset = 0x0610,
 	.efuse_mask = 0x3f,
 	.rev_offset = 0x600,
+	.multi_regulator = false,
 };
 
 static struct ti_cpufreq_soc_data dra7_soc_data = {
@@ -112,6 +116,7 @@ static struct ti_cpufreq_soc_data dra7_soc_data = {
 	.efuse_mask = 0xf80000,
 	.efuse_shift = 19,
 	.rev_offset = 0x204,
+	.multi_regulator = true,
 };
 
 /**
@@ -201,7 +206,9 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
 	u32 version[VERSION_COUNT];
 	struct device_node *np;
 	const struct of_device_id *match;
+	struct opp_table *ti_opp_table;
 	struct ti_cpufreq_data *opp_data;
+	const char * const reg_names[] = {"vdd", "vbb"};
 	int ret;
 
 	np = of_find_node_by_path("/");
@@ -248,16 +255,29 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
 	if (ret)
 		goto fail_put_node;
 
-	ret = PTR_ERR_OR_ZERO(dev_pm_opp_set_supported_hw(opp_data->cpu_dev,
-							  version, VERSION_COUNT));
-	if (ret) {
+	ti_opp_table = dev_pm_opp_set_supported_hw(opp_data->cpu_dev,
+						   version, VERSION_COUNT);
+	if (IS_ERR(ti_opp_table)) {
 		dev_err(opp_data->cpu_dev,
 			"Failed to set supported hardware\n");
+		ret = PTR_ERR(ti_opp_table);
 		goto fail_put_node;
 	}
 
-	of_node_put(opp_data->opp_node);
+	opp_data->opp_table = ti_opp_table;
+
+	if (opp_data->soc_data->multi_regulator) {
+		ti_opp_table = dev_pm_opp_set_regulators(opp_data->cpu_dev,
+							 reg_names,
+							 ARRAY_SIZE(reg_names));
+		if (IS_ERR(ti_opp_table)) {
+			dev_pm_opp_put_supported_hw(opp_data->opp_table);
+			ret =  PTR_ERR(ti_opp_table);
+			goto fail_put_node;
+		}
+	}
 
+	of_node_put(opp_data->opp_node);
 register_cpufreq_dt:
 	platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
 
-- 
2.15.1

^ permalink raw reply related

* [PATCH 3/4] dt-bindings: opp: Introduce ti-opp-supply bindings
From: Dave Gerlach @ 2017-12-13 20:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213203358.20839-1-d-gerlach@ti.com>

Document the devicetree bindings that describe Texas Instruments
opp-supply which allow a platform to describe multiple regulators and
additional information, such as registers containing data needed to
program aforementioned regulators.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 .../bindings/opp/ti-omap5-opp-supply.txt           | 63 ++++++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt

diff --git a/Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt b/Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
new file mode 100644
index 000000000000..832346e489a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
@@ -0,0 +1,63 @@
+Texas Instruments OMAP compatible OPP supply description
+
+OMAP5, DRA7, and AM57 family of SoCs have Class0 AVS eFuse registers which
+contain data that can be used to adjust voltages programmed for some of their
+supplies for more efficient operation. This binding provides the information
+needed to read these values and use them to program the main regulator during
+an OPP transitions.
+
+Also, some supplies may have an associated vbb-supply which is an Adaptive Body
+Bias regulator which much be transitioned in a specific sequence with regards
+to the vdd-supply and clk when making an OPP transition. By supplying two
+regulators to the device that will undergo OPP transitions we can make use
+of the multi regulator binding that is part of the OPP core described here [1]
+to describe both regulators needed by the platform.
+
+[1] Documentation/devicetree/bindings/opp/opp.txt
+
+Required Properties for Device Node:
+- vdd-supply: phandle to regulator controlling VDD supply
+- vbb-supply: phandle to regulator controlling Body Bias supply
+	      (Usually Adaptive Body Bias regulator)
+
+Required Properties for opp-supply node:
+- compatible: Should be one of:
+	"ti,omap-opp-supply" - basic OPP supply controlling VDD and VBB
+	"ti,omap5-opp-supply" - OMAP5+ optimized voltages in efuse(class0)VDD
+			    along with VBB
+	"ti,omap5-core-opp-supply" - OMAP5+ optimized voltages in efuse(class0) VDD
+			    but no VBB.
+- reg: Address and length of the efuse register set for the device (mandatory
+	only for "ti,omap5-opp-supply")
+- ti,efuse-settings: An array of u32 tuple items providing information about
+	optimized efuse configuration. Each item consists of the following:
+	volt: voltage in uV - reference voltage (OPP voltage)
+	efuse_offseet: efuse offset from reg where the optimized voltage is stored.
+- ti,absolute-max-voltage-uv: absolute maximum voltage for the OPP supply.
+
+Example:
+
+/* Device Node (CPU)  */
+cpus {
+	cpu0: cpu at 0 {
+		device_type = "cpu";
+
+		...
+
+		vdd-supply = <&vcc>;
+		vbb-supply = <&abb_mpu>;
+	};
+};
+
+/* OMAP OPP Supply with Class0 registers */
+opp_supply_mpu: opp_supply at 4a003b20 {
+	compatible = "ti,omap5-opp-supply";
+	reg = <0x4a003b20 0x8>;
+	ti,efuse-settings = <
+	/* uV   offset */
+	1060000 0x0
+	1160000 0x4
+	1210000 0x8
+	>;
+	ti,absolute-max-voltage-uv = <1500000>;
+};
-- 
2.15.1

^ permalink raw reply related

* [PATCH 4/4] PM / OPP: Add ti-opp-supply driver
From: Dave Gerlach @ 2017-12-13 20:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213203358.20839-1-d-gerlach@ti.com>

Introduce a ti-opp-supply driver that will use new multiple regulator
support that is part of the OPP core This is needed on TI platforms like
DRA7/AM57 in order to control both CPU regulator and Adaptive Body Bias
(ABB) regulator. These regulators must be scaled in sequence during an
OPP transition depending on whether or not the frequency is being scaled
up or down.

This driver also implements AVS Class0 for these parts by looking up the
required values from registers in the SoC and programming adjusted
optimal voltage values for each OPP.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 drivers/opp/Makefile        |   1 +
 drivers/opp/ti-opp-supply.c | 428 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 429 insertions(+)
 create mode 100644 drivers/opp/ti-opp-supply.c

diff --git a/drivers/opp/Makefile b/drivers/opp/Makefile
index e70ceb406fe9..6ce6aefacc81 100644
--- a/drivers/opp/Makefile
+++ b/drivers/opp/Makefile
@@ -2,3 +2,4 @@ ccflags-$(CONFIG_DEBUG_DRIVER)	:= -DDEBUG
 obj-y				+= core.o cpu.o
 obj-$(CONFIG_OF)		+= of.o
 obj-$(CONFIG_DEBUG_FS)		+= debugfs.o
+obj-$(CONFIG_ARM_TI_CPUFREQ)	+= ti-opp-supply.o
diff --git a/drivers/opp/ti-opp-supply.c b/drivers/opp/ti-opp-supply.c
new file mode 100644
index 000000000000..73d795c90b79
--- /dev/null
+++ b/drivers/opp/ti-opp-supply.c
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/
+ *	Nishanth Menon <nm@ti.com>
+ *	Dave Gerlach <d-gerlach@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * TI OPP supply driver that provides override into the regulator control
+ * for generic opp core to handle devices with ABB regulator and/or
+ * SmartReflex Class0.
+ */
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+/**
+ * struct ti_opp_supply_optimum_voltage_table - optimized voltage table
+ * @reference_uv:	reference voltage (usually Nominal voltage)
+ * @optimized_uv:	Optimized voltage from efuse
+ */
+struct ti_opp_supply_optimum_voltage_table {
+	unsigned int reference_uv;
+	unsigned int optimized_uv;
+};
+
+/**
+ * struct ti_opp_supply_data - OMAP specific opp supply data
+ * @vdd_table:	Optimized voltage mapping table
+ * @num_vdd_table: number of entries in vdd_table
+ * @vdd_absolute_max_voltage_uv: absolute maximum voltage in UV for the supply
+ */
+struct ti_opp_supply_data {
+	struct ti_opp_supply_optimum_voltage_table *vdd_table;
+	u32 num_vdd_table;
+	u32 vdd_absolute_max_voltage_uv;
+};
+
+static struct ti_opp_supply_data opp_data;
+
+/**
+ * struct ti_opp_supply_of_data - device tree match data
+ * @flags:	specific type of opp supply
+ * @efuse_voltage_mask: mask required for efuse register representing voltage
+ * @efuse_voltage_uv: Are the efuse entries in micro-volts? if not, assume
+ *		milli-volts.
+ */
+struct ti_opp_supply_of_data {
+#define OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE	BIT(1)
+#define OPPDM_HAS_NO_ABB			BIT(2)
+	const u8 flags;
+	const u32 efuse_voltage_mask;
+	const bool efuse_voltage_uv;
+};
+
+/**
+ * _store_optimized_voltages() - store optimized voltages
+ * @dev:	ti opp supply device for which we need to store info
+ * @data:	data specific to the device
+ *
+ * Picks up efuse based optimized voltages for VDD unique per device and
+ * stores it in internal data structure for use during transition requests.
+ *
+ * Return: If successful, 0, else appropriate error value.
+ */
+static int _store_optimized_voltages(struct device *dev,
+				     struct ti_opp_supply_data *data)
+{
+	void __iomem *base;
+	struct property *prop;
+	struct resource *res;
+	const __be32 *val;
+	int proplen, i;
+	int ret = 0;
+	struct ti_opp_supply_optimum_voltage_table *table;
+	const struct ti_opp_supply_of_data *of_data = dev_get_drvdata(dev);
+
+	/* pick up Efuse based voltages */
+	res = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "Unable to get IO resource\n");
+		ret = -ENODEV;
+		goto out_map;
+	}
+
+	base = ioremap_nocache(res->start, resource_size(res));
+	if (!base) {
+		dev_err(dev, "Unable to map Efuse registers\n");
+		ret = -ENOMEM;
+		goto out_map;
+	}
+
+	/* Fetch efuse-settings. */
+	prop = of_find_property(dev->of_node, "ti,efuse-settings", NULL);
+	if (!prop) {
+		dev_err(dev, "No 'ti,efuse-settings' property found\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	proplen = prop->length / sizeof(int);
+	data->num_vdd_table = proplen / 2;
+	/* Verify for corrupted OPP entries in dt */
+	if (data->num_vdd_table * 2 * sizeof(int) != prop->length) {
+		dev_err(dev, "Invalid 'ti,efuse-settings'\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = of_property_read_u32(dev->of_node, "ti,absolute-max-voltage-uv",
+				   &data->vdd_absolute_max_voltage_uv);
+	if (ret) {
+		dev_err(dev, "ti,absolute-max-voltage-uv is missing\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	table = kzalloc(sizeof(*data->vdd_table) *
+				  data->num_vdd_table, GFP_KERNEL);
+	if (!table) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	data->vdd_table = table;
+
+	val = prop->value;
+	for (i = 0; i < data->num_vdd_table; i++, table++) {
+		u32 efuse_offset;
+		u32 tmp;
+
+		table->reference_uv = be32_to_cpup(val++);
+		efuse_offset = be32_to_cpup(val++);
+
+		tmp = readl(base + efuse_offset);
+		tmp &= of_data->efuse_voltage_mask;
+		tmp >>= __ffs(of_data->efuse_voltage_mask);
+
+		table->optimized_uv = of_data->efuse_voltage_uv ? tmp :
+					tmp * 1000;
+
+		dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d vset=%d\n",
+			i, efuse_offset, table->reference_uv,
+			table->optimized_uv);
+
+		/*
+		 * Some older samples might not have optimized efuse
+		 * Use reference voltage for those - just add debug message
+		 * for them.
+		 */
+		if (!table->optimized_uv) {
+			dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d:vset0\n",
+				i, efuse_offset, table->reference_uv);
+			table->optimized_uv = table->reference_uv;
+		}
+	}
+out:
+	iounmap(base);
+out_map:
+	return ret;
+}
+
+/**
+ * _free_optimized_voltages() - free resources for optvoltages
+ * @dev:	device for which we need to free info
+ * @data:	data specific to the device
+ */
+static void _free_optimized_voltages(struct device *dev,
+				     struct ti_opp_supply_data *data)
+{
+	kfree(data->vdd_table);
+	data->vdd_table = NULL;
+	data->num_vdd_table = 0;
+}
+
+/**
+ * _get_optimal_vdd_voltage() - Finds optimal voltage for the supply
+ * @dev:	device for which we need to find info
+ * @data:	data specific to the device
+ * @reference_uv:	reference voltage (OPP voltage) for which we need value
+ *
+ * Return: if a match is found, return optimized voltage, else return
+ * reference_uv, also return reference_uv if no optimization is needed.
+ */
+static int _get_optimal_vdd_voltage(struct device *dev,
+				    struct ti_opp_supply_data *data,
+				    int reference_uv)
+{
+	int i;
+	struct ti_opp_supply_optimum_voltage_table *table;
+
+	if (!data->num_vdd_table)
+		return reference_uv;
+
+	table = data->vdd_table;
+	if (!table)
+		return -EINVAL;
+
+	/* Find a exact match - this list is usually very small */
+	for (i = 0; i < data->num_vdd_table; i++, table++)
+		if (table->reference_uv == reference_uv)
+			return table->optimized_uv;
+
+	/* IF things are screwed up, we'd make a mess on console.. ratelimit */
+	dev_err_ratelimited(dev, "%s: Failed optimized voltage match for %d\n",
+			    __func__, reference_uv);
+	return reference_uv;
+}
+
+static int _opp_set_voltage(struct device *dev,
+			    struct dev_pm_opp_supply *supply,
+			    int new_target_uv, struct regulator *reg,
+			    char *reg_name)
+{
+	int ret;
+	unsigned long vdd_uv, uv_max;
+
+	if (new_target_uv)
+		vdd_uv = new_target_uv;
+	else
+		vdd_uv = supply->u_volt;
+
+	/*
+	 * If we do have an absolute max voltage specified, then we should
+	 * use that voltage instead to allow for cases where the voltage rails
+	 * are ganged (example if we set the max for an opp as 1.12v, and
+	 * the absolute max is 1.5v, for another rail to get 1.25v, it cannot
+	 * be achieved if the regulator is constrainted to max of 1.12v, even
+	 * if it can function at 1.25v
+	 */
+	if (opp_data.vdd_absolute_max_voltage_uv)
+		uv_max = opp_data.vdd_absolute_max_voltage_uv;
+	else
+		uv_max = supply->u_volt_max;
+
+	if (vdd_uv > uv_max ||
+	    vdd_uv < supply->u_volt_min ||
+	    supply->u_volt_min > uv_max) {
+		dev_warn(dev,
+			 "Invalid range voltages [Min:%lu target:%lu Max:%lu]\n",
+			 supply->u_volt_min, vdd_uv, uv_max);
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "%s scaling to %luuV[min %luuV max %luuV]\n", reg_name,
+		vdd_uv, supply->u_volt_min,
+		uv_max);
+
+	ret = regulator_set_voltage_triplet(reg,
+					    supply->u_volt_min,
+					    vdd_uv,
+					    uv_max);
+	if (ret) {
+		dev_err(dev, "%s failed for %luuV[min %luuV max %luuV]\n",
+			reg_name, vdd_uv, supply->u_volt_min,
+			uv_max);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_opp_supply_set_opp() - do the opp supply transition
+ * @data:	information on regulators and new and old opps provided by
+ *		opp core to use in transition
+ *
+ * Return: If successful, 0, else appropriate error value.
+ */
+int ti_opp_supply_set_opp(struct dev_pm_set_opp_data *data)
+{
+	struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0];
+	struct dev_pm_opp_supply *old_supply_vbb = &data->old_opp.supplies[1];
+	struct dev_pm_opp_supply *new_supply_vdd = &data->new_opp.supplies[0];
+	struct dev_pm_opp_supply *new_supply_vbb = &data->new_opp.supplies[1];
+	struct device *dev = data->dev;
+	unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate;
+	struct clk *clk = data->clk;
+	struct regulator *vdd_reg = data->regulators[0];
+	struct regulator *vbb_reg = data->regulators[1];
+	int vdd_uv;
+	int ret;
+
+	vdd_uv = _get_optimal_vdd_voltage(dev, &opp_data,
+					  new_supply_vbb->u_volt);
+
+	/* Scaling up? Scale voltage before frequency */
+	if (freq > old_freq) {
+		ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg,
+				       "vdd");
+		if (ret)
+			goto restore_voltage;
+
+		ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb");
+		if (ret)
+			goto restore_voltage;
+	}
+
+	/* Change frequency */
+	dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n",
+		__func__, old_freq, freq);
+
+	ret = clk_set_rate(clk, freq);
+	if (ret) {
+		dev_err(dev, "%s: failed to set clock rate: %d\n", __func__,
+			ret);
+		goto restore_voltage;
+	}
+
+	/* Scaling down? Scale voltage after frequency */
+	if (freq < old_freq) {
+		ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb");
+		if (ret)
+			goto restore_freq;
+
+		ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg,
+				       "vdd");
+		if (ret)
+			goto restore_freq;
+	}
+
+	return 0;
+
+restore_freq:
+	ret = clk_set_rate(clk, old_freq);
+	if (ret)
+		dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
+			__func__, old_freq);
+restore_voltage:
+	/* This shouldn't harm even if the voltages weren't updated earlier */
+	if (old_supply_vdd->u_volt) {
+		ret = _opp_set_voltage(dev, old_supply_vbb, 0, vbb_reg, "vbb");
+		if (ret)
+			return ret;
+
+		ret = _opp_set_voltage(dev, old_supply_vdd, 0, vdd_reg,
+				       "vdd");
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static const struct ti_opp_supply_of_data omap_generic_of_data = {
+};
+
+static const struct ti_opp_supply_of_data omap_omap5_of_data = {
+	.flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE,
+	.efuse_voltage_mask = 0xFFF,
+	.efuse_voltage_uv = false,
+};
+
+static const struct ti_opp_supply_of_data omap_omap5core_of_data = {
+	.flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE | OPPDM_HAS_NO_ABB,
+	.efuse_voltage_mask = 0xFFF,
+	.efuse_voltage_uv = false,
+};
+
+static const struct of_device_id ti_opp_supply_of_match[] = {
+	{.compatible = "ti,omap-opp-supply", .data = &omap_generic_of_data},
+	{.compatible = "ti,omap5-opp-supply", .data = &omap_omap5_of_data},
+	{.compatible = "ti,omap5-core-opp-supply",
+	 .data = &omap_omap5core_of_data},
+	{},
+};
+MODULE_DEVICE_TABLE(of, ti_opp_supply_of_match);
+
+static int ti_opp_supply_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device *cpu_dev = get_cpu_device(0);
+	const struct of_device_id *match;
+	const struct ti_opp_supply_of_data *of_data;
+	int ret = 0;
+
+	match = of_match_device(ti_opp_supply_of_match, dev);
+	if (!match) {
+		/* We do not expect this to happen */
+		dev_err(dev, "%s: Unable to match device\n", __func__);
+		return -ENODEV;
+	}
+	if (!match->data) {
+		/* Again, unlikely.. but mistakes do happen */
+		dev_err(dev, "%s: Bad data in match\n", __func__);
+		return -EINVAL;
+	}
+	of_data = match->data;
+
+	dev_set_drvdata(dev, (void *)of_data);
+
+	/* If we need optimized voltage */
+	if (of_data->flags & OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE) {
+		ret = _store_optimized_voltages(dev, &opp_data);
+		if (ret)
+			return ret;
+	}
+
+	ret = PTR_ERR_OR_ZERO(dev_pm_opp_register_set_opp_helper(cpu_dev,
+								 ti_opp_supply_set_opp));
+	if (ret)
+		_free_optimized_voltages(dev, &opp_data);
+
+	return ret;
+}
+
+static struct platform_driver ti_opp_supply_driver = {
+	.probe = ti_opp_supply_probe,
+	.driver = {
+		   .name = "ti_opp_supply",
+		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(ti_opp_supply_of_match),
+		   },
+};
+module_platform_driver(ti_opp_supply_driver);
+
+MODULE_DESCRIPTION("Texas Instruments OMAP OPP Supply driver");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
-- 
2.15.1

^ permalink raw reply related

* [PATCH] Staging: vc04_services: fix brace coding style issues in vchiq_shim.c
From: Tomas Marek @ 2017-12-13 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

This patch fix brace on next line coding style errors reported by
checkpatch.

Signed-off-by: Tomas Marek <marek_tomas@centrum.cz>
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
index d465e1c..29984f9 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
@@ -800,8 +800,7 @@ int32_t vchi_get_peer_version(const VCHI_SERVICE_HANDLE_T handle, short *peer_ve
 	int32_t ret = -1;
 	struct shim_service *service = (struct shim_service *)handle;
 
-	if (service)
-	{
+	if (service) {
 		VCHIQ_STATUS_T status;
 
 		status = vchiq_get_peer_version(service->handle, peer_version);
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 1/2] acpi, spcr: Make SPCR avialable to other architectures
From: Timur Tabi @ 2017-12-13 21:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171213124533.GA32362@red-moon>

On 12/13/2017 06:45 AM, Lorenzo Pieralisi wrote:
>> +/*
>> + * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
>> + * occasionally getting stuck as 1. To avoid the potential for a hang, check
>> + * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
>> + * implementations, so only do so if an affected platform is detected in
>> + * acpi_parse_spcr().
>> + */
>> +bool qdf2400_e44_present;
>> +EXPORT_SYMBOL(qdf2400_e44_present);
> 
> My eyes, this is horrible but it is not introduced by this patch. It
> would have been much better if:
> 
> drivers/tty/serial/amba-pl011.c
> 
> parsed the SPCR table (again) to detect it instead of relying on this
> horrible exported flag.

I didn't want to put any ACPI code in amba-pl011.c, so putting it in 
spcr.c made the most sense.  I agree the global variable is ugly.  If 
you have a better idea, I'm all ears.

If it's any consolation, this erratum affects only 1.x silicon, which is 
technically pre-production (although a lot of people have them).  This 
work-around will eventually be reverted.

>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index 46505396869e..9ae98eeada76 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -79,7 +79,12 @@ config ACPI_DEBUGGER_USER
>>   endif
>>   
>>   config ACPI_SPCR_TABLE
>> -	bool
>> +	bool "ACPI Serial Port Console Redirection Support"
>> +	default y if ARM64
> 
> You need to remove the selection in arch/arm64 then. Also, moving away
> from a non-visible config may have consequences on ARM64, Graeme and
> Mark are more familiar with the SPCR dependencies so please chime in.

I did raise this as a concern in the previous version of the patch.  I 
also think it should not be a selectable option.

Keeping the "select" does force SPCR to be enabled on ARM64 ACPI 
platforms, but if it's an option for x86, it should be an option for ARM.

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH] ARM: dts: am43xx: Fix inverted DS0_PULL_UP_DOWN_EN macro
From: Dave Gerlach @ 2017-12-13 21:24 UTC (permalink / raw)
  To: linux-arm-kernel

Due to a mistake in documentation the DS0_PULL_UP_DOWN_EN macro was
mistakenly defined as an active high bit, however setting the bit
actually disables the internal pull resistor on the pin, so correct this
macro and introduce a new DS0_PULL_UP_DOWN_DIS macro with the proper bit
value set now that the documentation has been updated.

Change based on AM437x Techninal Reference Manual SPRUHL7G Revised June
2017 Section 7.2.1.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 include/dt-bindings/pinctrl/am43xx.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/dt-bindings/pinctrl/am43xx.h b/include/dt-bindings/pinctrl/am43xx.h
index a69e310789c5..6ce4a32f77d4 100644
--- a/include/dt-bindings/pinctrl/am43xx.h
+++ b/include/dt-bindings/pinctrl/am43xx.h
@@ -25,7 +25,8 @@
 #define DS0_FORCE_OFF_MODE	(1 << 24)
 #define DS0_INPUT		(1 << 25)
 #define DS0_FORCE_OUT_HIGH	(1 << 26)
-#define DS0_PULL_UP_DOWN_EN	(1 << 27)
+#define DS0_PULL_UP_DOWN_EN	(0 << 27)
+#define DS0_PULL_UP_DOWN_DIS	(1 << 27)
 #define DS0_PULL_UP_SEL		(1 << 28)
 #define WAKEUP_ENABLE		(1 << 29)
 
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2] arm64: cpu_errata: Add Kryo to Falkor 1003 errata
From: Stephen Boyd @ 2017-12-13 21:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171212181156.GA25244@arm.com>

On 12/12, Will Deacon wrote:
> Hi Stephen,
> 
> On Wed, Nov 29, 2017 at 03:03:53PM -0800, Stephen Boyd wrote:
> > The Kryo CPUs are also affected by the Falkor 1003 errata, so
> > we need to do the same workaround on Kryo CPUs. The MIDR is
> > slightly more complicated here, where the PART number is not
> > always the same when looking at all the bits from 15 to 4. Drop
> > the lower 8 bits and just look at the top 4 to see if it's '2'
> > and then consider those as Kryo CPUs. This covers all the
> > combinations without having to list them all out.
> > 
> > Introduce a new hardware cap bit for the combination of hardware
> > PAN support and this errata so that we can disable support for
> > software PAN at runtime if this errata is present and the CPU
> > doesn't support HW PAN. This happens on some Kryo CPUs where the
> > HW PAN feature isn't supported but we can't prevent software PAN
> > from being selected in the configuration. Previously, Falkor CPUs
> > were all known to have HW PAN support, so we didn't need to worry
> > about this case.
> > 
> > Fixes: 38fd94b0275c ("arm64: Work around Falkor erratum 1003")
> > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > ---
> 
> Can you respin this on top of for-next/core please? The PAN bits should
> be much simpler with the KPTI code.
> 

No problem. I'll send it out in a couple hours.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH] kbuild: fix dependency of dtbs targets
From: Rob Herring @ 2017-12-13 21:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK7LNASCQqaBvERg6NXPym62Dyza00TuZVOWtj0YqLDKPT2D5g@mail.gmail.com>

On Wed, Oct 25, 2017 at 12:40 AM, Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
> Hi.
>
>
> 2017-10-10 0:05 GMT+09:00 Russell King - ARM Linux <linux@armlinux.org.uk>:
>> On Wed, Oct 04, 2017 at 01:27:20PM +0900, Masahiro Yamada wrote:
>>> The target "dtbs" should depend on "scripts" because it needs to
>>> build dtc.  The "prepare" target is unneeded here.
>>
>> Looks fine for ARM, as the only thing the dtbs should depend on is
>> the kernel configuration (to decide which to build) and DT tooling.
>>
>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>>
>> --
>
>
> I found a potential issue on this
> because the default DTB install path depends on $(KERNELRELEASE).
>
>
> In top-level Makefile:
> export INSTALL_DTBS_PATH ?= $(INSTALL_PATH)/dtbs/$(KERNELRELEASE)
>
>
> The include/config/kernel.release is created by "prepare3" target.
>
> If the dependency on "parepare" is removed,
> it is possible to run "make dtbs" and "make dtbs_install"
> without creating include/config/kernel.release.
>
> So, the $(KERNELRELEASE) could be empty when installing DTB.
>
>
> Maybe, drop this patch, or reduce the dependency to "parepare3"?

I was doing some work to get dtb builds to work without depending on
$arch cross compiler and this patch fixes some of the issues. The
dtbs_install target has the prepare dependency, so that should be
sufficient and your patch should be fine. BTW, Based on prior
discussion on "ARM: kbuild: Fix forced rebuild after 'make dtbs'"
thread, prepare should not be needed just for $(KERNELRELEASE).

Rob

^ permalink raw reply

* [PATCH v3] arm64: cpu_errata: Add Kryo to Falkor 1003 errata
From: Stephen Boyd @ 2017-12-13 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

The Kryo CPUs are also affected by the Falkor 1003 errata, so
we need to do the same workaround on Kryo CPUs. The MIDR is
slightly more complicated here, where the PART number is not
always the same when looking at all the bits from 15 to 4. Drop
the lower 8 bits and just look at the top 4 to see if it's '2'
and then consider those as Kryo CPUs. This covers all the
combinations without having to list them all out.

Fixes: 38fd94b0275c ("arm64: Work around Falkor erratum 1003")
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---

Changes from v2:
 * Dropped the new cap bit, rebased onto for-next/core in arm64 tree

 Documentation/arm64/silicon-errata.txt |  2 +-
 arch/arm64/include/asm/cputype.h       |  2 ++
 arch/arm64/kernel/cpu_errata.c         | 21 +++++++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 304bf22bb83c..b9d93e981a05 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -72,6 +72,6 @@ stable kernels.
 | Hisilicon      | Hip0{6,7}       | #161010701      | N/A                         |
 | Hisilicon      | Hip07           | #161600802      | HISILICON_ERRATUM_161600802 |
 |                |                 |                 |                             |
-| Qualcomm Tech. | Falkor v1       | E1003           | QCOM_FALKOR_ERRATUM_1003    |
+| Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
 | Qualcomm Tech. | Falkor v1       | E1009           | QCOM_FALKOR_ERRATUM_1009    |
 | Qualcomm Tech. | QDF2400 ITS     | E0065           | QCOM_QDF2400_ERRATUM_0065   |
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 235e77d98261..b5afa6668646 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -91,6 +91,7 @@
 #define BRCM_CPU_PART_VULCAN		0x516
 
 #define QCOM_CPU_PART_FALKOR_V1		0x800
+#define QCOM_CPU_PART_KRYO		0x200
 
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
@@ -99,6 +100,7 @@
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
 #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
 #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1)
+#define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 0e27f86ee709..e4c78630a730 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -30,6 +30,20 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
 				       entry->midr_range_max);
 }
 
+static bool __maybe_unused
+is_kryo_midr(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	u32 model;
+
+	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+
+	model = read_cpuid_id();
+	model &= MIDR_IMPLEMENTOR_MASK | (0xf00 << MIDR_PARTNUM_SHIFT) |
+		 MIDR_ARCHITECTURE_MASK;
+
+	return model == entry->midr_model;
+}
+
 static bool
 has_mismatched_cache_line_size(const struct arm64_cpu_capabilities *entry,
 				int scope)
@@ -169,6 +183,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 			   MIDR_CPU_VAR_REV(0, 0),
 			   MIDR_CPU_VAR_REV(0, 0)),
 	},
+	{
+		.desc = "Qualcomm Technologies Kryo erratum 1003",
+		.capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003,
+		.def_scope = SCOPE_LOCAL_CPU,
+		.midr_model = MIDR_QCOM_KRYO,
+		.matches = is_kryo_midr,
+	},
 #endif
 #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
 	{
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related


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