* [FAIL bisect] Sound card probe error
From: Krzysztof Kozlowski @ 2018-05-14 12:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJKOXPc6Yj0+Z6zd-Gm-fYvfQB4rPPn0k6ED8bWScJ-tdZ=Ysw@mail.gmail.com>
On Mon, May 14, 2018 at 2:45 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> On Mon, May 14, 2018 at 2:40 PM, Sylwester Nawrocki
> <s.nawrocki@samsung.com> wrote:
>> On 05/14/2018 02:29 PM, Krzysztof Kozlowski wrote:
>>> Ah, I missed these messages because I was looking at err dmesg level
>>> (and for some reason these are warn). Anyway do you have any thoughts
>>> how is it connected with missing Odroid XU3 sound card and max98090
>>> codec?
>>
>> One reason is that the DRM driver registers an ASoC codec object which
>> is required for the sound card registration to complete. But I wonder
>> why there is no any error messages related to this.
>
> Thanks Marek and Sylwester. Another point is that probably OOPS later
> should not happen...
Separate topic (trim Cc list):
... and this means that disabling Exynos DRM causes lack of Audio. I
tried it now and indeed without DRM there is no audio again. I think
it is not nice... There are not many such use cases but there are
(playing audio from console/ssh with a headless board).\
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 08/18] arm64: convert raw syscall invocation to C
From: Dave Martin @ 2018-05-14 12:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514114104.oubxdf526hf2m6t5@lakrids.cambridge.arm.com>
On Mon, May 14, 2018 at 12:41:10PM +0100, Mark Rutland wrote:
> On Mon, May 14, 2018 at 12:07:18PM +0100, Dave Martin wrote:
> > On Mon, May 14, 2018 at 10:46:30AM +0100, Mark Rutland wrote:
> > > As a first step towards invoking syscalls with a pt_regs argument,
> > > convert the raw syscall invocation logic to C. We end up with a bit more
> > > register shuffling, but the unified invocation logic means we can unify
> > > the tracing paths, too.
> > >
> > > This only converts the invocation of the syscall. The rest of the
> > > syscall triage and tracing is left in assembly for now, and will be
> > > converted in subsequent patches.
> > >
> > > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > > Cc: Will Deacon <will.deacon@arm.com>
> > > ---
> > > arch/arm64/kernel/Makefile | 3 ++-
> > > arch/arm64/kernel/entry.S | 36 ++++++++++--------------------------
> > > arch/arm64/kernel/syscall.c | 29 +++++++++++++++++++++++++++++
> > > 3 files changed, 41 insertions(+), 27 deletions(-)
> > > create mode 100644 arch/arm64/kernel/syscall.c
> > >
> > > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> > > index bf825f38d206..c22e8ace5ea3 100644
> > > --- a/arch/arm64/kernel/Makefile
> > > +++ b/arch/arm64/kernel/Makefile
> > > @@ -18,7 +18,8 @@ arm64-obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
> > > hyp-stub.o psci.o cpu_ops.o insn.o \
> > > return_address.o cpuinfo.o cpu_errata.o \
> > > cpufeature.o alternative.o cacheinfo.o \
> > > - smp.o smp_spin_table.o topology.o smccc-call.o
> > > + smp.o smp_spin_table.o topology.o smccc-call.o \
> > > + syscall.o
> > >
> > > extra-$(CONFIG_EFI) := efi-entry.o
> > >
> > > diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > > index 08ea3cbfb08f..d6e057500eaf 100644
> > > --- a/arch/arm64/kernel/entry.S
> > > +++ b/arch/arm64/kernel/entry.S
> > > @@ -873,7 +873,6 @@ ENDPROC(el0_error)
> > > */
> > > ret_fast_syscall:
> > > disable_daif
> > > - str x0, [sp, #S_X0] // returned x0
> > > ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for syscall tracing
> > > and x2, x1, #_TIF_SYSCALL_WORK
> > > cbnz x2, ret_fast_syscall_trace
> > > @@ -946,15 +945,11 @@ el0_svc_naked: // compat entry point
> > >
> > > tst x16, #_TIF_SYSCALL_WORK // check for syscall hooks
> > > b.ne __sys_trace
> > > - cmp wscno, wsc_nr // check upper syscall limit
> > > - b.hs ni_sys
> > > - mask_nospec64 xscno, xsc_nr, x19 // enforce bounds for syscall number
> > > - ldr x16, [stbl, xscno, lsl #3] // address in the syscall table
> > > - blr x16 // call sys_* routine
> > > - b ret_fast_syscall
> > > -ni_sys:
> > > mov x0, sp
> > > - bl do_ni_syscall
> > > + mov w1, wscno
> > > + mov w2, wsc_nr
> > > + mov x3, stbl
> > > + bl invoke_syscall
> > > b ret_fast_syscall
> > > ENDPROC(el0_svc)
> > >
> > > @@ -971,29 +966,18 @@ __sys_trace:
> > > bl syscall_trace_enter
> > > cmp w0, #NO_SYSCALL // skip the syscall?
> > > b.eq __sys_trace_return_skipped
> > > - mov wscno, w0 // syscall number (possibly new)
> > > - mov x1, sp // pointer to regs
> > > - cmp wscno, wsc_nr // check upper syscall limit
> > > - b.hs __ni_sys_trace
> > > - ldp x0, x1, [sp] // restore the syscall args
> > > - ldp x2, x3, [sp, #S_X2]
> > > - ldp x4, x5, [sp, #S_X4]
> > > - ldp x6, x7, [sp, #S_X6]
> > > - ldr x16, [stbl, xscno, lsl #3] // address in the syscall table
> > > - blr x16 // call sys_* routine
> > >
> > > -__sys_trace_return:
> > > - str x0, [sp, #S_X0] // save returned x0
> > > + mov x0, sp
> > > + mov w1, wscno
> > > + mov w2, wsc_nr
> > > + mov x3, stbl
> > > + bl invoke_syscall
> > > +
> > > __sys_trace_return_skipped:
> > > mov x0, sp
> > > bl syscall_trace_exit
> > > b ret_to_user
> > >
> > > -__ni_sys_trace:
> > > - mov x0, sp
> > > - bl do_ni_syscall
> > > - b __sys_trace_return
> > > -
> >
> > Can you explain why ni_syscall is special here,
>
> This is for out-of-range syscall numbers, instances of ni_syscall in the
> syscall table are handled by the regular path. When the syscall number
> is out-of-range, we can't index the syscall table, and have to call
> ni_sys directly.
>
> The c invoke_syscall() wrapper handles that case internally so that we
> don't have to open-code it everywhere.
>
> > why __sys_trace_return existed,
>
> The __sys_trace_return label existed so that the special __ni_sys_trace
> path could return into a common tracing return path.
>
> > and why its disappearance doesn't break anything?
>
> Now that invoke_syscall() handles out-of-range syscall numbers, and we
> can remove the __ni_sys_trace path, nothing branches to
> __sys_trace_return.
>
> Only the label has been removed, not the usual return path.
OK, I think I understand. I think the name "__sys_trace_return" was
confusing me, as if this was something special that only relates to the
ni_syscall case. If it was only ever intended as the merge point for
those two paths, then I can see that merging the paths for real enables
us to get rid of it.
> > Not saying there's a bug, just that I'm a little confuse -- I see no
> > real reason for ni_syscall being special, and this may be a good
> > opportunity to decruft it. (See also comments below.)
>
> Hopefully the above clarifies things?
Yes, I think so.
> I've updated the commit message with a description.
>
> [...]
>
> > > +asmlinkage void invoke_syscall(struct pt_regs *regs, int scno, int sc_nr,
> > > + syscall_fn_t syscall_table[])
> > > +{
> > > + if (scno < sc_nr) {
> >
> > What if (int)scno < 0? Should those args both by unsigned ints?
>
> Yes, they should -- I've fixed that up locally.
>
> That is a *very* good point, thanks!
>
> > "sc_nr" sounds too much like "syscall number" to me. Might
> > "syscall_table_size" might be clearer? Similarly, we could have
> > "stbl_size" or similar in the asm. This is purely cosmetic,
> > though.
>
> I'd tried to stick to the naming used in assembly to keep the conversion
> clearer for those familiar with the asm.
>
> I agree the names aren't great.
Not a big deal. If you feel you would like to rename them though, I
won't argue with it ;)
> > > + syscall_fn_t syscall_fn;
> > > + syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> > > + __invoke_syscall(regs, syscall_fn);
> > > + } else {
> > > + regs->regs[0] = do_ni_syscall(regs);
> >
> > Can we make __invoke_syscall() the universal syscall wrapper, and give
> > do_ni_syscall() the same interface as any other syscall body?
>
> Not at this point in time, since the prototype (in core code) differs.
>
> I agree that would be nicer, but there are a number of complications;
> more details below.
>
> > Then you could factor this as
> >
> > static syscall_fn_t syscall_fn(syscall_fn_t const syscall_table[],
> > (unsigned) int scno, (unsigned) int sc_nr)
> > {
> > if (sc_no >= sc_nr)
> > return sys_ni_syscall;
> >
> > return syscall_table[array_index_nospec(scno, sc_nr)];
> > }
> >
> > ...
> > __invoke_syscall(regs, syscall_fn(syscall_table, scno, sc_nr);
> >
> >
> >
> > This is cosmetic too, of course.
> >
> > do_ni_syscall() should be given a pt_regs-based wrapper like all the
> > rest.
>
> I agree it would be nicer if it had a wrapper that took a pt_regs, even
> if it does nothing with it.
>
> We can't use SYSCALL_DEFINE0() due to the fault injection muck, we'd
> need a ksys_ni_syscall() for our traps.c logic, and adding this
> uniformly would involve some arch-specific rework for x86, too, so I
> decided it was not worth the effort.
Does allowing error injection for ni_syscall actually matter? Error
injection is an ABI break by itself. It would arguably be a bit
strange though.
Cheers
---Dave
^ permalink raw reply
* [PATCH 02/18] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h>
From: Mark Rutland @ 2018-05-14 13:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514124122.GJ7753@e103592.cambridge.arm.com>
On Mon, May 14, 2018 at 01:41:23PM +0100, Dave Martin wrote:
> On Mon, May 14, 2018 at 01:06:10PM +0100, Mark Rutland wrote:
> > On Mon, May 14, 2018 at 12:56:09PM +0100, Robin Murphy wrote:
> > > On 14/05/18 12:20, Dave Martin wrote:
> > > > How about the following?
> > > >
> > > > /* Watch out for #if evaluation rules: ~0 is not ~(int)0! */
> > >
> > > Or, more formally, perhaps something even less vague like "Note that in
> > > preprocessor arithmetic these constants are effectively of type intmax_t,
> > > which is 64-bit, thus ~0 is not what we want."
> >
> > I'll drop something in the commit message to that effect, rather than a
> > comment.
> >
> > A comment will end up terse and vague or large and bloatsome (and
> > redundant as we have this pattern twice).
> >
> > Anyone attempting to "clean" this up will find things break, and they can
> > look at the git log to find out why it is the way it is...
>
> Fair enough. So long as we say something somewhere, that's
> sufficient for me.
>
> With that,
>
> Reviewed-by: Dave Martin <Dave.Martin@arm.com>
>
> (as previously stated).
Cheers!
Mark.
^ permalink raw reply
* Delivery Status Notification (Failure)
From: Lucas Stach @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOuPNLiFr3qbNVAwF4wj2aAG0UXRVsgRo-8JfaKFCsoL+Ggk9w@mail.gmail.com>
Am Montag, den 14.05.2018, 17:42 +0530 schrieb Pintu Kumar:
> Hi,
>
> Is there any work around possible to set IRQ affinity for some GPIO
> interrupt ?
> How to avoid CPU0 to receive the current GPIO interrupt ?
> How do we assign GPIO interrupts to any CPU other than CPU0 ?
> Is it possible to isolate CPU0 for a sometime, from my GPIO driver so
> that GPIO interrupt can be served by another CPU ?
>
> Need your inputs to decide whether it is still possible to set
> affinity for GPIO interrupt, or its impossible ?
This is not possible. The GPIO IRQs are aggregated into one GPC/GIC IRQ
line per GPIO bank, so it is not possible to change affinity of a
single GPIO interrupt to another CPU. Best we could do is change the
affinity of the whole bank, but given the limited usefulness of
something like that, nobody bothered to implement such a thing.
Regards,
Lucas
>
>
> On Fri, May 11, 2018 at 8:07 PM, Pintu Kumar <pintu.ping@gmail.com>
> wrote:
> > On Fri, May 11, 2018 at 6:34 PM, Lucas Stach <l.stach@pengutronix.d
> > e> wrote:
> > > Am Freitag, den 11.05.2018, 13:39 +0100 schrieb Russell King -
> > > ARM Linux:
> > > > On Fri, May 11, 2018 at 05:07:37PM +0530, Pintu Kumar wrote:
> > > > > Hi,
> > > > >
> > > > > I need one help.
> > > > > I am using i.MX7 Sabre board with kernel version 4.1.15
> > > > >
> > > > > Let's say I am interested in GPIO number: 21
> > > > > I wanted to set CPU affinity for particular GPIO->IRQ number,
> > > > > so I
> > > > > tried the below steps:
> > > > > root at 10:~# echo 21 > /sys/class/gpio/export
> > > > > root at 10:~# echo "rising" > /sys/class/gpio/gpio21/edge
> > > > > root at 10:~# cat /proc/interrupts | grep 21
> > > > > ? 47: 0 0 gpio-mxc 21 Edge gpiolib
> > > > > root at 10:~# cat /sys/class/gpio/gpio21/direction
> > > > > in
> > > > > root at 10:~# cat /proc/irq/47/smp_affinity
> > > > > 3
> > > > > root at 10:~# echo 2 > /proc/irq/47/smp_affinity
> > > > > -bash: echo: write error: Input/output error
> > > > >
> > > > > But I get input/output error.
> > > > > When I debug further, found that irq_can_set_affinity is
> > > > > returning 0:
> > > > > [????0.000000] genirq: irq_can_set_affinity (0): balance: 1,
> > > > > irq_data.chip: a81b7e48, irq_set_affinity:???(null)
> > > > > [????0.000000] write_irq_affinity: FAIL
> > > > >
> > > > > I also tried first setting /proc/irq/default_smp_affinity to
> > > > > 2 (from 3).
> > > > > This change is working, but the smp_affinity setting for the
> > > > > new IRQ
> > > > > is not working.
> > > > >
> > > > > When I try to set smp_affinity for mmc0, then it works.
> > > > > # cat /proc/interrupts | grep mmc
> > > > > 295:?????????55??????????0?????GPCV2??22 Edge??????mmc0
> > > > > 296:??????????0??????????0?????GPCV2??23 Edge??????mmc1
> > > > > 297:?????????52??????????0?????GPCV2??24 Edge??????mmc2
> > > > >
> > > > > root at 10:~# echo 2 > /proc/irq/295/smp_affinity
> > > > > root at 10:~#
> > > > >
> > > > >
> > > > > So, I wanted to know what are the conditions for which
> > > > > setting
> > > > > smp_affinity for an IRQ will work ?
> > > > >
> > > > > Is there any way by which I can set CPU affinity to a GPIO ->
> > > > > IRQ ?
> > > > > Whether, irq_set_affinity_hint() will work in this case ?
> > > >
> > > > IRQ affinity is only supported where interrupts are _directly_
> > > > wired to
> > > > the GIC.??It's the GIC which does the interrupt steering to the
> > > > CPU
> > > > cores.
> > > >
> > > > Interrupts on downstream interrupt controllers (such as GPCV2)
> > > > have no
> > > > ability to be directed independently to other CPUs - the only
> > > > possible
> > > > way to change the mapping is to move _all_ interrupts on that
> > > > controller,
> > > > and any downstream chained interrupts at GIC level.
> > > >
> > > > Hence why Interrupt 295 has no irq_set_affinity function: there
> > > > is no way
> > > > for the interrupt controller itself to change the affinity of
> > > > the input
> > > > interrupt.
> > >
> > > The GPCv2 though is a secondary IRQ controller which has a 1:1
> > > mapping
> > > of its input IRQs to the upstream GIC IRQ lines. Affinity can
> > > thus be
> > > handled by forwarding the request to the GIC by
> > > irq_chip_set_affinity_parent().
> > >
> > > As this is handled correctly in the upstream kernel since the
> > > first
> > > commit introducing support for the GPCv2, it seems the issue is
> > > only
> > > present in some downstream kernel.
> > >
> >
> > OK. Thanks so much for your reply.
> >
> > I saw some of the drivers using irq_set_affinity_hint() to force
> > the
> > IRQ affinity to a particular CPU.
> > This is the sample:
> > {
> > cpumask_clear(mask);
> > cpumask_set_cpu(cpu, mask);
> > irq_set_affinity_hint(irq, mask);
> > }
> >
> > Whether this logic will work for a particular GPIO pin ?
> >
> >
> > > Regards,
> > > Lucas
^ permalink raw reply
* [PATCH v6 00/14] CPU scaling support for msm8996
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
[v6]
* Addressed comments from Viresh about:
** Comments style
** Kconfig bool instead of tristate
** DT and documentation style
** Resourses deallocation on an error
** Typos
[v5]
* Rebased
* Addressed comments from Bjorn about SPDX style,
functions and parameters naming
* Addressed comments from Viresh DT properties and style, comments style,
resourses deallocation, documentation placement
* Addressed comments from Sricharan about unnessesary include
* Addressed comments from Nicolas
* Addressed comments from Rob about the commit messages and acks
* Addressed comments from Mark
[v4]
* Adressed all comments from Stephen
* Added CPU regulator support
* Added qcom-cpufreq-kryo driver
[v3]
* Rebased on top of the latest PLL driver changes
* Addressed comment from Rob Herring for bindings
[v2]
* Addressed comments from Rob Herring for bindings
* Addressed comments from Mark Rutland for memory barrier
* Addressed comments from Julien Thierry for clock reenabling condition
* Tuned the HW configuration for clock frequencies below 600MHz
Clocks:
This series adds support for the CPU clocks on msm8996 devices.
The driver uses the existing PLL drivers and is required to control
the CPU frequency scaling on the MSM8996.
Regulators:
Added SAW regulator support to the SPMI regulator driver. The SAW regulators
will be controlled through special CPU registers instead of direct
SPMI accesses.
Cpufreq:
The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.
A previous post of RFC can be found here:
https://patchwork.kernel.org/patch/10377887/
Ilia Lin (11):
soc: qcom: Separate kryo l2 accessors from PMU driver
clk: qcom: Add CPU clock driver for msm8996
clk: qcom: Add DT bindings for CPU clock driver for msm8996
clk: qcom: Add ACD path to CPU clock driver for msm8996
dt: qcom: Add opp and thermal to the msm8996
regulator: qcom_spmi: Add support for SAW
dt-bindings: qcom_spmi: Add support for SAW documentation
dt: qcom: Add SAW regulator for 8x96 CPUs
cpufreq: Add Kryo CPU scaling driver
dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu
dt: qcom: Add qcom-cpufreq-kryo driver configuration
Rajendra Nayak (3):
clk: qcom: Make clk_alpha_pll_configure available to modules
clk: qcom: cpu-8996: Add support to switch to alternate PLL
clk: qcom: cpu-8996: Add support to switch below 600Mhz
.../devicetree/bindings/clock/qcom,kryocc.txt | 17 +
.../devicetree/bindings/opp/kryo-cpufreq.txt | 680 +++++++++++++++++++++
.../bindings/regulator/qcom,spmi-regulator.txt | 45 ++
arch/arm64/boot/dts/qcom/apq8096-db820c.dts | 2 +-
arch/arm64/boot/dts/qcom/msm8996.dtsi | 650 +++++++++++++++++++-
drivers/clk/clk-fixed-factor.c | 2 +-
drivers/clk/qcom/Kconfig | 9 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/clk-alpha-pll.c | 1 +
drivers/clk/qcom/clk-alpha-pll.h | 6 +
drivers/clk/qcom/clk-cpu-8996.c | 519 ++++++++++++++++
drivers/cpufreq/Kconfig.arm | 11 +
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/cpufreq-dt-platdev.c | 3 +
drivers/cpufreq/qcom-cpufreq-kryo.c | 148 +++++
drivers/perf/Kconfig | 1 +
drivers/perf/qcom_l2_pmu.c | 90 +--
drivers/regulator/qcom_spmi-regulator.c | 133 +++-
drivers/soc/qcom/Kconfig | 3 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/kryo-l2-accessors.c | 65 ++
include/soc/qcom/kryo-l2-accessors.h | 21 +
22 files changed, 2329 insertions(+), 80 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c
create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
create mode 100644 include/soc/qcom/kryo-l2-accessors.h
--
1.9.1
^ permalink raw reply
* [PATCH v6 01/14] soc: qcom: Separate kryo l2 accessors from PMU driver
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/perf/Kconfig | 1 +
drivers/perf/qcom_l2_pmu.c | 90 ++++++++++--------------------------
drivers/soc/qcom/Kconfig | 3 ++
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/kryo-l2-accessors.c | 65 ++++++++++++++++++++++++++
include/soc/qcom/kryo-l2-accessors.h | 21 +++++++++
6 files changed, 115 insertions(+), 66 deletions(-)
create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
create mode 100644 include/soc/qcom/kryo-l2-accessors.h
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..561252a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -69,6 +69,7 @@ config HISI_PMU
config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+ select QCOM_KRYO_L2_ACCESSORS
help
Provides support for the L2 cache performance monitor unit (PMU)
in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..cc31f51 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
#include <asm/barrier.h>
#include <asm/local64.h>
#include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
#define MAX_L2_CTRS 9
@@ -87,8 +88,6 @@
#define L2_COUNTER_RELOAD BIT_ULL(31)
#define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1 sys_reg(3, 3, 15, 0, 7)
#define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
@@ -107,48 +106,7 @@
#define L2_EVENT_STREX 0x421
#define L2_EVENT_CLREX 0x422
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2_access_lock, flags);
- write_sysreg_s(reg, L2CPUSRSELR_EL1);
- isb();
- write_sysreg_s(val, L2CPUSRDR_EL1);
- isb();
- raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
- u64 val;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2_access_lock, flags);
- write_sysreg_s(reg, L2CPUSRSELR_EL1);
- isb();
- val = read_sysreg_s(L2CPUSRDR_EL1);
- raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-
- return val;
-}
struct cluster_pmu;
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
static void cluster_pmu_reset(void)
{
/* Reset all counters */
- set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
- set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
- set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
- set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+ kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
}
static inline void cluster_pmu_enable(void)
{
- set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
}
static inline void cluster_pmu_disable(void)
{
- set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
}
static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
{
if (idx == l2_cycle_ctr_idx)
- set_l2_indirect_reg(L2PMCCNTR, value);
+ kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
}
static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
if (idx == l2_cycle_ctr_idx)
- value = get_l2_indirect_reg(L2PMCCNTR);
+ value = kryo_l2_get_indirect_reg(L2PMCCNTR);
else
- value = get_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
+ value = kryo_l2_get_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
return value;
}
static inline void cluster_pmu_counter_enable(u32 idx)
{
- set_l2_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_disable(u32 idx)
{
- set_l2_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_enable_interrupt(u32 idx)
{
- set_l2_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_disable_interrupt(u32 idx)
{
- set_l2_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_set_evccntcr(u32 val)
{
- set_l2_indirect_reg(L2PMCCNTCR, val);
+ kryo_l2_set_indirect_reg(L2PMCCNTCR, val);
}
static inline void cluster_pmu_set_evcntcr(u32 ctr, u32 val)
{
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
}
static inline void cluster_pmu_set_evtyper(u32 ctr, u32 val)
{
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
}
static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
@@ -303,11 +261,11 @@ static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
spin_lock_irqsave(&cluster->pmu_lock, flags);
- resr_val = get_l2_indirect_reg(L2PMRESR);
+ resr_val = kryo_l2_get_indirect_reg(L2PMRESR);
resr_val &= ~(L2PMRESR_GROUP_MASK << shift);
resr_val |= field;
resr_val |= L2PMRESR_EN;
- set_l2_indirect_reg(L2PMRESR, resr_val);
+ kryo_l2_set_indirect_reg(L2PMRESR, resr_val);
spin_unlock_irqrestore(&cluster->pmu_lock, flags);
}
@@ -323,14 +281,14 @@ static inline void cluster_pmu_set_evfilter_sys_mode(u32 ctr)
L2PMXEVFILTER_ORGFILTER_IDINDEP |
L2PMXEVFILTER_ORGFILTER_ALL;
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
}
static inline u32 cluster_pmu_getreset_ovsr(void)
{
- u32 result = get_l2_indirect_reg(L2PMOVSSET);
+ u32 result = kryo_l2_get_indirect_reg(L2PMOVSSET);
- set_l2_indirect_reg(L2PMOVSCLR, result);
+ kryo_l2_set_indirect_reg(L2PMOVSCLR, result);
return result;
}
@@ -783,7 +741,7 @@ static int get_num_counters(void)
{
int val;
- val = get_l2_indirect_reg(L2PMCR);
+ val = kryo_l2_get_indirect_reg(L2PMCR);
/*
* Read number of counters from L2PMCR and add 1
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 7093fe7..0567dff 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -39,6 +39,9 @@ config QCOM_GSBI
functions for connecting the underlying serial UART, SPI, and I2C
devices to the output pins.
+config QCOM_KRYO_L2_ACCESSORS
+ bool
+
config QCOM_MDT_LOADER
tristate
select QCOM_SCM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index cbf414c..e4d3f5a 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
obj-$(CONFIG_QCOM_SMSM) += smsm.o
obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
+obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) += kryo-l2-accessors.o
diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c
new file mode 100644
index 0000000..d35a860
--- /dev/null
+++ b/drivers/soc/qcom/kryo-l2-accessors.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2015, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/spinlock.h>
+#include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
+
+#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
+#define L2CPUSRDR_EL1 sys_reg(3, 3, 15, 0, 7)
+
+static DEFINE_RAW_SPINLOCK(l2_access_lock);
+
+/**
+ * kryo_l2_set_indirect_reg() - write value to an L2 register
+ * @reg: Address of L2 register.
+ * @value: Value to be written to register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+void kryo_l2_set_indirect_reg(u64 reg, u64 val)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2_access_lock, flags);
+ write_sysreg_s(reg, L2CPUSRSELR_EL1);
+ isb();
+ write_sysreg_s(val, L2CPUSRDR_EL1);
+ isb();
+ raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+}
+EXPORT_SYMBOL(kryo_l2_set_indirect_reg);
+
+/**
+ * kryo_l2_get_indirect_reg() - read an L2 register value
+ * @reg: Address of L2 register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+u64 kryo_l2_get_indirect_reg(u64 reg)
+{
+ u64 val;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2_access_lock, flags);
+ write_sysreg_s(reg, L2CPUSRSELR_EL1);
+ isb();
+ val = read_sysreg_s(L2CPUSRDR_EL1);
+ raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+
+ return val;
+}
+EXPORT_SYMBOL(kryo_l2_get_indirect_reg);
diff --git a/include/soc/qcom/kryo-l2-accessors.h b/include/soc/qcom/kryo-l2-accessors.h
new file mode 100644
index 0000000..0840e87
--- /dev/null
+++ b/include/soc/qcom/kryo-l2-accessors.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+#define __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+
+void kryo_l2_set_indirect_reg(u64 reg, u64 val);
+u64 kryo_l2_get_indirect_reg(u64 reg);
+
+#endif
--
1.9.1
^ permalink raw reply related
* [PATCH v6 02/14] clk: qcom: Make clk_alpha_pll_configure available to modules
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
From: Rajendra Nayak <rnayak@codeaurora.org>
Allow clk_alpha_pll_configure to be called from loadable
kernel modules.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/clk-alpha-pll.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9722b70..57f2084 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -228,6 +228,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
}
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
{
--
1.9.1
^ permalink raw reply related
* [PATCH v6 03/14] clk: qcom: Add CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below
+-------+
XO | |
+------------------>0 |
| |
PLL/2 | SMUX +----+
+------->1 | |
| | | |
| +-------+ | +-------+
| +---->0 |
| | |
+---------------+ | +----------->1 | CPU clk
|Primary PLL +----+ PLL_EARLY | | +------>
| +------+-----------+ +------>2 PMUX |
+---------------+ | | | |
| +------+ | +-->3 |
+--^+ ACD +-----+ | +-------+
+---------------+ +------+ |
|Alt PLL | |
| +---------------------------+
+---------------+ PLL_EARLY
The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.
The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.
So for frequencies above 600MHz we follow the following path
Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.
ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops. We do not add support for ACD as yet.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/clk-fixed-factor.c | 2 +-
drivers/clk/qcom/Kconfig | 9 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/clk-alpha-pll.h | 6 +
drivers/clk/qcom/clk-cpu-8996.c | 412 +++++++++++++++++++++++++++++++++++++++
5 files changed, 429 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a5d402d..8e39bda 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
init.num_parents = 1;
hw = &fix->hw;
- ret = clk_hw_register(dev, hw);
+ ret = devm_clk_hw_register(dev, hw);
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..866ce1f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,15 @@ config QCOM_CLK_APCS_MSM8916
Say Y if you want to support CPU frequency scaling on devices
such as msm8916.
+config QCOM_CLK_APCC_MSM8996
+ tristate "MSM8996 CPU Clock Controller"
+ depends on COMMON_CLK_QCOM
+ select QCOM_KRYO_L2_ACCESSORS
+ help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
+
config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 7c09ab1..a822fc8 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b48..9ce2a32 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -50,6 +50,12 @@ struct pll_vco {
u32 val;
};
+#define VCO(a, b, c) { \
+ .val = a,\
+ .min_freq = b,\
+ .max_freq = c,\
+}
+
/**
* struct clk_alpha_pll - phase locked loop (PLL)
* @offset: base address of registers
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index 0000000..beb97eb
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown below
+ *
+ * +-------+
+ * XO | |
+ * +------------------>0 |
+ * | |
+ * PLL/2 | SMUX +----+
+ * +------->1 | |
+ * | | | |
+ * | +-------+ | +-------+
+ * | +---->0 |
+ * | | |
+ * +---------------+ | +----------->1 | CPU clk
+ * |Primary PLL +----+ PLL_EARLY | | +------>
+ * | +------+-----------+ +------>2 PMUX |
+ * +---------------+ | | | |
+ * | +------+ | +-->3 |
+ * +--^+ ACD +-----+ | +-------+
+ * +---------------+ +------+ |
+ * |Alt PLL | |
+ * | +---------------------------+
+ * +---------------+ PLL_EARLY
+ *
+ * The primary PLL is what drives the CPU clk, except for times
+ * when we are reprogramming the PLL itself (for rate changes) when
+ * we temporarily switch to an alternate PLL. A subsequent patch adds
+ * support to switch between primary and alternate PLL during rate
+ * changes.
+ *
+ * The primary PLL operates on a single VCO range, between 600MHz
+ * and 3GHz. However the CPUs do support OPPs with frequencies
+ * between 300MHz and 600MHz. In order to support running the CPUs
+ * at those frequencies we end up having to lock the PLL at twice
+ * the rate and drive the CPU clk via the PLL/2 output and SMUX.
+ *
+ * So for frequencies above 600MHz we follow the following path
+ * Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
+ * and for frequencies between 300MHz and 600MHz we follow
+ * Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
+ * Support for this is added in a subsequent patch as well.
+ *
+ * ACD stands for Adaptive Clock Distribution and is used to
+ * detect voltage droops. We do not add support for ACD as yet.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-regmap.h"
+
+enum _pmux_input {
+ DIV_2_INDEX = 0,
+ PLL_INDEX,
+ ACD_INDEX,
+ ALT_INDEX,
+ NUM_OF_PMUX_INPUTS
+};
+
+static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
+ [PLL_OFF_L_VAL] = 0x04,
+ [PLL_OFF_ALPHA_VAL] = 0x08,
+ [PLL_OFF_USER_CTL] = 0x10,
+ [PLL_OFF_CONFIG_CTL] = 0x18,
+ [PLL_OFF_CONFIG_CTL_U] = 0x1c,
+ [PLL_OFF_TEST_CTL] = 0x20,
+ [PLL_OFF_TEST_CTL_U] = 0x24,
+ [PLL_OFF_STATUS] = 0x28,
+};
+
+static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
+ [PLL_OFF_L_VAL] = 0x04,
+ [PLL_OFF_ALPHA_VAL] = 0x08,
+ [PLL_OFF_ALPHA_VAL_U] = 0x0c,
+ [PLL_OFF_USER_CTL] = 0x10,
+ [PLL_OFF_USER_CTL_U] = 0x14,
+ [PLL_OFF_CONFIG_CTL] = 0x18,
+ [PLL_OFF_TEST_CTL] = 0x20,
+ [PLL_OFF_TEST_CTL_U] = 0x24,
+ [PLL_OFF_STATUS] = 0x28,
+};
+
+/* PLLs */
+
+static const struct alpha_pll_config hfpll_config = {
+ .l = 60,
+ .config_ctl_val = 0x200d4828,
+ .config_ctl_hi_val = 0x006,
+ .pre_div_mask = BIT(12),
+ .post_div_mask = 0x3 << 8,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_pll = {
+ .offset = 0x80000,
+ .regs = prim_pll_regs,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "perfcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_pll = {
+ .offset = 0x0,
+ .regs = prim_pll_regs,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pwrcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+};
+
+static const struct pll_vco alt_pll_vco_modes[] = {
+ VCO(3, 250000000, 500000000),
+ VCO(2, 500000000, 750000000),
+ VCO(1, 750000000, 1000000000),
+ VCO(0, 1000000000, 2150400000),
+};
+
+static const struct alpha_pll_config altpll_config = {
+ .l = 16,
+ .vco_val = 0x3 << 20,
+ .vco_mask = 0x3 << 20,
+ .config_ctl_val = 0x4001051b,
+ .post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_alt_pll = {
+ .offset = 0x80100,
+ .regs = alt_pll_regs,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_alt_pll = {
+ .offset = 0x100,
+ .regs = alt_pll_regs,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+/* Mux'es */
+
+struct clk_cpu_8996_mux {
+ u32 reg;
+ u8 shift;
+ u8 width;
+ struct clk_hw *pll;
+ struct clk_regmap clkr;
+};
+
+static inline
+struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
+{
+ return container_of(to_clk_regmap(hw), struct clk_cpu_8996_mux, clkr);
+}
+
+static u8 clk_cpu_8996_mux_get_parent(struct clk_hw *hw)
+{
+ u32 val;
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ u32 mask = (u32)GENMASK(cpuclk->width - 1, 0);
+
+ regmap_read(clkr->regmap, cpuclk->reg, &val);
+ val >>= (u32)(cpuclk->shift);
+
+ return (u8)(val & mask);
+}
+
+static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ u32 val;
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ unsigned int mask = GENMASK(cpuclk->width + cpuclk->shift - 1,
+ cpuclk->shift);
+
+ val = (u32)index;
+ val <<= (u32)(cpuclk->shift);
+
+ return regmap_update_bits(clkr->regmap, cpuclk->reg, mask, val);
+}
+
+static int
+clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ struct clk_hw *parent = cpuclk->pll;
+
+ req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
+ req->best_parent_hw = parent;
+
+ return 0;
+}
+
+const struct clk_ops clk_cpu_8996_mux_ops = {
+ .set_parent = clk_cpu_8996_mux_set_parent,
+ .get_parent = clk_cpu_8996_mux_get_parent,
+ .determine_rate = clk_cpu_8996_mux_determine_rate,
+};
+
+static struct clk_cpu_8996_mux pwrcl_smux = {
+ .reg = 0x40,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "pwrcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_smux = {
+ .reg = 0x80040,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "perfcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux pwrcl_pmux = {
+ .reg = 0x40,
+ .shift = 0,
+ .width = 2,
+ .pll = &pwrcl_pll.clkr.hw,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_pmux",
+ .parent_names = (const char *[]){
+ "pwrcl_smux",
+ "pwrcl_pll",
+ "pwrcl_pll_acd",
+ "pwrcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_pmux = {
+ .reg = 0x80040,
+ .shift = 0,
+ .width = 2,
+ .pll = &perfcl_pll.clkr.hw,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_pmux",
+ .parent_names = (const char *[]){
+ "perfcl_smux",
+ "perfcl_pll",
+ "perfcl_pll_acd",
+ "perfcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ },
+};
+
+static const struct regmap_config cpu_msm8996_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x80210,
+ .fast_io = true,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+struct clk_regmap *clks[] = {
+ &perfcl_pll.clkr,
+ &pwrcl_pll.clkr,
+ &perfcl_alt_pll.clkr,
+ &pwrcl_alt_pll.clkr,
+ &perfcl_smux.clkr,
+ &pwrcl_smux.clkr,
+ &perfcl_pmux.clkr,
+ &pwrcl_pmux.clkr,
+};
+
+static int
+qcom_cpu_clk_msm8996_register_clks(struct device *dev, struct regmap *regmap)
+{
+ int i, ret;
+
+ perfcl_smux.pll = clk_hw_register_fixed_factor(dev, "perfcl_pll_main",
+ "perfcl_pll",
+ CLK_SET_RATE_PARENT, 1, 2);
+
+ pwrcl_smux.pll = clk_hw_register_fixed_factor(dev, "pwrcl_pll_main",
+ "pwrcl_pll",
+ CLK_SET_RATE_PARENT, 1, 2);
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ ret = devm_clk_register_regmap(dev, clks[i]);
+ if (ret)
+ return ret;
+ }
+
+ clk_alpha_pll_configure(&perfcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&pwrcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
+ clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+
+ return ret;
+}
+
+static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
+{
+ int ret;
+ void __iomem *base;
+ struct resource *res;
+ struct regmap *regmap;
+ struct clk_hw_onecell_data *data;
+ struct device *dev = &pdev->dev;
+
+ data = devm_kzalloc(dev, sizeof(*data) + 2 * sizeof(struct clk_hw *),
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ regmap = devm_regmap_init_mmio(dev, base, &cpu_msm8996_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ret = qcom_cpu_clk_msm8996_register_clks(dev, regmap);
+ if (ret)
+ return ret;
+
+ data->hws[0] = &pwrcl_pmux.clkr.hw;
+ data->hws[1] = &perfcl_pmux.clkr.hw;
+ data->num = 2;
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
+}
+
+static const struct of_device_id qcom_cpu_clk_msm8996_match_table[] = {
+ { .compatible = "qcom,msm8996-apcc" },
+ {}
+};
+
+static struct platform_driver qcom_cpu_clk_msm8996_driver = {
+ .probe = qcom_cpu_clk_msm8996_driver_probe,
+ .driver = {
+ .name = "qcom-msm8996-apcc",
+ .of_match_table = qcom_cpu_clk_msm8996_match_table,
+ },
+};
+module_platform_driver(qcom_cpu_clk_msm8996_driver);
+
+MODULE_ALIAS("platform:msm8996-apcc");
+MODULE_DESCRIPTION("QCOM MSM8996 CPU Clock Driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* [PATCH v6 04/14] clk: qcom: Add DT bindings for CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below
+-------+
XO | |
+------------------>0 |
| |
PLL/2 | SMUX +----+
+------->1 | |
| | | |
| +-------+ | +-------+
| +---->0 |
| | |
+---------------+ | +----------->1 | CPU clk
|Primary PLL +----+ PLL_EARLY | | +------>
| +------+-----------+ +------>2 PMUX |
+---------------+ | | | |
| +------+ | +-->3 |
+--^+ ACD +-----+ | +-------+
+---------------+ +------+ |
|Alt PLL | |
| +---------------------------+
+---------------+ PLL_EARLY
The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.
The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/clock/qcom,kryocc.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index 0000000..8458783
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+----------------------------------------------------
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+ "qcom,msm8996-apcc"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+ kryocc: clock-controller at 6400000 {
+ compatible = "qcom,msm8996-apcc";
+ reg = <0x6400000 0x90000>;
+ #clock-cells = <1>;
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v6 05/14] clk: qcom: cpu-8996: Add support to switch to alternate PLL
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
From: Rajendra Nayak <rnayak@codeaurora.org>
Each of the CPU clusters on msm8996 are powered via a primary
PLL and a secondary PLL. The primary PLL is what drives the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/clk-cpu-8996.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index beb97eb..390b369 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -61,6 +61,7 @@
* detect voltage droops. We do not add support for ACD as yet.
*/
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -187,10 +188,14 @@ struct clk_cpu_8996_mux {
u32 reg;
u8 shift;
u8 width;
+ struct notifier_block nb;
struct clk_hw *pll;
struct clk_regmap clkr;
};
+#define to_clk_cpu_8996_mux_nb(_nb) \
+ container_of(_nb, struct clk_cpu_8996_mux, nb)
+
static inline
struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
{
@@ -236,6 +241,26 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
return 0;
}
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ int ret;
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+ break;
+ case POST_RATE_CHANGE:
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return notifier_from_errno(ret);
+};
const struct clk_ops clk_cpu_8996_mux_ops = {
.set_parent = clk_cpu_8996_mux_set_parent,
.get_parent = clk_cpu_8996_mux_get_parent,
@@ -279,6 +304,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
.parent_names = (const char *[]){
@@ -298,6 +324,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
.parent_names = (const char *[]){
@@ -356,6 +383,12 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+ ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
+ if (ret)
+ return ret;
+
+ ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
+
return ret;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v6 06/14] clk: qcom: cpu-8996: Add support to switch below 600Mhz
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
From: Rajendra Nayak <rnayak@codeaurora.org>
The CPU clock controller's primary PLL operates on a single VCO range,
between 600MHz and 3GHz. However the CPUs do support OPPs with
frequencies between 300MHz and 600MHz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.
So for frequencies above 600MHz we follow the following path
Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Conflicts:
drivers/clk/qcom/clk-cpu-8996.c
---
drivers/clk/qcom/clk-cpu-8996.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 390b369..3ea0446 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -77,6 +77,8 @@ enum _pmux_input {
NUM_OF_PMUX_INPUTS
};
+#define DIV_2_THRESHOLD 600000000
+
static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
[PLL_OFF_ALPHA_VAL] = 0x08,
@@ -104,10 +106,11 @@ enum _pmux_input {
static const struct alpha_pll_config hfpll_config = {
.l = 60,
- .config_ctl_val = 0x200d4828,
+ .config_ctl_val = 0x200d4aa8,
.config_ctl_hi_val = 0x006,
.pre_div_mask = BIT(12),
.post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
};
@@ -149,7 +152,7 @@ enum _pmux_input {
.vco_mask = 0x3 << 20,
.config_ctl_val = 0x4001051b,
.post_div_mask = 0x3 << 8,
- .post_div_val = 0x1,
+ .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
};
@@ -190,6 +193,7 @@ struct clk_cpu_8996_mux {
u8 width;
struct notifier_block nb;
struct clk_hw *pll;
+ struct clk_hw *pll_div_2;
struct clk_regmap clkr;
};
@@ -235,6 +239,13 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
struct clk_hw *parent = cpuclk->pll;
+ if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+ if (req->rate < (DIV_2_THRESHOLD / 2))
+ return -EINVAL;
+
+ parent = cpuclk->pll_div_2;
+ }
+
req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
req->best_parent_hw = parent;
@@ -246,13 +257,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
{
int ret;
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+ struct clk_notifier_data *cnd = data;
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
break;
case POST_RATE_CHANGE:
- ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+ if (cnd->new_rate < DIV_2_THRESHOLD)
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ DIV_2_INDEX);
+ else
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ PLL_INDEX);
break;
default:
ret = 0;
@@ -304,6 +321,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
+ .pll_div_2 = &pwrcl_smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
@@ -324,6 +342,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
+ .pll_div_2 = &perfcl_smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
--
1.9.1
^ permalink raw reply related
* [PATCH v6 07/14] clk: qcom: Add ACD path to CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
The PMUX for each duplex allows for selection of ACD clock source.
The DVM (Dynamic Variation Monitor) will flag an error
when a voltage droop event is detected. This flagged error
enables ACD to provide a div-by-2 clock, sourced from the primary PLL.
The duplex will be provided the divided clock
until a pre-programmed delay has expired.
This change configures ACD during the probe and switches
the PMUXes to the ACD clock source.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/clk-cpu-8996.c | 75 +++++++++++++++++++++++++++++++++++------
1 file changed, 65 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 3ea0446..396285c 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -62,9 +62,11 @@
*/
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <soc/qcom/kryo-l2-accessors.h>
#include "clk-alpha-pll.h"
#include "clk-regmap.h"
@@ -78,6 +80,11 @@ enum _pmux_input {
};
#define DIV_2_THRESHOLD 600000000
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x80000
+#define MUX_OFFSET 0x40
+#define ALT_PLL_OFFSET 0x100
+#define SSSCTL_OFFSET 0x160
static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
@@ -116,7 +123,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll perfcl_pll = {
- .offset = 0x80000,
+ .offset = PERFCL_REG_OFFSET,
.regs = prim_pll_regs,
.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
.clkr.hw.init = &(struct clk_init_data){
@@ -128,7 +135,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll pwrcl_pll = {
- .offset = 0x0,
+ .offset = PWRCL_REG_OFFSET,
.regs = prim_pll_regs,
.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
.clkr.hw.init = &(struct clk_init_data){
@@ -158,7 +165,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll perfcl_alt_pll = {
- .offset = 0x80100,
+ .offset = PERFCL_REG_OFFSET + ALT_PLL_OFFSET,
.regs = alt_pll_regs,
.vco_table = alt_pll_vco_modes,
.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
@@ -172,7 +179,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll pwrcl_alt_pll = {
- .offset = 0x100,
+ .offset = PWRCL_REG_OFFSET + ALT_PLL_OFFSET,
.regs = alt_pll_regs,
.vco_table = alt_pll_vco_modes,
.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
@@ -185,6 +192,9 @@ enum _pmux_input {
},
};
+void __iomem *base;
+static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base);
+
/* Mux'es */
struct clk_cpu_8996_mux {
@@ -262,6 +272,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+ qcom_cpu_clk_msm8996_acd_init(base);
break;
case POST_RATE_CHANGE:
if (cnd->new_rate < DIV_2_THRESHOLD)
@@ -269,7 +280,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
DIV_2_INDEX);
else
ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
- PLL_INDEX);
+ ACD_INDEX);
break;
default:
ret = 0;
@@ -285,7 +296,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux pwrcl_smux = {
- .reg = 0x40,
+ .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
.shift = 2,
.width = 2,
.clkr.hw.init = &(struct clk_init_data) {
@@ -301,7 +312,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux perfcl_smux = {
- .reg = 0x80040,
+ .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
.shift = 2,
.width = 2,
.clkr.hw.init = &(struct clk_init_data) {
@@ -317,7 +328,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux pwrcl_pmux = {
- .reg = 0x40,
+ .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
@@ -338,7 +349,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux perfcl_pmux = {
- .reg = 0x80040,
+ .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
@@ -402,6 +413,10 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+ /* Enable alt PLLs */
+ clk_prepare_enable(pwrcl_alt_pll.clkr.hw.clk);
+ clk_prepare_enable(perfcl_alt_pll.clkr.hw.clk);
+
ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
if (ret)
return ret;
@@ -411,10 +426,48 @@ struct clk_regmap *clks[] = {
return ret;
}
+#define CPU_AFINITY_MASK 0xFFF
+#define PWRCL_CPU_REG_MASK 0x3
+#define PERFCL_CPU_REG_MASK 0x103
+
+#define L2ACDCR_REG 0x580ULL
+#define L2ACDTD_REG 0x581ULL
+#define L2ACDDVMRC_REG 0x584ULL
+#define L2ACDSSCR_REG 0x589ULL
+
+static DEFINE_SPINLOCK(acd_lock);
+
+static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base)
+{
+ u64 hwid;
+ unsigned long flags;
+
+ spin_lock_irqsave(&acd_lock, flags);
+
+ hwid = read_cpuid_mpidr() & CPU_AFINITY_MASK;
+
+ kryo_l2_set_indirect_reg(L2ACDTD_REG, 0x00006A11);
+ kryo_l2_set_indirect_reg(L2ACDDVMRC_REG, 0x000E0F0F);
+ kryo_l2_set_indirect_reg(L2ACDSSCR_REG, 0x00000601);
+
+ if (PWRCL_CPU_REG_MASK == (hwid | PWRCL_CPU_REG_MASK)) {
+ writel(0xF, base + PWRCL_REG_OFFSET + SSSCTL_OFFSET);
+ wmb();
+ kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002C5FFD);
+ }
+
+ if (PERFCL_CPU_REG_MASK == (hwid | PERFCL_CPU_REG_MASK)) {
+ kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002C5FFD);
+ writel(0xF, base + PERFCL_REG_OFFSET + SSSCTL_OFFSET);
+ wmb();
+ }
+
+ spin_unlock_irqrestore(&acd_lock, flags);
+}
+
static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
{
int ret;
- void __iomem *base;
struct resource *res;
struct regmap *regmap;
struct clk_hw_onecell_data *data;
@@ -438,6 +491,8 @@ static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
if (ret)
return ret;
+ qcom_cpu_clk_msm8996_acd_init(base);
+
data->hws[0] = &pwrcl_pmux.clkr.hw;
data->hws[1] = &perfcl_pmux.clkr.hw;
data->num = 2;
--
1.9.1
^ permalink raw reply related
* [PATCH v6 08/14] dt: qcom: Add opp and thermal to the msm8996
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
arch/arm64/boot/dts/qcom/msm8996.dtsi | 269 ++++++++++++++++++++++++++++++++--
1 file changed, 260 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 37b7152c..e6cf290 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -14,6 +14,7 @@
#include <dt-bindings/clock/qcom,gcc-msm8996.h>
#include <dt-bindings/clock/qcom,mmcc-msm8996.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
model = "Qualcomm Technologies, Inc. MSM8996";
@@ -97,6 +98,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x0>;
enable-method = "psci";
+ clocks = <&kryocc 0>;
+ operating-points-v2 = <&cluster0_opp>;
+ #cooling-cells = <2>;
next-level-cache = <&L2_0>;
L2_0: l2-cache {
compatible = "cache";
@@ -109,6 +113,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x1>;
enable-method = "psci";
+ clocks = <&kryocc 0>;
+ operating-points-v2 = <&cluster0_opp>;
+ #cooling-cells = <2>;
next-level-cache = <&L2_0>;
};
@@ -117,6 +124,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x100>;
enable-method = "psci";
+ clocks = <&kryocc 1>;
+ operating-points-v2 = <&cluster1_opp>;
+ #cooling-cells = <2>;
next-level-cache = <&L2_1>;
L2_1: l2-cache {
compatible = "cache";
@@ -129,6 +139,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x101>;
enable-method = "psci";
+ clocks = <&kryocc 1>;
+ operating-points-v2 = <&cluster1_opp>;
+ #cooling-cells = <2>;
next-level-cache = <&L2_1>;
};
@@ -155,6 +168,182 @@
};
};
+ cluster0_opp: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-307200000 {
+ opp-hz = /bits/ 64 <307200000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-422400000 {
+ opp-hz = /bits/ 64 <422400000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-556800000 {
+ opp-hz = /bits/ 64 <556800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-729600000 {
+ opp-hz = /bits/ 64 <729600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-844800000 {
+ opp-hz = /bits/ 64 <844800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1036800000 {
+ opp-hz = /bits/ 64 <1036800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1190400000 {
+ opp-hz = /bits/ 64 <1190400000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1228800000 {
+ opp-hz = /bits/ 64 <1228800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1401600000 {
+ opp-hz = /bits/ 64 <1401600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1478400000 {
+ opp-hz = /bits/ 64 <1478400000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1593600000 {
+ opp-hz = /bits/ 64 <1593600000>;
+ clock-latency-ns = <200000>;
+ };
+ };
+
+ cluster1_opp: opp_table1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-307200000 {
+ opp-hz = /bits/ 64 <307200000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-403200000 {
+ opp-hz = /bits/ 64 <403200000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-556800000 {
+ opp-hz = /bits/ 64 <556800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-729600000 {
+ opp-hz = /bits/ 64 <729600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-806400000 {
+ opp-hz = /bits/ 64 <806400000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-883200000 {
+ opp-hz = /bits/ 64 <883200000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-940800000 {
+ opp-hz = /bits/ 64 <940800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1036800000 {
+ opp-hz = /bits/ 64 <1036800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1190400000 {
+ opp-hz = /bits/ 64 <1190400000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1248000000 {
+ opp-hz = /bits/ 64 <1248000000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1401600000 {
+ opp-hz = /bits/ 64 <1401600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1478400000 {
+ opp-hz = /bits/ 64 <1478400000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1555200000 {
+ opp-hz = /bits/ 64 <1555200000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1632000000 {
+ opp-hz = /bits/ 64 <1632000000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1708800000 {
+ opp-hz = /bits/ 64 <1708800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1785600000 {
+ opp-hz = /bits/ 64 <1785600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1824000000 {
+ opp-hz = /bits/ 64 <1824000000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1920000000 {
+ opp-hz = /bits/ 64 <1920000000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2073600000 {
+ opp-hz = /bits/ 64 <2073600000>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2150400000 {
+ opp-hz = /bits/ 64 <2150400000>;
+ clock-latency-ns = <200000>;
+ };
+ };
+
thermal-zones {
cpu-thermal0 {
polling-delay-passive = <250>;
@@ -163,18 +352,34 @@
thermal-sensors = <&tsens0 3>;
trips {
- cpu_alert0: trip0 {
+ cpu_alert0: cpu_alert0 {
temperature = <75000>;
hysteresis = <2000>;
+ type = "active";
+ };
+ cpu_warn0: cpu_warn0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
type = "passive";
};
- cpu_crit0: trip1 {
+ cpu_crit0: cpu_crit0 {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT 7>;
+ };
+ map1 {
+ trip = <&cpu_warn0>;
+ cooling-device = <&CPU0 8 THERMAL_NO_LIMIT>;
+ };
+ };
};
cpu-thermal1 {
@@ -184,18 +389,34 @@
thermal-sensors = <&tsens0 5>;
trips {
- cpu_alert1: trip0 {
+ cpu_alert1: cpu_alert1 {
temperature = <75000>;
hysteresis = <2000>;
+ type = "active";
+ };
+ cpu_warn1: cpu_warn1 {
+ temperature = <90000>;
+ hysteresis = <2000>;
type = "passive";
};
- cpu_crit1: trip1 {
+ cpu_crit1: cpu_crit1 {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert1>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT 7>;
+ };
+ map1 {
+ trip = <&cpu_warn1>;
+ cooling-device = <&CPU0 8 THERMAL_NO_LIMIT>;
+ };
+ };
};
cpu-thermal2 {
@@ -205,18 +426,33 @@
thermal-sensors = <&tsens0 8>;
trips {
- cpu_alert2: trip0 {
+ cpu_alert2: cpu_alert2 {
temperature = <75000>;
hysteresis = <2000>;
+ type = "active";
+ };
+ cpu_warn2: cpu_warn2 {
+ temperature = <90000>;
+ hysteresis = <2000>;
type = "passive";
};
- cpu_crit2: trip1 {
+ cpu_crit2: cpu_crit2 {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
};
};
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert2>;
+ cooling-device = <&CPU2 THERMAL_NO_LIMIT 7>;
+ };
+ map1 {
+ trip = <&cpu_warn2>;
+ cooling-device = <&CPU2 8 THERMAL_NO_LIMIT>;
+ };
+ };
};
cpu-thermal3 {
@@ -226,9 +462,14 @@
thermal-sensors = <&tsens0 10>;
trips {
- cpu_alert3: trip0 {
+ cpu_alert3: cpu_alert3 {
temperature = <75000>;
hysteresis = <2000>;
+ type = "active";
+ };
+ cpu_warn3: cpu_warn3 {
+ temperature = <90000>;
+ hysteresis = <2000>;
type = "passive";
};
@@ -238,6 +479,16 @@
type = "critical";
};
};
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert3>;
+ cooling-device = <&CPU2 THERMAL_NO_LIMIT 7>;
+ };
+ map1 {
+ trip = <&cpu_warn3>;
+ cooling-device = <&CPU2 8 THERMAL_NO_LIMIT>;
+ };
+ };
};
};
@@ -414,7 +665,7 @@
};
kryocc: clock-controller at 6400000 {
- compatible = "qcom,apcc-msm8996";
+ compatible = "qcom,msm8996-apcc";
reg = <0x6400000 0x90000>;
#clock-cells = <1>;
};
@@ -1001,7 +1252,7 @@
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pcie2_clkreq_default &pcie2_perst_default &pcie2_wake_default>;
- pinctrl-1 = <&pcie2_clkreq_sleep &pcie2_perst_default &pcie2_wake_sleep >;
+ pinctrl-1 = <&pcie2_clkreq_sleep &pcie2_perst_default &pcie2_wake_sleep>;
vdda-supply = <&pm8994_l28>;
--
1.9.1
^ permalink raw reply related
* [PATCH v6 09/14] regulator: qcom_spmi: Add support for SAW
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
Add support for SAW controlled regulators.
The regulators defined as SAW controlled in the device tree
will be controlled through special CPU registers instead of direct
SPMI accesses.
This is required especially for CPU supply regulators to synchronize
with clock scaling and for Automatic Voltage Switching.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/regulator/qcom_spmi-regulator.c | 133 +++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 3 deletions(-)
diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c
index 63c7a0c..9817f1a 100644
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -25,6 +25,8 @@
#include <linux/regulator/driver.h>
#include <linux/regmap.h>
#include <linux/list.h>
+#include <linux/mfd/syscon.h>
+#include <linux/io.h>
/* Pin control enable input pins. */
#define SPMI_REGULATOR_PIN_CTRL_ENABLE_NONE 0x00
@@ -181,6 +183,23 @@ enum spmi_boost_byp_registers {
SPMI_BOOST_BYP_REG_CURRENT_LIMIT = 0x4b,
};
+enum spmi_saw3_registers {
+ SAW3_SECURE = 0x00,
+ SAW3_ID = 0x04,
+ SAW3_SPM_STS = 0x0C,
+ SAW3_AVS_STS = 0x10,
+ SAW3_PMIC_STS = 0x14,
+ SAW3_RST = 0x18,
+ SAW3_VCTL = 0x1C,
+ SAW3_AVS_CTL = 0x20,
+ SAW3_AVS_LIMIT = 0x24,
+ SAW3_AVS_DLY = 0x28,
+ SAW3_AVS_HYSTERESIS = 0x2C,
+ SAW3_SPM_STS2 = 0x38,
+ SAW3_SPM_PMIC_DATA_3 = 0x4C,
+ SAW3_VERSION = 0xFD0,
+};
+
/* Used for indexing into ctrl_reg. These are offets from 0x40 */
enum spmi_common_control_register_index {
SPMI_COMMON_IDX_VOLTAGE_RANGE = 0,
@@ -1035,6 +1054,89 @@ static irqreturn_t spmi_regulator_vs_ocp_isr(int irq, void *data)
return IRQ_HANDLED;
}
+#define SAW3_VCTL_DATA_MASK 0xFF
+#define SAW3_VCTL_CLEAR_MASK 0x700FF
+#define SAW3_AVS_CTL_EN_MASK 0x1
+#define SAW3_AVS_CTL_TGGL_MASK 0x8000000
+#define SAW3_AVS_CTL_CLEAR_MASK 0x7efc00
+
+static struct regmap *saw_regmap = NULL;
+
+static void spmi_saw_set_vdd(void *data)
+{
+ u32 vctl, data3, avs_ctl, pmic_sts;
+ bool avs_enabled = false;
+ unsigned long timeout;
+ u8 voltage_sel = *(u8 *)data;
+
+ regmap_read(saw_regmap, SAW3_AVS_CTL, &avs_ctl);
+ regmap_read(saw_regmap, SAW3_VCTL, &vctl);
+ regmap_read(saw_regmap, SAW3_SPM_PMIC_DATA_3, &data3);
+
+ /* select the band */
+ vctl &= ~SAW3_VCTL_CLEAR_MASK;
+ vctl |= (u32)voltage_sel;
+
+ data3 &= ~SAW3_VCTL_CLEAR_MASK;
+ data3 |= (u32)voltage_sel;
+
+ /* If AVS is enabled, switch it off during the voltage change */
+ avs_enabled = SAW3_AVS_CTL_EN_MASK & avs_ctl;
+ if (avs_enabled) {
+ avs_ctl &= ~SAW3_AVS_CTL_TGGL_MASK;
+ regmap_write(saw_regmap, SAW3_AVS_CTL, avs_ctl);
+ }
+
+ regmap_write(saw_regmap, SAW3_RST, 1);
+ regmap_write(saw_regmap, SAW3_VCTL, vctl);
+ regmap_write(saw_regmap, SAW3_SPM_PMIC_DATA_3, data3);
+
+ timeout = jiffies + usecs_to_jiffies(100);
+ do {
+ regmap_read(saw_regmap, SAW3_PMIC_STS, &pmic_sts);
+ pmic_sts &= SAW3_VCTL_DATA_MASK;
+ if (pmic_sts == (u32)voltage_sel)
+ break;
+
+ cpu_relax();
+
+ } while (time_before(jiffies, timeout));
+
+ /* After successful voltage change, switch the AVS back on */
+ if (avs_enabled) {
+ pmic_sts &= 0x3f;
+ avs_ctl &= ~SAW3_AVS_CTL_CLEAR_MASK;
+ avs_ctl |= ((pmic_sts - 4) << 10);
+ avs_ctl |= (pmic_sts << 17);
+ avs_ctl |= SAW3_AVS_CTL_TGGL_MASK;
+ regmap_write(saw_regmap, SAW3_AVS_CTL, avs_ctl);
+ }
+}
+
+static int
+spmi_regulator_saw_set_voltage(struct regulator_dev *rdev, unsigned selector)
+{
+ struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
+ int ret;
+ u8 range_sel, voltage_sel;
+
+ ret = spmi_sw_selector_to_hw(vreg, selector, &range_sel, &voltage_sel);
+ if (ret)
+ return ret;
+
+ if (0 != range_sel) {
+ dev_dbg(&rdev->dev, "range_sel = %02X voltage_sel = %02X", \
+ range_sel, voltage_sel);
+ return -EINVAL;
+ }
+
+ /* Always do the SAW register writes on the first CPU */
+ return smp_call_function_single(0, spmi_saw_set_vdd, \
+ &voltage_sel, true);
+}
+
+static struct regulator_ops spmi_saw_ops = {};
+
static struct regulator_ops spmi_smps_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -1250,6 +1352,7 @@ static int spmi_regulator_match(struct spmi_regulator *vreg, u16 force_type)
}
dig_major_rev = version[SPMI_COMMON_REG_DIG_MAJOR_REV
- SPMI_COMMON_REG_DIG_MAJOR_REV];
+
if (!force_type) {
type = version[SPMI_COMMON_REG_TYPE -
SPMI_COMMON_REG_DIG_MAJOR_REV];
@@ -1648,7 +1751,9 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
struct regmap *regmap;
const char *name;
struct device *dev = &pdev->dev;
- int ret;
+ struct device_node *node = pdev->dev.of_node;
+ struct device_node *syscon;
+ int ret, lenp;
struct list_head *vreg_list;
vreg_list = devm_kzalloc(dev, sizeof(*vreg_list), GFP_KERNEL);
@@ -1665,7 +1770,22 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
if (!match)
return -ENODEV;
+ if (of_find_property(node, "qcom,saw-reg", &lenp)) {
+ syscon = of_parse_phandle(node, "qcom,saw-reg", 0);
+ saw_regmap = syscon_node_to_regmap(syscon);
+ of_node_put(syscon);
+ if (IS_ERR(regmap))
+ dev_err(dev, "ERROR reading SAW regmap\n");
+ }
+
for (reg = match->data; reg->name; reg++) {
+
+ if (saw_regmap && \
+ of_find_property(of_find_node_by_name(node, reg->name), \
+ "qcom,saw-slave", &lenp)) {
+ continue;
+ }
+
vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
if (!vreg)
return -ENOMEM;
@@ -1673,7 +1793,6 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
vreg->dev = dev;
vreg->base = reg->base;
vreg->regmap = regmap;
-
if (reg->ocp) {
vreg->ocp_irq = platform_get_irq_byname(pdev, reg->ocp);
if (vreg->ocp_irq < 0) {
@@ -1681,7 +1800,6 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
goto err;
}
}
-
vreg->desc.id = -1;
vreg->desc.owner = THIS_MODULE;
vreg->desc.type = REGULATOR_VOLTAGE;
@@ -1698,6 +1816,15 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
if (ret)
continue;
+ if (saw_regmap && \
+ of_find_property(of_find_node_by_name(node, reg->name), \
+ "qcom,saw-leader", &lenp)) {
+ spmi_saw_ops = *(vreg->desc.ops);
+ spmi_saw_ops.set_voltage_sel = \
+ spmi_regulator_saw_set_voltage;
+ vreg->desc.ops = &spmi_saw_ops;
+ }
+
config.dev = dev;
config.driver_data = vreg;
config.regmap = regmap;
--
1.9.1
^ permalink raw reply related
* [PATCH v6 10/14] dt-bindings: qcom_spmi: Add support for SAW documentation
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
Add support for SAW controlled regulators.
The regulators defined as SAW controlled in the device tree
will be controlled through special CPU registers instead of direct
SPMI accesses.
This is required especially for CPU supply regulators to synchronize
with clock scaling and for Automatic Voltage Switching.
Document it.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../bindings/regulator/qcom,spmi-regulator.txt | 45 ++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt
index 57d2c65..406f2e5 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt
@@ -110,6 +110,11 @@ Qualcomm SPMI Regulators
Definition: Reference to regulator supplying the input pin, as
described in the data sheet.
+- qcom,saw-reg:
+ Usage: optional
+ Value type: <phandle>
+ Description: Reference to syscon node defining the SAW registers.
+
The regulator node houses sub-nodes for each regulator within the device. Each
sub-node is identified using the node's name, with valid values listed for each
@@ -201,6 +206,17 @@ see regulator.txt - with additional custom properties described below:
2 = 0.55 uA
3 = 0.75 uA
+- qcom,saw-slave:
+ Usage: optional
+ Value type: <boo>
+ Description: SAW controlled gang slave. Will not be configured.
+
+- qcom,saw-leader:
+ Usage: optional
+ Value type: <boo>
+ Description: SAW controlled gang leader. Will be configured as
+ SAW regulator.
+
Example:
regulators {
@@ -221,3 +237,32 @@ Example:
....
};
+
+Example 2:
+
+ saw3: syscon at 9A10000 {
+ compatible = "syscon";
+ reg = <0x9A10000 0x1000>;
+ };
+
+ ...
+
+ spm-regulators {
+ compatible = "qcom,pm8994-regulators";
+ qcom,saw-reg = <&saw3>;
+ s8 {
+ qcom,saw-slave;
+ };
+ s9 {
+ qcom,saw-slave;
+ };
+ s10 {
+ qcom,saw-slave;
+ };
+ pm8994_s11_saw: s11 {
+ qcom,saw-leader;
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1140000>;
+ };
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v6 11/14] dt: qcom: Add SAW regulator for 8x96 CPUs
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
1. Add syscon node for the SAW CPU registers
2. Add SAW regulators gang definition for s8-s11
3. Add voltages to the OPP tables
4. Add the s11 SAW regulator as CPU regulator
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
arch/arm64/boot/dts/qcom/msm8996.dtsi | 75 +++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index e6cf290..d7adef9 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -15,6 +15,7 @@
#include <dt-bindings/clock/qcom,mmcc-msm8996.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/spmi/spmi.h>
/ {
model = "Qualcomm Technologies, Inc. MSM8996";
@@ -99,6 +100,7 @@
reg = <0x0 0x0>;
enable-method = "psci";
clocks = <&kryocc 0>;
+ cpu-supply = <&pm8994_s11_saw>;
operating-points-v2 = <&cluster0_opp>;
#cooling-cells = <2>;
next-level-cache = <&L2_0>;
@@ -114,6 +116,7 @@
reg = <0x0 0x1>;
enable-method = "psci";
clocks = <&kryocc 0>;
+ cpu-supply = <&pm8994_s11_saw>;
operating-points-v2 = <&cluster0_opp>;
#cooling-cells = <2>;
next-level-cache = <&L2_0>;
@@ -125,6 +128,7 @@
reg = <0x0 0x100>;
enable-method = "psci";
clocks = <&kryocc 1>;
+ cpu-supply = <&pm8994_s11_saw>;
operating-points-v2 = <&cluster1_opp>;
#cooling-cells = <2>;
next-level-cache = <&L2_1>;
@@ -140,6 +144,7 @@
reg = <0x0 0x101>;
enable-method = "psci";
clocks = <&kryocc 1>;
+ cpu-supply = <&pm8994_s11_saw>;
operating-points-v2 = <&cluster1_opp>;
#cooling-cells = <2>;
next-level-cache = <&L2_1>;
@@ -174,66 +179,82 @@
opp-307200000 {
opp-hz = /bits/ 64 <307200000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-422400000 {
opp-hz = /bits/ 64 <422400000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-480000000 {
opp-hz = /bits/ 64 <480000000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-556800000 {
opp-hz = /bits/ 64 <556800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-652800000 {
opp-hz = /bits/ 64 <652800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-729600000 {
opp-hz = /bits/ 64 <729600000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-844800000 {
opp-hz = /bits/ 64 <844800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-960000000 {
opp-hz = /bits/ 64 <960000000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1036800000 {
opp-hz = /bits/ 64 <1036800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1113600000 {
opp-hz = /bits/ 64 <1113600000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1190400000 {
opp-hz = /bits/ 64 <1190400000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1228800000 {
opp-hz = /bits/ 64 <1228800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1324800000 {
opp-hz = /bits/ 64 <1324800000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1401600000 {
opp-hz = /bits/ 64 <1401600000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1478400000 {
opp-hz = /bits/ 64 <1478400000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1593600000 {
opp-hz = /bits/ 64 <1593600000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
};
@@ -244,102 +265,127 @@
opp-307200000 {
opp-hz = /bits/ 64 <307200000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-403200000 {
opp-hz = /bits/ 64 <403200000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-480000000 {
opp-hz = /bits/ 64 <480000000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-556800000 {
opp-hz = /bits/ 64 <556800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-652800000 {
opp-hz = /bits/ 64 <652800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-729600000 {
opp-hz = /bits/ 64 <729600000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-806400000 {
opp-hz = /bits/ 64 <806400000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-883200000 {
opp-hz = /bits/ 64 <883200000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-940800000 {
opp-hz = /bits/ 64 <940800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1036800000 {
opp-hz = /bits/ 64 <1036800000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1113600000 {
opp-hz = /bits/ 64 <1113600000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1190400000 {
opp-hz = /bits/ 64 <1190400000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1248000000 {
opp-hz = /bits/ 64 <1248000000>;
+ opp-microvolt = <905000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1324800000 {
opp-hz = /bits/ 64 <1324800000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1401600000 {
opp-hz = /bits/ 64 <1401600000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1478400000 {
opp-hz = /bits/ 64 <1478400000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1555200000 {
opp-hz = /bits/ 64 <1555200000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1632000000 {
opp-hz = /bits/ 64 <1632000000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1708800000 {
opp-hz = /bits/ 64 <1708800000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1785600000 {
opp-hz = /bits/ 64 <1785600000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1824000000 {
opp-hz = /bits/ 64 <1824000000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1920000000 {
opp-hz = /bits/ 64 <1920000000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-1996800000 {
opp-hz = /bits/ 64 <1996800000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-2073600000 {
opp-hz = /bits/ 64 <2073600000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
opp-2150400000 {
opp-hz = /bits/ 64 <2150400000>;
+ opp-microvolt = <1140000 905000 1140000>;
clock-latency-ns = <200000>;
};
};
@@ -656,6 +702,10 @@
#mbox-cells = <1>;
};
+ saw3: syscon at 9A10000 {
+ compatible = "syscon";
+ reg = <0x9A10000 0x1000>;
+ };
gcc: clock-controller at 300000 {
compatible = "qcom,gcc-msm8996";
#clock-cells = <1>;
@@ -882,6 +932,31 @@
#size-cells = <0>;
interrupt-controller;
#interrupt-cells = <4>;
+ pmic at 1 {
+ compatible = "qcom,pm8994", "qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spm-regulators {
+ compatible = "qcom,pm8994-regulators";
+ qcom,saw-reg = <&saw3>;
+ s8 {
+ qcom,saw-slave;
+ };
+ s9 {
+ qcom,saw-slave;
+ };
+ s10 {
+ qcom,saw-slave;
+ };
+ pm8994_s11_saw: s11 {
+ qcom,saw-leader;
+ regulator-always-on;
+ regulator-min-microvolt = <905000>;
+ regulator-max-microvolt = <1140000>;
+ };
+ };
+ };
};
mmcc: clock-controller at 8c0000 {
--
1.9.1
^ permalink raw reply related
* [PATCH v6 12/14] cpufreq: Add Kryo CPU scaling driver
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
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 | 148 +++++++++++++++++++++++++++++++++++
4 files changed, 163 insertions(+)
create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de55c7d..5c16f05 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
+ bool "Qualcomm Technologies, Inc. Kryo based CPUFreq"
+ 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..04bd0fa
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem.h>
+
+#define MSM_ID_SMEM 137
+#define SILVER_LEAD 0
+#define GOLD_LEAD 2
+
+enum _msm_id {
+ MSM8996V3 = 0xF6ul,
+ APQ8096V3 = 0x123ul,
+ MSM8996SG = 0x131ul,
+ APQ8096SG = 0x138ul,
+};
+
+enum _msm8996_version {
+ MSM8996_V3,
+ MSM8996_SG,
+ NUM_OF_MSM8996_VERSIONS,
+};
+
+static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
+{
+ size_t len;
+ u32 *msm_id;
+ enum _msm8996_version version;
+
+ msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len);
+ /* The first 4 bytes are format, next to them is the actual msm-id */
+ msm_id++;
+
+ switch ((enum _msm_id)*msm_id) {
+ case MSM8996V3:
+ case APQ8096V3:
+ version = MSM8996_V3;
+ break;
+ case MSM8996SG:
+ case APQ8096SG:
+ version = MSM8996_SG;
+ break;
+ default:
+ version = NUM_OF_MSM8996_VERSIONS;
+ }
+
+ return version;
+}
+
+static int __init qcom_cpufreq_kryo_driver_init(void)
+{
+ size_t len;
+ int ret;
+ u32 versions;
+ enum _msm8996_version msm8996_version;
+ u8 *speedbin;
+ struct device *cpu_dev;
+ struct device_node *np;
+ struct nvmem_cell *speedbin_nvmem;
+ struct opp_table *opp_temp = NULL;
+
+ cpu_dev = get_cpu_device(SILVER_LEAD);
+ if (IS_ERR_OR_NULL(cpu_dev))
+ return PTR_ERR(cpu_dev);
+
+ msm8996_version = qcom_cpufreq_kryo_get_msm_id();
+ if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
+ dev_err(cpu_dev, "Not Snapdragon 820/821!");
+ return -ENODEV;
+ }
+
+ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+ if (IS_ERR_OR_NULL(np))
+ return PTR_ERR(np);
+
+ if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
+ ret = -ENOENT;
+ goto free_np;
+ }
+
+ speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+ if (IS_ERR(speedbin_nvmem)) {
+ ret = PTR_ERR(speedbin_nvmem);
+ dev_err(cpu_dev, "Could not get nvmem cell: %d\n", ret);
+ goto free_np;
+ }
+
+ speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+
+ switch (msm8996_version) {
+ case MSM8996_V3:
+ versions = 1 << (unsigned int)(*speedbin);
+ break;
+ case MSM8996_SG:
+ versions = 1 << ((unsigned int)(*speedbin) + 4);
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ ret = PTR_ERR_OR_ZERO(opp_temp = \
+ dev_pm_opp_set_supported_hw(cpu_dev,&versions,1));
+ if (0 > ret)
+ goto free_np;
+
+ dev_pm_opp_put_supported_hw(opp_temp);
+
+ cpu_dev = get_cpu_device(GOLD_LEAD);
+ ret = PTR_ERR_OR_ZERO(opp_temp = \
+ dev_pm_opp_set_supported_hw(cpu_dev,&versions,1));
+ if (0 > ret)
+ goto free_np;
+
+ ret = PTR_ERR_OR_ZERO(platform_device_register_simple("cpufreq-dt", \
+ -1, NULL, 0));
+
+ dev_pm_opp_put_supported_hw(opp_temp);
+
+free_np:
+ of_node_put(np);
+
+ return ret;
+}
+late_initcall(qcom_cpufreq_kryo_driver_init);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* [PATCH v6 13/14] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu
From: Ilia Lin @ 2018-05-14 13:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
In Certain Qualcomm Technologies, Inc. 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 Technologies, Inc. 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.
This change adds documentation.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
.../devicetree/bindings/opp/kryo-cpufreq.txt | 680 +++++++++++++++++++++
1 file changed, 680 insertions(+)
create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
diff --git a/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
new file mode 100644
index 0000000..c2127b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
@@ -0,0 +1,680 @@
+Qualcomm Technologies, Inc. KRYO CPUFreq and OPP bindings
+===================================
+
+In Certain Qualcomm Technologies, Inc. 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 Technologies, Inc. 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 (existing HW bitmap).
+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.
+
+Required properties:
+--------------------
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+ - 'operating-points-v2-kryo-cpu' for apq8096 and msm8996.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+ efuse registers that has information about the
+ speedbin that is used to select the right frequency/voltage
+ value pair.
+ Please refer the for nvmem-cells
+ bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
+ and also examples below.
+
+In every OPP node:
+- opp-supported-hw: A single 32 bit bitmap value, representing compatible HW.
+ Bitmap:
+ 0: MSM8996 V3, speedbin 0
+ 1: MSM8996 V3, speedbin 1
+ 2: MSM8996 V3, speedbin 2
+ 3: unused
+ 4: MSM8996 SG, speedbin 0
+ 5: MSM8996 SG, speedbin 1
+ 6: MSM8996 SG, speedbin 2
+ 7-31: unused
+
+Example 1:
+---------
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ CPU0: cpu at 0 {
+ device_type = "cpu";
+ compatible = "qcom,kryo";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ clocks = <&kryocc 0>;
+ cpu-supply = <&pm8994_s11_saw>;
+ operating-points-v2 = <&cluster0_opp>;
+ #cooling-cells = <2>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+
+ CPU1: cpu at 1 {
+ device_type = "cpu";
+ compatible = "qcom,kryo";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ clocks = <&kryocc 0>;
+ cpu-supply = <&pm8994_s11_saw>;
+ operating-points-v2 = <&cluster0_opp>;
+ #cooling-cells = <2>;
+ next-level-cache = <&L2_0>;
+ };
+
+ CPU2: cpu at 100 {
+ device_type = "cpu";
+ compatible = "qcom,kryo";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ clocks = <&kryocc 1>;
+ cpu-supply = <&pm8994_s11_saw>;
+ operating-points-v2 = <&cluster1_opp>;
+ #cooling-cells = <2>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+
+ CPU3: cpu at 101 {
+ device_type = "cpu";
+ compatible = "qcom,kryo";
+ reg = <0x0 0x101>;
+ enable-method = "psci";
+ clocks = <&kryocc 1>;
+ cpu-supply = <&pm8994_s11_saw>;
+ operating-points-v2 = <&cluster1_opp>;
+ #cooling-cells = <2>;
+ next-level-cache = <&L2_1>;
+ };
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+
+ core1 {
+ cpu = <&CPU1>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&CPU2>;
+ };
+
+ core1 {
+ cpu = <&CPU3>;
+ };
+ };
+ };
+ };
+
+ cluster0_opp: opp_table0 {
+ compatible = "operating-points-v2-kryo-cpu";
+ nvmem-cells = <&speedbin_efuse>;
+ opp-shared;
+
+ opp-307200000 {
+ opp-hz = /bits/ 64 <307200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-422400000 {
+ opp-hz = /bits/ 64 <422400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-460800000 {
+ opp-hz = /bits/ 64 <460800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-537600000 {
+ opp-hz = /bits/ 64 <537600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-556800000 {
+ opp-hz = /bits/ 64 <556800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-614400000 {
+ opp-hz = /bits/ 64 <614400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-729600000 {
+ opp-hz = /bits/ 64 <729600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-768000000 {
+ opp-hz = /bits/ 64 <768000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-844800000 {
+ opp-hz = /bits/ 64 <844800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1036800000 {
+ opp-hz = /bits/ 64 <1036800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1132800000 {
+ opp-hz = /bits/ 64 <1132800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1190400000 {
+ opp-hz = /bits/ 64 <1190400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1209600000 {
+ opp-hz = /bits/ 64 <1209600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1228800000 {
+ opp-hz = /bits/ 64 <1228800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1286400000 {
+ opp-hz = /bits/ 64 <1286400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x5>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1363200000 {
+ opp-hz = /bits/ 64 <1363200000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x72>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1401600000 {
+ opp-hz = /bits/ 64 <1401600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x5>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1440000000 {
+ opp-hz = /bits/ 64 <1440000000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1478400000 {
+ opp-hz = /bits/ 64 <1478400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1497600000 {
+ opp-hz = /bits/ 64 <1497600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x4>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1593600000 {
+ opp-hz = /bits/ 64 <1593600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x71>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x20>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2188800000 {
+ opp-hz = /bits/ 64 <2188800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x10>;
+ clock-latency-ns = <200000>;
+ };
+ };
+
+ cluster1_opp: opp_table1 {
+ compatible = "operating-points-v2-kryo-cpu";
+ nvmem-cells = <&speedbin_efuse>;
+ opp-shared;
+
+ opp-307200000 {
+ opp-hz = /bits/ 64 <307200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-403200000 {
+ opp-hz = /bits/ 64 <403200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-460800000 {
+ opp-hz = /bits/ 64 <460800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-537600000 {
+ opp-hz = /bits/ 64 <537600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-556800000 {
+ opp-hz = /bits/ 64 <556800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-614400000 {
+ opp-hz = /bits/ 64 <614400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-729600000 {
+ opp-hz = /bits/ 64 <729600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-748800000 {
+ opp-hz = /bits/ 64 <748800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-806400000 {
+ opp-hz = /bits/ 64 <806400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-825600000 {
+ opp-hz = /bits/ 64 <825600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-883200000 {
+ opp-hz = /bits/ 64 <883200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-940800000 {
+ opp-hz = /bits/ 64 <940800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1036800000 {
+ opp-hz = /bits/ 64 <1036800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1132800000 {
+ opp-hz = /bits/ 64 <1132800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1190400000 {
+ opp-hz = /bits/ 64 <1190400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1209600000 {
+ opp-hz = /bits/ 64 <1209600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1248000000 {
+ opp-hz = /bits/ 64 <1248000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1286400000 {
+ opp-hz = /bits/ 64 <1286400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1363200000 {
+ opp-hz = /bits/ 64 <1363200000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1401600000 {
+ opp-hz = /bits/ 64 <1401600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1440000000 {
+ opp-hz = /bits/ 64 <1440000000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1478400000 {
+ opp-hz = /bits/ 64 <1478400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1555200000 {
+ opp-hz = /bits/ 64 <1555200000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1593600000 {
+ opp-hz = /bits/ 64 <1593600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1632000000 {
+ opp-hz = /bits/ 64 <1632000000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1670400000 {
+ opp-hz = /bits/ 64 <1670400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1708800000 {
+ opp-hz = /bits/ 64 <1708800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1747200000 {
+ opp-hz = /bits/ 64 <1747200000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1785600000 {
+ opp-hz = /bits/ 64 <1785600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1804800000 {
+ opp-hz = /bits/ 64 <1804800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x6>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1824000000 {
+ opp-hz = /bits/ 64 <1824000000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x71>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1900800000 {
+ opp-hz = /bits/ 64 <1900800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x74>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1920000000 {
+ opp-hz = /bits/ 64 <1920000000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1977600000 {
+ opp-hz = /bits/ 64 <1977600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x30>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2054400000 {
+ opp-hz = /bits/ 64 <2054400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x30>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2073600000 {
+ opp-hz = /bits/ 64 <2073600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2150400000 {
+ opp-hz = /bits/ 64 <2150400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x31>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2246400000 {
+ opp-hz = /bits/ 64 <2246400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x10>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2342400000 {
+ opp-hz = /bits/ 64 <2342400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x10>;
+ clock-latency-ns = <200000>;
+ };
+ };
+
+....
+
+reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+....
+ smem_mem: smem-mem at 86000000 {
+ reg = <0x0 0x86000000 0x0 0x200000>;
+ no-map;
+ };
+....
+};
+
+smem {
+ compatible = "qcom,smem";
+ memory-region = <&smem_mem>;
+ hwlocks = <&tcsr_mutex 3>;
+};
+
+soc {
+....
+ qfprom: qfprom at 74000 {
+ compatible = "qcom,qfprom";
+ reg = <0x00074000 0x8ff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ....
+ speedbin_efuse: speedbin at 133 {
+ reg = <0x133 0x1>;
+ bits = <5 3>;
+ };
+ };
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v6 14/14] dt: qcom: Add qcom-cpufreq-kryo driver configuration
From: Ilia Lin @ 2018-05-14 13:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526303520-5843-1-git-send-email-ilialin@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
arch/arm64/boot/dts/qcom/apq8096-db820c.dts | 2 +-
arch/arm64/boot/dts/qcom/msm8996.dtsi | 310 +++++++++++++++++++++++++++-
2 files changed, 309 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
index 230e9c8..da23bda 100644
--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
@@ -17,5 +17,5 @@
/ {
model = "Qualcomm Technologies, Inc. DB820c";
- compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc";
+ compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc", "qcom,apq8096";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index d7adef9..fbf92f6 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -174,218 +174,519 @@
};
cluster0_opp: opp_table0 {
- compatible = "operating-points-v2";
+ compatible = "operating-points-v2-kryo-cpu";
+ nvmem-cells = <&speedbin_efuse>;
opp-shared;
opp-307200000 {
opp-hz = /bits/ 64 <307200000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-422400000 {
opp-hz = /bits/ 64 <422400000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-460800000 {
+ opp-hz = /bits/ 64 <460800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-480000000 {
opp-hz = /bits/ 64 <480000000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-537600000 {
+ opp-hz = /bits/ 64 <537600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-556800000 {
opp-hz = /bits/ 64 <556800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-614400000 {
+ opp-hz = /bits/ 64 <614400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-652800000 {
opp-hz = /bits/ 64 <652800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-729600000 {
opp-hz = /bits/ 64 <729600000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-768000000 {
+ opp-hz = /bits/ 64 <768000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-844800000 {
opp-hz = /bits/ 64 <844800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-960000000 {
opp-hz = /bits/ 64 <960000000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1036800000 {
opp-hz = /bits/ 64 <1036800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1113600000 {
opp-hz = /bits/ 64 <1113600000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1132800000 {
+ opp-hz = /bits/ 64 <1132800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1190400000 {
opp-hz = /bits/ 64 <1190400000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1209600000 {
+ opp-hz = /bits/ 64 <1209600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1228800000 {
opp-hz = /bits/ 64 <1228800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1286400000 {
+ opp-hz = /bits/ 64 <1286400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1324800000 {
opp-hz = /bits/ 64 <1324800000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x5>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1363200000 {
+ opp-hz = /bits/ 64 <1363200000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x72>;
clock-latency-ns = <200000>;
};
opp-1401600000 {
opp-hz = /bits/ 64 <1401600000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x5>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1440000000 {
+ opp-hz = /bits/ 64 <1440000000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1478400000 {
opp-hz = /bits/ 64 <1478400000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1497600000 {
+ opp-hz = /bits/ 64 <1497600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x4>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1593600000 {
opp-hz = /bits/ 64 <1593600000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x71>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x20>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2188800000 {
+ opp-hz = /bits/ 64 <2188800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x10>;
clock-latency-ns = <200000>;
};
};
cluster1_opp: opp_table1 {
- compatible = "operating-points-v2";
+ compatible = "operating-points-v2-kryo-cpu";
+ nvmem-cells = <&speedbin_efuse>;
opp-shared;
opp-307200000 {
opp-hz = /bits/ 64 <307200000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-403200000 {
opp-hz = /bits/ 64 <403200000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-460800000 {
+ opp-hz = /bits/ 64 <460800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-480000000 {
opp-hz = /bits/ 64 <480000000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-537600000 {
+ opp-hz = /bits/ 64 <537600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-556800000 {
opp-hz = /bits/ 64 <556800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-614400000 {
+ opp-hz = /bits/ 64 <614400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-652800000 {
opp-hz = /bits/ 64 <652800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-729600000 {
opp-hz = /bits/ 64 <729600000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-748800000 {
+ opp-hz = /bits/ 64 <748800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-806400000 {
opp-hz = /bits/ 64 <806400000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-825600000 {
+ opp-hz = /bits/ 64 <825600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-883200000 {
opp-hz = /bits/ 64 <883200000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-940800000 {
opp-hz = /bits/ 64 <940800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1036800000 {
opp-hz = /bits/ 64 <1036800000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1113600000 {
opp-hz = /bits/ 64 <1113600000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1132800000 {
+ opp-hz = /bits/ 64 <1132800000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1190400000 {
opp-hz = /bits/ 64 <1190400000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1209600000 {
+ opp-hz = /bits/ 64 <1209600000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1248000000 {
opp-hz = /bits/ 64 <1248000000>;
opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1286400000 {
+ opp-hz = /bits/ 64 <1286400000>;
+ opp-microvolt = <905000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1324800000 {
opp-hz = /bits/ 64 <1324800000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1363200000 {
+ opp-hz = /bits/ 64 <1363200000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1401600000 {
opp-hz = /bits/ 64 <1401600000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1440000000 {
+ opp-hz = /bits/ 64 <1440000000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1478400000 {
opp-hz = /bits/ 64 <1478400000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1555200000 {
opp-hz = /bits/ 64 <1555200000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1593600000 {
+ opp-hz = /bits/ 64 <1593600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1632000000 {
opp-hz = /bits/ 64 <1632000000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1670400000 {
+ opp-hz = /bits/ 64 <1670400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1708800000 {
opp-hz = /bits/ 64 <1708800000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1747200000 {
+ opp-hz = /bits/ 64 <1747200000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1785600000 {
opp-hz = /bits/ 64 <1785600000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1804800000 {
+ opp-hz = /bits/ 64 <1804800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x6>;
clock-latency-ns = <200000>;
};
opp-1824000000 {
opp-hz = /bits/ 64 <1824000000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x71>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1900800000 {
+ opp-hz = /bits/ 64 <1900800000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x74>;
clock-latency-ns = <200000>;
};
opp-1920000000 {
opp-hz = /bits/ 64 <1920000000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1977600000 {
+ opp-hz = /bits/ 64 <1977600000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x30>;
clock-latency-ns = <200000>;
};
opp-1996800000 {
opp-hz = /bits/ 64 <1996800000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2054400000 {
+ opp-hz = /bits/ 64 <2054400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x30>;
clock-latency-ns = <200000>;
};
opp-2073600000 {
opp-hz = /bits/ 64 <2073600000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x1>;
clock-latency-ns = <200000>;
};
opp-2150400000 {
opp-hz = /bits/ 64 <2150400000>;
opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x31>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2246400000 {
+ opp-hz = /bits/ 64 <2246400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x10>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2342400000 {
+ opp-hz = /bits/ 64 <2342400000>;
+ opp-microvolt = <1140000 905000 1140000>;
+ opp-supported-hw = <0x10>;
clock-latency-ns = <200000>;
};
};
@@ -992,6 +1293,11 @@
reg = <0x24f 0x1>;
bits = <1 4>;
};
+
+ speedbin_efuse: speedbin at 133 {
+ reg = <0x133 0x1>;
+ bits = <5 3>;
+ };
};
phy at 34000 {
--
1.9.1
^ permalink raw reply related
* [PATCH 00/12] introduce support for early platform drivers
From: Rob Herring @ 2018-05-14 13:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMRc=McDNYQ5uk8EyRkDf8eh9q7tyF=t7PcUd6DBLqXcseJ3AQ@mail.gmail.com>
On Mon, May 14, 2018 at 6:38 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> 2018-05-11 22:13 GMT+02:00 Rob Herring <robh+dt@kernel.org>:
>> On Fri, May 11, 2018 at 11:20 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>> This series is a follow-up to the RFC[1] posted a couple days ago.
>>>
>>> NOTE: this series applies on top of my recent patches[2] that move the previous
>>> implementation of early platform devices to arch/sh.
>>>
>>> Problem:
>>>
>>> Certain class of devices, such as timers, certain clock drivers and irq chip
>>> drivers need to be probed early in the boot sequence. The currently preferred
>>> approach is using one of the OF_DECLARE() macros. This however does not create
>>> a platform device which has many drawbacks - such as not being able to use
>>> devres routines, dev_ log functions or no way of deferring the init OF function
>>> if some other resources are missing.
>>
>> I skimmed though this and it doesn't look horrible (how's that for
>> positive feedback? ;) ). But before going into the details, I think
>> first there needs to be agreement this is the right direction.
>>
>> The question does remain though as to whether this class of devices
>> should be platform drivers. They can't be modules. They can't be
>> hotplugged. Can they be runtime-pm enabled? So the advantage is ...
>>
>
> The main (but not the only) advantage for drivers that can both be
> platform drivers and OF_DECLARE drivers is that we get a single entry
> point and can reuse code without resorting to checking if (!dev). It
> results in more consistent code base. Another big advantage is
> consolidation of device tree and machine code for SoC drivers used in
> different boards of which some are still using board files and others
> are defined in DT (see: DaVinci).
>
>> I assume that the clock maintainers had some reason to move clocks to
>> be platform drivers. It's just not clear to me what that was.
>>
>>> For drivers that use both platform drivers and OF_DECLARE the situation is even
>>> more complicated as the code needs to take into account that there can possibly
>>> be no struct device present. For a specific use case that we're having problems
>>> with, please refer to the recent DaVinci common-clock conversion patches and
>>> the nasty workaround that this problem implies[3].
>>
>> So devm_kzalloc will work with this solution? Why did we need
>> devm_kzalloc in the first place? The clocks can never be removed and
>> cleaning up on error paths is kind of pointless. The system would be
>> hosed, right?
>>
>
> It depends - not all clocks are necessary for system to boot.
That doesn't matter. You have a single driver for all/most of the
clocks, so the driver can't be removed.
>>> We also used to have an early platform drivers implementation but they were not
>>> integrated with the linux device model at all - they merely used the same data
>>> structures. The users could not use devres, defer probe and the early devices
>>> never became actual platform devices later on.
>>>
>>> Proposed solution:
>>>
>>> This series aims at solving this problem by (re-)introducing the concept of
>>> early platform drivers and devices - this time however in a way that seamlessly
>>> integrates with the existing platform drivers and also offers device-tree
>>> support.
>>>
>>> The idea is to provide a way for users to probe devices early, while already
>>> being able to use devres, devices resources and properties and also deferred
>>> probing.
>>>
>>> New structures are introduced: the early platform driver contains the
>>> early_probe callback which has the same signature as regular platform_device
>>> probe. This callback is called early on. The user can have both the early and
>>> regular probe speficied or only one of them and they both receive the same
>>> platform device object as argument. Any device data allocated early will be
>>> carried over to the normal probe.
>>>
>>> The architecture code is responsible for calling early_platform_start() in
>>> which the early drivers will be registered and devices populated from DT.
>>
>> Can we really do this in one spot for different devices (clk, timers,
>> irq). The sequence is all very carefully crafted. Platform specific
>> hooks is another thing to consider.
>>
>
> This is why I added support for early probe deferral - so that we can
> stop caring for the order as long as the drivers are aware of other
> resources they need and we call early_platform_start() the moment the
> earliest of the early devices is needed.
Deferred probe helps for inter-device dependencies, but I am more
concerned about timing of trying to register clocksources, irqchips,
etc. What happens if we probe drivers before the infrastructure is
initialized?
Rob
^ permalink raw reply
* [PATCH] ARM: dts: at91-sama5d2_xplained: Use IRQ_TYPE specifier
From: Alexandre Belloni @ 2018-05-14 13:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526253724-3596-1-git-send-email-hernan@vanguardiasur.com.ar>
On 13/05/2018 20:22:04-0300, Hern?n Gonzalez wrote:
> GPIO_ACTIVE_LOW was being used to specify an interrupt, use
> IRQ_TYPE_EDGE_RISING instead. This improves DT readability.
>
> Signed-off-by: Hern?n Gonzalez <hernan@vanguardiasur.com.ar>
> ---
> arch/arm/boot/dts/at91-sama5d2_xplained.dts | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Applied, thanks.
--
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH v2] ARM: dts: imx6/7: Remove unit-address from anatop regulators
From: Fabio Estevam @ 2018-05-14 13:31 UTC (permalink / raw)
To: linux-arm-kernel
From: Fabio Estevam <fabio.estevam@nxp.com>
Remove unit-address and reg property from anatop regulators to fix
the following DTC warnings with W=1:
arch/arm/boot/dts/imx6dl-apf6dev.dtb: Warning (unique_unit_address): /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddcore at 20c8140: duplicate unit-address (also used in node /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddpu at 20c8140)
arch/arm/boot/dts/imx6dl-apf6dev.dtb: Warning (unique_unit_address): /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddcore at 20c8140: duplicate unit-address (also used in node /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddsoc at 20c8140)
arch/arm/boot/dts/imx6dl-apf6dev.dtb: Warning (unique_unit_address): /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddpu at 20c8140: duplicate unit-address (also used in node /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddsoc at 20c8140)
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
---
Changes since v1:
- Send it is a standalone patch instead of a patch series.
arch/arm/boot/dts/imx6qdl.dtsi | 20 ++++++--------------
arch/arm/boot/dts/imx6sl.dtsi | 20 ++++++--------------
arch/arm/boot/dts/imx6sx.dtsi | 20 ++++++--------------
arch/arm/boot/dts/imx6ul.dtsi | 11 +++--------
arch/arm/boot/dts/imx7s.dtsi | 8 ++------
5 files changed, 23 insertions(+), 56 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 69648e2..22942dd 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -692,11 +692,8 @@
interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
<0 54 IRQ_TYPE_LEVEL_HIGH>,
<0 127 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- regulator-1p1 at 20c8110 {
- reg = <0x20c8110>;
+ regulator-1p1 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd1p1";
regulator-min-microvolt = <1000000>;
@@ -711,8 +708,7 @@
anatop-enable-bit = <0>;
};
- regulator-3p0 at 20c8120 {
- reg = <0x20c8120>;
+ regulator-3p0 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
regulator-min-microvolt = <2800000>;
@@ -727,8 +723,7 @@
anatop-enable-bit = <0>;
};
- regulator-2p5 at 20c8130 {
- reg = <0x20c8130>;
+ regulator-2p5 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd2p5";
regulator-min-microvolt = <2250000>;
@@ -743,8 +738,7 @@
anatop-enable-bit = <0>;
};
- reg_arm: regulator-vddcore at 20c8140 {
- reg = <0x20c8140>;
+ reg_arm: regulator-vddcore {
compatible = "fsl,anatop-regulator";
regulator-name = "vddarm";
regulator-min-microvolt = <725000>;
@@ -761,8 +755,7 @@
anatop-max-voltage = <1450000>;
};
- reg_pu: regulator-vddpu at 20c8140 {
- reg = <0x20c8140>;
+ reg_pu: regulator-vddpu {
compatible = "fsl,anatop-regulator";
regulator-name = "vddpu";
regulator-min-microvolt = <725000>;
@@ -779,8 +772,7 @@
anatop-max-voltage = <1450000>;
};
- reg_soc: regulator-vddsoc at 20c8140 {
- reg = <0x20c8140>;
+ reg_soc: regulator-vddsoc {
compatible = "fsl,anatop-regulator";
regulator-name = "vddsoc";
regulator-min-microvolt = <725000>;
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 2002db2..8c838ba 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -524,11 +524,8 @@
interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
<0 54 IRQ_TYPE_LEVEL_HIGH>,
<0 127 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- regulator-1p1 at 20c8110 {
- reg = <0x20c8110>;
+ regulator-1p1 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd1p1";
regulator-min-microvolt = <800000>;
@@ -543,8 +540,7 @@
anatop-enable-bit = <0>;
};
- regulator-3p0 at 20c8120 {
- reg = <0x20c8120>;
+ regulator-3p0 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
regulator-min-microvolt = <2800000>;
@@ -559,8 +555,7 @@
anatop-enable-bit = <0>;
};
- regulator-2p5 at 20c8130 {
- reg = <0x20c8130>;
+ regulator-2p5 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd2p5";
regulator-min-microvolt = <2100000>;
@@ -575,8 +570,7 @@
anatop-enable-bit = <0>;
};
- reg_arm: regulator-vddcore at 20c8140 {
- reg = <0x20c8140>;
+ reg_arm: regulator-vddcore {
compatible = "fsl,anatop-regulator";
regulator-name = "vddarm";
regulator-min-microvolt = <725000>;
@@ -593,8 +587,7 @@
anatop-max-voltage = <1450000>;
};
- reg_pu: regulator-vddpu at 20c8140 {
- reg = <0x20c8140>;
+ reg_pu: regulator-vddpu {
compatible = "fsl,anatop-regulator";
regulator-name = "vddpu";
regulator-min-microvolt = <725000>;
@@ -611,8 +604,7 @@
anatop-max-voltage = <1450000>;
};
- reg_soc: regulator-vddsoc at 20c8140 {
- reg = <0x20c8140>;
+ reg_soc: regulator-vddsoc {
compatible = "fsl,anatop-regulator";
regulator-name = "vddsoc";
regulator-min-microvolt = <725000>;
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 7e463d2..4a97513 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -591,11 +591,8 @@
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- regulator-1p1 at 20c8110 {
- reg = <0x20c8110>;
+ regulator-1p1 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd1p1";
regulator-min-microvolt = <800000>;
@@ -610,8 +607,7 @@
anatop-enable-bit = <0>;
};
- regulator-3p0 at 20c8120 {
- reg = <0x20c8120>;
+ regulator-3p0 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
regulator-min-microvolt = <2800000>;
@@ -626,8 +622,7 @@
anatop-enable-bit = <0>;
};
- regulator-2p5 at 20c8130 {
- reg = <0x20c8130>;
+ regulator-2p5 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd2p5";
regulator-min-microvolt = <2100000>;
@@ -642,8 +637,7 @@
anatop-enable-bit = <0>;
};
- reg_arm: regulator-vddcore at 20c8140 {
- reg = <0x20c8140>;
+ reg_arm: regulator-vddcore {
compatible = "fsl,anatop-regulator";
regulator-name = "vddarm";
regulator-min-microvolt = <725000>;
@@ -660,8 +654,7 @@
anatop-max-voltage = <1450000>;
};
- reg_pcie: regulator-vddpcie at 20c8140 {
- reg = <0x20c8140>;
+ reg_pcie: regulator-vddpcie {
compatible = "fsl,anatop-regulator";
regulator-name = "vddpcie";
regulator-min-microvolt = <725000>;
@@ -677,8 +670,7 @@
anatop-max-voltage = <1450000>;
};
- reg_soc: regulator-vddsoc at 20c8140 {
- reg = <0x20c8140>;
+ reg_soc: regulator-vddsoc {
compatible = "fsl,anatop-regulator";
regulator-name = "vddsoc";
regulator-min-microvolt = <725000>;
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 2b854d1..1818b6c 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -551,11 +551,8 @@
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- reg_3p0: regulator-3p0 at 20c8110 {
- reg = <0x20c8110>;
+ reg_3p0: regulator-3p0 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
regulator-min-microvolt = <2625000>;
@@ -569,8 +566,7 @@
anatop-enable-bit = <0>;
};
- reg_arm: regulator-vddcore at 20c8140 {
- reg = <0x20c8140>;
+ reg_arm: regulator-vddcore {
compatible = "fsl,anatop-regulator";
regulator-name = "cpu";
regulator-min-microvolt = <725000>;
@@ -587,8 +583,7 @@
anatop-max-voltage = <1450000>;
};
- reg_soc: regulator-vddsoc at 20c8140 {
- reg = <0x20c8140>;
+ reg_soc: regulator-vddsoc {
compatible = "fsl,anatop-regulator";
regulator-name = "vddsoc";
regulator-min-microvolt = <725000>;
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index b416d2b..99f92ec 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -557,11 +557,8 @@
reg = <0x30360000 0x10000>;
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- reg_1p0d: regulator-vdd1p0d at 30360210 {
- reg = <0x30360210>;
+ reg_1p0d: regulator-vdd1p0d {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd1p0d";
regulator-min-microvolt = <800000>;
@@ -575,8 +572,7 @@
anatop-enable-bit = <0>;
};
- reg_1p2: regulator-vdd1p2 at 30360220 {
- reg = <0x30360220>;
+ reg_1p2: regulator-vdd1p2 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd1p2";
regulator-min-microvolt = <1100000>;
--
2.7.4
^ permalink raw reply related
* [FAIL bisect] Sound card probe error
From: Sylwester Nawrocki @ 2018-05-14 13:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJKOXPeNJtmU2+8CdMRwXignMTetn=LScdcMspfkP3MVmTSHrg@mail.gmail.com>
On 05/14/2018 02:50 PM, Krzysztof Kozlowski wrote:
> On Mon, May 14, 2018 at 2:45 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>> On Mon, May 14, 2018 at 2:40 PM, Sylwester Nawrocki
>> <s.nawrocki@samsung.com> wrote:
>>> On 05/14/2018 02:29 PM, Krzysztof Kozlowski wrote:
>>>> Ah, I missed these messages because I was looking at err dmesg level
>>>> (and for some reason these are warn). Anyway do you have any thoughts
>>>> how is it connected with missing Odroid XU3 sound card and max98090
>>>> codec?
>>> One reason is that the DRM driver registers an ASoC codec object which
>>> is required for the sound card registration to complete. But I wonder
>>> why there is no any error messages related to this.
>> Thanks Marek and Sylwester. Another point is that probably OOPS later
>> should not happen...
> Separate topic (trim Cc list):
>
> ... and this means that disabling Exynos DRM causes lack of Audio. I
> tried it now and indeed without DRM there is no audio again. I think
> it is not nice... There are not many such use cases but there are
> (playing audio from console/ssh with a headless board).\
As we discussed off the mailing list, what we could probably do now
is to add a compile time dependency on CONFIG_DRM_EXYNOS_HDMI, a fallback
to the max98098 codec only when the HDMI driver is disabled.
That might require modifying snd_soc_of_get_dai_link_codecs() so it can
skip optional codecs.
--
Regards,
Sylwester
^ permalink raw reply
* [PATCH v2 0/3] perf: make Arm CCI driver modular
From: Robin Murphy @ 2018-05-14 13:34 UTC (permalink / raw)
To: linux-arm-kernel
Now that it has been surgically removed from the MCPM port-control code,
we can let the CCI PMU driver be modular. Probing the PMU in the first
place still depends on the bus driver stub being built-in, but it's a
small price to pay compared to the major upheaval of completely reworking
the DT-handling code across the two drivers.
Robin.
v2: Fix Kconfig dependencies per kbuild robot report
Robin Murphy (3):
perf/arm-cc*: Fix MODULE_LICENSE() tags
perf/arm-cci: Remove pointless PMU disabling
perf/arm-cci: Allow building as a module
drivers/perf/Kconfig | 34 ++++++++++++++++++----------------
drivers/perf/arm-cci.c | 32 ++++++++++++++++++++------------
drivers/perf/arm-ccn.c | 2 +-
3 files changed, 39 insertions(+), 29 deletions(-)
--
2.17.0.dirty
^ permalink raw reply
* [PATCH v2 1/3] perf/arm-cc*: Fix MODULE_LICENSE() tags
From: Robin Murphy @ 2018-05-14 13:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1526303815.git.robin.murphy@arm.com>
The CCI/CCN drivers are licensed under GPLv2, but the MODULE_LICENSE()
tags are using the bare "GPL" string implying GPLv2 or later. Fix them
to match their actual file license.
Acked-by: Pawel Moll <pawel.moll@arm.com>
Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
v2: No change
drivers/perf/arm-cci.c | 2 +-
drivers/perf/arm-ccn.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index 383b2d3dcbc6..53c774b20563 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1718,5 +1718,5 @@ static struct platform_driver cci_pmu_driver = {
};
builtin_platform_driver(cci_pmu_driver);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ARM CCI PMU support");
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 65b7e4042ece..917b47e776df 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -1594,4 +1594,4 @@ module_init(arm_ccn_init);
module_exit(arm_ccn_exit);
MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
--
2.17.0.dirty
^ permalink raw reply related
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