* [PATCH 7/7] ARM: dts: sun7i: Add dts file for the A20-linova1-7 HMI
From: Sergey Suloev @ 2018-05-04 21:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <afc78821-2d08-3f4f-d008-5b2d216e96c0@micronovasrl.com>
Hi, Giulio,
On 05/05/2018 12:52 AM, Giulio Benetti wrote:
> Hi Maxime!
>
> Il 04/05/2018 10:06, Maxime Ripard ha scritto:
>> Hi,
>>
>> On Wed, May 02, 2018 at 06:41:34PM +0200, Giulio Benetti wrote:
>>>>> You don't have to handcode the fragments anymore with the new syntax,
>>>>> and U-Boot makes it really trivial to use if you use the FIT image
>>>>> format to have multiple overlays bundled in the same image. You can
>>>>> choose to apply them dynamically, for example based on an EEPROM or
>>>>> some other metric to see which combination you have.
>>>>
>>>> Ah, this is interesting. I'm going to experiment with that.
>>>>
>>>
>>> I'm struggling against this, I don't really know how to proceed,
>>> except keeping monolithic dts files including other dtsi files.
>>>
>>> About dt-overlays I've tried to look around lot of time,
>>> but the only thing I've found is this:
>>> https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/tree/arch/arm/boot/dts?h=topic/renesas-overlays
>>>
>>>
>>> where they use .dtso tagging them as "/plugin/;"
>>> and compile all .dtso found in dts folder.
>>> Then they obtain .dtbo files that should be the dt-overlays we have
>>> spoken
>>> about right?
>>
>> Yes. You don't have to do that though, you can just rely on dtc to
>> compile them, outside of the linux build system.
>>
>>> What I can't understand is if there's a real standard at this time to
>>> follow, because on renesas-driver they use their way to handle all
>>> .dtso
>>> files, but on mainline there seems to be nothing about that.
>>
>> I'm not sure what you mean here. It's just fragments of device tree,
>> that have to be compiled using dtc, that's it. You can use the Linux
>> build system infrastructure to do that, or you can build your own
>> simpler one. That's really up to you. See for example
>> https://github.com/NextThingCo/CHIP-dt-overlays/blob/master/Makefile
>>
>> (even though the overlays themselves use the legacy syntax and
>> shouldn't really be used an examples)
>
> Everything works now!
> Thank you very much!
> I've setted up a Repo on Github to give an example on how make it work
> with no pain:
> https://github.com/micronovasrl/linova-dtoverlays
>
> At the moment it's a mess all around, but it's working and give an
> idea on how to make it work. Though I'm going to clean it up well as a
> base for linova dtoverlays.
>
> Ah, btw, can you confirm me that base dts file must be compiled
> outside kernel with:
> dtc -@ ....
> Otherwise as in-tree dts with make dtbs "-@" argument is not passed.
> Right?
>
> Thank you a lot for your help and time again!
>
> Best regards!
>
I'd highly recommend you to look at Armbian overlay support: it is easy
and elegant.
https://github.com/armbian/build/blob/master/patch/kernel/sunxi-next/add-overlay-compilation-support.patch
https://github.com/armbian/build/blob/master/patch/kernel/sunxi-next/add-sunxi-overlays.patch
Sergey
^ permalink raw reply
* [PATCH 7/7] ARM: dts: sun7i: Add dts file for the A20-linova1-7 HMI
From: Giulio Benetti @ 2018-05-04 21:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504080652.dniwaqqhbeuknp7y@flea>
Hi Maxime!
Il 04/05/2018 10:06, Maxime Ripard ha scritto:
> Hi,
>
> On Wed, May 02, 2018 at 06:41:34PM +0200, Giulio Benetti wrote:
>>>> You don't have to handcode the fragments anymore with the new syntax,
>>>> and U-Boot makes it really trivial to use if you use the FIT image
>>>> format to have multiple overlays bundled in the same image. You can
>>>> choose to apply them dynamically, for example based on an EEPROM or
>>>> some other metric to see which combination you have.
>>>
>>> Ah, this is interesting. I'm going to experiment with that.
>>>
>>
>> I'm struggling against this, I don't really know how to proceed,
>> except keeping monolithic dts files including other dtsi files.
>>
>> About dt-overlays I've tried to look around lot of time,
>> but the only thing I've found is this:
>> https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/tree/arch/arm/boot/dts?h=topic/renesas-overlays
>>
>> where they use .dtso tagging them as "/plugin/;"
>> and compile all .dtso found in dts folder.
>> Then they obtain .dtbo files that should be the dt-overlays we have spoken
>> about right?
>
> Yes. You don't have to do that though, you can just rely on dtc to
> compile them, outside of the linux build system.
>
>> What I can't understand is if there's a real standard at this time to
>> follow, because on renesas-driver they use their way to handle all .dtso
>> files, but on mainline there seems to be nothing about that.
>
> I'm not sure what you mean here. It's just fragments of device tree,
> that have to be compiled using dtc, that's it. You can use the Linux
> build system infrastructure to do that, or you can build your own
> simpler one. That's really up to you. See for example
> https://github.com/NextThingCo/CHIP-dt-overlays/blob/master/Makefile
>
> (even though the overlays themselves use the legacy syntax and
> shouldn't really be used an examples)
Everything works now!
Thank you very much!
I've setted up a Repo on Github to give an example on how make it work
with no pain:
https://github.com/micronovasrl/linova-dtoverlays
At the moment it's a mess all around, but it's working and give an idea
on how to make it work. Though I'm going to clean it up well as a base
for linova dtoverlays.
Ah, btw, can you confirm me that base dts file must be compiled outside
kernel with:
dtc -@ ....
Otherwise as in-tree dts with make dtbs "-@" argument is not passed.
Right?
Thank you a lot for your help and time again!
Best regards!
--
Giulio Benetti
CTO
MICRONOVA SRL
Sede: Via A. Niedda 3 - 35010 Vigonza (PD)
Tel. 049/8931563 - Fax 049/8931346
Cod.Fiscale - P.IVA 02663420285
Capitale Sociale ? 26.000 i.v.
Iscritta al Reg. Imprese di Padova N. 02663420285
Numero R.E.A. 258642
^ permalink raw reply
* Motorola Droid 4 progress, power consumption
From: Pavel Machek @ 2018-05-04 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504203819.GF98604@atomide.com>
Hi!
> > But I guess I can sample charge_counter every minute or so and get
> > what I need?
>
> Not sure what the max time range is for the PMIC, but yeah I'd
> assume once a minute is duoable. Maybe compare it to the chart
> you already have?
Yes, I can try some more graph painting.
OTOH... battery life is "good enough" and I can already tell when the
battery is full :-). So this part is not critical.
> > I agree this should not be done in kernel as it requires persistent
> > storage.
> >
> > Battery is not user-replacable (and this will recalibrate itself on
> > charge/discharge cycle) so.. I don't think keying is strictly
> > neccessary for D4.
>
> Yeah right, that can be added later on if needed if you just
> plan accordingly. It's replaceable with a T5 after you peel off the
> sticker from the corners :)
Aha, I wanted to ask what kind of phone T5 is, and T5 is probably torx
5 screwdriver, right? Well, I don't have second battery, so these
experiments will have to wait.
Best regards,
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/43e08e08/attachment.sig>
^ permalink raw reply
* [PATCH v6 3/6] kernel/reboot.c: export pm_power_off_prepare
From: Andrew Morton @ 2018-05-04 20:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504185052.bjhfkvpgrblc7tfc@pengutronix.de>
On Fri, 4 May 2018 20:50:52 +0200 Oleksij Rempel <o.rempel@pengutronix.de> wrote:
> Hallo Andrew,
> I need your ACK or NACK for this patch.
>
> This function is used to configure external PMIC to interpret
> signal which will be triggered by pm_power_off as power off.
> Since same signal can be used for stand by, I linked PMIC configuration
> with pm_power_off_prepare to avoid possible conflicts.
>
> ...
>
> > --- a/kernel/reboot.c
> > +++ b/kernel/reboot.c
> > @@ -49,6 +49,7 @@ int reboot_force;
> > */
> >
> > void (*pm_power_off_prepare)(void);
> > +EXPORT_SYMBOL(pm_power_off_prepare);
> >
OK by me, but it's more of a Rafael thing.
^ permalink raw reply
* Motorola Droid 4 progress, power consumption
From: Tony Lindgren @ 2018-05-04 20:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504202044.GC22519@amd>
* Pavel Machek <pavel@ucw.cz> [180504 20:22]:
> Hi!
>
> > > user at devuan:/sys/class/power_supply/battery$ date; cat current_now
> > > current_avg
> > > Thu May 3 09:33:07 CEST 2018
> > > -56000
> > > -72308
> > > user at devuan:/sys/class/power_supply/battery$ date; cat current_now
> > > current_avg
> > > Thu May 3 09:33:08 CEST 2018
> > > -37000
> > > -211362
> >
> > I recall it just being calculated based on the time between
> > the reads. Hard to say what it does, -ENODOCS.. Maybe the mc13783
> > PMIC docs have something similar.
>
> Hmm. current_avg is world readable; if it does changes to the
> hardware, that's somehow bad.
No it just calls cpcap_battery_cc_get_avg_current() that calculates
the average from last time it got sampled based on number of samples
collected between the two reads. Seems to match what I see on my
power supply here.
> But I guess I can sample charge_counter every minute or so and get
> what I need?
Not sure what the max time range is for the PMIC, but yeah I'd
assume once a minute is duoable. Maybe compare it to the chart
you already have?
> > > > Hmm oh and the POWER_SUPPLY_CHARGE_COUNTER value should be monitored
> > > > by your libbattery and it's low value and high value should be saved
> > > > to a file. Low should be saved when we get the battery low interrupt
> > > > and battery state changes to POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL.
> > > > High value should be saved on POWER_SUPPLY_CAPACITY_LEVEL_FULL.
> > > >
> > > > Then when you know the high value and low value, you can calculate
> > > > the remaining capacity based on the current value and
> > > > POWER_SUPPLY_POWER_AVG.
> > >
> > > I'll look into that... but probably will do experiments with python,
> > > first.
> >
> > Sure. The reason why I think we should not do it in the kernel in
> > addition to the earlier reasoning is that we don't have a place
> > to store the min and max values across reboot. I think there's
> > some flash on the battery over 1w bus, but it probably just
> > contains battery serial number or something and is not intended
> > for writing much to it. I guess the min and max values should be
> > really keyd based on this battery id in case the battery gets
> > changed.
>
> I agree this should not be done in kernel as it requires persistent
> storage.
>
> Battery is not user-replacable (and this will recalibrate itself on
> charge/discharge cycle) so.. I don't think keying is strictly
> neccessary for D4.
Yeah right, that can be added later on if needed if you just
plan accordingly. It's replaceable with a T5 after you peel off the
sticker from the corners :)
Regards,
Tony
^ permalink raw reply
* [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
From: Rob Herring @ 2018-05-04 20:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <26de0a75-e4e1-7c43-e31d-599d3c7de0ff@st.com>
On Thu, May 3, 2018 at 4:55 AM, Ludovic BARRE <ludovic.barre@st.com> wrote:
>
>
> On 05/02/2018 07:45 PM, Rob Herring wrote:
>>
>> On Wed, May 2, 2018 at 11:03 AM, Ludovic BARRE <ludovic.barre@st.com>
>> wrote:
>>>
>>> Hi Rob
>>>
>>>
>>>
>>> On 05/01/2018 04:56 PM, Rob Herring wrote:
>>>>
>>>>
>>>> On Thu, Apr 26, 2018 at 06:18:30PM +0200, Ludovic Barre wrote:
>>>>>
>>>>>
>>>>> From: Ludovic Barre <ludovic.barre@st.com>
>>>>>
>>>>> Exti controller has been differently integrated on stm32mp1 SoC.
>>>>> A parent irq has only one external interrupt. A hierachy domain could
>>>>> be used. Handlers are call by parent, each parent interrupt could be
>>>>> masked and unmasked according to the needs.
>>>>>
>>>>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>>>>> ---
>>>>> .../interrupt-controller/st,stm32-exti.txt | 3 +
>>>>> drivers/irqchip/irq-stm32-exti.c | 322
>>>>> +++++++++++++++++++++
>>>>> 2 files changed, 325 insertions(+)
>>>>>
>>>>> diff --git
>>>>>
>>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>>
>>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>> index edf03f0..136bd61 100644
>>>>> ---
>>>>>
>>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>> +++
>>>>>
>>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>> @@ -5,11 +5,14 @@ Required properties:
>>>>> - compatible: Should be:
>>>>> "st,stm32-exti"
>>>>> "st,stm32h7-exti"
>>>>> + "st,stm32mp1-exti"
>>>>> - reg: Specifies base physical address and size of the registers
>>>>> - interrupt-controller: Indentifies the node as an interrupt
>>>>> controller
>>>>> - #interrupt-cells: Specifies the number of cells to encode an
>>>>> interrupt
>>>>> specifier, shall be 2
>>>>> - interrupts: interrupts references to primary interrupt controller
>>>>> + (only needed for exti controller with multiple exti under
>>>>> + same parent interrupt: st,stm32-exti and st,stm32h7-exti")
>>>>> Example:
>>>>> diff --git a/drivers/irqchip/irq-stm32-exti.c
>>>>> b/drivers/irqchip/irq-stm32-exti.c
>>>>> index b38c655..ebf7146 100644
>>>>> --- a/drivers/irqchip/irq-stm32-exti.c
>>>>> +++ b/drivers/irqchip/irq-stm32-exti.c
>>>>
>>>>
>>>>
>>>> [...]
>>>>
>>>>> +static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
>>>>> + { .exti = 1, .irq_parent = 7 },
>>>>> + { .exti = 2, .irq_parent = 8 },
>>>>> + { .exti = 3, .irq_parent = 9 },
>>>>> + { .exti = 4, .irq_parent = 10 },
>>>>> + { .exti = 5, .irq_parent = 23 },
>>>>> + { .exti = 6, .irq_parent = 64 },
>>>>> + { .exti = 7, .irq_parent = 65 },
>>>>> + { .exti = 8, .irq_parent = 66 },
>>>>> + { .exti = 9, .irq_parent = 67 },
>>>>> + { .exti = 10, .irq_parent = 40 },
>>>>> + { .exti = 11, .irq_parent = 42 },
>>>>> + { .exti = 12, .irq_parent = 76 },
>>>>> + { .exti = 13, .irq_parent = 77 },
>>>>> + { .exti = 14, .irq_parent = 121 },
>>>>> + { .exti = 15, .irq_parent = 127 },
>>>>> + { .exti = 16, .irq_parent = 1 },
>>>>> + { .exti = 65, .irq_parent = 144 },
>>>>> + { .exti = 68, .irq_parent = 143 },
>>>>> + { .exti = 73, .irq_parent = 129 },
>>>>> +};
>>>>
>>>>
>>>>
>>>> You can use an interrupt-map property rather than put this into the
>>>> driver.
>>>
>>>
>>>
>>> interrupt-map seemed interesting and promising like used in pci host.
>>> At first sight this property can't be used into node with
>>> "interrupt-controller" property (see in drivers/of/irq.c function:
>>> of_irq_parse_raw) because "of_irq_parse_raw" checks if node got
>>> it first, and after lookup the interrupt-map.
>>>
>>> Rob, Thomas, Jason, Marc what do you prefers or the right ways...?
>>
>>
>> I believe the correct thing to do is simply drop "interrupt-controller".
>
Actually, that's not right.
> if I drop "interrupt-controller" of my node, my driver will not be
> initialized by "of_irq_init"
> (start_kernel->init_IRQ->irqchip_init->of_irq_init).
> Probably, we could replace "IRQCHIP_DECLARE" by a
> "module_platform_driver" or "postcore_initcall" but I'm not a big fan of
> this solution. what do you think ?
You'd have to parse 'interrupt-map' yourself to extract the data for
this to work because interrupt-map currently only works when the
translation is transparent (i.e. doesn't need s/w handling). So I
guess leave this in the driver. Sorry for the noise.
Rob
^ permalink raw reply
* [PATCH v2] tty/serial: atmel: use port->name as name in request_irq()
From: Rob Herring @ 2018-05-04 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d62a945c-f81e-d7e5-8431-a7948a0b833c@sorico.fr>
On Fri, May 4, 2018 at 5:28 AM, Richard Genoud <richard.genoud@gmail.com> wrote:
> On 04/05/2018 10:14, Sebastian Andrzej Siewior wrote:
>> I was puzzled while looking at /proc/interrupts and random things showed
>> up between reboots. This occurred more often but I realised it later. The
>> "correct" output should be:
>> |38: 11861 atmel-aic5 2 Level ttyS0
>>
>> but I saw sometimes
>> |38: 6426 atmel-aic5 2 Level tty1
>>
>> and accounted it wrongly as correct. This is use after free and the
>> former example randomly got the "old" pointer which pointed to the same
>> content. With SLAB_FREELIST_RANDOM and HARDENED I even got
>> |38: 7067 atmel-aic5 2 Level E=Started User Manager for UID 0
>>
>> or other nonsense.
>> As it turns out the tty, pointer that is accessed in atmel_startup(), is
>> freed() before atmel_shutdown(). It seems to happen quite often that the
>> tty for ttyS0 is allocated and freed while ->shutdown is not invoked. I
>> don't do anything special - just a systemd boot :)
>>
>> Use port->name as the IRQ name for request_irq(). This exists as long as
>> the driver is loaded so no use-after-free here.
>> For backports before v4.12 I suggest to use `"atmel_serial"' instead
>> `port->name' (that member was introduced in f7048b15900f ("tty: serial_core:
>> Add name field to uart_port struct").
>>
>> Cc: stable at vger.kernel.org
> I think it's safer to use:
> Cc: stable at vger.kernel.org # 4.14
> Because the stable team may miss your comment, and even if they don't, I
> think it's not their role to adapt the patch to 4.9.x (and test it !)
> IMHO, the best way is to add # 4.14 and when it's applied on 4.14.x,
> send a tested backport for 4.9.x
>
> Besides that, you can add my:
> Acked-by: Richard Genoud <richard.genoud@gmail.com>
>
> Rob, do you agree with this fix ?
Yes, one less dependency on tty struct in serial drivers is a good
thing. However, I find port->name to be a somewhat pointless addition.
Most platform drivers (which most serial drivers are) use the device
name for registering their IRQ. And now serial drivers may not even
have a tty with serdev. Using the device name would also solve your
backporting issue. But either way:
Acked-by: Rob Herring <robh@kernel.org>
Rob
^ permalink raw reply
* Motorola Droid 4 progress, power consumption
From: Pavel Machek @ 2018-05-04 20:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503142240.GQ98604@atomide.com>
Hi!
> > user at devuan:/sys/class/power_supply/battery$ date; cat current_now
> > current_avg
> > Thu May 3 09:33:07 CEST 2018
> > -56000
> > -72308
> > user at devuan:/sys/class/power_supply/battery$ date; cat current_now
> > current_avg
> > Thu May 3 09:33:08 CEST 2018
> > -37000
> > -211362
>
> I recall it just being calculated based on the time between
> the reads. Hard to say what it does, -ENODOCS.. Maybe the mc13783
> PMIC docs have something similar.
Hmm. current_avg is world readable; if it does changes to the
hardware, that's somehow bad.
But I guess I can sample charge_counter every minute or so and get
what I need?
> > > Hmm oh and the POWER_SUPPLY_CHARGE_COUNTER value should be monitored
> > > by your libbattery and it's low value and high value should be saved
> > > to a file. Low should be saved when we get the battery low interrupt
> > > and battery state changes to POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL.
> > > High value should be saved on POWER_SUPPLY_CAPACITY_LEVEL_FULL.
> > >
> > > Then when you know the high value and low value, you can calculate
> > > the remaining capacity based on the current value and
> > > POWER_SUPPLY_POWER_AVG.
> >
> > I'll look into that... but probably will do experiments with python,
> > first.
>
> Sure. The reason why I think we should not do it in the kernel in
> addition to the earlier reasoning is that we don't have a place
> to store the min and max values across reboot. I think there's
> some flash on the battery over 1w bus, but it probably just
> contains battery serial number or something and is not intended
> for writing much to it. I guess the min and max values should be
> really keyd based on this battery id in case the battery gets
> changed.
I agree this should not be done in kernel as it requires persistent
storage.
Battery is not user-replacable (and this will recalibrate itself on
charge/discharge cycle) so.. I don't think keying is strictly
neccessary for D4.
Best regards,
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/1468df3d/attachment.sig>
^ permalink raw reply
* No subject
From: Bjorn Helgaas @ 2018-05-04 20:06 UTC (permalink / raw)
To: linux-arm-kernel
Bcc:
Subject: Re: [PATCH] PCI: Check whether bridges allow access to extended
config space
Reply-To:
In-Reply-To: <5AEC8002.5000309@kontron.com>
[+cc Fred, Sinan]
On Fri, May 04, 2018 at 03:45:07PM +0000, Gilles Buloz wrote:
> Le 04/05/2018 00:31, Bjorn Helgaas a ?crit :
> > [+cc LKML]
> >
> > On Thu, May 03, 2018 at 12:40:27PM +0000, Gilles Buloz wrote:
> >> Subject: [PATCH] For exception at PCI probe due to bridge reporting UR
> >>
> >> Even if a device supports extended config access, no such access must be
> >> done to this device If there's a bridge not supporting that in the path
> >> to this device. Doing such access with UR reporting enabled on the root
> >> bridge leads to an exception.
> >>
> >> This is the case on a LS1043A CPU (NXP QorIQ Layerscape) platform with
> >> the following bus topology :
> >> LS1043 PCIe root
> >> -> PEX8112 PCIe-to-PCI bridge (not supporting ext cfg on PCI side)
> >> -> PMC slot connector (for legacy PMC modules)
> >> With a PMC module topology as follows :
> >> PMC connector
> >> -> PCI-to-PCIe bridge
> >> -> PCIe switch (4 ports)
> >> -> 4 PCIe devices (one on each port)
> >> In this case all devices behind the PEX8112 are supporting extended config
> >> access but this is prohibited by the PEX8112. Without this patch, an
> >> exception (synchronous abort) occurs in pci_cfg_space_size_ext().
> >>
> >> This patch checks the parent bridge of each allocated child bus to know if
> >> extended config access is supported on the child bus, and sets a flag in
> >> child->bus_flags if not supported. This flag is inherited by all children
> >> buses of this child bus and then is checked to avoid this unsupported
> >> accesses to every device on these buses.
> > Hi Gilles,
> >
> > Thanks for the patch! I reworked it a little bit to simplify the code
> > in pci_alloc_child_bus(). Can you test it and make sure I didn't
> > break anything?
> >
> Hi Bjorn,
>
> Your rework works as expected. Tested on LS1043A platform with kernel 4.17-rc1, and with some backport on kernel 4.1.35
>
> Suggestion : maybe change the pci_info() string to have :
> pci_bus 0000:xx: extended config space not accessible
> instead of
> pci_bus 0000:xx: extended config space not accessible on secondary bus
> as xx is already the number of the secondary bus
Oops, when I wrote that I was thinking it would be printed for the
bridge device (not the bus). I changed it as you suggest.
Interesting, I didn't think about the fact that pci_info() would work
on a struct pci_bus * as well as on a struct pci_dev *, since it's a
macro and they both have a "dev" member.
> Info : with kernel 4.17-rc1, it turns out I need pcie_aspm=off to
> have the PMC devices behind the PCI-to-PCIe bridge of the PMC safely
> detected/configured. But this is not caused by the patch.
> Without pcie_aspm=off I saw this at one boot :
> "pci 0000:02:0e.0: ASPM: Could not configure common clock" for this bridge, but devices
> correctly detected/configured
> but at most boots I get :
> no ASPM message but "pci 0000:04:02.0: bridge configuration invalid ([bus ff-ff]), reconfiguring "
> instead, and some devices are missing. Also lspci show "rev ff" for some devices.
> I don't see this problem on 4.1.35 with the same backported patch.
This is interesting, especially since you have this unusual topology
of a path to the device that is PCIe, then conventional PCI, then PCIe
again. We *should* be able to use ASPM on the PCIe links, but it's
definitely not a well-tested scenario.
Can you tell if something is actually broken? Sinan's recent change,
04875177dbe0 ("PCI/ASPM: Don't warn if already in common clock mode"),
which appeared in v4.17-rc1, turns off the message in some cases.
The "bridge configuration invalid" message just means the firmware
didn't configure the bridge. We *should* still set it up correctly,
but please report a bug if we don't.
lspci showing "ff" for some devices might be a symptom of the devices
being powered off. In that case config reads normally return ~0 data
(though on your platform maybe it would cause exceptions). I've seen
this in other situations and wondered if it would be worth adding a
hint to lspci so it could say "device may be powered off".
Anyway, if you are seeing something broken (more than just the
messages), please start a new thread about each one. If you do, could
you please:
- open a report at https://bugzilla.kernel.org/, in the Drivers/PCI
component (open a separate bug for each issue you see)
- use kernel version 4.17-rc1 and mark it as a regression if
appropriate
- attach (don't paste inline) the complete dmesg log and "lspci -vv"
output (as root) to the bug
- post a note to linux-pci at vger.kernel.org, cc Fred, Sinan, and me,
and include the link to the bugzilla
Bjorn
^ permalink raw reply
* [PATCH 04/15] media: pxa_camera: remove the dmaengine compat need
From: Mauro Carvalho Chehab @ 2018-05-04 19:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <89f3e97c-08a4-33b6-8fd3-0c1b4dea2065@xs4all.nl>
Em Sun, 22 Apr 2018 13:06:12 +0200
Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> On 04/02/2018 04:26 PM, Robert Jarzmik wrote:
> > From: Robert Jarzmik <robert.jarzmik@renault.com>
> >
> > As the pxa architecture switched towards the dmaengine slave map, the
> > old compatibility mechanism to acquire the dma requestor line number and
> > priority are not needed anymore.
> >
> > This patch simplifies the dma resource acquisition, using the more
> > generic function dma_request_slave_channel().
> >
> > Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>
> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
I'm assuming that you'll be applying it together with other PXA patches.
So:
Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Regards,
Mauro
>
> Regards,
>
> Hans
>
> > ---
> > drivers/media/platform/pxa_camera.c | 22 +++-------------------
> > 1 file changed, 3 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
> > index c71a00736541..4c82d1880753 100644
> > --- a/drivers/media/platform/pxa_camera.c
> > +++ b/drivers/media/platform/pxa_camera.c
> > @@ -2357,8 +2357,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
> > .src_maxburst = 8,
> > .direction = DMA_DEV_TO_MEM,
> > };
> > - dma_cap_mask_t mask;
> > - struct pxad_param params;
> > char clk_name[V4L2_CLK_NAME_SIZE];
> > int irq;
> > int err = 0, i;
> > @@ -2432,34 +2430,20 @@ static int pxa_camera_probe(struct platform_device *pdev)
> > pcdev->base = base;
> >
> > /* request dma */
> > - dma_cap_zero(mask);
> > - dma_cap_set(DMA_SLAVE, mask);
> > - dma_cap_set(DMA_PRIVATE, mask);
> > -
> > - params.prio = 0;
> > - params.drcmr = 68;
> > - pcdev->dma_chans[0] =
> > - dma_request_slave_channel_compat(mask, pxad_filter_fn,
> > - ¶ms, &pdev->dev, "CI_Y");
> > + pcdev->dma_chans[0] = dma_request_slave_channel(&pdev->dev, "CI_Y");
> > if (!pcdev->dma_chans[0]) {
> > dev_err(&pdev->dev, "Can't request DMA for Y\n");
> > return -ENODEV;
> > }
> >
> > - params.drcmr = 69;
> > - pcdev->dma_chans[1] =
> > - dma_request_slave_channel_compat(mask, pxad_filter_fn,
> > - ¶ms, &pdev->dev, "CI_U");
> > + pcdev->dma_chans[1] = dma_request_slave_channel(&pdev->dev, "CI_U");
> > if (!pcdev->dma_chans[1]) {
> > dev_err(&pdev->dev, "Can't request DMA for Y\n");
> > err = -ENODEV;
> > goto exit_free_dma_y;
> > }
> >
> > - params.drcmr = 70;
> > - pcdev->dma_chans[2] =
> > - dma_request_slave_channel_compat(mask, pxad_filter_fn,
> > - ¶ms, &pdev->dev, "CI_V");
> > + pcdev->dma_chans[2] = dma_request_slave_channel(&pdev->dev, "CI_V");
> > if (!pcdev->dma_chans[2]) {
> > dev_err(&pdev->dev, "Can't request DMA for V\n");
> > err = -ENODEV;
> >
>
Thanks,
Mauro
^ permalink raw reply
* [PATCH v5 12/14] cpufreq: Add Kryo CPU scaling driver
From: ilialin at codeaurora.org @ 2018-05-04 19:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504065709.62kacfext6bbprlo@vireshk-i7>
> -----Original Message-----
> From: Viresh Kumar <viresh.kumar@linaro.org>
> Sent: Friday, May 4, 2018 09:57
> To: ilialin at codeaurora.org
> Cc: mturquette at baylibre.com; sboyd at kernel.org; robh at kernel.org;
> mark.rutland at arm.com; rjw at rjwysocki.net; lgirdwood at gmail.com;
> broonie at kernel.org; andy.gross at linaro.org; david.brown at linaro.org;
> catalin.marinas at arm.com; will.deacon at arm.com; linux-clk at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> pm at vger.kernel.org; linux-arm-msm at vger.kernel.org; linux-
> soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> rnayak at codeaurora.org; amit.kucheria at linaro.org;
> nicolas.dechesne at linaro.org; celster at codeaurora.org;
> tfinkel at codeaurora.org
> Subject: Re: [PATCH v5 12/14] cpufreq: Add Kryo CPU scaling driver
>
> On 04-05-18, 09:44, ilialin at codeaurora.org wrote:
> >
> >
> > > -----Original Message-----
> > > From: Viresh Kumar <viresh.kumar@linaro.org>
> > > Sent: Friday, May 4, 2018 09:08
> > > To: Ilia Lin <ilialin@codeaurora.org>
> > > Cc: mturquette at baylibre.com; sboyd at kernel.org; robh at kernel.org;
> > > mark.rutland at arm.com; rjw at rjwysocki.net; lgirdwood at gmail.com;
> > > broonie at kernel.org; andy.gross at linaro.org; david.brown at linaro.org;
> > > catalin.marinas at arm.com; will.deacon at arm.com;
> > > linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
> > > linux-kernel at vger.kernel.org; linux- pm at vger.kernel.org;
> > > linux-arm-msm at vger.kernel.org; linux- soc at vger.kernel.org;
> > > linux-arm-kernel at lists.infradead.org;
> > > rnayak at codeaurora.org; amit.kucheria at linaro.org;
> > > nicolas.dechesne at linaro.org; celster at codeaurora.org;
> > > tfinkel at codeaurora.org
> > > Subject: Re: [PATCH v5 12/14] cpufreq: Add Kryo CPU scaling driver
> > >
> > > On 03-05-18, 14:52, Ilia Lin wrote:
> > > > In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO
> > > > processors, the CPU ferequencies subset and voltage value of each
> > > > OPP varies based on the silicon variant in use. Qualcomm Process
> > > > Voltage Scaling Tables defines the voltage and frequency value
> > > > based on the msm-id in SMEM and speedbin blown in the efuse
> combination.
> > > > The qcom-cpufreq-kryo driver reads the msm-id and efuse value from
> > > > the SoC to provide the OPP framework with required information.
> > > > This is used to determine the voltage and frequency value for each
> > > > OPP of
> > > > operating-points-v2 table when it is parsed by the OPP framework.
> > > >
> > > > Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
> > > > ---
> > > > drivers/cpufreq/Kconfig.arm | 11 +++
> > > > drivers/cpufreq/Makefile | 1 +
> > > > drivers/cpufreq/cpufreq-dt-platdev.c | 3 +
> > > > drivers/cpufreq/qcom-cpufreq-kryo.c | 153
> > > > +++++++++++++++++++++++++++++++++++
> > > > 4 files changed, 168 insertions(+) create mode 100644
> > > > drivers/cpufreq/qcom-cpufreq-kryo.c
> > > >
> > > > diff --git a/drivers/cpufreq/Kconfig.arm
> > > > b/drivers/cpufreq/Kconfig.arm index de55c7d..f9da18c 100644
> > > > --- a/drivers/cpufreq/Kconfig.arm
> > > > +++ b/drivers/cpufreq/Kconfig.arm
> > > > @@ -124,6 +124,17 @@ config ARM_OMAP2PLUS_CPUFREQ
> > > > depends on ARCH_OMAP2PLUS
> > > > default ARCH_OMAP2PLUS
> > > >
> > > > +config ARM_QCOM_CPUFREQ_KRYO
> > > > + tristate "Qualcomm Technologies, Inc. Kryo based CPUFreq"
> > >
> > > I don't see any reply to Sricharan's query on this being tristate.
> >
> > Why shouldn't we leave possibility to compile the cpufreq-dt built-in,
> > and the qcom-cpufreq-kryo module?
>
> I was not saying this is incorrect, all I am saying is that you never
replied to a
> comment from one of the reviewers.
>
> And I don't see a reason why this should be a tristate really.
> cpufreq-dt is already capable of being a module, all your driver does is
that it
> creates the cpufreq-dt platform device after setting the OPP hw
properties..
>
> Over that, have you ever tried inserting, then removing and inserting the
> driver module again? I feel it will fail.
>
> The reason is that you never provided an exit routine which can get rid of
the
> platform device created in the first place.
Convinced. I'll change it to bool.
>
> > > > + depends on QCOM_QFPROM
> > > > + depends on QCOM_SMEM
> > > > + select PM_OPP
> > > > + help
> > > > + This adds the CPUFreq driver for
> > > > + Qualcomm Technologies, Inc. Kryo SoC based boards.
> > > > +
> > > > + If in doubt, say N.
> > > > +
> > > > config ARM_S3C_CPUFREQ
> > > > bool
> > > > help
> > > > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> > > > index 8d24ade..fb4a2ec 100644
> > > > --- a/drivers/cpufreq/Makefile
> > > > +++ b/drivers/cpufreq/Makefile
> > > > @@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_MVEBU_V7) +=
> > > mvebu-cpufreq.o
> > > > obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
> > > > obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
> > > > obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
> > > > +obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO) += qcom-cpufreq-
> > > kryo.o
> > > > obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
> > > > obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
> > > > obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
> > > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c
> > > > b/drivers/cpufreq/cpufreq-dt-platdev.c
> > > > index 3b585e4..77d6ab8 100644
> > > > --- a/drivers/cpufreq/cpufreq-dt-platdev.c
> > > > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
> > > > @@ -118,6 +118,9 @@
> > > >
> > > > { .compatible = "nvidia,tegra124", },
> > > >
> > > > + { .compatible = "qcom,apq8096", },
> > > > + { .compatible = "qcom,msm8996", },
> > > > +
> > > > { .compatible = "st,stih407", },
> > > > { .compatible = "st,stih410", },
> > > >
> > > > diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c
> > > > b/drivers/cpufreq/qcom-cpufreq-kryo.c
> > > > new file mode 100644
> > > > index 0000000..32371cc
> > > > --- /dev/null
> > > > +++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
> > > > @@ -0,0 +1,153 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
> > >
> > > Incorrect multi line comment.
> >
> > This was done as per Bjorn's instruction.
>
> You haven't followed him correctly.
>
> What he asked for is:
>
> // SPDX...
> /*
> * XXXX
> */
>
> What you have done is:
>
> // SPDX...
> /* XXXX
> */
OK. Got you. Will fix.
>
> --
> viresh
^ permalink raw reply
* [PATCH v9 12/12] ARM: shmobile: Convert file to use cntvoff
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
Now that a common function is available for CNTVOFF's
initialization, let's convert shmobile-apmu code to use
this function.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm/mach-shmobile/common.h | 1 -
arch/arm/mach-shmobile/headsmp-apmu.S | 22 +---------------------
arch/arm/mach-shmobile/setup-rcar-gen2.c | 3 ++-
3 files changed, 3 insertions(+), 23 deletions(-)
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index 43c1ac696274..2109f123bdfb 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -2,7 +2,6 @@
#ifndef __ARCH_MACH_COMMON_H
#define __ARCH_MACH_COMMON_H
-extern void shmobile_init_cntvoff(void);
extern void shmobile_init_delay(void);
extern void shmobile_boot_vector(void);
extern unsigned long shmobile_boot_fn;
diff --git a/arch/arm/mach-shmobile/headsmp-apmu.S b/arch/arm/mach-shmobile/headsmp-apmu.S
index 5672b5849401..d49ab194766a 100644
--- a/arch/arm/mach-shmobile/headsmp-apmu.S
+++ b/arch/arm/mach-shmobile/headsmp-apmu.S
@@ -11,29 +11,9 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
-ENTRY(shmobile_init_cntvoff)
- /*
- * CNTVOFF has to be initialized either from non-secure Hypervisor
- * mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled
- * then it should be handled by the secure code
- */
- cps #MON_MODE
- mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */
- orr r0, r1, #1
- mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */
- instr_sync
- mov r0, #0
- mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */
- instr_sync
- mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */
- instr_sync
- cps #SVC_MODE
- ret lr
-ENDPROC(shmobile_init_cntvoff)
-
#ifdef CONFIG_SMP
ENTRY(shmobile_boot_apmu)
- bl shmobile_init_cntvoff
+ bl secure_cntvoff_init
b secondary_startup
ENDPROC(shmobile_boot_apmu)
#endif
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index 5561dbed7a33..4a881026d740 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -26,6 +26,7 @@
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
+#include <asm/secure_cntvoff.h>
#include "common.h"
#include "rcar-gen2.h"
@@ -70,7 +71,7 @@ void __init rcar_gen2_timer_init(void)
void __iomem *base;
u32 freq;
- shmobile_init_cntvoff();
+ secure_cntvoff_init();
if (of_machine_is_compatible("renesas,r8a7745") ||
of_machine_is_compatible("renesas,r8a7792") ||
--
2.11.0
^ permalink raw reply related
* [PATCH v9 11/12] ARM: dts: sun8i: Add enable-method for SMP support for the A83T SoC
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
Add the use of enable-method property for SMP support which allows
to handle the SMP support for this specific SoC.
This commit adds enable-method properties to all CPU nodes.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
---
arch/arm/boot/dts/sun8i-a83t.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 0669b8dc499d..2be23d600957 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -67,6 +67,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
cci-control-port = <&cci_control0>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <0>;
};
@@ -75,6 +76,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
cci-control-port = <&cci_control0>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <1>;
};
@@ -83,6 +85,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
cci-control-port = <&cci_control0>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <2>;
};
@@ -91,6 +94,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
cci-control-port = <&cci_control0>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <3>;
};
@@ -101,6 +105,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
cci-control-port = <&cci_control1>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <0x100>;
};
@@ -109,6 +114,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
cci-control-port = <&cci_control1>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <0x101>;
};
@@ -117,6 +123,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
cci-control-port = <&cci_control1>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <0x102>;
};
@@ -125,6 +132,7 @@
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
cci-control-port = <&cci_control1>;
+ enable-method = "allwinner,sun8i-a83t-smp";
reg = <0x103>;
};
};
--
2.11.0
^ permalink raw reply related
* [PATCH v9 10/12] ARM: sun8i: smp: Add support for A83T
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
Add the support for A83T.
A83T SoC has an additional register than A80 to handle CPU configurations:
R_CPUS_CFG. Information about the register comes from Allwinner's BSP
driver.
An important difference is the Power Off Gating register for clusters
which is BIT(4) in case of SUN9I-A80 and BIT(0) in case of SUN8I-A83T.
There is also a bit swap between sun8i-a83t and sun9i-a80 that must be
handled.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
arch/arm/mach-sunxi/Kconfig | 2 +-
arch/arm/mach-sunxi/mc_smp.c | 151 ++++++++++++++++++++++++++++++++++++++-----
2 files changed, 137 insertions(+), 16 deletions(-)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index ce53ceaf4cc5..d9c8ecf88ec6 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -51,7 +51,7 @@ config MACH_SUN9I
config ARCH_SUNXI_MC_SMP
bool
depends on SMP
- default MACH_SUN9I
+ default MACH_SUN9I || MACH_SUN8I
select ARM_CCI400_PORT_CTRL
select ARM_CPU_SUSPEND
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
index fc10e3a3268f..b4037b603897 100644
--- a/arch/arm/mach-sunxi/mc_smp.c
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -55,22 +55,31 @@
#define CPUCFG_CX_RST_CTRL_L2_RST BIT(8)
#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
#define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n)
+#define CPUCFG_CX_RST_CTRL_CORE_RST_ALL (0xf << 0)
#define PRCM_CPU_PO_RST_CTRL(c) (0x4 + 0x4 * (c))
#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
#define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf
#define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c))
+/* The power off register for clusters are different from a80 and a83t */
+#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I BIT(0)
#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I BIT(4)
#define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n)
#define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu))
#define PRCM_CPU_SOFT_ENTRY_REG 0x164
+/* R_CPUCFG registers, specific to sun8i-a83t */
+#define R_CPUCFG_CLUSTER_PO_RST_CTRL(c) (0x30 + (c) * 0x4)
+#define R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(n) BIT(n)
+#define R_CPUCFG_CPU_SOFT_ENTRY_REG 0x01a4
+
#define CPU0_SUPPORT_HOTPLUG_MAGIC0 0xFA50392F
#define CPU0_SUPPORT_HOTPLUG_MAGIC1 0x790DCA3A
static void __iomem *cpucfg_base;
static void __iomem *prcm_base;
static void __iomem *sram_b_smp_base;
+static void __iomem *r_cpucfg_base;
extern void sunxi_mc_smp_secondary_startup(void);
extern void sunxi_mc_smp_resume(void);
@@ -161,6 +170,16 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster)
reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu);
writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+ if (is_a83t) {
+ /* assert cpu power-on reset */
+ reg = readl(r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ reg &= ~(R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu));
+ writel(reg, r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* Cortex-A7: hold L1 reset disable signal low */
if (!sunxi_core_is_cortex_a15(cpu, cluster)) {
reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
@@ -184,17 +203,38 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster)
/* open power switch */
sunxi_cpu_power_switch_set(cpu, cluster, true);
+ /* Handle A83T bit swap */
+ if (is_a83t) {
+ if (cpu == 0)
+ cpu = 4;
+ }
+
/* clear processor power gate */
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu);
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
+ /* Handle A83T bit swap */
+ if (is_a83t) {
+ if (cpu == 4)
+ cpu = 0;
+ }
+
/* de-assert processor power-on reset */
reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu);
writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+ if (is_a83t) {
+ reg = readl(r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ reg |= R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu);
+ writel(reg, r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* de-assert all processor resets */
reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu);
@@ -216,6 +256,14 @@ static int sunxi_cluster_powerup(unsigned int cluster)
if (cluster >= SUNXI_NR_CLUSTERS)
return -EINVAL;
+ /* For A83T, assert cluster cores resets */
+ if (is_a83t) {
+ reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+ reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; /* Core Reset */
+ writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* assert ACINACTM */
reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
reg |= CPUCFG_CX_CTRL_REG1_ACINACTM;
@@ -226,6 +274,16 @@ static int sunxi_cluster_powerup(unsigned int cluster)
reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL;
writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+ /* assert cluster cores resets */
+ if (is_a83t) {
+ reg = readl(r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL;
+ writel(reg, r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* assert cluster resets */
reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST;
@@ -256,7 +314,10 @@ static int sunxi_cluster_powerup(unsigned int cluster)
/* clear cluster power gate */
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
- reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
+ if (is_a83t)
+ reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I;
+ else
+ reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
@@ -453,7 +514,10 @@ static int sunxi_cluster_powerdown(unsigned int cluster)
/* gate cluster power */
pr_debug("%s: gate cluster power\n", __func__);
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
- reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
+ if (is_a83t)
+ reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I;
+ else
+ reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
@@ -535,8 +599,12 @@ static int sunxi_mc_smp_cpu_kill(unsigned int l_cpu)
return !ret;
}
-static bool sunxi_mc_smp_cpu_can_disable(unsigned int __unused)
+static bool sunxi_mc_smp_cpu_can_disable(unsigned int cpu)
{
+ /* CPU0 hotplug not handled for sun8i-a83t */
+ if (is_a83t)
+ if (cpu == 0)
+ return false;
return true;
}
#endif
@@ -619,6 +687,7 @@ struct sunxi_mc_smp_nodes {
struct device_node *prcm_node;
struct device_node *cpucfg_node;
struct device_node *sram_node;
+ struct device_node *r_cpucfg_node;
};
/* This structure holds SoC-specific bits tied to an enable-method string. */
@@ -633,6 +702,7 @@ static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes)
of_node_put(nodes->prcm_node);
of_node_put(nodes->cpucfg_node);
of_node_put(nodes->sram_node);
+ of_node_put(nodes->r_cpucfg_node);
memset(nodes, 0, sizeof(*nodes));
}
@@ -662,11 +732,42 @@ static int __init sun9i_a80_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes)
return 0;
}
+static int __init sun8i_a83t_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes)
+{
+ nodes->prcm_node = of_find_compatible_node(NULL, NULL,
+ "allwinner,sun8i-a83t-r-ccu");
+ if (!nodes->prcm_node) {
+ pr_err("%s: PRCM not available\n", __func__);
+ return -ENODEV;
+ }
+
+ nodes->cpucfg_node = of_find_compatible_node(NULL, NULL,
+ "allwinner,sun8i-a83t-cpucfg");
+ if (!nodes->cpucfg_node) {
+ pr_err("%s: CPUCFG not available\n", __func__);
+ return -ENODEV;
+ }
+
+ nodes->r_cpucfg_node = of_find_compatible_node(NULL, NULL,
+ "allwinner,sun8i-a83t-r-cpucfg");
+ if (!nodes->r_cpucfg_node) {
+ pr_err("%s: RCPUCFG not available\n", __func__);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static const struct sunxi_mc_smp_data sunxi_mc_smp_data[] __initconst = {
{
.enable_method = "allwinner,sun9i-a80-smp",
.get_smp_nodes = sun9i_a80_get_smp_nodes,
},
+ {
+ .enable_method = "allwinner,sun8i-a83t-smp",
+ .get_smp_nodes = sun8i_a83t_get_smp_nodes,
+ .is_a83t = true,
+ },
};
static int __init sunxi_mc_smp_init(void)
@@ -674,6 +775,7 @@ static int __init sunxi_mc_smp_init(void)
struct sunxi_mc_smp_nodes nodes = { 0 };
struct device_node *node;
struct resource res;
+ void __iomem *addr;
int i, ret;
/*
@@ -738,12 +840,23 @@ static int __init sunxi_mc_smp_init(void)
goto err_unmap_prcm;
}
- sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0,
- "sunxi-mc-smp");
- if (IS_ERR(sram_b_smp_base)) {
- ret = PTR_ERR(sram_b_smp_base);
- pr_err("%s: failed to map secure SRAM\n", __func__);
- goto err_unmap_release_cpucfg;
+ if (is_a83t) {
+ r_cpucfg_base = of_io_request_and_map(nodes.r_cpucfg_node,
+ 0, "sunxi-mc-smp");
+ if (IS_ERR(r_cpucfg_base)) {
+ ret = PTR_ERR(r_cpucfg_base);
+ pr_err("%s: failed to map R-CPUCFG registers\n",
+ __func__);
+ goto err_unmap_release_cpucfg;
+ }
+ } else {
+ sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0,
+ "sunxi-mc-smp");
+ if (IS_ERR(sram_b_smp_base)) {
+ ret = PTR_ERR(sram_b_smp_base);
+ pr_err("%s: failed to map secure SRAM\n", __func__);
+ goto err_unmap_release_cpucfg;
+ }
}
/* Configure CCI-400 for boot cluster */
@@ -751,15 +864,18 @@ static int __init sunxi_mc_smp_init(void)
if (ret) {
pr_err("%s: failed to configure boot cluster: %d\n",
__func__, ret);
- goto err_unmap_release_secure_sram;
+ goto err_unmap_release_sram_rcpucfg;
}
/* We don't need the device nodes anymore */
sunxi_mc_smp_put_nodes(&nodes);
/* Set the hardware entry point address */
- writel(__pa_symbol(sunxi_mc_smp_secondary_startup),
- prcm_base + PRCM_CPU_SOFT_ENTRY_REG);
+ if (is_a83t)
+ addr = r_cpucfg_base + R_CPUCFG_CPU_SOFT_ENTRY_REG;
+ else
+ addr = prcm_base + PRCM_CPU_SOFT_ENTRY_REG;
+ writel(__pa_symbol(sunxi_mc_smp_secondary_startup), addr);
/* Actually enable multi cluster SMP */
smp_set_ops(&sunxi_mc_smp_smp_ops);
@@ -768,9 +884,14 @@ static int __init sunxi_mc_smp_init(void)
return 0;
-err_unmap_release_secure_sram:
- iounmap(sram_b_smp_base);
- of_address_to_resource(nodes.sram_node, 0, &res);
+err_unmap_release_sram_rcpucfg:
+ if (is_a83t) {
+ iounmap(r_cpucfg_base);
+ of_address_to_resource(nodes.r_cpucfg_node, 0, &res);
+ } else {
+ iounmap(sram_b_smp_base);
+ of_address_to_resource(nodes.sram_node, 0, &res);
+ }
release_mem_region(res.start, resource_size(&res));
err_unmap_release_cpucfg:
iounmap(cpucfg_base);
--
2.11.0
^ permalink raw reply related
* [PATCH v9 09/12] ARM: sun9i: smp: Add is_a83t field
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
To prepare the support of sun8i-a83t, add a field in the smp_data
structure to know if we are on sun9i-a80 or sun8i-a83t.
Add also a global variable to retrieve which architecture we are
having.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
arch/arm/mach-sunxi/mc_smp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
index 03f021d0c73e..fc10e3a3268f 100644
--- a/arch/arm/mach-sunxi/mc_smp.c
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -74,6 +74,7 @@ static void __iomem *sram_b_smp_base;
extern void sunxi_mc_smp_secondary_startup(void);
extern void sunxi_mc_smp_resume(void);
+static bool is_a83t;
static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster)
{
@@ -624,6 +625,7 @@ struct sunxi_mc_smp_nodes {
struct sunxi_mc_smp_data {
const char *enable_method;
int (*get_smp_nodes)(struct sunxi_mc_smp_nodes *nodes);
+ bool is_a83t;
};
static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes)
@@ -697,6 +699,8 @@ static int __init sunxi_mc_smp_init(void)
break;
}
+ is_a83t = sunxi_mc_smp_data[i].is_a83t;
+
of_node_put(node);
if (ret)
return -ENODEV;
--
2.11.0
^ permalink raw reply related
* [PATCH v9 08/12] ARM: sun9i: smp: Rename clusters's power-off
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
To prepare the support for sun8i-a83t, rename the macro that handles
the power-off of clusters because it is different from sun9i-a80 to
sun8i-a83t.
The power off register for clusters are different from a80 and a83t.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
arch/arm/mach-sunxi/mc_smp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
index 727968d6a3e5..03f021d0c73e 100644
--- a/arch/arm/mach-sunxi/mc_smp.c
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -60,7 +60,7 @@
#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
#define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf
#define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c))
-#define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4)
+#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I BIT(4)
#define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n)
#define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu))
#define PRCM_CPU_SOFT_ENTRY_REG 0x164
@@ -255,7 +255,7 @@ static int sunxi_cluster_powerup(unsigned int cluster)
/* clear cluster power gate */
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
- reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER;
+ reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
@@ -452,7 +452,7 @@ static int sunxi_cluster_powerdown(unsigned int cluster)
/* gate cluster power */
pr_debug("%s: gate cluster power\n", __func__);
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
- reg |= PRCM_PWROFF_GATING_REG_CLUSTER;
+ reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
--
2.11.0
^ permalink raw reply related
* [PATCH v9 07/12] ARM: sunxi: Add initialization of CNTVOFF
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
Add the initialization of CNTVOFF for sun8i-a83t.
For boot CPU, create a new machine that handles this
function's call in an "init_early" callback. We need to initialize
CNTVOFF before the arch timer's initialization otherwise, it will
not be taken into account and fails to boot correctly.
Because of that, this function can't be called in SMP's early_initcall
function which is called after timer's init.
For secondary CPUs, add this function into secondary_startup
assembly entry.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
arch/arm/mach-sunxi/headsmp.S | 1 +
arch/arm/mach-sunxi/sunxi.c | 20 +++++++++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-sunxi/headsmp.S b/arch/arm/mach-sunxi/headsmp.S
index 37dc772701f3..32d76be98541 100644
--- a/arch/arm/mach-sunxi/headsmp.S
+++ b/arch/arm/mach-sunxi/headsmp.S
@@ -71,6 +71,7 @@ ENDPROC(sunxi_mc_smp_cluster_cache_enable)
ENTRY(sunxi_mc_smp_secondary_startup)
bl sunxi_mc_smp_cluster_cache_enable
+ bl secure_cntvoff_init
b secondary_startup
ENDPROC(sunxi_mc_smp_secondary_startup)
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 5e9602ce1573..752e0748b0c8 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
+#include <asm/secure_cntvoff.h>
static const char * const sunxi_board_dt_compat[] = {
"allwinner,sun4i-a10",
@@ -62,7 +63,6 @@ MACHINE_END
static const char * const sun8i_board_dt_compat[] = {
"allwinner,sun8i-a23",
"allwinner,sun8i-a33",
- "allwinner,sun8i-a83t",
"allwinner,sun8i-h2-plus",
"allwinner,sun8i-h3",
"allwinner,sun8i-r40",
@@ -75,6 +75,24 @@ DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i Family")
.dt_compat = sun8i_board_dt_compat,
MACHINE_END
+void __init sun8i_a83t_cntvoff_init(void)
+{
+#ifdef CONFIG_SMP
+ secure_cntvoff_init();
+#endif
+}
+
+static const char * const sun8i_a83t_cntvoff_board_dt_compat[] = {
+ "allwinner,sun8i-a83t",
+ NULL,
+};
+
+DT_MACHINE_START(SUN8I_A83T_CNTVOFF_DT, "Allwinner sun8i-a83t board")
+ .init_early = sun8i_a83t_cntvoff_init,
+ .init_time = sun6i_timer_init,
+ .dt_compat = sun8i_a83t_cntvoff_board_dt_compat,
+MACHINE_END
+
static const char * const sun9i_board_dt_compat[] = {
"allwinner,sun9i-a80",
NULL,
--
2.11.0
^ permalink raw reply related
* [PATCH v9 06/12] ARM: smp: Add initialization of CNTVOFF
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
The CNTVOFF register from arch timer is uninitialized.
It should be done by the bootloader but it is currently not the case,
even for boot CPU because this SoC is booting in secure mode.
It leads to an random offset value meaning that each CPU will have a
different time, which isn't working very well.
Add assembly code used for boot CPU and secondary CPU cores to make
sure that the CNTVOFF register is initialized. Because this code can
be used by different platforms, add this assembly file in ARM's common
folder.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
arch/arm/common/Makefile | 1 +
arch/arm/common/secure_cntvoff.S | 31 +++++++++++++++++++++++++++++++
arch/arm/include/asm/secure_cntvoff.h | 8 ++++++++
3 files changed, 40 insertions(+)
create mode 100644 arch/arm/common/secure_cntvoff.S
create mode 100644 arch/arm/include/asm/secure_cntvoff.h
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 70b4a14ed993..1e9f7af8f70f 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
+obj-$(CONFIG_SMP) += secure_cntvoff.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
CFLAGS_REMOVE_mcpm_entry.o = -pg
diff --git a/arch/arm/common/secure_cntvoff.S b/arch/arm/common/secure_cntvoff.S
new file mode 100644
index 000000000000..68a4a8344319
--- /dev/null
+++ b/arch/arm/common/secure_cntvoff.S
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ *
+ * Initialization of CNTVOFF register from secure mode
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ENTRY(secure_cntvoff_init)
+ .arch armv7-a
+ /*
+ * CNTVOFF has to be initialized either from non-secure Hypervisor
+ * mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled
+ * then it should be handled by the secure code
+ */
+ cps #MON_MODE
+ mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */
+ orr r0, r1, #1
+ mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */
+ isb
+ mov r0, #0
+ mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */
+ isb
+ mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */
+ isb
+ cps #SVC_MODE
+ ret lr
+ENDPROC(secure_cntvoff_init)
diff --git a/arch/arm/include/asm/secure_cntvoff.h b/arch/arm/include/asm/secure_cntvoff.h
new file mode 100644
index 000000000000..1f93aee1f630
--- /dev/null
+++ b/arch/arm/include/asm/secure_cntvoff.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASMARM_ARCH_CNTVOFF_H
+#define __ASMARM_ARCH_CNTVOFF_H
+
+extern void secure_cntvoff_init(void);
+
+#endif
--
2.11.0
^ permalink raw reply related
* [PATCH v9 05/12] ARM: dts: sun8i: a83t: Add CCI-400 node
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
Add CCI-400 node and control-port on CPUs needed by SMP bringup.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
arch/arm/boot/dts/sun8i-a83t.dtsi | 41 +++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 53ace066b7dc..0669b8dc499d 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -66,6 +66,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
+ cci-control-port = <&cci_control0>;
reg = <0>;
};
@@ -73,6 +74,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
+ cci-control-port = <&cci_control0>;
reg = <1>;
};
@@ -80,6 +82,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
+ cci-control-port = <&cci_control0>;
reg = <2>;
};
@@ -87,6 +90,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
+ cci-control-port = <&cci_control0>;
reg = <3>;
};
@@ -96,6 +100,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
+ cci-control-port = <&cci_control1>;
reg = <0x100>;
};
@@ -103,6 +108,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
+ cci-control-port = <&cci_control1>;
reg = <0x101>;
};
@@ -110,6 +116,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
+ cci-control-port = <&cci_control1>;
reg = <0x102>;
};
@@ -117,6 +124,7 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
operating-points-v2 = <&cpu1_opp_table>;
+ cci-control-port = <&cci_control1>;
reg = <0x103>;
};
};
@@ -354,6 +362,39 @@
reg = <0x01700000 0x400>;
};
+ cci at 1790000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x01790000 0x10000>;
+ ranges = <0x0 0x01790000 0x10000>;
+
+ cci_control0: slave-if at 4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+
+ cci_control1: slave-if at 5000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x5000 0x1000>;
+ };
+
+ pmu at 9000 {
+ compatible = "arm,cci-400-pmu,r1";
+ reg = <0x9000 0x5000>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
syscon: syscon at 1c00000 {
compatible = "allwinner,sun8i-a83t-system-controller",
"syscon";
--
2.11.0
^ permalink raw reply related
* [PATCH v9 04/12] ARM: dts: sun8i: Add R_CPUCFG device node for the A83T dtsi
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
The R_CPUCFG is a collection of registers needed for SMP bringup
on clusters and cluster's reset.
For the moment, documentation about this register is found in
Allwinner's code only.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
arch/arm/boot/dts/sun8i-a83t.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index a50ccb475de8..53ace066b7dc 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -938,6 +938,11 @@
#reset-cells = <1>;
};
+ r_cpucfg at 1f01c00 {
+ compatible = "allwinner,sun8i-a83t-r-cpucfg";
+ reg = <0x1f01c00 0x400>;
+ };
+
r_pio: pinctrl at 1f02c00 {
compatible = "allwinner,sun8i-a83t-r-pinctrl";
reg = <0x01f02c00 0x400>;
--
2.11.0
^ permalink raw reply related
* [PATCH v9 03/12] ARM: dts: sun8i: Add CPUCFG device node for A83T dtsi
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
As we found in sun9i-a80, CPUCFG is a collection of registers that are
mapped to the SoC's signals from each individual processor core and
associated peripherals.
These registers are used for SMP bringup and CPU hotplugging.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
arch/arm/boot/dts/sun8i-a83t.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 379981389eea..a50ccb475de8 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -349,6 +349,11 @@
};
};
+ cpucfg at 1700000 {
+ compatible = "allwinner,sun8i-a83t-cpucfg";
+ reg = <0x01700000 0x400>;
+ };
+
syscon: syscon at 1c00000 {
compatible = "allwinner,sun8i-a83t-system-controller",
"syscon";
--
2.11.0
^ permalink raw reply related
* [PATCH v9 02/12] ARM: sunxi: smp: Move assembly code into a file
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
Move the assembly code for cluster cache enabling and resuming
into an assembly file instead of having it directly in C code.
Remove the CFLAGS because we are using the ARM directive "arch"
instead.
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
arch/arm/mach-sunxi/Makefile | 2 +-
arch/arm/mach-sunxi/headsmp.S | 80 +++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-sunxi/mc_smp.c | 82 +++----------------------------------------
3 files changed, 85 insertions(+), 79 deletions(-)
create mode 100644 arch/arm/mach-sunxi/headsmp.S
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 7de9cc286d53..71429aa85143 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,5 +1,5 @@
CFLAGS_mc_smp.o += -march=armv7-a
obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
-obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o
+obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o headsmp.o
obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-sunxi/headsmp.S b/arch/arm/mach-sunxi/headsmp.S
new file mode 100644
index 000000000000..37dc772701f3
--- /dev/null
+++ b/arch/arm/mach-sunxi/headsmp.S
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 Chen-Yu Tsai
+ * Copyright (c) 2018 Bootlin
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ * Myl?ne Josserand <mylene.josserand@bootlin.com>
+ *
+ * SMP support for sunxi based systems with Cortex A7/A15
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/cputype.h>
+
+ENTRY(sunxi_mc_smp_cluster_cache_enable)
+ .arch armv7-a
+ /*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ *
+ * Also enable regional clock gating and L2 data latency settings for
+ * Cortex-A15. These settings are from the vendor kernel.
+ */
+ mrc p15, 0, r1, c0, c0, 0
+ movw r2, #(ARM_CPU_PART_MASK & 0xffff)
+ movt r2, #(ARM_CPU_PART_MASK >> 16)
+ and r1, r1, r2
+ movw r2, #(ARM_CPU_PART_CORTEX_A15 & 0xffff)
+ movt r2, #(ARM_CPU_PART_CORTEX_A15 >> 16)
+ cmp r1, r2
+ bne not_a15
+
+ /* The following is Cortex-A15 specific */
+
+ /* ACTLR2: Enable CPU regional clock gates */
+ mrc p15, 1, r1, c15, c0, 4
+ orr r1, r1, #(0x1 << 31)
+ mcr p15, 1, r1, c15, c0, 4
+
+ /* L2ACTLR */
+ mrc p15, 1, r1, c15, c0, 0
+ /* Enable L2, GIC, and Timer regional clock gates */
+ orr r1, r1, #(0x1 << 26)
+ /* Disable clean/evict from being pushed to external */
+ orr r1, r1, #(0x1<<3)
+ mcr p15, 1, r1, c15, c0, 0
+
+ /* L2CTRL: L2 data RAM latency */
+ mrc p15, 1, r1, c9, c0, 2
+ bic r1, r1, #(0x7 << 0)
+ orr r1, r1, #(0x3 << 0)
+ mcr p15, 1, r1, c9, c0, 2
+
+ /* End of Cortex-A15 specific setup */
+ not_a15:
+
+ /* Get value of sunxi_mc_smp_first_comer */
+ adr r1, first
+ ldr r0, [r1]
+ ldr r0, [r1, r0]
+
+ /* Skip cci_enable_port_for_self if not first comer */
+ cmp r0, #0
+ bxeq lr
+ b cci_enable_port_for_self
+
+ .align 2
+ first: .word sunxi_mc_smp_first_comer - .
+ENDPROC(sunxi_mc_smp_cluster_cache_enable)
+
+ENTRY(sunxi_mc_smp_secondary_startup)
+ bl sunxi_mc_smp_cluster_cache_enable
+ b secondary_startup
+ENDPROC(sunxi_mc_smp_secondary_startup)
+
+ENTRY(sunxi_mc_smp_resume)
+ bl sunxi_mc_smp_cluster_cache_enable
+ b cpu_resume
+ENDPROC(sunxi_mc_smp_resume)
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
index c0246ec54a0a..727968d6a3e5 100644
--- a/arch/arm/mach-sunxi/mc_smp.c
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -72,6 +72,9 @@ static void __iomem *cpucfg_base;
static void __iomem *prcm_base;
static void __iomem *sram_b_smp_base;
+extern void sunxi_mc_smp_secondary_startup(void);
+extern void sunxi_mc_smp_resume(void);
+
static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster)
{
struct device_node *node;
@@ -300,74 +303,7 @@ static void sunxi_cluster_cache_disable_without_axi(void)
}
static int sunxi_mc_smp_cpu_table[SUNXI_NR_CLUSTERS][SUNXI_CPUS_PER_CLUSTER];
-static int sunxi_mc_smp_first_comer;
-
-/*
- * Enable cluster-level coherency, in preparation for turning on the MMU.
- *
- * Also enable regional clock gating and L2 data latency settings for
- * Cortex-A15. These settings are from the vendor kernel.
- */
-static void __naked sunxi_mc_smp_cluster_cache_enable(void)
-{
- asm volatile (
- "mrc p15, 0, r1, c0, c0, 0\n"
- "movw r2, #" __stringify(ARM_CPU_PART_MASK & 0xffff) "\n"
- "movt r2, #" __stringify(ARM_CPU_PART_MASK >> 16) "\n"
- "and r1, r1, r2\n"
- "movw r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 & 0xffff) "\n"
- "movt r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 >> 16) "\n"
- "cmp r1, r2\n"
- "bne not_a15\n"
-
- /* The following is Cortex-A15 specific */
-
- /* ACTLR2: Enable CPU regional clock gates */
- "mrc p15, 1, r1, c15, c0, 4\n"
- "orr r1, r1, #(0x1<<31)\n"
- "mcr p15, 1, r1, c15, c0, 4\n"
-
- /* L2ACTLR */
- "mrc p15, 1, r1, c15, c0, 0\n"
- /* Enable L2, GIC, and Timer regional clock gates */
- "orr r1, r1, #(0x1<<26)\n"
- /* Disable clean/evict from being pushed to external */
- "orr r1, r1, #(0x1<<3)\n"
- "mcr p15, 1, r1, c15, c0, 0\n"
-
- /* L2CTRL: L2 data RAM latency */
- "mrc p15, 1, r1, c9, c0, 2\n"
- "bic r1, r1, #(0x7<<0)\n"
- "orr r1, r1, #(0x3<<0)\n"
- "mcr p15, 1, r1, c9, c0, 2\n"
-
- /* End of Cortex-A15 specific setup */
- "not_a15:\n"
-
- /* Get value of sunxi_mc_smp_first_comer */
- "adr r1, first\n"
- "ldr r0, [r1]\n"
- "ldr r0, [r1, r0]\n"
-
- /* Skip cci_enable_port_for_self if not first comer */
- "cmp r0, #0\n"
- "bxeq lr\n"
- "b cci_enable_port_for_self\n"
-
- ".align 2\n"
- "first: .word sunxi_mc_smp_first_comer - .\n"
- );
-}
-
-static void __naked sunxi_mc_smp_secondary_startup(void)
-{
- asm volatile(
- "bl sunxi_mc_smp_cluster_cache_enable\n"
- "b secondary_startup"
- /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */
- :: "i" (sunxi_mc_smp_cluster_cache_enable)
- );
-}
+int sunxi_mc_smp_first_comer;
static DEFINE_SPINLOCK(boot_lock);
@@ -637,16 +573,6 @@ static bool __init sunxi_mc_smp_cpu_table_init(void)
*/
typedef typeof(cpu_reset) phys_reset_t;
-static void __init __naked sunxi_mc_smp_resume(void)
-{
- asm volatile(
- "bl sunxi_mc_smp_cluster_cache_enable\n"
- "b cpu_resume"
- /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */
- :: "i" (sunxi_mc_smp_cluster_cache_enable)
- );
-}
-
static int __init nocache_trampoline(unsigned long __unused)
{
phys_reset_t phys_reset;
--
2.11.0
^ permalink raw reply related
* [PATCH v9 01/12] ARM: Allow this header to be included by assembly files
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504190545.5114-1-mylene.josserand@bootlin.com>
From: Doug Berger <opendmb@gmail.com>
The constants defined in this file are equally useful in assembly and C
source files. The arm64 architecture version of this file allows
inclusion in both assembly and C source files, so this this commit adds
that capability to the arm architecture version so that the constants
don't need to be defined in multiple places.
Signed-off-by: Doug Berger <opendmb@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Myl?ne Josserand <mylene.josserand@bootlin.com>
---
arch/arm/include/asm/cputype.h | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index cb546425da8a..e7632f536633 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -2,9 +2,6 @@
#ifndef __ASM_ARM_CPUTYPE_H
#define __ASM_ARM_CPUTYPE_H
-#include <linux/stringify.h>
-#include <linux/kernel.h>
-
#define CPUID_ID 0
#define CPUID_CACHETYPE 1
#define CPUID_TCM 2
@@ -98,6 +95,11 @@
/* Qualcomm implemented cores */
#define ARM_CPU_PART_SCORPION 0x510002d0
+#ifndef __ASSEMBLY__
+
+#include <linux/stringify.h>
+#include <linux/kernel.h>
+
extern unsigned int processor_id;
#ifdef CONFIG_CPU_CP15
@@ -326,4 +328,6 @@ static inline int __attribute_const__ cpuid_feature_extract_field(u32 features,
#define cpuid_feature_extract(reg, field) \
cpuid_feature_extract_field(read_cpuid_ext(reg), field)
+#endif /* __ASSEMBLY__ */
+
#endif
--
2.11.0
^ permalink raw reply related
* [PATCH v9 00/12] Sunxi: Add SMP support on A83T
From: Mylène Josserand @ 2018-05-04 19:05 UTC (permalink / raw)
To: linux-arm-kernel
Hello everyone,
This is a V9 of my series that adds SMP support for Allwinner sun8i-a83t.
Based on sunxi's tree, sunxi/for-next branch.
Depends on a patch from Doug Berger that allows to include the "cpu-type"
header on assembly files that I included in my series (patch 01).
The difference with the v8 is just that the machine is renamed in sun8i-a83t
(see patch 07), according to Maxime's review.
Thank you in advance,
Best regards,
Myl?ne
Changes from v8:
- Rename machine into "sun8i-a83t"
Changes from v7:
- Add the patch of Doug Berger in my series.
- Rename the machine name to start secure_cntvoff into "sun8i-a83t",
according to Maxime's review.
- Change the type of is_a83t field from integer into boolean.
Changes from v6:
- Correct the commit log on patch 07 according to Sergei Shtylyov's
review.
- Rename the field "is_sun8i" into "is_a83t".
- Add all Tested-by and Reviewed-by from previous version.
Changes from v5:
- Remove my patch 01 and use the patch of Doug Berger to be able to
include the cpu-type header on assembly files.
- Rename smp_init_cntvoff function into secure_cntvoff_init according
to Marc Zyngier's review.
- According to Chen-Yu and Maxime's reviews, remove the patch that was
moving structures. Instead of using an index to retrieve which
architecture we are having, use a global variable.
- Merge the 2 patches that move assembly code from C to assembly file.
- Use a sun8i field instead of sun9i to know on which architecture we
are using because many modifications/additions of the code are for
sun8i-a83t.
- Rework the patch "add is_sun8i field" to add only this field in this
patch. The part of the patch that was starting to handle the differences
between sun8i-a83t and sun9i-a80 is merged in the patch that adds the
support of sun8i-a83t.
- Add a new patch that refactor the shmobile code to use the new function
secure_cntvoff_init introduced in this series.
Changes from v4:
- Rebased my series according to new Chen-Yu series:
"ARM: sunxi: Clean and improvements for multi-cluster SMP"
https://lkml.org/lkml/2018/3/8/886
- Updated my series according to Marc Zyngier's reviews to add CNTVOFF
initialization's function into ARM's common part. Thanks to that, other
platforms such as Renesa can use this function.
- For boot CPU, create a new machine to handle the CNTVOFF initialization
using "init_early" callback.
Changes from v3:
- Take into account Maxime's reviews:
- split the first patch into 4 new patches: add sun9i device tree
parsing, rename some variables, add a83t support and finally,
add hotplug support.
- Move the code of previous patch 07 (to disable CPU0 disabling)
into hotplug support patch (see patch 04)
- Remove the patch that added PRCM register because it is already
available. Because of that, update the device tree parsing to use
"sun8i-a83t-r-ccu".
- Use a variable to know which SoC we currently have
- Take into account Chen-Yu's reviews: create two iounmap functions
to release the resources of the device tree parsing.
- Take into account Marc's review: Update the code to initialize CNTVOFF
register. As there is already assembly code in the driver, I decided
to create an assembly file not to mix assembly and C code.
For that, I create 3 new patches: move the current assembly code that
handles the cluster cache enabling into a file, move the cpu_resume entry
in this file and finally, add a new assembly entry to initialize the timer
offset for boot CPU and secondary CPUs.
Changes from v2:
- Rebased my modifications according to new Chen Yu's patch series
that adds SMP support for sun9i-a80 (without MCPM).
- Split the device-tree patches into 3 patches for CPUCFG, R_CPUCFG
and PRCM registers for more visibility.
- The hotplug of CPU0 is currently not working (even after trying what
Allwinner's code is doing) so remove the possibility of disabling
this CPU. Created a new patch for it.
Changes from v1:
- Add Chen Yu's patch in my series (see path 01)
- Add new compatibles for prcm and cpucfg registers for sun8i-a83t.
Create two functions to separate the DT parsing of sun9i-a80 and
sun8i-a83t.
- Thanks to Maxime's review: order device tree's nodes according
to physical addresses, remove unused label and fix registers' sizes.
Update the commit log and commit title of my last patch (see
patch 05).
Doug Berger (1):
ARM: Allow this header to be included by assembly files
Myl?ne Josserand (11):
ARM: sunxi: smp: Move assembly code into a file
ARM: dts: sun8i: Add CPUCFG device node for A83T dtsi
ARM: dts: sun8i: Add R_CPUCFG device node for the A83T dtsi
ARM: dts: sun8i: a83t: Add CCI-400 node
ARM: smp: Add initialization of CNTVOFF
ARM: sunxi: Add initialization of CNTVOFF
ARM: sun9i: smp: Rename clusters's power-off
ARM: sun9i: smp: Add is_a83t field
ARM: sun8i: smp: Add support for A83T
ARM: dts: sun8i: Add enable-method for SMP support for the A83T SoC
ARM: shmobile: Convert file to use cntvoff
arch/arm/boot/dts/sun8i-a83t.dtsi | 59 ++++++++
arch/arm/common/Makefile | 1 +
arch/arm/common/secure_cntvoff.S | 31 ++++
arch/arm/include/asm/cputype.h | 10 +-
arch/arm/include/asm/secure_cntvoff.h | 8 ++
arch/arm/mach-shmobile/common.h | 1 -
arch/arm/mach-shmobile/headsmp-apmu.S | 22 +--
arch/arm/mach-shmobile/setup-rcar-gen2.c | 3 +-
arch/arm/mach-sunxi/Kconfig | 2 +-
arch/arm/mach-sunxi/Makefile | 2 +-
arch/arm/mach-sunxi/headsmp.S | 81 +++++++++++
arch/arm/mach-sunxi/mc_smp.c | 239 +++++++++++++++++++------------
arch/arm/mach-sunxi/sunxi.c | 20 ++-
13 files changed, 356 insertions(+), 123 deletions(-)
create mode 100644 arch/arm/common/secure_cntvoff.S
create mode 100644 arch/arm/include/asm/secure_cntvoff.h
create mode 100644 arch/arm/mach-sunxi/headsmp.S
--
2.11.0
^ permalink raw reply
* [PATCH v7 08/24] ASoC: qdsp6: q6core: Add q6core driver
From: Banajit Goswami @ 2018-05-04 19:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180501120820.11016-9-srinivas.kandagatla@linaro.org>
On 5/1/2018 5:08 AM, Srinivas Kandagatla wrote:
> This patch adds support to core apr service, which is used to query
> status of other static and dynamic services on the dsp.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Reviewed-and-tested-by: Rohit kumar <rohitkr@codeaurora.org>
> ---
> sound/soc/qcom/Kconfig | 4 +
> sound/soc/qcom/qdsp6/Makefile | 1 +
> sound/soc/qcom/qdsp6/q6core.c | 380 ++++++++++++++++++++++++++++++++++++++++++
> sound/soc/qcom/qdsp6/q6core.h | 15 ++
> 4 files changed, 400 insertions(+)
> create mode 100644 sound/soc/qcom/qdsp6/q6core.c
> create mode 100644 sound/soc/qcom/qdsp6/q6core.h
>
> diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
> index b44a9fcd7ed3..37ee0d958145 100644
> --- a/sound/soc/qcom/Kconfig
> +++ b/sound/soc/qcom/Kconfig
> @@ -44,10 +44,14 @@ config SND_SOC_APQ8016_SBC
> config SND_SOC_QDSP6_COMMON
> tristate
>
> +config SND_SOC_QDSP6_CORE
> + tristate
> +
> config SND_SOC_QDSP6
> tristate "SoC ALSA audio driver for QDSP6"
> depends on QCOM_APR && HAS_DMA
> select SND_SOC_QDSP6_COMMON
> + select SND_SOC_QDSP6_CORE
> help
> To add support for MSM QDSP6 Soc Audio.
> This will enable sound soc platform specific
> diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
> index accebdb49306..03b8e89c9731 100644
> --- a/sound/soc/qcom/qdsp6/Makefile
> +++ b/sound/soc/qcom/qdsp6/Makefile
> @@ -1 +1,2 @@
> obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
> +obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
> diff --git a/sound/soc/qcom/qdsp6/q6core.c b/sound/soc/qcom/qdsp6/q6core.c
> new file mode 100644
> index 000000000000..701aa3f50a6a
> --- /dev/null
> +++ b/sound/soc/qcom/qdsp6/q6core.c
> @@ -0,0 +1,380 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
> +// Copyright (c) 2018, Linaro Limited
> +
> +#include <linux/slab.h>
> +#include <linux/wait.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/sched.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/jiffies.h>
> +#include <linux/wait.h>
> +#include <linux/soc/qcom/apr.h>
> +#include "q6core.h"
> +#include "q6dsp-errno.h"
> +
> +#define ADSP_STATE_READY_TIMEOUT_MS 3000
> +#define Q6_READY_TIMEOUT_MS 100
> +#define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C
> +#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D
> +#define AVCS_GET_VERSIONS 0x00012905
> +#define AVCS_GET_VERSIONS_RSP 0x00012906
> +#define AVCS_CMD_GET_FWK_VERSION 0x001292c
> +#define AVCS_CMDRSP_GET_FWK_VERSION 0x001292d
> +
> +struct avcs_svc_info {
<snip>
> +};
> +
> +static struct q6core *g_core;
> +
> +static int q6core_callback(struct apr_device *adev, struct apr_resp_pkt *data)
> +{
> + struct q6core *core = dev_get_drvdata(&adev->dev);
> + struct aprv2_ibasic_rsp_result_t *result;
> + struct apr_hdr *hdr = &data->hdr;
> +
> + result = data->payload;
> + switch (hdr->opcode) {
> + case APR_BASIC_RSP_RESULT:{
> + result = data->payload;
> + switch (result->opcode) {
> + case AVCS_GET_VERSIONS:
> + if (result->status == ADSP_EUNSUPPORTED)
> + core->get_version_supported = false;
> + core->resp_received = true;
> + break;
> + case AVCS_CMD_GET_FWK_VERSION:
> + if (result->status == ADSP_EUNSUPPORTED)
> + core->fwk_version_supported = false;
> + core->resp_received = true;
> + break;
> + case AVCS_CMD_ADSP_EVENT_GET_STATE:
> + if (result->status == ADSP_EUNSUPPORTED)
> + core->get_state_supported = false;
> + core->resp_received = true;
> + break;
> + }
> + break;
> + }
> + case AVCS_CMDRSP_GET_FWK_VERSION: {
> + struct avcs_cmdrsp_get_fwk_version *fwk;
> + int bytes;
> +
> + fwk = data->payload;
> + core->fwk_version_supported = true;
> + bytes = sizeof(*fwk) + fwk->num_services *
> + sizeof(fwk->svc_api_info[0]);
> +
> + core->fwk_version = kzalloc(bytes, GFP_ATOMIC);
> + if (!core->fwk_version)
> + return -ENOMEM;
When the above allocation fails,? core->fwk_version_supported will be
still true, and q6core_get_fwk_versions() will return 0 (timeout as
core->resp_received will not be set to true). This can cause a NULL
pointer dereference inside the if() loop pointed below (added comment).
Please move the line to set core->fwk_version_supported flag to after
memset() to copy fwk version info.
> +
> + memcpy(core->fwk_version, data->payload, bytes);
> +
> + core->resp_received = true;
> +
> + break;
> + }
> + case AVCS_GET_VERSIONS_RSP: {
> + struct avcs_cmdrsp_get_version *v;
> + int len;
> +
> + v = data->payload;
> + core->get_version_supported = true;
> +
<snip>
> + }
> +
> + return rc;
> +}
> +
> +static bool __q6core_is_adsp_ready(struct q6core *core)
> +{
> + struct apr_device *adev = core->adev;
> + struct apr_pkt pkt;
> + int rc;
> +
> + core->get_state_supported = false;
> +
> + pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
> + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
> + pkt.hdr.pkt_size = APR_HDR_SIZE;
> + pkt.hdr.opcode = AVCS_CMD_ADSP_EVENT_GET_STATE;
> +
> + rc = apr_send_pkt(adev, &pkt);
> + if (rc < 0)
> + return false;
> +
> + rc = wait_event_timeout(core->wait, (core->resp_received),
> + msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
> + if (rc > 0 && core->resp_received) {
> + core->resp_received = false;
> +
> + if (core->avcs_state == 0x1)
The AVCS state can be different non-zero value then 0x1.
A better way to handle this can be check for (core->avcs_state > 0) for
success, and then return the "core->avcs_state" to the caller.
> + return true;
> + }
> +
> + /* assume that the adsp is up if we not support this command */
> + if (!core->get_state_supported)
> + return true;
> +
> + return false;
> +}
> +
> +/**
> + * q6core_get_svc_api_info() - Get version number of a service.
> + *
> + * @svc_id: service id of the service.
> + * @info: Valid struct pointer to fill svc api information.
> + *
> + * Return: zero on success and error code on failure or unsupported
> + */
> +int q6core_get_svc_api_info(int svc_id, struct q6core_svc_api_info *ainfo)
> +{
> + int i;
> + int ret = -ENOTSUPP;
> +
> + if (!g_core || !ainfo)
> + return 0;
> +
> + mutex_lock(&g_core->lock);
> + if (!g_core->is_version_requested) {
> + if (q6core_get_fwk_versions(g_core) == -ENOTSUPP)
> + q6core_get_svc_versions(g_core);
> + g_core->is_version_requested = true;
> + }
> +
> + if (g_core->fwk_version_supported) {
> + for (i = 0; i < g_core->fwk_version->num_services; i++) {
..NULL pointer dereference here.
> + struct avcs_svc_api_info *info;
> +
> + info = &g_core->fwk_version->svc_api_info[i];
> + if (svc_id != info->service_id)
> + continue;
> +
> + ainfo->api_version = info->api_version;
> + ainfo->api_branch_version = info->api_branch_version;
> + ret = 0;
> + break;
> + }
> + } else if (g_core->get_version_supported) {
> + for (i = 0; i < g_core->svc_version->num_services; i++) {
Similar issue of NULL pointer dereference is also present for
g_core->get_version_supported flag.
> + struct avcs_svc_info *info;
> +
> + info = &g_core->svc_version->svc_api_info[i];
> + if (svc_id != info->service_id)
> + continue;
> +
> + ainfo->api_version = info->version;
> + ainfo->api_branch_version = 0;
> + ret = 0;
> + break;
<snip>
> + init_waitqueue_head(&g_core->wait);
> + return 0;
> +}
> +
> +static int q6core_exit(struct apr_device *adev)
> +{
> + struct q6core *core = dev_get_drvdata(&adev->dev);
> +
> + if (core->fwk_version_supported)
> + kfree(core->fwk_version);
> + if (core->get_version_supported)
> + kfree(core->svc_version);
> +
> + kfree(core);
> + g_core = NULL;
This assignment can be before kfree() to avoid any possible issue in
using g_core, after the pointer is freed.
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox