* Re: [PATCH V2 8/8] dt-bindings: stm32: add compatible for syscon
From: Rob Herring @ 2018-05-17 12:37 UTC (permalink / raw)
To: Christophe ROULLIER
Cc: mark.rutland@arm.com, mcoquelin.stm32@gmail.com, Alexandre TORGUE,
Peppe CAVALLARO, devicetree@vger.kernel.org, andrew@lunn.ch,
linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org
In-Reply-To: <d2b4cd1845b949a7bf9c42a17a5358a2@SFHDAG5NODE3.st.com>
On Tue, May 15, 2018 at 11:19 AM, Christophe ROULLIER
<christophe.roullier@st.com> wrote:
> Hi Rob,
Please don't top post to lists.
>
> I do not understand, so let me explain our status:
>
> We have syscfg IP Harware in our SOC.
Add a compatible string that uniquely identifies what the block is. So
something like "st,stm32f746-syscfg".
> But we do not have SoC specific driver to manage syscfg, we are using a generic driver "syscon".
That does not matter. We're talking about the binding. Design
decisions in the OS should not define the binding. It doesn't matter
that the OS currently doesn't use the compatible string.
> So can you tell me what you wish to describe this part in our SOC bindings ?
>
> Thanks for your help.
>
> Christophe.
>
> -----Original Message-----
> From: Rob Herring [mailto:robh@kernel.org]
> Sent: lundi 7 mai 2018 18:36
> To: Christophe ROULLIER <christophe.roullier@st.com>
> Cc: mark.rutland@arm.com; mcoquelin.stm32@gmail.com; Alexandre TORGUE <alexandre.torgue@st.com>; Peppe CAVALLARO <peppe.cavallaro@st.com>; devicetree@vger.kernel.org; andrew@lunn.ch; linux-arm-kernel@lists.infradead.org; netdev@vger.kernel.org
> Subject: Re: [PATCH V2 8/8] dt-bindings: stm32: add compatible for syscon
>
> On Wed, May 02, 2018 at 04:18:43PM +0200, Christophe Roullier wrote:
>> This patch describes syscon DT bindings.
>>
>> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
>> ---
>> Documentation/devicetree/bindings/arm/stm32.txt | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/stm32.txt
>> b/Documentation/devicetree/bindings/arm/stm32.txt
>> index 6808ed9..06e3834 100644
>> --- a/Documentation/devicetree/bindings/arm/stm32.txt
>> +++ b/Documentation/devicetree/bindings/arm/stm32.txt
>> @@ -8,3 +8,7 @@ using one of the following compatible strings:
>> st,stm32f746
>> st,stm32h743
>> st,stm32mp157
>> +
>> +Required nodes:
>> +- syscon: the soc bus node must have a system controller node
>> +pointing to the
>> + global control registers, with the compatible string "syscon";
>
> You misunderstood my prior comment. 'syscon' alone is not valid. You need SoC specific compatible string for it and 'stm32' is not SoC specific. IOW, the compatible property for a syscon should imply every single register field in the block.
>
> Rob
^ permalink raw reply
* Re: [PATCH v5 05/14] usb: typec: add API to get typec basic port power and data config
From: Heikki Krogerus @ 2018-05-17 12:35 UTC (permalink / raw)
To: Mats Karrman
Cc: Jun Li, robh+dt@kernel.org, gregkh@linuxfoundation.org,
linux@roeck-us.net, a.hajda@samsung.com, cw00.choi@samsung.com,
shufan_lee@richtek.com, Peter Chen, gsomlo@gmail.com,
devicetree@vger.kernel.org, linux-usb@vger.kernel.org,
dl-linux-imx
In-Reply-To: <33d02e76-bdf2-be50-68ec-9d520acdbe82@gmail.com>
On Wed, May 16, 2018 at 10:55:36PM +0200, Mats Karrman wrote:
> Hi,
>
> On 05/16/2018 02:25 PM, Heikki Krogerus wrote:
>
> > Hi guys,
> >
> > On Tue, May 15, 2018 at 10:52:57PM +0200, Mats Karrman wrote:
> >> Hi,
> >>
> >> On 05/14/2018 11:36 AM, Jun Li wrote:
> >>
> >>> Hi
> >>>> -----Original Message-----
> >>>> From: Mats Karrman [mailto:mats.dev.list@gmail.com]
> >>>> Sent: 2018???5???12??? 3:56
> >>>> To: Jun Li <jun.li@nxp.com>; robh+dt@kernel.org; gregkh@linuxfoundation.org;
> >>>> heikki.krogerus@linux.intel.com; linux@roeck-us.net
> >>>> Cc: a.hajda@samsung.com; cw00.choi@samsung.com;
> >>>> shufan_lee@richtek.com; Peter Chen <peter.chen@nxp.com>;
> >>>> gsomlo@gmail.com; devicetree@vger.kernel.org; linux-usb@vger.kernel.org;
> >>>> dl-linux-imx <linux-imx@nxp.com>
> >>>> Subject: Re: [PATCH v5 05/14] usb: typec: add API to get typec basic port power
> >>>> and data config
> >>>>
> >>>> Hi Li Jun,
> >>>>
> >>>> On 2018-05-03 02:24, Li Jun wrote:
> >>>>
> >>>>> This patch adds 3 APIs to get the typec port power and data type, and
> >>>>> preferred power role by its name string.
> >>>>>
> >>>>> Signed-off-by: Li Jun <jun.li@nxp.com>
> >>>>> ---
> >>>>> drivers/usb/typec/class.c | 52
> >>>> +++++++++++++++++++++++++++++++++++++++++++++++
> >>>>> include/linux/usb/typec.h | 3 +++
> >>>>> 2 files changed, 55 insertions(+)
> >>>>>
> >>>>> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> >>>>> index 53df10d..5981e18 100644
> >>>>> --- a/drivers/usb/typec/class.c
> >>>>> +++ b/drivers/usb/typec/class.c
> >>>>> @@ -9,6 +9,7 @@
> >>>>> #include <linux/device.h>
> >>>>> #include <linux/module.h>
> >>>>> #include <linux/mutex.h>
> >>>>> +#include <linux/property.h>
> > I don't think you need that anymore.
> >
> >>>>> #include <linux/slab.h>
> >>>>> #include <linux/usb/typec.h>
> >>>>> #include <linux/usb/typec_mux.h>
> >>>>> @@ -802,6 +803,12 @@ static const char * const typec_port_types[] = {
> >>>>> [TYPEC_PORT_DRP] = "dual",
> >>>>> };
> >>>>>
> >>>>> +static const char * const typec_data_types[] = {
> >>>>> + [TYPEC_PORT_DFP] = "host",
> >>>>> + [TYPEC_PORT_UFP] = "device",
> >>>>> + [TYPEC_PORT_DRD] = "dual",
> >>>>> +};
> >>>>> +
> >>>>> static const char * const typec_port_types_drp[] = {
> >>>>> [TYPEC_PORT_SRC] = "dual [source] sink",
> >>>>> [TYPEC_PORT_SNK] = "dual source [sink]", @@ -1252,6 +1259,51
> >>>> @@
> >>>>> void typec_set_pwr_opmode(struct typec_port *port,
> >>>>> }
> >>>>> EXPORT_SYMBOL_GPL(typec_set_pwr_opmode);
> >>>>>
> >>>>> +/**
> >>>>> + * typec_find_power_type - Get the typec port power type
> >>>> Why is this function called typec_find_power_type() and not
> >>>> typec_find_port_type()?
> >>>> It's called port_type in sysfs, having different names just adds confusion.
> >>>> (Otherwise I agree power_type is a better name but...)
> >>> We have "port type" before the power and data role separation,
> >>> this API name's intention is to reflect the power cap, anyway I
> >>> leave this to be decided by Heikki then.
> > I really hate the "*_type" naming. It was understandable when there
> > was no separate power and data roles defined in the specification, but
> > now that there are, it's just confusing. IMO we should not use it
> > anywhere.
> >
> > So to me typec_find_type() is just as bad as typec_find_power_type()
> > because it has the "type" in it. I wonder if this function is
> > necessary at all? If it is, then perhaps we can think of some better
> > name for it, name that gives a better hint what it is used for.
>
> I reread this patch and tried to see it more in the context of the other
> patches and the existing code. The naming of the existing string tables
> doesn't help in getting this right, however I have a proposal:
>
> typec_find_port_power_role() to get to TYPEC_PORT_SRC/SNK/DRP
> typec_find_port_data_role() to get to TYPEC_PORT_DFP/UFP/DRD
> typec_find_power_role() to get to TYPEC_SINK/SOURCE
>
> and sometime, if the use should arise
>
> typec_find_data_role() to get to TYPEC_DEVICE/HOST
>
> I think it is fairly comprehensible, *_port_* concerns a capability and
> without *_port_* it is an actual state. Plus it matches the names of the
> constants.
Well, there are now four things to consider:
1) the roles (power and data) the port is capable of supporting
2) Try.SRC and Try.SNK, i.e. the preferred role
3) the current roles
4) the role(s) the user want's to limit the use of a port with DRP ports
The last one I don't know if it's relevant with these functions. It's
not information that we would get for example from firmware.
I also don't think we need to use these functions with the current
roles the port is in.
If the preferred role is "sink" or "source", so just like the power
role, we don't need separate function for it here.
So isn't two functions all we need here: one for the power and one for
data role?
Thanks,
--
heikki
^ permalink raw reply
* Re: [PATCH V1 2/5] backlight: qcom-wled: Add support for WLED4 peripheral
From: Rob Herring @ 2018-05-17 12:31 UTC (permalink / raw)
To: Kiran Gunda
Cc: Mark Rutland, devicetree, Daniel Thompson,
Bartlomiej Zolnierkiewicz, Jingoo Han,
linux-kernel@vger.kernel.org, dri-devel, Bjorn Andersson,
linux-fbdev, Jacek Anaszewski, Pavel Machek, linux-arm-msm,
Lee Jones, Linux LED Subsystem
In-Reply-To: <82fa847760309cb3382bf0a8da50162c@codeaurora.org>
On Thu, May 17, 2018 at 4:47 AM, <kgunda@codeaurora.org> wrote:
> On 2018-05-08 15:55, kgunda@codeaurora.org wrote:
>>
>> On 2018-05-07 21:50, Bjorn Andersson wrote:
>>>
>>> On Thu 03 May 02:57 PDT 2018, Kiran Gunda wrote:
>>>
>>>> WLED4 peripheral is present on some PMICs like pmi8998
>>>> and pm660l. It has a different register map and also
>>>> configurations are different. Add support for it.
>>>>
>>>
>>> Several things are going on in this patch, it needs to be split to
>>> not hide the functional changes from the structural/renames.
>>>
>> Ok. I will split it in the next series.
>>>>
>>>> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
>>>> ---
>>>> .../bindings/leds/backlight/qcom-wled.txt | 172 ++++-
>>>> drivers/video/backlight/qcom-wled.c | 749
>>>> +++++++++++++++------
>>>> 2 files changed, 696 insertions(+), 225 deletions(-)
>>>>
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
>>>> b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
>>>> index fb39e32..0ceffa1 100644
>>>> --- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
>>>> +++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt
>>>> @@ -1,30 +1,129 @@
>>>> Binding for Qualcomm Technologies, Inc. WLED driver
>>>>
>>>> -Required properties:
>>>> -- compatible: should be "qcom,pm8941-wled"
>>>> -- reg: slave address
>>>> -
>>>> -Optional properties:
>>>> -- default-brightness: brightness value on boot, value from: 0-4095
>>>> - default: 2048
>>>> -- label: The name of the backlight device
>>>> -- qcom,cs-out: bool; enable current sink output
>>>> -- qcom,cabc: bool; enable content adaptive backlight control
>>>> -- qcom,ext-gen: bool; use externally generated modulator signal to dim
>>>> -- qcom,current-limit: mA; per-string current limit; value from 0 to 25
>>>> - default: 20mA
>>>> -- qcom,current-boost-limit: mA; boost current limit; one of:
>>>> - 105, 385, 525, 805, 980, 1260, 1400, 1680
>>>> - default: 805mA
>>>> -- qcom,switching-freq: kHz; switching frequency; one of:
>>>> - 600, 640, 685, 738, 800, 872, 960, 1066, 1200, 1371,
>>>> - 1600, 1920, 2400, 3200, 4800, 9600,
>>>> - default: 1600kHz
>>>> -- qcom,ovp: V; Over-voltage protection limit; one of:
>>>> - 27, 29, 32, 35
>>>> - default: 29V
>>>> -- qcom,num-strings: #; number of led strings attached; value from 1 to
>>>> 3
>>>> - default: 2
>>>> +WLED (White Light Emitting Diode) driver is used for controlling
>>>> display
>>>> +backlight that is part of PMIC on Qualcomm Technologies, Inc. reference
>>>> +platforms. The PMIC is connected to the host processor via SPMI bus.
>>>> +
>>>> +- compatible
>>>> + Usage: required
>>>> + Value type: <string>
>>>> + Definition: should be "qcom,pm8941-wled" or
>>>> "qcom,pmi8998-wled".
>>>> + or "qcom,pm660l-wled".
>>>
>>>
>>> Better written as
>>>
>>> should be one of:
>>> X
>>> Y
>>> Z
>>>
>> Will do it in the next series.
>>>>
>>>> +
>>>> +- reg
>>>> + Usage: required
>>>> + Value type: <prop encoded array>
>>>> + Definition: Base address of the WLED modules.
>>>> +
>>>> +- interrupts
>>>> + Usage: optional
>>>> + Value type: <prop encoded array>
>>>> + Definition: Interrupts associated with WLED. Interrupts can be
>>>> + specified as per the encoding listed under
>>>> + Documentation/devicetree/bindings/spmi/
>>>> + qcom,spmi-pmic-arb.txt.
>>>
>>>
>>> Better to describe that this should be the "short" and "ovp" interrupts
>>> in this property than in the interrupt-names.
>>>
>> Ok. I will do it in the next series.
>>>>
>>>> +
>>>> +- interrupt-names
>>>> + Usage: optional
>>>> + Value type: <string>
>>>> + Definition: Interrupt names associated with the interrupts.
>>>> + Must be "short" and "ovp". The short circuit
>>>> detection
>>>> + is not supported for PM8941.
>>>> +
>>>> +- label
>>>> + Usage: required
>>>> + Value type: <string>
>>>> + Definition: The name of the backlight device
>>>> +
>>>> +- default-brightness
>>>> + Usage: optional
>>>> + Value type: <u32>
>>>> + Definition: brightness value on boot, value from: 0-4095
>>>> + Default: 2048
>>>> +
>>>> +- qcom,current-limit
>>>> + Usage: optional
>>>> + Value type: <u32>
>>>> + Definition: uA; per-string current limit
>>>
>>>
>>> You can't change unit on an existing property, that breaks any existing
>>> dts using the qcom,pm8941-wled compatible.
>>>
>>
>>>> + value:
>>>> + For pm8941: from 0 to 25000 with 5000 ua step
>>>> + Default 20000 uA
>>>> + For pmi8998: from 0 to 30000 with 5000 ua step
>>>> + Default 25000 uA.
>>>
>>>
>>> These values could be described just as well in mA, so keep the original
>>> unit - in particular since the boot-limit is in mA...
>>>
>> Ok. Will keep the original as is in the next series.
>
> Here, I may have to go with the approach as in "qcom,ovp". Because for
> pm8941
> the current step is 1 mA (I have wrongly mentioned as 5000uA here) and for
> PMI8998
> the current step is 2.5 mA. Hence, I will add another variable
> "qcom,current-limit-ua"
> just like "qcom,ovp-mv".
Use unit suffixes defined in bindings/property-units.txt.
Rob
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [PATCH v2 3/3] ARM: multi_v7_defconfig: enable STM32 RTC
From: Amelie Delaunay @ 2018-05-17 12:07 UTC (permalink / raw)
To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland,
Russell King, Arnd Bergmann
Cc: linux-arm-kernel, devicetree, linux-kernel, Amelie Delaunay
In-Reply-To: <1526558828-24456-1-git-send-email-amelie.delaunay@st.com>
Enable the STM32 Real Time Clock (RTC) driver, implemented on STM32MP1 SoC.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
arch/arm/configs/multi_v7_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 89167cd..8e02f86 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -863,6 +863,7 @@ CONFIG_RTC_DRV_SUN6I=y
CONFIG_RTC_DRV_SUNXI=y
CONFIG_RTC_DRV_MV=y
CONFIG_RTC_DRV_TEGRA=y
+CONFIG_RTC_DRV_STM32=y
CONFIG_RTC_DRV_CPCAP=m
CONFIG_DMADEVICES=y
CONFIG_DW_DMAC=y
--
2.7.4
^ permalink raw reply related
* [PATCH v2 2/3] ARM: dts: stm32: enable RTC on stm32mp157c-ed1
From: Amelie Delaunay @ 2018-05-17 12:07 UTC (permalink / raw)
To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland,
Russell King, Arnd Bergmann
Cc: linux-arm-kernel, devicetree, linux-kernel, Amelie Delaunay
In-Reply-To: <1526558828-24456-1-git-send-email-amelie.delaunay@st.com>
Enable RTC (Real Time Clock) on stm32mp157c-ed1 board.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
arch/arm/boot/dts/stm32mp157c-ed1.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts b/arch/arm/boot/dts/stm32mp157c-ed1.dts
index ae33653..050c30d 100644
--- a/arch/arm/boot/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts
@@ -68,6 +68,10 @@
status = "okay";
};
+&rtc {
+ status = "okay";
+};
+
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/3] ARM: dts: stm32: add RTC support to stm32mp157c
From: Amelie Delaunay @ 2018-05-17 12:07 UTC (permalink / raw)
To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland,
Russell King, Arnd Bergmann
Cc: linux-arm-kernel, devicetree, linux-kernel, Amelie Delaunay
In-Reply-To: <1526558828-24456-1-git-send-email-amelie.delaunay@st.com>
Add support for RTC (Real Time Clock) to STM32MP157C SoC.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
arch/arm/boot/dts/stm32mp157c.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi
index b66f673..df2d874 100644
--- a/arch/arm/boot/dts/stm32mp157c.dtsi
+++ b/arch/arm/boot/dts/stm32mp157c.dtsi
@@ -818,6 +818,15 @@
status = "disabled";
};
+ rtc: rtc@5c004000 {
+ compatible = "st,stm32mp1-rtc";
+ reg = <0x5c004000 0x400>;
+ clocks = <&rcc RTCAPB>, <&rcc RTC>;
+ clock-names = "pclk", "rtc_ck";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
i2c6: i2c@5c009000 {
compatible = "st,stm32f7-i2c";
reg = <0x5c009000 0x400>;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/3] Add STM32 RTC to stm32mp157c
From: Amelie Delaunay @ 2018-05-17 12:07 UTC (permalink / raw)
To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland,
Russell King, Arnd Bergmann
Cc: linux-arm-kernel, devicetree, linux-kernel, Amelie Delaunay
This series adds support for STM32 RTC to stm32mp157c SoC and enables it
on stm32mp157c-ed1 board.
---
Changes in v2:
* Enable STM32 RTC in multi_v7_defconfig
Amelie Delaunay (3):
ARM: dts: stm32: add RTC support to stm32mp157c
ARM: dts: stm32: enable RTC on stm32mp157c-ed1
ARM: multi_v7_defconfig: enable STM32 RTC
arch/arm/boot/dts/stm32mp157c-ed1.dts | 4 ++++
arch/arm/boot/dts/stm32mp157c.dtsi | 9 +++++++++
arch/arm/configs/multi_v7_defconfig | 1 +
3 files changed, 14 insertions(+)
--
2.7.4
^ permalink raw reply
* [PATCH v3 4/4] rtc: stm32: add stm32mp1 rtc support
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
Maxime Coquelin, Alexandre Torgue
Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel,
Amelie Delaunay
In-Reply-To: <1526558666-24243-1-git-send-email-amelie.delaunay@st.com>
This patch adds support for stm32mp1 RTC.
Some common registers with previous RTC version have a different offset.
It is the case for Control Register (CR) and ALaRMA Register (ALRMAR).
There are also new registers regarding event flags: now, Alarm event flag
is in Status Register (SR) and write 1 in Status Clear Register (SCR) is
required to clear the event.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
drivers/rtc/rtc-stm32.c | 103 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 89 insertions(+), 14 deletions(-)
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 8254e38..c5908cf 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -11,6 +11,7 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
@@ -39,7 +40,7 @@
#define STM32_RTC_CR_ALRAE BIT(8)
#define STM32_RTC_CR_ALRAIE BIT(12)
-/* STM32_RTC_ISR bit fields */
+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
#define STM32_RTC_ISR_ALRAWF BIT(0)
#define STM32_RTC_ISR_INITS BIT(4)
#define STM32_RTC_ISR_RSF BIT(5)
@@ -71,21 +72,36 @@
#define STM32_RTC_ALRMXR_WDAY GENMASK(27, 24)
#define STM32_RTC_ALRMXR_DATE_MASK BIT(31)
+/* STM32_RTC_SR/_SCR bit fields */
+#define STM32_RTC_SR_ALRA BIT(0)
+
+/* STM32_RTC_VERR bit fields */
+#define STM32_RTC_VERR_MINREV_SHIFT 0
+#define STM32_RTC_VERR_MINREV GENMASK(3, 0)
+#define STM32_RTC_VERR_MAJREV_SHIFT 4
+#define STM32_RTC_VERR_MAJREV GENMASK(7, 4)
+
/* STM32_RTC_WPR key constants */
#define RTC_WPR_1ST_KEY 0xCA
#define RTC_WPR_2ND_KEY 0x53
#define RTC_WPR_WRONG_KEY 0xFF
+/* Max STM32 RTC register offset is 0x3FC */
+#define UNDEF_REG 0xFFFF
+
struct stm32_rtc;
struct stm32_rtc_registers {
- u8 tr;
- u8 dr;
- u8 cr;
- u8 isr;
- u8 prer;
- u8 alrmar;
- u8 wpr;
+ u16 tr;
+ u16 dr;
+ u16 cr;
+ u16 isr;
+ u16 prer;
+ u16 alrmar;
+ u16 wpr;
+ u16 sr;
+ u16 scr;
+ u16 verr;
};
struct stm32_rtc_events {
@@ -98,6 +114,7 @@ struct stm32_rtc_data {
void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
bool has_pclk;
bool need_dbp;
+ bool has_wakeirq;
};
struct stm32_rtc {
@@ -110,6 +127,7 @@ struct stm32_rtc {
struct clk *rtc_ck;
const struct stm32_rtc_data *data;
int irq_alarm;
+ int wakeirq_alarm;
};
static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -193,7 +211,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
mutex_lock(&rtc->rtc_dev->ops_lock);
- status = readl_relaxed(rtc->base + regs->isr);
+ status = readl_relaxed(rtc->base + regs->sr);
cr = readl_relaxed(rtc->base + regs->cr);
if ((status & evts->alra) &&
@@ -325,7 +343,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
alrmar = readl_relaxed(rtc->base + regs->alrmar);
cr = readl_relaxed(rtc->base + regs->cr);
- status = readl_relaxed(rtc->base + regs->isr);
+ status = readl_relaxed(rtc->base + regs->sr);
if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
/*
@@ -533,6 +551,7 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
static const struct stm32_rtc_data stm32_rtc_data = {
.has_pclk = false,
.need_dbp = true,
+ .has_wakeirq = false,
.regs = {
.tr = 0x00,
.dr = 0x04,
@@ -541,6 +560,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
.prer = 0x10,
.alrmar = 0x1C,
.wpr = 0x24,
+ .sr = 0x0C, /* set to ISR offset to ease alarm management */
+ .scr = UNDEF_REG,
+ .verr = UNDEF_REG,
},
.events = {
.alra = STM32_RTC_ISR_ALRAF,
@@ -551,6 +573,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
static const struct stm32_rtc_data stm32h7_rtc_data = {
.has_pclk = true,
.need_dbp = true,
+ .has_wakeirq = false,
.regs = {
.tr = 0x00,
.dr = 0x04,
@@ -559,6 +582,9 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
.prer = 0x10,
.alrmar = 0x1C,
.wpr = 0x24,
+ .sr = 0x0C, /* set to ISR offset to ease alarm management */
+ .scr = UNDEF_REG,
+ .verr = UNDEF_REG,
},
.events = {
.alra = STM32_RTC_ISR_ALRAF,
@@ -566,9 +592,41 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
.clear_events = stm32_rtc_clear_events,
};
+static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
+ unsigned int flags)
+{
+ struct stm32_rtc_registers regs = rtc->data->regs;
+
+ /* Flags are cleared by writing 1 in RTC_SCR */
+ writel_relaxed(flags, rtc->base + regs.scr);
+}
+
+static const struct stm32_rtc_data stm32mp1_data = {
+ .has_pclk = true,
+ .need_dbp = false,
+ .has_wakeirq = true,
+ .regs = {
+ .tr = 0x00,
+ .dr = 0x04,
+ .cr = 0x18,
+ .isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
+ .prer = 0x10,
+ .alrmar = 0x40,
+ .wpr = 0x24,
+ .sr = 0x50,
+ .scr = 0x5C,
+ .verr = 0x3F4,
+ },
+ .events = {
+ .alra = STM32_RTC_SR_ALRA,
+ },
+ .clear_events = stm32mp1_rtc_clear_events,
+};
+
static const struct of_device_id stm32_rtc_of_match[] = {
{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
+ { .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
{}
};
MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@@ -727,12 +785,19 @@ static int stm32_rtc_probe(struct platform_device *pdev)
goto err;
}
- platform_set_drvdata(pdev, rtc);
-
ret = device_init_wakeup(&pdev->dev, true);
+ if (rtc->data->has_wakeirq) {
+ rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
+ if (rtc->wakeirq_alarm <= 0)
+ ret = rtc->wakeirq_alarm;
+ else
+ ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+ rtc->wakeirq_alarm);
+ }
if (ret)
- dev_warn(&pdev->dev,
- "alarm won't be able to wake up the system");
+ dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+
+ platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
&stm32_rtc_ops, THIS_MODULE);
@@ -760,6 +825,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
dev_warn(&pdev->dev, "Date/Time must be initialized\n");
+ if (regs->verr != UNDEF_REG) {
+ u32 ver = readl_relaxed(rtc->base + regs->verr);
+
+ dev_info(&pdev->dev, "registered rev:%d.%d\n",
+ (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
+ (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
+ }
+
return 0;
err:
if (rtc->data->has_pclk)
@@ -769,6 +842,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
+ dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
return ret;
@@ -795,6 +869,7 @@ static int stm32_rtc_remove(struct platform_device *pdev)
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
+ dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
return 0;
--
2.7.4
^ permalink raw reply related
* [PATCH v3 3/4] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
Maxime Coquelin, Alexandre Torgue
Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel,
Amelie Delaunay
In-Reply-To: <1526558666-24243-1-git-send-email-amelie.delaunay@st.com>
RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
doesn't require to disable backup domain write protection, and rtc_ck
parent clock assignment isn't allowed.
To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
alarm interrupt.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
.../devicetree/bindings/rtc/st,stm32-rtc.txt | 27 ++++++++++++++++------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
index 00f8b5d..c920e27 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -1,25 +1,29 @@
STM32 Real Time Clock
Required properties:
-- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
- the device is compatible with stm32(f4/f7) or stm32h7.
+- compatible: can be one of the following:
+ - "st,stm32-rtc" for devices compatible with stm32(f4/f7).
+ - "st,stm32h7-rtc" for devices compatible with stm32h7.
+ - "st,stm32mp1-rtc" for devices compatible with stm32mp1.
- reg: address range of rtc register set.
- clocks: can use up to two clocks, depending on part used:
- "rtc_ck": RTC clock source.
- It is required on stm32(f4/f7) and stm32h7.
- "pclk": RTC APB interface clock.
It is not present on stm32(f4/f7).
- It is required on stm32h7.
+ It is required on stm32(h7/mp1).
- clock-names: must be "rtc_ck" and "pclk".
- It is required only on stm32h7.
+ It is required on stm32(h7/mp1).
- interrupt-parent: phandle for the interrupt controller.
-- interrupts: rtc alarm interrupt.
+ It is required on stm32(f4/f7/h7).
+- interrupts: rtc alarm interrupt. On stm32mp1, a second interrupt is required
+ for rtc alarm wakeup interrupt.
- st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
access control register at offset, and change the dbp (Disable Backup
Protection) bit represented by the mask, mandatory to disable/enable backup
domain (RTC registers) write protection.
+ It is required on stm32(f4/f7/h7).
-Optional properties (to override default rtc_ck parent clock):
+Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
- assigned-clocks: reference to the rtc_ck clock entry.
- assigned-clock-parents: phandle of the new parent clock of rtc_ck.
@@ -48,3 +52,12 @@ Example:
interrupt-names = "alarm";
st,syscfg = <&pwrcfg 0x00 0x100>;
};
+
+ rtc: rtc@5c004000 {
+ compatible = "st,stm32mp1-rtc";
+ reg = <0x5c004000 0x400>;
+ clocks = <&rcc RTCAPB>, <&rcc RTC>;
+ clock-names = "pclk", "rtc_ck";
+ interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
+ <&exti 19 1>;
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v3 2/4] rtc: stm32: rework register management to prepare other version of RTC
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
Maxime Coquelin, Alexandre Torgue
Cc: linux-rtc, devicetree, Amelie Delaunay, linux-kernel,
linux-arm-kernel
In-Reply-To: <1526558666-24243-1-git-send-email-amelie.delaunay@st.com>
This patch reworks register/bits management because next version of RTC
uses the same way of working but with different register's offset or bits
moved in new registers.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
drivers/rtc/rtc-stm32.c | 184 +++++++++++++++++++++++++++++++++---------------
1 file changed, 127 insertions(+), 57 deletions(-)
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index d41f804..8254e38 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -16,15 +16,6 @@
#define DRIVER_NAME "stm32_rtc"
-/* STM32 RTC registers */
-#define STM32_RTC_TR 0x00
-#define STM32_RTC_DR 0x04
-#define STM32_RTC_CR 0x08
-#define STM32_RTC_ISR 0x0C
-#define STM32_RTC_PRER 0x10
-#define STM32_RTC_ALRMAR 0x1C
-#define STM32_RTC_WPR 0x24
-
/* STM32_RTC_TR bit fields */
#define STM32_RTC_TR_SEC_SHIFT 0
#define STM32_RTC_TR_SEC GENMASK(6, 0)
@@ -85,7 +76,26 @@
#define RTC_WPR_2ND_KEY 0x53
#define RTC_WPR_WRONG_KEY 0xFF
+struct stm32_rtc;
+
+struct stm32_rtc_registers {
+ u8 tr;
+ u8 dr;
+ u8 cr;
+ u8 isr;
+ u8 prer;
+ u8 alrmar;
+ u8 wpr;
+};
+
+struct stm32_rtc_events {
+ u32 alra;
+};
+
struct stm32_rtc_data {
+ const struct stm32_rtc_registers regs;
+ const struct stm32_rtc_events events;
+ void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
bool has_pclk;
bool need_dbp;
};
@@ -96,30 +106,35 @@ struct stm32_rtc {
struct regmap *dbp;
unsigned int dbp_reg;
unsigned int dbp_mask;
- struct stm32_rtc_data *data;
struct clk *pclk;
struct clk *rtc_ck;
+ const struct stm32_rtc_data *data;
int irq_alarm;
};
static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
{
- writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
- writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+ writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs->wpr);
+ writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs->wpr);
}
static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
{
- writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+ writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
}
static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
{
- unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+ unsigned int isr = readl_relaxed(rtc->base + regs->isr);
if (!(isr & STM32_RTC_ISR_INITF)) {
isr |= STM32_RTC_ISR_INIT;
- writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+ writel_relaxed(isr, rtc->base + regs->isr);
/*
* It takes around 2 rtc_ck clock cycles to enter in
@@ -128,7 +143,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
* 1MHz, we poll every 10 us with a timeout of 100ms.
*/
return readl_relaxed_poll_timeout_atomic(
- rtc->base + STM32_RTC_ISR,
+ rtc->base + regs->isr,
isr, (isr & STM32_RTC_ISR_INITF),
10, 100000);
}
@@ -138,40 +153,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
{
- unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+ unsigned int isr = readl_relaxed(rtc->base + regs->isr);
isr &= ~STM32_RTC_ISR_INIT;
- writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+ writel_relaxed(isr, rtc->base + regs->isr);
}
static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
{
- unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+ unsigned int isr = readl_relaxed(rtc->base + regs->isr);
isr &= ~STM32_RTC_ISR_RSF;
- writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+ writel_relaxed(isr, rtc->base + regs->isr);
/*
* Wait for RSF to be set to ensure the calendar registers are
* synchronised, it takes around 2 rtc_ck clock cycles
*/
- return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+ return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
isr,
(isr & STM32_RTC_ISR_RSF),
10, 100000);
}
+static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
+ unsigned int flags)
+{
+ rtc->data->clear_events(rtc, flags);
+}
+
static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
{
struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
- unsigned int isr, cr;
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+ const struct stm32_rtc_events *evts = &rtc->data->events;
+ unsigned int status, cr;
mutex_lock(&rtc->rtc_dev->ops_lock);
- isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
- cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+ status = readl_relaxed(rtc->base + regs->isr);
+ cr = readl_relaxed(rtc->base + regs->cr);
- if ((isr & STM32_RTC_ISR_ALRAF) &&
+ if ((status & evts->alra) &&
(cr & STM32_RTC_CR_ALRAIE)) {
/* Alarm A flag - Alarm interrupt */
dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@@ -179,9 +204,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
/* Pass event to the kernel */
rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
- /* Clear event flag, otherwise new events won't be received */
- writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
- rtc->base + STM32_RTC_ISR);
+ /* Clear event flags, otherwise new events won't be received */
+ stm32_rtc_clear_event_flags(rtc, evts->alra);
}
mutex_unlock(&rtc->rtc_dev->ops_lock);
@@ -228,11 +252,12 @@ static void bcd2tm(struct rtc_time *tm)
static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int tr, dr;
/* Time and Date in BCD format */
- tr = readl_relaxed(rtc->base + STM32_RTC_TR);
- dr = readl_relaxed(rtc->base + STM32_RTC_DR);
+ tr = readl_relaxed(rtc->base + regs->tr);
+ dr = readl_relaxed(rtc->base + regs->dr);
tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@@ -253,6 +278,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int tr, dr;
int ret = 0;
@@ -277,8 +303,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
goto end;
}
- writel_relaxed(tr, rtc->base + STM32_RTC_TR);
- writel_relaxed(dr, rtc->base + STM32_RTC_DR);
+ writel_relaxed(tr, rtc->base + regs->tr);
+ writel_relaxed(dr, rtc->base + regs->dr);
stm32_rtc_exit_init_mode(rtc);
@@ -292,12 +318,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+ const struct stm32_rtc_events *evts = &rtc->data->events;
struct rtc_time *tm = &alrm->time;
- unsigned int alrmar, cr, isr;
+ unsigned int alrmar, cr, status;
- alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
- cr = readl_relaxed(rtc->base + STM32_RTC_CR);
- isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+ alrmar = readl_relaxed(rtc->base + regs->alrmar);
+ cr = readl_relaxed(rtc->base + regs->cr);
+ status = readl_relaxed(rtc->base + regs->isr);
if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
/*
@@ -350,7 +378,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
bcd2tm(tm);
alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
- alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+ alrm->pending = (status & evts->alra) ? 1 : 0;
return 0;
}
@@ -358,9 +386,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
- unsigned int isr, cr;
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+ const struct stm32_rtc_events *evts = &rtc->data->events;
+ unsigned int cr;
- cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+ cr = readl_relaxed(rtc->base + regs->cr);
stm32_rtc_wpr_unlock(rtc);
@@ -369,12 +399,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
else
cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
- writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+ writel_relaxed(cr, rtc->base + regs->cr);
- /* Clear event flag, otherwise new events won't be received */
- isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
- isr &= ~STM32_RTC_ISR_ALRAF;
- writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+ /* Clear event flags, otherwise new events won't be received */
+ stm32_rtc_clear_event_flags(rtc, evts->alra);
stm32_rtc_wpr_lock(rtc);
@@ -383,9 +411,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
{
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
- unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
- unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
+ unsigned int dr = readl_relaxed(rtc->base + regs->dr);
+ unsigned int tr = readl_relaxed(rtc->base + regs->tr);
cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@@ -419,6 +448,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
struct rtc_time *tm = &alrm->time;
unsigned int cr, isr, alrmar;
int ret = 0;
@@ -450,15 +480,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
stm32_rtc_wpr_unlock(rtc);
/* Disable Alarm */
- cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+ cr = readl_relaxed(rtc->base + regs->cr);
cr &= ~STM32_RTC_CR_ALRAE;
- writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+ writel_relaxed(cr, rtc->base + regs->cr);
/*
* Poll Alarm write flag to be sure that Alarm update is allowed: it
* takes around 2 rtc_ck clock cycles
*/
- ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+ ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
isr,
(isr & STM32_RTC_ISR_ALRAWF),
10, 100000);
@@ -469,7 +499,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
}
/* Write to Alarm register */
- writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
+ writel_relaxed(alrmar, rtc->base + regs->alrmar);
if (alrm->enabled)
stm32_rtc_alarm_irq_enable(dev, 1);
@@ -490,14 +520,50 @@ static const struct rtc_class_ops stm32_rtc_ops = {
.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
};
+static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
+ unsigned int flags)
+{
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+ /* Flags are cleared by writing 0 in RTC_ISR */
+ writel_relaxed(readl_relaxed(rtc->base + regs->isr) & ~flags,
+ rtc->base + regs->isr);
+}
+
static const struct stm32_rtc_data stm32_rtc_data = {
.has_pclk = false,
.need_dbp = true,
+ .regs = {
+ .tr = 0x00,
+ .dr = 0x04,
+ .cr = 0x08,
+ .isr = 0x0C,
+ .prer = 0x10,
+ .alrmar = 0x1C,
+ .wpr = 0x24,
+ },
+ .events = {
+ .alra = STM32_RTC_ISR_ALRAF,
+ },
+ .clear_events = stm32_rtc_clear_events,
};
static const struct stm32_rtc_data stm32h7_rtc_data = {
.has_pclk = true,
.need_dbp = true,
+ .regs = {
+ .tr = 0x00,
+ .dr = 0x04,
+ .cr = 0x08,
+ .isr = 0x0C,
+ .prer = 0x10,
+ .alrmar = 0x1C,
+ .wpr = 0x24,
+ },
+ .events = {
+ .alra = STM32_RTC_ISR_ALRAF,
+ },
+ .clear_events = stm32_rtc_clear_events,
};
static const struct of_device_id stm32_rtc_of_match[] = {
@@ -510,6 +576,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
static int stm32_rtc_init(struct platform_device *pdev,
struct stm32_rtc *rtc)
{
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
unsigned int rate;
int ret = 0;
@@ -550,14 +617,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
}
prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
- writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+ writel_relaxed(prer, rtc->base + regs->prer);
prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
- writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+ writel_relaxed(prer, rtc->base + regs->prer);
/* Force 24h time format */
- cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+ cr = readl_relaxed(rtc->base + regs->cr);
cr &= ~STM32_RTC_CR_FMT;
- writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+ writel_relaxed(cr, rtc->base + regs->cr);
stm32_rtc_exit_init_mode(rtc);
@@ -571,6 +638,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
static int stm32_rtc_probe(struct platform_device *pdev)
{
struct stm32_rtc *rtc;
+ const struct stm32_rtc_registers *regs;
struct resource *res;
int ret;
@@ -585,6 +653,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
rtc->data = (struct stm32_rtc_data *)
of_device_get_match_data(&pdev->dev);
+ regs = &rtc->data->regs;
if (rtc->data->need_dbp) {
rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
@@ -688,7 +757,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
* If INITS flag is reset (calendar year field set to 0x00), calendar
* must be initialized
*/
- if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
+ if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
dev_warn(&pdev->dev, "Date/Time must be initialized\n");
return 0;
@@ -708,13 +777,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
static int stm32_rtc_remove(struct platform_device *pdev)
{
struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+ const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int cr;
/* Disable interrupts */
stm32_rtc_wpr_unlock(rtc);
- cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+ cr = readl_relaxed(rtc->base + regs->cr);
cr &= ~STM32_RTC_CR_ALRAIE;
- writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+ writel_relaxed(cr, rtc->base + regs->cr);
stm32_rtc_wpr_lock(rtc);
clk_disable_unprepare(rtc->rtc_ck);
--
2.7.4
^ permalink raw reply related
* [PATCH v3 1/4] rtc: stm32: fix misspelling and misalignment issues
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
Maxime Coquelin, Alexandre Torgue
Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel,
Amelie Delaunay
In-Reply-To: <1526558666-24243-1-git-send-email-amelie.delaunay@st.com>
This patch cleans the following checkpatch complaints:
CHECK: 'initalized' may be misspelled - perhaps 'initialized'?
#644: FILE: drivers/rtc/rtc-stm32.c:644:
+ * the calendar has been initalized or not. INITS flag is reset by a
CHECK: Alignment should match open parenthesis
#669: FILE: drivers/rtc/rtc-stm32.c:669:
+ rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &stm32_rtc_ops, THIS_MODULE);
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
drivers/rtc/rtc-stm32.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index de49b5b..d41f804 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -641,7 +641,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
/*
* After a system reset, RTC_ISR.INITS flag can be read to check if
- * the calendar has been initalized or not. INITS flag is reset by a
+ * the calendar has been initialized or not. INITS flag is reset by a
* power-on reset (no vbat, no power-supply). It is not reset if
* rtc_ck parent clock has changed (so RTC prescalers need to be
* changed). That's why we cannot rely on this flag to know if RTC
@@ -666,7 +666,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
"alarm won't be able to wake up the system");
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
- &stm32_rtc_ops, THIS_MODULE);
+ &stm32_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
ret = PTR_ERR(rtc->rtc_dev);
dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
--
2.7.4
^ permalink raw reply related
* [PATCH v3 0/4] Introduce STM32MP1 RTC
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
Maxime Coquelin, Alexandre Torgue
Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel,
Amelie Delaunay
This series introduces STM32MP1 RTC.
On STM32MP1:
- two clocks are needed, plck and rtc_ck;
- to wakeup the system, a wakeup alarm interrupt is needed;
- some registers or bits have moved, but the operation is the same;
- the Backup Domain Protection (DBP) is not managed by RTC driver.
---
Changes in v3:
* Move cleanup changes in a separate patch
* Replace regs and evts by pointers to ensure no copy is made
* Set all registers offset as u16 instead of u8 and u16
* Fix Kbuild smatch warning:
drivers/rtc/rtc-stm32.c:827 stm32_rtc_probe()
warn: always true condition '(regs.verr != ~0) => (0-u16max != (-1))'
Changes in v2:
* One compatible per line in bindings file
* Remove unnecessary comment under rtc_ck as this clock is required for all
* Remove interrupts-extended and add stm32mp1 rtc alarm wakeup interrupt in
interrupts property description
Amelie Delaunay (4):
rtc: stm32: fix misspelling and misalignment issues
rtc: stm32: rework register management to prepare other version of RTC
dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
rtc: stm32: add stm32mp1 rtc support
.../devicetree/bindings/rtc/st,stm32-rtc.txt | 27 +-
drivers/rtc/rtc-stm32.c | 273 ++++++++++++++++-----
2 files changed, 229 insertions(+), 71 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH v5 3/3] ARM: dts: tegra: Work safely with 256 MB Colibri-T20 modules
From: Stefan Agner @ 2018-05-17 11:42 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
devicetree, linux-tegra, linux-kernel, Marcel Ziswiler,
Lucas Stach
In-Reply-To: <1526543103-21668-3-git-send-email-krzk@kernel.org>
On 17.05.2018 09:45, Krzysztof Kozlowski wrote:
> Colibri-T20 can come in 256 MB RAM (with 512 MB NAND) or 512 MB RAM
> (with 1024 MB NAND) flavors. Both of them will use the same DTSI
> expecting the bootloader to do the fixup of /memory node. However in
> case it does not happen, let's stay on safe side by limiting the memory
> to 256 MB for both versions of Colibri-T20.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
>
> ---
>
> RFT:
> Not tested on 512 MB module as I have only the 256 MB one.
>
> Changes since v4:
> 1. Drop the 512 suffix from file names (suggested by Stefan).
>
> Changes since v3:
> 1. Reduce the memory in existing DTSI instead of creating a new one
> (suggested by Marcel).
>
> Changes since v2:
> 1. Do not add new compatible but use everywhere existing
> "toradex,colibri_t20-512" (suggested by Rob).
>
> Changes since v1:
> 1. Fix memory size in tegra20-colibri-256.dtsi (was working fine because
> my bootloader uses mem= argument).
> ---
> arch/arm/boot/dts/Makefile | 2 +-
> .../boot/dts/{tegra20-colibri-512.dtsi => tegra20-colibri.dtsi} | 9 +++++++--
> arch/arm/boot/dts/{tegra20-iris-512.dts => tegra20-iris.dts} | 4 ++--
Almost.
Since we rename anyway, I would add the module name here too. The
hardware actually consists of the Tegra 2 SoC on a Colibri Module,
sitting in a Iris board.
So:
arch/arm/boot/dts/tegra20-colibri-iris.dts
This would align with the other modules we have upstream, e.g.:
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
--
Stefan
> 3 files changed, 10 insertions(+), 5 deletions(-)
> rename arch/arm/boot/dts/{tegra20-colibri-512.dtsi =>
> tegra20-colibri.dtsi} (98%)
> rename arch/arm/boot/dts/{tegra20-iris-512.dts => tegra20-iris.dts} (95%)
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index ec2024ea8b1e..837f8274b3ee 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1030,7 +1030,7 @@ dtb-$(CONFIG_ARCH_TANGO) += \
> tango4-vantage-1172.dtb
> dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
> tegra20-harmony.dtb \
> - tegra20-iris-512.dtb \
> + tegra20-iris.dtb \
> tegra20-medcom-wide.dtb \
> tegra20-paz00.dtb \
> tegra20-plutux.dtb \
> diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> b/arch/arm/boot/dts/tegra20-colibri.dtsi
> similarity index 98%
> rename from arch/arm/boot/dts/tegra20-colibri-512.dtsi
> rename to arch/arm/boot/dts/tegra20-colibri.dtsi
> index 305efb275b48..b9387c540450 100644
> --- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> +++ b/arch/arm/boot/dts/tegra20-colibri.dtsi
> @@ -2,7 +2,7 @@
> #include "tegra20.dtsi"
>
> / {
> - model = "Toradex Colibri T20 512MB";
> + model = "Toradex Colibri T20 256/512 MB";
> compatible = "toradex,colibri_t20-512", "nvidia,tegra20";
>
> aliases {
> @@ -12,7 +12,12 @@
>
> memory@0 {
> device_type = "memory";
> - reg = <0x00000000 0x20000000>;
> + /*
> + * Set memory to 256 MB to be safe as this could be used on
> + * 256 or 512 MB module. It is expected from bootloader
> + * to fix this up for 512 MB version.
> + */
> + reg = <0x00000000 0x10000000>;
> };
>
> host1x@50000000 {
> diff --git a/arch/arm/boot/dts/tegra20-iris-512.dts
> b/arch/arm/boot/dts/tegra20-iris.dts
> similarity index 95%
> rename from arch/arm/boot/dts/tegra20-iris-512.dts
> rename to arch/arm/boot/dts/tegra20-iris.dts
> index 40126388946d..57f16c0e9917 100644
> --- a/arch/arm/boot/dts/tegra20-iris-512.dts
> +++ b/arch/arm/boot/dts/tegra20-iris.dts
> @@ -1,10 +1,10 @@
> // SPDX-License-Identifier: GPL-2.0
> /dts-v1/;
>
> -#include "tegra20-colibri-512.dtsi"
> +#include "tegra20-colibri.dtsi"
>
> / {
> - model = "Toradex Colibri T20 512MB on Iris";
> + model = "Toradex Colibri T20 256/512 MB on Iris";
> compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20";
>
> aliases {
^ permalink raw reply
* Re: [PATCH v5 1/3] ARM: dts: tegra: Remove skeleton.dtsi and fix DTC warnings for /memory
From: Stefan Agner @ 2018-05-17 11:39 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
devicetree, linux-tegra, linux-kernel, Marcel Ziswiler,
Lucas Stach
In-Reply-To: <1526543103-21668-1-git-send-email-krzk@kernel.org>
On 17.05.2018 09:45, Krzysztof Kozlowski wrote:
> Remove the usage of skeleton.dtsi and add necessary properties to /memory
> node to fix the DTC warnings:
>
> arch/arm/boot/dts/tegra20-harmony.dtb: Warning (unit_address_vs_reg):
> /memory: node has a reg or ranges property, but no unit name
>
> The DTB after the change is the same as before except adding
> unit-address to /memory node.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
>
> ---
>
> Changes since v4:
> 1. None
> ---
> arch/arm/boot/dts/tegra114-dalmore.dts | 3 ++-
> arch/arm/boot/dts/tegra114-roth.dts | 3 ++-
> arch/arm/boot/dts/tegra114-tn7.dts | 3 ++-
> arch/arm/boot/dts/tegra114.dtsi | 4 ++--
> arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi | 3 ++-
> arch/arm/boot/dts/tegra124-apalis.dtsi | 3 ++-
> arch/arm/boot/dts/tegra124-jetson-tk1.dts | 3 ++-
> arch/arm/boot/dts/tegra124-nyan.dtsi | 3 ++-
> arch/arm/boot/dts/tegra124-venice2.dts | 3 ++-
> arch/arm/boot/dts/tegra124.dtsi | 2 --
> arch/arm/boot/dts/tegra20-colibri-512.dtsi | 3 ++-
> arch/arm/boot/dts/tegra20-harmony.dts | 3 ++-
> arch/arm/boot/dts/tegra20-paz00.dts | 3 ++-
> arch/arm/boot/dts/tegra20-seaboard.dts | 3 ++-
> arch/arm/boot/dts/tegra20-tamonten.dtsi | 3 ++-
> arch/arm/boot/dts/tegra20-trimslice.dts | 3 ++-
> arch/arm/boot/dts/tegra20-ventana.dts | 3 ++-
> arch/arm/boot/dts/tegra20.dtsi | 7 +++++--
> arch/arm/boot/dts/tegra30-apalis.dtsi | 5 +++++
> arch/arm/boot/dts/tegra30-beaver.dts | 3 ++-
> arch/arm/boot/dts/tegra30-cardhu.dtsi | 3 ++-
> arch/arm/boot/dts/tegra30-colibri.dtsi | 3 ++-
> arch/arm/boot/dts/tegra30.dtsi | 7 +++++--
> 23 files changed, 53 insertions(+), 26 deletions(-)
>
> diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts
> b/arch/arm/boot/dts/tegra114-dalmore.dts
> index eafff16765b4..5cdcedfc19cb 100644
> --- a/arch/arm/boot/dts/tegra114-dalmore.dts
> +++ b/arch/arm/boot/dts/tegra114-dalmore.dts
> @@ -23,7 +23,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@80000000 {
> + device_type = "memory";
> reg = <0x80000000 0x40000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra114-roth.dts
> b/arch/arm/boot/dts/tegra114-roth.dts
> index 7ed7370ee67a..b4f329a07c60 100644
> --- a/arch/arm/boot/dts/tegra114-roth.dts
> +++ b/arch/arm/boot/dts/tegra114-roth.dts
> @@ -28,7 +28,8 @@
> };
> };
>
> - memory {
> + memory@80000000 {
> + device_type = "memory";
> /* memory >= 0x79600000 is reserved for firmware usage */
> reg = <0x80000000 0x79600000>;
> };
> diff --git a/arch/arm/boot/dts/tegra114-tn7.dts
> b/arch/arm/boot/dts/tegra114-tn7.dts
> index 7fc4a8b31e45..12092d344ce8 100644
> --- a/arch/arm/boot/dts/tegra114-tn7.dts
> +++ b/arch/arm/boot/dts/tegra114-tn7.dts
> @@ -28,7 +28,8 @@
> };
> };
>
> - memory {
> + memory@80000000 {
> + device_type = "memory";
> /* memory >= 0x37e00000 is reserved for firmware usage */
> reg = <0x80000000 0x37e00000>;
> };
> diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
> index 0e4a13295d8a..b917784d3f97 100644
> --- a/arch/arm/boot/dts/tegra114.dtsi
> +++ b/arch/arm/boot/dts/tegra114.dtsi
> @@ -5,11 +5,11 @@
> #include <dt-bindings/pinctrl/pinctrl-tegra.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
>
> -#include "skeleton.dtsi"
> -
> / {
> compatible = "nvidia,tegra114";
> interrupt-parent = <&lic>;
> + #address-cells = <1>;
> + #size-cells = <1>;
>
> host1x@50000000 {
> compatible = "nvidia,tegra114-host1x", "simple-bus";
> diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
> b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
> index bb67edb016c5..80b52c612891 100644
> --- a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
> +++ b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
> @@ -15,7 +15,8 @@
> compatible = "toradex,apalis-tk1-v1.2", "toradex,apalis-tk1",
> "nvidia,tegra124";
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x0 0x80000000 0x0 0x80000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra124-apalis.dtsi
> b/arch/arm/boot/dts/tegra124-apalis.dtsi
> index 65a2161b9b8e..3ca7601cafe9 100644
> --- a/arch/arm/boot/dts/tegra124-apalis.dtsi
> +++ b/arch/arm/boot/dts/tegra124-apalis.dtsi
> @@ -50,7 +50,8 @@
> model = "Toradex Apalis TK1";
> compatible = "toradex,apalis-tk1", "nvidia,tegra124";
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x0 0x80000000 0x0 0x80000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
> b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
> index 6dbcf84dafbc..8d9e6ee6c6a7 100644
> --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
> +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
> @@ -24,7 +24,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x0 0x80000000 0x0 0x80000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi
> b/arch/arm/boot/dts/tegra124-nyan.dtsi
> index 3609367037a6..15a2b0e3237e 100644
> --- a/arch/arm/boot/dts/tegra124-nyan.dtsi
> +++ b/arch/arm/boot/dts/tegra124-nyan.dtsi
> @@ -13,7 +13,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x0 0x80000000 0x0 0x80000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra124-venice2.dts
> b/arch/arm/boot/dts/tegra124-venice2.dts
> index 89bcc178994d..241cdc4b6600 100644
> --- a/arch/arm/boot/dts/tegra124-venice2.dts
> +++ b/arch/arm/boot/dts/tegra124-venice2.dts
> @@ -18,7 +18,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x0 0x80000000 0x0 0x80000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
> index 174092bfac90..df1642876a4c 100644
> --- a/arch/arm/boot/dts/tegra124.dtsi
> +++ b/arch/arm/boot/dts/tegra124.dtsi
> @@ -7,8 +7,6 @@
> #include <dt-bindings/reset/tegra124-car.h>
> #include <dt-bindings/thermal/tegra124-soctherm.h>
>
> -#include "skeleton.dtsi"
> -
> / {
> compatible = "nvidia,tegra124";
> interrupt-parent = <&lic>;
> diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> index 5c202b3e3bb1..305efb275b48 100644
> --- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> +++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> @@ -10,7 +10,8 @@
> rtc1 = "/rtc@7000e000";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x00000000 0x20000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra20-harmony.dts
> b/arch/arm/boot/dts/tegra20-harmony.dts
> index 628a55a9318b..5009a55ae15c 100644
> --- a/arch/arm/boot/dts/tegra20-harmony.dts
> +++ b/arch/arm/boot/dts/tegra20-harmony.dts
> @@ -18,7 +18,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x00000000 0x40000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra20-paz00.dts
> b/arch/arm/boot/dts/tegra20-paz00.dts
> index 30436969adc0..e794ac5442ef 100644
> --- a/arch/arm/boot/dts/tegra20-paz00.dts
> +++ b/arch/arm/boot/dts/tegra20-paz00.dts
> @@ -19,7 +19,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x00000000 0x20000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts
> b/arch/arm/boot/dts/tegra20-seaboard.dts
> index 284aae351ff2..6cb832cfa4f3 100644
> --- a/arch/arm/boot/dts/tegra20-seaboard.dts
> +++ b/arch/arm/boot/dts/tegra20-seaboard.dts
> @@ -18,7 +18,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x00000000 0x40000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi
> b/arch/arm/boot/dts/tegra20-tamonten.dtsi
> index 872046d48709..6ceb1228fed3 100644
> --- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
> +++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
> @@ -15,7 +15,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x00000000 0x20000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts
> b/arch/arm/boot/dts/tegra20-trimslice.dts
> index d55c6b240a30..3f94be3da9e5 100644
> --- a/arch/arm/boot/dts/tegra20-trimslice.dts
> +++ b/arch/arm/boot/dts/tegra20-trimslice.dts
> @@ -18,7 +18,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x00000000 0x40000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra20-ventana.dts
> b/arch/arm/boot/dts/tegra20-ventana.dts
> index ee3fbf941e79..c897a90289bc 100644
> --- a/arch/arm/boot/dts/tegra20-ventana.dts
> +++ b/arch/arm/boot/dts/tegra20-ventana.dts
> @@ -18,7 +18,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@0 {
> + device_type = "memory";
> reg = <0x00000000 0x40000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> index 0a7136462a1a..290ebbeb210f 100644
> --- a/arch/arm/boot/dts/tegra20.dtsi
> +++ b/arch/arm/boot/dts/tegra20.dtsi
> @@ -4,11 +4,14 @@
> #include <dt-bindings/pinctrl/pinctrl-tegra.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
>
> -#include "skeleton.dtsi"
> -
> / {
> compatible = "nvidia,tegra20";
> interrupt-parent = <&lic>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + chosen { };
> + aliases { };
>
> iram@40000000 {
> compatible = "mmio-sram";
> diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi
> b/arch/arm/boot/dts/tegra30-apalis.dtsi
> index d1d21ec2a844..184f60c720fa 100644
> --- a/arch/arm/boot/dts/tegra30-apalis.dtsi
> +++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
> @@ -10,6 +10,11 @@
> model = "Toradex Apalis T30";
> compatible = "toradex,apalis_t30", "nvidia,tegra30";
>
> + memory@0 {
> + device_type = "memory";
> + reg = <0 0>;
> + };
> +
> pcie@3000 {
> avdd-pexa-supply = <&vdd2_reg>;
> vdd-pexa-supply = <&vdd2_reg>;
> diff --git a/arch/arm/boot/dts/tegra30-beaver.dts
> b/arch/arm/boot/dts/tegra30-beaver.dts
> index ae52a5039506..72369877d284 100644
> --- a/arch/arm/boot/dts/tegra30-beaver.dts
> +++ b/arch/arm/boot/dts/tegra30-beaver.dts
> @@ -17,7 +17,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@80000000 {
> + device_type = "memory";
> reg = <0x80000000 0x7ff00000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi
> b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> index 92a9740c533f..24c04d4c335d 100644
> --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
> +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> @@ -40,7 +40,8 @@
> stdout-path = "serial0:115200n8";
> };
>
> - memory {
> + memory@80000000 {
> + device_type = "memory";
> reg = <0x80000000 0x40000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi
> b/arch/arm/boot/dts/tegra30-colibri.dtsi
> index c44d8c40c410..cc46cedf80b9 100644
> --- a/arch/arm/boot/dts/tegra30-colibri.dtsi
> +++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
> @@ -10,7 +10,8 @@
> model = "Toradex Colibri T30";
> compatible = "toradex,colibri_t30", "nvidia,tegra30";
>
> - memory {
> + memory@80000000 {
> + device_type = "memory";
> reg = <0x80000000 0x40000000>;
> };
>
> diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
> index a110cf84d85f..4383f0fd789d 100644
> --- a/arch/arm/boot/dts/tegra30.dtsi
> +++ b/arch/arm/boot/dts/tegra30.dtsi
> @@ -5,11 +5,14 @@
> #include <dt-bindings/pinctrl/pinctrl-tegra.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
>
> -#include "skeleton.dtsi"
> -
> / {
> compatible = "nvidia,tegra30";
> interrupt-parent = <&lic>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + chosen { };
> + aliases { };
Could we not add
memory { device_type = "memory"; };
in the SoC level device trees?
This would save device_type in all other instances.
That is also how it is done in other places, e.g.
arch/arm/boot/dts/imx6qdl.dtsi
Also, could we maybe split this in two?
ARM: dts: tegra: Remove skeleton.dtsi
ARM: dts: tegra: fix DTC warnings for /memory
The first would only touch SoC level dts.
The second then would fix DTC warnings by adding the address to the
memory nodes in all board files.
--
Stefan
>
> pcie@3000 {
> compatible = "nvidia,tegra30-pcie";
^ permalink raw reply
* Re: [PATCH v5 2/3] ARM: dts: tegra: Fix unit_address_vs_reg and avoid_unnecessary_addr_size DTC warnings
From: Stefan Agner @ 2018-05-17 11:30 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
devicetree, linux-tegra, linux-kernel, Marcel Ziswiler,
Lucas Stach
In-Reply-To: <1526543103-21668-2-git-send-email-krzk@kernel.org>
On 17.05.2018 09:45, Krzysztof Kozlowski wrote:
> Remove unneeded address/size cells properties and unit addresses to fix
> DTC warnings like:
>
> arch/arm/boot/dts/tegra30-apalis-eval.dtb: Warning (unit_address_vs_reg):
> /i2c@7000d000/stmpe811@41/stmpe_touchscreen@0: node has a unit
> name, but no reg property
> arch/arm/boot/dts/tegra30-apalis-eval.dtb: Warning
> (avoid_unnecessary_addr_size):
> /i2c@7000d000/stmpe811@41: unnecessary
> #address-cells/#size-cells without "ranges" or child "reg" property
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Looks good!
Reviewed-by: Stefan Agner <stefan@agner.ch>
>
> ---
>
> Changes since v4:
> 1. None
> ---
> arch/arm/boot/dts/tegra30-apalis.dtsi | 4 +---
> arch/arm/boot/dts/tegra30-beaver.dts | 3 ---
> arch/arm/boot/dts/tegra30-colibri.dtsi | 2 --
> 3 files changed, 1 insertion(+), 8 deletions(-)
>
> diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi
> b/arch/arm/boot/dts/tegra30-apalis.dtsi
> index 184f60c720fa..5038ca7b68af 100644
> --- a/arch/arm/boot/dts/tegra30-apalis.dtsi
> +++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
> @@ -590,8 +590,6 @@
> /* STMPE811 touch screen controller */
> stmpe811@41 {
> compatible = "st,stmpe811";
> - #address-cells = <1>;
> - #size-cells = <0>;
> reg = <0x41>;
> interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
> interrupt-parent = <&gpio>;
> @@ -600,7 +598,7 @@
> blocks = <0x5>;
> irq-trigger = <0x1>;
>
> - stmpe_touchscreen@0 {
> + stmpe_touchscreen {
> compatible = "st,stmpe-ts";
> /* 3.25 MHz ADC clock speed */
> st,adc-freq = <1>;
> diff --git a/arch/arm/boot/dts/tegra30-beaver.dts
> b/arch/arm/boot/dts/tegra30-beaver.dts
> index 72369877d284..961934f70639 100644
> --- a/arch/arm/boot/dts/tegra30-beaver.dts
> +++ b/arch/arm/boot/dts/tegra30-beaver.dts
> @@ -1791,9 +1791,6 @@
> vccio-supply = <&vdd_5v_in_reg>;
>
> regulators {
> - #address-cells = <1>;
> - #size-cells = <0>;
> -
> vdd1_reg: vdd1 {
> regulator-name = "vddio_ddr_1v2";
> regulator-min-microvolt = <1200000>;
> diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi
> b/arch/arm/boot/dts/tegra30-colibri.dtsi
> index cc46cedf80b9..a593dc8be47f 100644
> --- a/arch/arm/boot/dts/tegra30-colibri.dtsi
> +++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
> @@ -352,8 +352,6 @@
> /* STMPE811 touch screen controller */
> stmpe811@41 {
> compatible = "st,stmpe811";
> - #address-cells = <1>;
> - #size-cells = <0>;
> reg = <0x41>;
> interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
> interrupt-parent = <&gpio>;
^ permalink raw reply
* RE: [v4 2/6] dmaengine: fsl-qdma: Add qDMA controller driver for Layerscape SoCs
From: Wen He @ 2018-05-17 11:27 UTC (permalink / raw)
To: Vinod
Cc: dmaengine@vger.kernel.org, robh+dt@kernel.org,
devicetree@vger.kernel.org, Leo Li, Jiafei Pan, Jiaheng Fan
In-Reply-To: <20180517060430.GU13271@vkoul-mobl>
> -----Original Message-----
> From: Vinod [mailto:vkoul@kernel.org]
> Sent: 2018年5月17日 14:05
> To: Wen He <wen.he_1@nxp.com>
> Cc: vinod.koul@intel.com; dmaengine@vger.kernel.org; robh+dt@kernel.org;
> devicetree@vger.kernel.org; Leo Li <leoyang.li@nxp.com>; Jiafei Pan
> <jiafei.pan@nxp.com>; Jiaheng Fan <jiaheng.fan@nxp.com>
> Subject: Re: [v4 2/6] dmaengine: fsl-qdma: Add qDMA controller driver for
> Layerscape SoCs
>
> On 14-05-18, 20:03, Wen He wrote:
>
> > +
> > +/* Registers for bit and genmask */
> > +#define FSL_QDMA_CQIDR_SQT 0x8000
>
> BIT() ?
Sorry, Maybe I should replace 0x8000 to BIT(15).
>
> > +#define QDMA_CCDF_MASK GENMASK(28, 20)
> > +#define QDMA_CCDF_FOTMAT BIT(29)
> > +#define QDMA_CCDF_SER BIT(30)
> > +#define QDMA_SG_FIN BIT(30)
> > +#define QDMA_SG_EXT BIT(31)
> > +#define QDMA_SG_LEN_MASK GENMASK(29, 0)
> > +
> > +#define QDMA_CCDF_STATUS 20
> > +#define QDMA_CCDF_OFFSET 20
> > +#define FSL_QDMA_BCQIER_CQTIE 0x8000
> > +#define FSL_QDMA_BCQIER_CQPEIE 0x800000
> > +#define FSL_QDMA_BSQICR_ICEN 0x80000000
>
> here and few other places as well
>
Got it, will be next version replace to BIT() definition.
> > +
> > +u64 pre_addr, pre_queue;
>
> why do we have a global?
Let's us see qDMA that how is works?
First, the status notification for DMA jobs are reported back to the status queue.
Status information is carried within the command descriptor status/command field,
bits 120-127. The command descriptor dequeue pointer advances only after the
transaction has completed and the status information field has been updated.
Then, the command descriptor address field wiil pointer to the command descriptor in
its original format. It is the responsibity of the address of the status queue consumer
to deallocate buffers as needed when the command descriptor address pointer is non-zero.
More details of the Status Queue can be found in QorIQ Layerscape Soc datasheet.
So, these variable is used to record latest value that command descriptor queue
and status field.
Every time variables value is zero when set these variable to local, that's not what I want.
>
> > +static void fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp,
> > + dma_addr_t dst, dma_addr_t src, u32 len) {
> > + struct fsl_qdma_format *ccdf, *csgf_desc, *csgf_src, *csgf_dest;
> > + struct fsl_qdma_sdf *sdf;
> > + struct fsl_qdma_ddf *ddf;
> > +
> > + ccdf = (struct fsl_qdma_format *)fsl_comp->virt_addr;
>
> Cast are not required to/away from void
>
Does means: remove force conver?
> > + csgf_desc = (struct fsl_qdma_format *)fsl_comp->virt_addr + 1;
> > + csgf_src = (struct fsl_qdma_format *)fsl_comp->virt_addr + 2;
> > + csgf_dest = (struct fsl_qdma_format *)fsl_comp->virt_addr + 3;
> > + sdf = (struct fsl_qdma_sdf *)fsl_comp->virt_addr + 4;
> > + ddf = (struct fsl_qdma_ddf *)fsl_comp->virt_addr + 5;
> > +
> > + memset(fsl_comp->virt_addr, 0, FSL_QDMA_BASE_BUFFER_SIZE);
> > + /* Head Command Descriptor(Frame Descriptor) */
> > + qdma_desc_addr_set64(ccdf, fsl_comp->bus_addr + 16);
> > + qdma_ccdf_set_format(ccdf, qdma_ccdf_get_offset(ccdf));
> > + qdma_ccdf_set_ser(ccdf, qdma_ccdf_get_status(ccdf));
> > +
> > + /* Status notification is enqueued to status queue. */
> > + /* Compound Command Descriptor(Frame List Table) */
> > + qdma_desc_addr_set64(csgf_desc, fsl_comp->bus_addr + 64);
> > + /* It must be 32 as Compound S/G Descriptor */
> > + qdma_csgf_set_len(csgf_desc, 32);
> > + qdma_desc_addr_set64(csgf_src, src);
> > + qdma_csgf_set_len(csgf_src, len);
> > + qdma_desc_addr_set64(csgf_dest, dst);
> > + qdma_csgf_set_len(csgf_dest, len);
> > + /* This entry is the last entry. */
> > + qdma_csgf_set_f(csgf_dest, len);
> > + /* Descriptor Buffer */
> > + sdf->cmd = cpu_to_le32(
> > + FSL_QDMA_CMD_RWTTYPE <<
> FSL_QDMA_CMD_RWTTYPE_OFFSET);
> > + ddf->cmd = cpu_to_le32(
> > + FSL_QDMA_CMD_RWTTYPE <<
> FSL_QDMA_CMD_RWTTYPE_OFFSET);
> > + ddf->cmd |= cpu_to_le32(
> > + FSL_QDMA_CMD_LWC << FSL_QDMA_CMD_LWC_OFFSET); }
> > +
> > +/*
> > + * Pre-request full command descriptor for enqueue.
> > + */
> > +static int fsl_qdma_pre_request_enqueue_desc(struct fsl_qdma_queue
> > +*queue) {
> > + struct fsl_qdma_comp *comp_temp;
> > + int i;
> > +
> > + for (i = 0; i < queue->n_cq; i++) {
> > + comp_temp = kzalloc(sizeof(*comp_temp), GFP_KERNEL);
> > + if (!comp_temp)
> > + return -ENOMEM;
>
> where is the previous allocations freed? Return of this function is not even
> checked??
>
Sorry, Maybe I forget.
> > + comp_temp->virt_addr = dma_pool_alloc(queue->comp_pool,
> > + GFP_KERNEL,
> > + &comp_temp->bus_addr);
> > + if (!comp_temp->virt_addr)
> > + return -ENOMEM;
>
> and here too
okay
> > + list_add_tail(&comp_temp->list, &queue->comp_free);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * Request a command descriptor for enqueue.
> > + */
> > +static struct fsl_qdma_comp *fsl_qdma_request_enqueue_desc(
> > + struct fsl_qdma_chan *fsl_chan,
> > + unsigned int dst_nents,
> > + unsigned int src_nents)
> > +{
> > + struct fsl_qdma_comp *comp_temp;
> > + struct fsl_qdma_sg *sg_block;
> > + struct fsl_qdma_queue *queue = fsl_chan->queue;
> > + unsigned long flags;
> > + unsigned int dst_sg_entry_block, src_sg_entry_block, sg_entry_total,
> > +i;
> > +
> > + spin_lock_irqsave(&queue->queue_lock, flags);
> > + if (list_empty(&queue->comp_free)) {
> > + spin_unlock_irqrestore(&queue->queue_lock, flags);
> > + comp_temp = kzalloc(sizeof(*comp_temp), GFP_KERNEL);
> > + if (!comp_temp)
> > + return NULL;
> > + comp_temp->virt_addr = dma_pool_alloc(queue->comp_pool,
> > + GFP_KERNEL,
> > + &comp_temp->bus_addr);
> > + if (!comp_temp->virt_addr) {
> > + kfree(comp_temp);
> > + return NULL;
> > + }
> > +
> > + } else {
> > + comp_temp = list_first_entry(&queue->comp_free,
> > + struct fsl_qdma_comp,
> > + list);
> > + list_del(&comp_temp->list);
> > + spin_unlock_irqrestore(&queue->queue_lock, flags);
> > + }
> > +
> > + if (dst_nents != 0)
> > + dst_sg_entry_block = dst_nents /
> > + (FSL_QDMA_EXPECT_SG_ENTRY_NUM - 1) + 1;
>
> DIV_ROUND_UP()?
>
The DIV_ROUND_UP() definition see below:
#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP
#define __KERNEL_DIV_ROUND_UP(n ,d) (((n) + (d) - 1) / (d))
But here is 'd / (n - 1) + 1' ?
> > + else
> > + dst_sg_entry_block = 0;
> > +
> > + if (src_nents != 0)
> > + src_sg_entry_block = src_nents /
> > + (FSL_QDMA_EXPECT_SG_ENTRY_NUM - 1) + 1;
> > + else
> > + src_sg_entry_block = 0;
> > +
> > + sg_entry_total = dst_sg_entry_block + src_sg_entry_block;
> > + if (sg_entry_total) {
> > + sg_block = kzalloc(sizeof(*sg_block) *
> > + sg_entry_total,
> > + GFP_KERNEL);
>
> kcalloc?
>
All right, replace.
> > + if (!sg_block) {
> > + dma_pool_free(queue->comp_pool,
> > + comp_temp->virt_addr,
> > + comp_temp->bus_addr);
> > + return NULL;
> > + }
> > + comp_temp->sg_block = sg_block;
> > + for (i = 0; i < sg_entry_total; i++) {
> > + sg_block->virt_addr = dma_pool_alloc(queue->sg_pool,
> > + GFP_KERNEL,
> > + &sg_block->bus_addr);
>
> no check if this succeeded?
>
Sorry, will be next version fix.
> > + memset(sg_block->virt_addr, 0,
> > + FSL_QDMA_EXPECT_SG_ENTRY_NUM * 16);
>
> why FSL_QDMA_EXPECT_SG_ENTRY_NUM * 16? and not what you
> allocated?
>
see line 497.
The sg_pool buffer size created is FSL_QDMA_EXPECT_SG_ENTRY_NUM * 16.
> > +static struct fsl_qdma_queue *fsl_qdma_alloc_queue_resources(
> > + struct platform_device *pdev,
> > + unsigned int queue_num)
> > +{
> > + struct fsl_qdma_queue *queue_head, *queue_temp;
> > + int ret, len, i;
> > + unsigned int queue_size[FSL_QDMA_QUEUE_MAX];
> > +
> > + if (queue_num > FSL_QDMA_QUEUE_MAX)
> > + queue_num = FSL_QDMA_QUEUE_MAX;
> > + len = sizeof(*queue_head) * queue_num;
> > + queue_head = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
> > + if (!queue_head)
> > + return NULL;
> > +
> > + ret = device_property_read_u32_array(&pdev->dev, "queue-sizes",
> > + queue_size, queue_num);
> > + if (ret) {
> > + dev_err(&pdev->dev, "Can't get queue-sizes.\n");
> > + return NULL;
> > + }
> > +
> > + for (i = 0; i < queue_num; i++) {
> > + if (queue_size[i] > FSL_QDMA_CIRCULAR_DESC_SIZE_MAX
> > + || queue_size[i] < FSL_QDMA_CIRCULAR_DESC_SIZE_MIN) {
> > + dev_err(&pdev->dev, "Get wrong queue-sizes.\n");
> > + return NULL;
> > + }
> > + queue_temp = queue_head + i;
> > + queue_temp->cq = dma_alloc_coherent(&pdev->dev,
> > + sizeof(struct fsl_qdma_format) *
> > + queue_size[i],
> > + &queue_temp->bus_addr,
> > + GFP_KERNEL);
> > + if (!queue_temp->cq)
> > + return NULL;
> > + queue_temp->n_cq = queue_size[i];
> > + queue_temp->id = i;
> > + queue_temp->virt_head = queue_temp->cq;
> > + queue_temp->virt_tail = queue_temp->cq;
> > + /*
> > + * The dma pool for queue command buffer
> > + */
> > + queue_temp->comp_pool = dma_pool_create("comp_pool",
> > + &pdev->dev,
> > + FSL_QDMA_BASE_BUFFER_SIZE,
> > + 16, 0);
> > + if (!queue_temp->comp_pool)
> > + goto err_free_comp;
> > +
> > + /*
> > + * The dma pool for queue command buffer
>
> same comment as prev?
>
okay, second comment should be remove.
> > +static int fsl_qdma_queue_transfer_complete(struct fsl_qdma_engine
> > +*fsl_qdma) {
> > + struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue;
> > + struct fsl_qdma_queue *fsl_status = fsl_qdma->status;
> > + struct fsl_qdma_queue *temp_queue;
> > + struct fsl_qdma_comp *fsl_comp;
> > + struct fsl_qdma_format *status_addr;
> > + struct fsl_qdma_format *csgf_src;
> > + void __iomem *block = fsl_qdma->block_base;
> > + u32 reg, i;
> > + bool duplicate, duplicate_handle;
> > +
> > + while (1) {
> > + duplicate = 0;
> > + duplicate_handle = 0;
> > + reg = qdma_readl(fsl_qdma, block + FSL_QDMA_BSQSR);
> > + if (reg & FSL_QDMA_BSQSR_QE)
> > + return 0;
> > + status_addr = fsl_status->virt_head;
> > + if (qdma_ccdf_get_queue(status_addr) == pre_queue &&
> > + qdma_ccdf_addr_get64(status_addr) == pre_addr)
> > + duplicate = 1;
> > + i = qdma_ccdf_get_queue(status_addr);
> > + pre_queue = qdma_ccdf_get_queue(status_addr);
> > + pre_addr = qdma_ccdf_addr_get64(status_addr);
> > + temp_queue = fsl_queue + i;
> > + spin_lock(&temp_queue->queue_lock);
> > + if (list_empty(&temp_queue->comp_used)) {
> > + if (duplicate)
> > + duplicate_handle = 1;
> > + else {
> > + spin_unlock(&temp_queue->queue_lock);
> > + return -1;
>
> -1? really. You are in while(1) wouldn't break make sense here?
>
Does means: using break?
> > +static enum dma_status fsl_qdma_tx_status(struct dma_chan *chan,
> > + dma_cookie_t cookie, struct dma_tx_state *txstate) {
> > + struct fsl_qdma_chan *fsl_chan = to_fsl_qdma_chan(chan);
>
> why do you need this here, its unused
>
okay , remove it.
> --
> ~Vinod
--
Best Regards,
Wen
^ permalink raw reply
* Re: [PATCH 1/2] clk: imx7d: correct enet clock CCGR register offset
From: Stefan Agner @ 2018-05-17 11:22 UTC (permalink / raw)
To: Anson Huang
Cc: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland,
mturquette, sboyd, adriana.reus, rui.silva, Linux-imx,
linux-arm-kernel, devicetree, linux-kernel, linux-clk
In-Reply-To: <1526546422-7431-1-git-send-email-Anson.Huang@nxp.com>
On 17.05.2018 10:40, Anson Huang wrote:
> Correct enet clock CCGR register offset.
>
> CCGR6: IMX7D_ENET_AXI_ROOT_CLK (enet1 and enet2 bus clocks)
> CCGR112: IMX7D_ENET1_TIME_ROOT_CLK, IMX7D_ENET1_IPG_ROOT_CLK
> CCGR113: IMX7D_ENET2_TIME_ROOT_CLK, IMX7D_ENET2_IPG_ROOT_CLK
>
> IMX7D_ENET_PHY_REF_ROOT_DIV supplies clock for PHY,
> no gate after this clock, its parent clock root has gate.
> IMX7D_ENET1_REF_ROOT_DIV/IMX7D_ENET2_REF_ROOT_DIV supplies clocks
> for enet IPG_CLK_RMII, no gate after the clock, its parent
> clock root has gate.
>
> IMX7D_PLL_ENET_MAIN_125M_CLK (anatop pll) supplies clock for
> enet RGMII tx_clk.
As far as I can tell there are two changes here in one patch:
1. The non existing IMX7D_ENET_PHY_REF_ROOT_CLK gate is removed
2. Shared clock gate for the enet time/ipg clock is taken into account.
I would rather prefer to have separate patches. The device tree change
also does two things, so this would lead to 4 patches total.
We can avoid the device tree change for the PHY clk and even maintain
backward compatibility for that part by renaming
IMX7D_ENET_PHY_REF_ROOT_DIV to IMX7D_ENET_PHY_REF_ROOT_CLK.
So this would end up with the following first patch to address the
PHY_ROOT clock issue:
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -738,7 +738,7 @@ static void __init imx7d_clocks_init(struct
device_node *ccm_node)
clks[IMX7D_ENET1_TIME_ROOT_DIV] =
imx_clk_divider2("enet1_time_post_div", "enet1_time_pre_div", base +
0xa780, 0, 6);
clks[IMX7D_ENET2_REF_ROOT_DIV] =
imx_clk_divider2("enet2_ref_post_div", "enet2_ref_pre_div", base +
0xa800, 0, 6);
clks[IMX7D_ENET2_TIME_ROOT_DIV] =
imx_clk_divider2("enet2_time_post_div", "enet2_time_pre_div", base +
0xa880, 0, 6);
- clks[IMX7D_ENET_PHY_REF_ROOT_DIV] =
imx_clk_divider2("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base +
0xa900, 0, 6);
+ clks[IMX7D_ENET_PHY_REF_ROOT_CLK] =
imx_clk_divider2("enet_phy_ref_root_clk", "enet_phy_ref_pre_div", base +
0xa900, 0, 6);
clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider2("eim_post_div",
"eim_pre_div", base + 0xa980, 0, 6);
clks[IMX7D_NAND_ROOT_CLK] = imx_clk_divider2("nand_root_clk",
"nand_pre_div", base + 0xaa00, 0, 6);
clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider2("qspi_post_div",
"qspi_pre_div", base + 0xaa80, 0, 6);
@@ -816,7 +816,6 @@ static void __init imx7d_clocks_init(struct
device_node *ccm_node)
clks[IMX7D_ENET1_TIME_ROOT_CLK] =
imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base +
0x44f0, 0);
clks[IMX7D_ENET2_REF_ROOT_CLK] =
imx_clk_gate4("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500,
0);
clks[IMX7D_ENET2_TIME_ROOT_CLK] =
imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base +
0x4510, 0);
- clks[IMX7D_ENET_PHY_REF_ROOT_CLK] =
imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base +
0x4520, 0);
clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk",
"eim_post_div", base + 0x4160, 0);
clks[IMX7D_NAND_RAWNAND_CLK] =
imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base +
0x4140, 0, &share_count_nand);
clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] =
imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk",
base + 0x4140, 0, &share_count_nand);
A second patch would then fix the clock gate issue and the third the
unavoidable device tree change for the ipg clock.
--
Stefan
>
> Based on Andy Duan's patch from the NXP kernel tree.
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> drivers/clk/imx/clk-imx7d.c | 11 ++++++-----
> include/dt-bindings/clock/imx7d-clock.h | 4 +++-
> 2 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
> index 975a20d..485ab49 100644
> --- a/drivers/clk/imx/clk-imx7d.c
> +++ b/drivers/clk/imx/clk-imx7d.c
> @@ -26,6 +26,8 @@ static u32 share_count_sai1;
> static u32 share_count_sai2;
> static u32 share_count_sai3;
> static u32 share_count_nand;
> +static u32 share_count_enet1;
> +static u32 share_count_enet2;
>
> static const struct clk_div_table test_div_table[] = {
> { .val = 3, .div = 1, },
> @@ -805,6 +807,10 @@ static void __init imx7d_clocks_init(struct
> device_node *ccm_node)
> clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk",
> "mipi_dsi_post_div", base + 0x4650, 0);
> clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk",
> "mipi_csi_post_div", base + 0x4640, 0);
> clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk",
> "mipi_dphy_post_div", base + 0x4660, 0);
> + clks[IMX7D_ENET1_IPG_ROOT_CLK] =
> imx_clk_gate2_shared2("enet1_ipg_root_clk", "enet_axi_post_div", base
> + 0x4700, 0, &share_count_enet1);
> + clks[IMX7D_ENET1_TIME_ROOT_CLK] =
> imx_clk_gate2_shared2("enet1_time_root_clk", "enet1_time_post_div",
> base + 0x4700, 0, &share_count_enet1);
> + clks[IMX7D_ENET2_IPG_ROOT_CLK] =
> imx_clk_gate2_shared2("enet2_ipg_root_clk", "enet_axi_post_div", base
> + 0x4710, 0, &share_count_enet2);
> + clks[IMX7D_ENET2_TIME_ROOT_CLK] =
> imx_clk_gate2_shared2("enet2_time_root_clk", "enet2_time_post_div",
> base + 0x4710, 0, &share_count_enet2);
> clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk",
> "sai1_post_div", base + 0x48c0, 0, &share_count_sai1);
> clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk",
> "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1);
> clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk",
> "sai2_post_div", base + 0x48d0, 0, &share_count_sai2);
> @@ -812,11 +818,6 @@ static void __init imx7d_clocks_init(struct
> device_node *ccm_node)
> clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk",
> "sai3_post_div", base + 0x48e0, 0, &share_count_sai3);
> clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk",
> "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3);
> clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk",
> "spdif_post_div", base + 0x44d0, 0);
> - clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk",
> "enet1_ref_post_div", base + 0x44e0, 0);
> - clks[IMX7D_ENET1_TIME_ROOT_CLK] =
> imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base +
> 0x44f0, 0);
> - clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate4("enet2_ref_root_clk",
> "enet2_ref_post_div", base + 0x4500, 0);
> - clks[IMX7D_ENET2_TIME_ROOT_CLK] =
> imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base +
> 0x4510, 0);
> - clks[IMX7D_ENET_PHY_REF_ROOT_CLK] =
> imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base +
> 0x4520, 0);
> clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk",
> "eim_post_div", base + 0x4160, 0);
> clks[IMX7D_NAND_RAWNAND_CLK] =
> imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base +
> 0x4140, 0, &share_count_nand);
> clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] =
> imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk",
> base + 0x4140, 0, &share_count_nand);
> diff --git a/include/dt-bindings/clock/imx7d-clock.h
> b/include/dt-bindings/clock/imx7d-clock.h
> index b2325d3e2..fef0647 100644
> --- a/include/dt-bindings/clock/imx7d-clock.h
> +++ b/include/dt-bindings/clock/imx7d-clock.h
> @@ -455,5 +455,7 @@
> #define IMX7D_SNVS_CLK 442
> #define IMX7D_CAAM_CLK 443
> #define IMX7D_KPP_ROOT_CLK 444
> -#define IMX7D_CLK_END 445
> +#define IMX7D_ENET1_IPG_ROOT_CLK 445
> +#define IMX7D_ENET2_IPG_ROOT_CLK 446
> +#define IMX7D_CLK_END 447
> #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
^ permalink raw reply
* [PATCH v8 15/15] dt: qcom: Add SAW regulator for 8x96 CPUs
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-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>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
arch/arm64/boot/dts/qcom/msm8996.dtsi | 119 ++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index d96a112..871bfac 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -8,6 +8,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";
@@ -92,6 +93,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>;
@@ -107,6 +109,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>;
@@ -118,6 +121,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>;
@@ -133,6 +137,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>;
@@ -169,171 +174,205 @@
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>;
};
@@ -346,251 +385,301 @@
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>;
};
@@ -908,6 +997,11 @@
#mbox-cells = <1>;
};
+ saw3: syscon@9A10000 {
+ compatible = "syscon";
+ reg = <0x9A10000 0x1000>;
+ };
+
gcc: clock-controller@300000 {
compatible = "qcom,gcc-msm8996";
#clock-cells = <1>;
@@ -1134,6 +1228,31 @@
#size-cells = <0>;
interrupt-controller;
#interrupt-cells = <4>;
+ pmic@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@8c0000 {
--
1.9.1
^ permalink raw reply related
* [PATCH v8 14/15] dt-bindings: qcom_spmi: Document SAW support
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-1-git-send-email-ilialin@codeaurora.org>
Document the DT bindings for the SAW regulators.
The saw-leader is the only property that is configurable in DT.
The saw-slave property allows ganging (grouping) of
several regulators so that their outputs can be combined.
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@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 v8 13/15] regulator: qcom_spmi: Add support for SAW
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-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 v8 12/15] dt: qcom: Add qcom-cpufreq-kryo driver configuration
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-1-git-send-email-ilialin@codeaurora.org>
1. Add NVMEM node for the speedbin
2. Add definitions for all possible MSM8996 CPU OPPs.
The qcom-cpufreq-kryo driver will select the appropriate subset.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
arch/arm64/boot/dts/qcom/apq8096-db820c.dts | 2 +-
arch/arm64/boot/dts/qcom/msm8996.dtsi | 281 ++++++++++++++++++++++++++--
2 files changed, 270 insertions(+), 13 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 e6cf290..d96a112 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -1,13 +1,6 @@
-/* Copyright (c) 2014-2015, 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.
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -169,177 +162,436 @@
};
cluster0_opp: opp_table0 {
- compatible = "operating-points-v2";
+ compatible = "operating-points-v2-kryo-cpu",
+ "operating-points-v2";
+ nvmem-cells = <&speedbin_efuse>;
opp-shared;
opp-307200000 {
opp-hz = /bits/ 64 <307200000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-422400000 {
opp-hz = /bits/ 64 <422400000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-460800000 {
+ opp-hz = /bits/ 64 <460800000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-480000000 {
opp-hz = /bits/ 64 <480000000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-537600000 {
+ opp-hz = /bits/ 64 <537600000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-556800000 {
opp-hz = /bits/ 64 <556800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-614400000 {
+ opp-hz = /bits/ 64 <614400000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-652800000 {
opp-hz = /bits/ 64 <652800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-729600000 {
opp-hz = /bits/ 64 <729600000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-768000000 {
+ opp-hz = /bits/ 64 <768000000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-844800000 {
opp-hz = /bits/ 64 <844800000>;
+ opp-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-960000000 {
opp-hz = /bits/ 64 <960000000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1036800000 {
opp-hz = /bits/ 64 <1036800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1113600000 {
opp-hz = /bits/ 64 <1113600000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1132800000 {
+ opp-hz = /bits/ 64 <1132800000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1190400000 {
opp-hz = /bits/ 64 <1190400000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1209600000 {
+ opp-hz = /bits/ 64 <1209600000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1228800000 {
opp-hz = /bits/ 64 <1228800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1286400000 {
+ opp-hz = /bits/ 64 <1286400000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1324800000 {
opp-hz = /bits/ 64 <1324800000>;
+ opp-supported-hw = <0x5>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1363200000 {
+ opp-hz = /bits/ 64 <1363200000>;
+ opp-supported-hw = <0x72>;
clock-latency-ns = <200000>;
};
opp-1401600000 {
opp-hz = /bits/ 64 <1401600000>;
+ opp-supported-hw = <0x5>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1440000000 {
+ opp-hz = /bits/ 64 <1440000000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1478400000 {
opp-hz = /bits/ 64 <1478400000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1497600000 {
+ opp-hz = /bits/ 64 <1497600000>;
+ opp-supported-hw = <0x4>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1593600000 {
opp-hz = /bits/ 64 <1593600000>;
+ opp-supported-hw = <0x71>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+ opp-supported-hw = <0x20>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2188800000 {
+ opp-hz = /bits/ 64 <2188800000>;
+ 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-supported-hw = <0x77>;
+ clock-latency-ns = <200000>;
+ };
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-403200000 {
opp-hz = /bits/ 64 <403200000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-460800000 {
+ opp-hz = /bits/ 64 <460800000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-480000000 {
opp-hz = /bits/ 64 <480000000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-537600000 {
+ opp-hz = /bits/ 64 <537600000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-556800000 {
opp-hz = /bits/ 64 <556800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-614400000 {
+ opp-hz = /bits/ 64 <614400000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-652800000 {
opp-hz = /bits/ 64 <652800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-729600000 {
opp-hz = /bits/ 64 <729600000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-748800000 {
+ opp-hz = /bits/ 64 <748800000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-806400000 {
opp-hz = /bits/ 64 <806400000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-825600000 {
+ opp-hz = /bits/ 64 <825600000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-883200000 {
opp-hz = /bits/ 64 <883200000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-940800000 {
opp-hz = /bits/ 64 <940800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1036800000 {
opp-hz = /bits/ 64 <1036800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1113600000 {
opp-hz = /bits/ 64 <1113600000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1132800000 {
+ opp-hz = /bits/ 64 <1132800000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1190400000 {
opp-hz = /bits/ 64 <1190400000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1209600000 {
+ opp-hz = /bits/ 64 <1209600000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1248000000 {
opp-hz = /bits/ 64 <1248000000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1286400000 {
+ opp-hz = /bits/ 64 <1286400000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1324800000 {
opp-hz = /bits/ 64 <1324800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1363200000 {
+ opp-hz = /bits/ 64 <1363200000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1401600000 {
opp-hz = /bits/ 64 <1401600000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1440000000 {
+ opp-hz = /bits/ 64 <1440000000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1478400000 {
opp-hz = /bits/ 64 <1478400000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1555200000 {
opp-hz = /bits/ 64 <1555200000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1593600000 {
+ opp-hz = /bits/ 64 <1593600000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1632000000 {
opp-hz = /bits/ 64 <1632000000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1670400000 {
+ opp-hz = /bits/ 64 <1670400000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1708800000 {
opp-hz = /bits/ 64 <1708800000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1747200000 {
+ opp-hz = /bits/ 64 <1747200000>;
+ opp-supported-hw = <0x70>;
clock-latency-ns = <200000>;
};
opp-1785600000 {
opp-hz = /bits/ 64 <1785600000>;
+ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1804800000 {
+ opp-hz = /bits/ 64 <1804800000>;
+ opp-supported-hw = <0x6>;
clock-latency-ns = <200000>;
};
opp-1824000000 {
opp-hz = /bits/ 64 <1824000000>;
+ opp-supported-hw = <0x71>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1900800000 {
+ opp-hz = /bits/ 64 <1900800000>;
+ opp-supported-hw = <0x74>;
clock-latency-ns = <200000>;
};
opp-1920000000 {
opp-hz = /bits/ 64 <1920000000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1977600000 {
+ opp-hz = /bits/ 64 <1977600000>;
+ opp-supported-hw = <0x30>;
clock-latency-ns = <200000>;
};
opp-1996800000 {
opp-hz = /bits/ 64 <1996800000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2054400000 {
+ opp-hz = /bits/ 64 <2054400000>;
+ opp-supported-hw = <0x30>;
clock-latency-ns = <200000>;
};
opp-2073600000 {
opp-hz = /bits/ 64 <2073600000>;
+ opp-supported-hw = <0x1>;
clock-latency-ns = <200000>;
};
opp-2150400000 {
opp-hz = /bits/ 64 <2150400000>;
+ opp-supported-hw = <0x31>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2246400000 {
+ opp-hz = /bits/ 64 <2246400000>;
+ opp-supported-hw = <0x10>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2342400000 {
+ opp-hz = /bits/ 64 <2342400000>;
+ opp-supported-hw = <0x10>;
clock-latency-ns = <200000>;
};
};
@@ -917,6 +1169,11 @@
reg = <0x24f 0x1>;
bits = <1 4>;
};
+
+ speedbin_efuse: speedbin@133 {
+ reg = <0x133 0x1>;
+ bits = <5 3>;
+ };
};
phy@34000 {
--
1.9.1
^ permalink raw reply related
* [PATCH v8 11/15] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-1-git-send-email-ilialin@codeaurora.org>
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 for the DT bindings.
The "operating-points-v2-kryo-cpu" DT extends the "operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-supported-hw: A single 32 bit bitmap value,
representing compatible HW:
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
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.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@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@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@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@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@86000000 {
+ reg = <0x0 0x86000000 0x0 0x200000>;
+ no-map;
+ };
+....
+};
+
+smem {
+ compatible = "qcom,smem";
+ memory-region = <&smem_mem>;
+ hwlocks = <&tcsr_mutex 3>;
+};
+
+soc {
+....
+ qfprom: qfprom@74000 {
+ compatible = "qcom,qfprom";
+ reg = <0x00074000 0x8ff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ....
+ speedbin_efuse: speedbin@133 {
+ reg = <0x133 0x1>;
+ bits = <5 3>;
+ };
+ };
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v8 10/15] cpufreq: Add Kryo CPU scaling driver
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-1-git-send-email-ilialin@codeaurora.org>
In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
the CPU frequency 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>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/Kconfig.arm | 10 +++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/cpufreq-dt-platdev.c | 3 +
drivers/cpufreq/qcom-cpufreq-kryo.c | 166 +++++++++++++++++++++++++++++++++++
4 files changed, 180 insertions(+)
create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de55c7d..0bfd40e 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -124,6 +124,16 @@ config ARM_OMAP2PLUS_CPUFREQ
depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS
+config ARM_QCOM_CPUFREQ_KRYO
+ bool "Qualcomm Kryo based CPUFreq"
+ depends on QCOM_QFPROM
+ depends on QCOM_SMEM
+ select PM_OPP
+ help
+ This adds the CPUFreq driver for Qualcomm 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..a2b9fb2
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
+ * the CPU frequency 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.
+ */
+
+#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 = 0;
+ u32 versions;
+ enum _msm8996_version msm8996_version;
+ u8 *speedbin;
+ struct device *cpu_dev_silver, *cpu_dev_gold;
+ struct device_node *np;
+ struct nvmem_cell *speedbin_nvmem;
+ struct platform_device *pdev;
+ struct opp_table *opp_silver = NULL;
+ struct opp_table *opp_gold = NULL;
+
+ cpu_dev_silver = get_cpu_device(SILVER_LEAD);
+ if (IS_ERR_OR_NULL(cpu_dev_silver))
+ return PTR_ERR(cpu_dev_silver);
+
+ cpu_dev_gold = get_cpu_device(SILVER_LEAD);
+ if (IS_ERR_OR_NULL(cpu_dev_gold))
+ return PTR_ERR(cpu_dev_gold);
+
+ msm8996_version = qcom_cpufreq_kryo_get_msm_id();
+ if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
+ dev_err(cpu_dev_silver, "Not Snapdragon 820/821!");
+ return -ENODEV;
+ }
+
+ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev_silver);
+ 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_silver, "Could not get nvmem cell: %d\n", ret);
+ goto free_np;
+ }
+
+ speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+ nvmem_cell_put(speedbin_nvmem);
+
+ 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;
+ }
+
+ opp_silver = dev_pm_opp_set_supported_hw(cpu_dev_silver,&versions,1);
+ if (IS_ERR_OR_NULL(opp_silver)) {
+ dev_err(cpu_dev_silver, "Failed to set supported hardware\n");
+ ret = PTR_ERR(opp_silver);
+ goto free_np;
+ }
+
+ opp_gold = dev_pm_opp_set_supported_hw(cpu_dev_gold,&versions,1);
+ if (IS_ERR_OR_NULL(opp_gold)) {
+ dev_err(cpu_dev_gold, "Failed to set supported hardware\n");
+ ret = PTR_ERR(opp_gold);
+ goto free_opp_silver;
+ }
+
+ pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+ if (!IS_ERR_OR_NULL(pdev))
+ goto out;
+
+ ret = PTR_ERR(pdev);
+ dev_err(cpu_dev_silver, "Failed to register platform device\n");
+ dev_pm_opp_put_supported_hw(opp_gold);
+
+free_opp_silver:
+ dev_pm_opp_put_supported_hw(opp_silver);
+
+free_np:
+ of_node_put(np);
+
+out:
+ 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 v8 09/15] dt: qcom: Add opp and thermal to the msm8996
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-1-git-send-email-ilialin@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.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@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 v8 08/15] clk: qcom: Add ACD path to CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-17 11:19 UTC (permalink / raw)
To: mturquette, sboyd, robh, mark.rutland, viresh.kumar, nm,
lgirdwood, broonie, andy.gross, david.brown, catalin.marinas,
will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, ilialin, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526555955-29960-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 ff5c0a5..0a908d8 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -53,9 +53,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"
@@ -69,6 +71,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,
@@ -107,7 +114,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){
@@ -119,7 +126,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){
@@ -149,7 +156,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),
@@ -163,7 +170,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),
@@ -176,6 +183,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 {
@@ -253,6 +263,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)
@@ -260,7 +271,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;
@@ -276,7 +287,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) {
@@ -292,7 +303,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) {
@@ -308,7 +319,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,
@@ -329,7 +340,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,
@@ -393,6 +404,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;
@@ -402,10 +417,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;
@@ -429,6 +482,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
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