Re: [PATCH 3/7] cpufreq: qcom-cpufreq-nvmem: dev_pm_opp_put_*() accepts NULL argument

2020-11-08 Thread Ilia Lin
Reviewed-by: Ilia Lin 

On Fri, Nov 6, 2020 at 9:05 AM Viresh Kumar  wrote:
>
> The dev_pm_opp_put_*() APIs now accepts a NULL opp_table pointer and so
> there is no need for us to carry the extra checks. Drop them.
>
> Signed-off-by: Viresh Kumar 
> ---
>  drivers/cpufreq/qcom-cpufreq-nvmem.c | 15 ++-
>  1 file changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c 
> b/drivers/cpufreq/qcom-cpufreq-nvmem.c
> index d06b37822c3d..747d602f221e 100644
> --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
> +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
> @@ -397,19 +397,19 @@ static int qcom_cpufreq_probe(struct platform_device 
> *pdev)
>
>  free_genpd_opp:
> for_each_possible_cpu(cpu) {
> -   if (IS_ERR_OR_NULL(drv->genpd_opp_tables[cpu]))
> +   if (IS_ERR(drv->genpd_opp_tables[cpu]))
> break;
> dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
> }
> kfree(drv->genpd_opp_tables);
>  free_opp:
> for_each_possible_cpu(cpu) {
> -   if (IS_ERR_OR_NULL(drv->names_opp_tables[cpu]))
> +   if (IS_ERR(drv->names_opp_tables[cpu]))
> break;
> dev_pm_opp_put_prop_name(drv->names_opp_tables[cpu]);
> }
> for_each_possible_cpu(cpu) {
> -   if (IS_ERR_OR_NULL(drv->hw_opp_tables[cpu]))
> +   if (IS_ERR(drv->hw_opp_tables[cpu]))
> break;
> dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
> }
> @@ -430,12 +430,9 @@ static int qcom_cpufreq_remove(struct platform_device 
> *pdev)
> platform_device_unregister(cpufreq_dt_pdev);
>
> for_each_possible_cpu(cpu) {
> -   if (drv->names_opp_tables[cpu])
> -   
> dev_pm_opp_put_supported_hw(drv->names_opp_tables[cpu]);
> -   if (drv->hw_opp_tables[cpu])
> -   dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
> -   if (drv->genpd_opp_tables[cpu])
> -   dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
> +   dev_pm_opp_put_supported_hw(drv->names_opp_tables[cpu]);
> +   dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
> +   dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
> }
>
> kfree(drv->names_opp_tables);
> --
> 2.25.0.rc1.19.g042ed3e048af
>


Re: [PATCH 0/7] opp: Allow dev_pm_opp_put_*() APIs to accept NULL opp_table

2020-11-08 Thread Ilia Lin
Reviewed-by: Ilia Lin 


On Fri, Nov 6, 2020 at 9:05 AM Viresh Kumar  wrote:
>
> Hello,
>
> This patchset updates the dev_pm_opp_put_*() helpers to accept a NULL
> pointer for the OPP table, in order to allow the callers to drop the
> unnecessary checks they had to carry.
>
> All these must get merged upstream through the OPP tree as there is a
> hard dependency on the first patch here. Thanks.
>
> Viresh Kumar (7):
>   opp: Allow dev_pm_opp_put_*() APIs to accept NULL opp_table
>   cpufreq: dt: dev_pm_opp_put_regulators() accepts NULL argument
>   cpufreq: qcom-cpufreq-nvmem: dev_pm_opp_put_*() accepts NULL argument
>   devfreq: exynos: dev_pm_opp_put_*() accepts NULL argument
>   drm/lima: dev_pm_opp_put_*() accepts NULL argument
>   drm/panfrost: dev_pm_opp_put_*() accepts NULL argument
>   media: venus: dev_pm_opp_put_*() accepts NULL argument
>
>  drivers/cpufreq/cpufreq-dt.c   |  6 ++
>  drivers/cpufreq/qcom-cpufreq-nvmem.c   | 15 ++-
>  drivers/devfreq/exynos-bus.c   | 12 
>  drivers/gpu/drm/lima/lima_devfreq.c| 13 -
>  drivers/gpu/drm/panfrost/panfrost_devfreq.c|  6 ++
>  drivers/media/platform/qcom/venus/pm_helpers.c |  3 +--
>  drivers/opp/core.c | 18 ++
>  7 files changed, 37 insertions(+), 36 deletions(-)
>
> --
> 2.25.0.rc1.19.g042ed3e048af
>


Re: [PATCH] net: dev: Add API to check net_dev readiness

2020-08-05 Thread Ilia Lin
My comments inline.

Thanks,
Ilia Lin

On Tue, Aug 4, 2020 at 10:24 PM Andrew Lunn  wrote:
>
> On Tue, Aug 04, 2020 at 08:47:18PM +0300, Ilia Lin wrote:
> > Hi Andrew and David,
>
> Hi Ilia
>
> Please don't top post.
>
> >
> > Thank you for your comments!
> >
> > The client driver is still work in progress, but it can be seen here:
> > https://source.codeaurora.org/quic/la/kernel/msm-4.19/tree/drivers/platform/msm/ipa/ipa_api.c#n3842
> >
> > For HW performance reasons, it has to be in subsys_initcall.
>
> Well, until the user of this new API is ready, we will not accept the
> patch.
OK, but once we submit the change in the driver, is it good to go?
>
> You also need to explain "For HW performance reasons". Why is this
> driver special that it can do things which no over driver does?
There are very strict KPI requirements. E.g. automotive rear mirror
must be online 3 sec since boot.
>
> And you should really be working on net-next, not this dead kernel
> version, if you want to get merged into mainline.
Of course, the upstream submition will be done on the mainline. I just
gave an example of an existing product driver.
>
> Network drivers do not belong is drivers/platform. There is also ready
> a drivers/net/ipa, so i assume you will move there.
Sure, the driver in the drivers/net/ipa is the one that will be
updated in the future.
>
>   Andrew


Re: [PATCH] net: dev: Add API to check net_dev readiness

2020-08-04 Thread Ilia Lin
Hi Andrew and David,

Thank you for your comments!

The client driver is still work in progress, but it can be seen here:
https://source.codeaurora.org/quic/la/kernel/msm-4.19/tree/drivers/platform/msm/ipa/ipa_api.c#n3842

For HW performance reasons, it has to be in subsys_initcall.

Here is the register_netdev call:
https://source.codeaurora.org/quic/la/kernel/msm-4.19/tree/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c#n2497

And it is going to be in the subsys_initcall as well.

Thanks,
Ilia

On Mon, Jul 27, 2020 at 8:32 PM David Miller  wrote:
>
> From: Andrew Lunn 
> Date: Sun, 26 Jul 2020 21:45:28 +0200
>
> > I also have to wonder why a network device driver is being probed the
> > subsys_initcall.
>
> This makes me wonder how this interface could even be useful.  The
> only way to fix the problem is to change when the device is probed,
> which would mean changing which initcall it uses.  So at run time,
> this information can't do much.


Re: [PATCH] net: dev: Add API to check net_dev readiness

2020-08-04 Thread Ilia Lin
Hi Andrew and David,

Thank you for your comments!

The client driver is still work in progress, but it can be seen here:
https://source.codeaurora.org/quic/la/kernel/msm-4.19/tree/drivers/platform/msm/ipa/ipa_api.c#n3842

For HW performance reasons, it has to be in subsys_initcall.

Here is the register_netdev call:
https://source.codeaurora.org/quic/la/kernel/msm-4.19/tree/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c#n2497

And it is going to be in the subsys_initcall as well.

Thanks,
Ilia



On Mon, Jul 27, 2020 at 8:32 PM David Miller  wrote:
>
> From: Andrew Lunn 
> Date: Sun, 26 Jul 2020 21:45:28 +0200
>
> > I also have to wonder why a network device driver is being probed the
> > subsys_initcall.
>
> This makes me wonder how this interface could even be useful.  The
> only way to fix the problem is to change when the device is probed,
> which would mean changing which initcall it uses.  So at run time,
> this information can't do much.


[PATCH] net: dev: Add API to check net_dev readiness

2020-07-26 Thread Ilia Lin
From: Ilia Lin 

Add an API that returns true, if the net_dev_init was already called,
and the driver was initialized.

Some early drivers, that are initialized during the subsys_initcall
may try accessing the net_dev or NAPI APIs before the net_dev_init,
and will encounter a kernel bug. This API provides a way to handle
this and manage by deferring or by other way.

Signed-off-by: Ilia Lin 
---
 include/linux/netdevice.h |  2 ++
 net/core/dev.c| 17 +
 2 files changed, 19 insertions(+)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 98d290c..d17d364 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2600,6 +2600,8 @@ enum netdev_cmd {
 };
 const char *netdev_cmd_to_name(enum netdev_cmd cmd);
 
+bool is_net_dev_initialized(void);
+
 int register_netdevice_notifier(struct notifier_block *nb);
 int unregister_netdevice_notifier(struct notifier_block *nb);
 int register_netdevice_notifier_net(struct net *net, struct notifier_block 
*nb);
diff --git a/net/core/dev.c b/net/core/dev.c
index 316349f..1b50488 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1793,6 +1793,23 @@ static void 
call_netdevice_unregister_net_notifiers(struct notifier_block *nb,
 static int dev_boot_phase = 1;
 
 /**
+ * is_net_dev_initialized - check, whether the net_dev was
+ * initialized
+ *
+ * Returns true, if the net_dev_init was already called, and
+ * the driver is initialized.
+ *
+ * This is useful for early drivers trying to call net_dev and
+ * NAPI APIs
+ */
+
+bool is_net_dev_initialized(void)
+{
+   return !(bool)dev_boot_phase;
+}
+EXPORT_SYMBOL(is_net_dev_initialized);
+
+/**
  * register_netdevice_notifier - register a network notifier block
  * @nb: notifier
  *



Re: [PATCH 04/13] cpufreq: qcom: Refactor the driver to make it easier to extend

2019-07-08 Thread Ilia Lin
Reviewed-by: Ilia Lin 

On Fri, Jul 5, 2019 at 12:58 PM Niklas Cassel  wrote:
>
> Refactor the driver to make it easier to extend in a later commit.
>
> Create a driver struct to collect all common resources, in order to make
> it easier to free up all common resources.
> Create a driver match_data struct to make it easier to extend the driver
> with support for new features that might only be supported on certain SoCs.
>
> Co-developed-by: Jorge Ramirez-Ortiz 
> Signed-off-by: Jorge Ramirez-Ortiz 
> Signed-off-by: Niklas Cassel 
> ---
> Changes since RFC:
> -Changed type of versions to u32 from u32*.
> -Make the driver use a match_data struct, so that different SoC can have
> different features.
> -Fixed error handling.
>
>  drivers/cpufreq/qcom-cpufreq-nvmem.c | 123 +--
>  1 file changed, 79 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c 
> b/drivers/cpufreq/qcom-cpufreq-nvmem.c
> index fad6509eecb5..c0377b0eb2f4 100644
> --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
> +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
> @@ -43,6 +43,20 @@ enum _msm8996_version {
> NUM_OF_MSM8996_VERSIONS,
>  };
>
> +struct qcom_cpufreq_drv;
> +
> +struct qcom_cpufreq_match_data {
> +   int (*get_version)(struct device *cpu_dev,
> +  struct nvmem_cell *speedbin_nvmem,
> +  struct qcom_cpufreq_drv *drv);
> +};
> +
> +struct qcom_cpufreq_drv {
> +   struct opp_table **opp_tables;
> +   u32 versions;
> +   const struct qcom_cpufreq_match_data *data;
> +};
> +
>  static struct platform_device *cpufreq_dt_pdev, *cpufreq_pdev;
>
>  static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
> @@ -76,7 +90,7 @@ static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
>
>  static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
>   struct nvmem_cell *speedbin_nvmem,
> - u32 *versions)
> + struct qcom_cpufreq_drv *drv)
>  {
> size_t len;
> u8 *speedbin;
> @@ -94,10 +108,10 @@ static int qcom_cpufreq_kryo_name_version(struct device 
> *cpu_dev,
>
> switch (msm8996_version) {
> case MSM8996_V3:
> -   *versions = 1 << (unsigned int)(*speedbin);
> +   drv->versions = 1 << (unsigned int)(*speedbin);
> break;
> case MSM8996_SG:
> -   *versions = 1 << ((unsigned int)(*speedbin) + 4);
> +   drv->versions = 1 << ((unsigned int)(*speedbin) + 4);
> break;
> default:
> BUG();
> @@ -108,17 +122,17 @@ static int qcom_cpufreq_kryo_name_version(struct device 
> *cpu_dev,
> return 0;
>  }
>
> +static const struct qcom_cpufreq_match_data match_data_kryo = {
> +   .get_version = qcom_cpufreq_kryo_name_version,
> +};
> +
>  static int qcom_cpufreq_probe(struct platform_device *pdev)
>  {
> -   struct opp_table **opp_tables;
> -   int (*get_version)(struct device *cpu_dev,
> -  struct nvmem_cell *speedbin_nvmem,
> -  u32 *versions);
> +   struct qcom_cpufreq_drv *drv;
> struct nvmem_cell *speedbin_nvmem;
> struct device_node *np;
> struct device *cpu_dev;
> unsigned cpu;
> -   u32 versions;
> const struct of_device_id *match;
> int ret;
>
> @@ -126,11 +140,6 @@ static int qcom_cpufreq_probe(struct platform_device 
> *pdev)
> if (!cpu_dev)
> return -ENODEV;
>
> -   match = pdev->dev.platform_data;
> -   get_version = match->data;
> -   if (!get_version)
> -   return -ENODEV;
> -
> np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
> if (!np)
> return -ENOENT;
> @@ -141,23 +150,43 @@ static int qcom_cpufreq_probe(struct platform_device 
> *pdev)
> return -ENOENT;
> }
>
> -   speedbin_nvmem = of_nvmem_cell_get(np, NULL);
> -   of_node_put(np);
> -   if (IS_ERR(speedbin_nvmem)) {
> -   if (PTR_ERR(speedbin_nvmem) != -EPROBE_DEFER)
> -   dev_err(cpu_dev, "Could not get nvmem cell: %ld\n",
> -   PTR_ERR(speedbin_nvmem));
> -   return PTR_ERR(speedbin_nvmem);
> +   drv = kzalloc(sizeof(*drv), GFP_KERNEL);
> +   if (!drv)
> +   return -ENOMEM;
> +
> +   match = pdev->dev.platform_data;
> +   drv->data = match-&g

Re: [PATCH 03/13] dt-bindings: cpufreq: qcom-nvmem: Make speedbin related properties optional

2019-07-08 Thread Ilia Lin
Reviewed-by: Ilia Lin 

On Fri, Jul 5, 2019 at 12:58 PM Niklas Cassel  wrote:
>
> Not all Qualcomm platforms need to care about the speedbin efuse,
> nor the value blown into the speedbin efuse.
> Therefore, make the nvmem-cells and opp-supported-hw properties
> optional.
>
> Signed-off-by: Niklas Cassel 
> ---
>  Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt 
> b/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
> index 198441e80ba8..c5ea8b90e35d 100644
> --- a/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
> +++ b/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
> @@ -20,6 +20,10 @@ In 'cpus' nodes:
>  In 'operating-points-v2' table:
>  - compatible: Should be
> - 'operating-points-v2-kryo-cpu' for apq8096 and msm8996.
> +
> +Optional properties:
> +
> +In 'operating-points-v2' table:
>  - 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
> --
> 2.21.0
>


Re: [PATCH 01/13] dt-bindings: cpufreq: Re-organise kryo cpufreq to use it for other nvmem based qcom socs

2019-07-08 Thread Ilia Lin
Reviewed-by: Ilia Lin 

On Fri, Jul 5, 2019 at 12:57 PM Niklas Cassel  wrote:
>
> From: Sricharan R 
>
> The kryo cpufreq driver reads the nvmem cell and uses that data to
> populate the opps. There are other qcom cpufreq socs like krait which
> does similar thing. Except for the interpretation of the read data,
> rest of the driver is same for both the cases. So pull the common things
> out for reuse.
>
> Signed-off-by: Sricharan R 
> [niklas.cas...@linaro.org: split dt-binding into a separate patch and
> do not rename the compatible string.]
> Signed-off-by: Niklas Cassel 
> ---
> Changes since RFC:
> -Made DT bindings a separate patch.
> -Keep the original compatible string, since renaming it breaks DT
> backwards compatibility.
>
>  .../opp/{kryo-cpufreq.txt => qcom-nvmem-cpufreq.txt}   | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>  rename Documentation/devicetree/bindings/opp/{kryo-cpufreq.txt => 
> qcom-nvmem-cpufreq.txt} (98%)
>
> diff --git a/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt 
> b/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
> similarity index 98%
> rename from Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
> rename to Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
> index c2127b96805a..198441e80ba8 100644
> --- a/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
> +++ b/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
> @@ -1,13 +1,13 @@
> -Qualcomm Technologies, Inc. KRYO CPUFreq and OPP bindings
> +Qualcomm Technologies, Inc. NVMEM 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.
> +In Certain Qualcomm Technologies, Inc. SoCs like apq8096 and msm8996,
> +the CPU frequencies 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
> +The qcom-cpufreq-nvmem 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.
> --
> 2.21.0
>


Re: [PATCH 02/13] cpufreq: qcom: Re-organise kryo cpufreq to use it for other nvmem based qcom socs

2019-07-08 Thread Ilia Lin
Reviewed-by: Ilia Lin 


On Fri, Jul 5, 2019 at 12:57 PM Niklas Cassel  wrote:
>
> From: Sricharan R 
>
> The kryo cpufreq driver reads the nvmem cell and uses that data to
> populate the opps. There are other qcom cpufreq socs like krait which
> does similar thing. Except for the interpretation of the read data,
> rest of the driver is same for both the cases. So pull the common things
> out for reuse.
>
> Signed-off-by: Sricharan R 
> [niklas.cas...@linaro.org: split dt-binding into a separate patch and
> do not rename the compatible string. Update MAINTAINERS file.]
> Signed-off-by: Niklas Cassel 
> ---
> Changes since RFC:
> -Made DT bindings a separate patch.
> -Keep the original compatible string, since renaming it breaks DT
> backwards compatibility.
>
>  MAINTAINERS   |   4 +-
>  drivers/cpufreq/Kconfig.arm   |   4 +-
>  drivers/cpufreq/Makefile  |   2 +-
>  ...om-cpufreq-kryo.c => qcom-cpufreq-nvmem.c} | 122 +++---
>  4 files changed, 78 insertions(+), 54 deletions(-)
>  rename drivers/cpufreq/{qcom-cpufreq-kryo.c => qcom-cpufreq-nvmem.c} (70%)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 04a66ba93c26..38ab8374fa7a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13242,8 +13242,8 @@ QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
>  M: Ilia Lin 
>  L: linux...@vger.kernel.org
>  S: Maintained
> -F: Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
> -F: drivers/cpufreq/qcom-cpufreq-kryo.c
> +F: Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
> +F: drivers/cpufreq/qcom-cpufreq-nvmem.c
>
>  QUALCOMM EMAC GIGABIT ETHERNET DRIVER
>  M: Timur Tabi 
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index 56c31a78c692..b1aa485a28dd 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -120,8 +120,8 @@ config ARM_OMAP2PLUS_CPUFREQ
> depends on ARCH_OMAP2PLUS
> default ARCH_OMAP2PLUS
>
> -config ARM_QCOM_CPUFREQ_KRYO
> -   tristate "Qualcomm Kryo based CPUFreq"
> +config ARM_QCOM_CPUFREQ_NVMEM
> +   tristate "Qualcomm nvmem based CPUFreq"
> depends on ARM64
> depends on QCOM_QFPROM
> depends on QCOM_SMEM
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 5a6c70d26c98..8572a918aa75 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -64,7 +64,7 @@ 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_HW)  += qcom-cpufreq-hw.o
> -obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)+= qcom-cpufreq-kryo.o
> +obj-$(CONFIG_ARM_QCOM_CPUFREQ_NVMEM)   += qcom-cpufreq-nvmem.o
>  obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ)  += raspberrypi-cpufreq.o
>  obj-$(CONFIG_ARM_S3C2410_CPUFREQ)  += s3c2410-cpufreq.o
>  obj-$(CONFIG_ARM_S3C2412_CPUFREQ)  += s3c2412-cpufreq.o
> diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
> b/drivers/cpufreq/qcom-cpufreq-nvmem.c
> similarity index 70%
> rename from drivers/cpufreq/qcom-cpufreq-kryo.c
> rename to drivers/cpufreq/qcom-cpufreq-nvmem.c
> index dd64dcf89c74..fad6509eecb5 100644
> --- a/drivers/cpufreq/qcom-cpufreq-kryo.c
> +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
> @@ -9,7 +9,7 @@
>   * 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
> + * The qcom-cpufreq 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.
> @@ -22,6 +22,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -42,9 +43,9 @@ enum _msm8996_version {
> NUM_OF_MSM8996_VERSIONS,
>  };
>
> -static struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
> +static struct platform_device *cpufreq_dt_pdev, *cpufreq_pdev;
>
> -static enum _msm8996_version qcom_cpufreq_kryo_get_msm_id(void)
> +static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
>  {
> size_t len;
> u32 *msm_id;
> @@ -73,28 +74,62 @@ static enum _msm8996_version 
> qcom_cpufreq_kryo_get_msm_id(void)
> return version;
>  }
>
>

Re: [PATCH] cpufreq: qcom-kryo: add NULL entry to the end of_device_id array

2018-07-23 Thread Ilia Lin
On Mon, Jul 23, 2018 at 3:38 PM YueHaibing  wrote:
>
> Make sure of_device_id tables are NULL terminated
> Found by coccinelle spatch "misc/of_table.cocci"
>
> Signed-off-by: YueHaibing 
> ---
>  drivers/cpufreq/qcom-cpufreq-kryo.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
> b/drivers/cpufreq/qcom-cpufreq-kryo.c
> index 29389ac..efc9a7a 100644
> --- a/drivers/cpufreq/qcom-cpufreq-kryo.c
> +++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
> @@ -183,6 +183,7 @@ static struct platform_driver qcom_cpufreq_kryo_driver = {
>  static const struct of_device_id qcom_cpufreq_kryo_match_list[] __initconst 
> = {
> { .compatible = "qcom,apq8096", },
> { .compatible = "qcom,msm8996", },
> +   {}
>  };
>
>  /*
> --
> 2.7.0
>
>

Acked-by: Ilia Lin 


Re: [PATCH] cpufreq: qcom-kryo: add NULL entry to the end of_device_id array

2018-07-23 Thread Ilia Lin
On Mon, Jul 23, 2018 at 3:38 PM YueHaibing  wrote:
>
> Make sure of_device_id tables are NULL terminated
> Found by coccinelle spatch "misc/of_table.cocci"
>
> Signed-off-by: YueHaibing 
> ---
>  drivers/cpufreq/qcom-cpufreq-kryo.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
> b/drivers/cpufreq/qcom-cpufreq-kryo.c
> index 29389ac..efc9a7a 100644
> --- a/drivers/cpufreq/qcom-cpufreq-kryo.c
> +++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
> @@ -183,6 +183,7 @@ static struct platform_driver qcom_cpufreq_kryo_driver = {
>  static const struct of_device_id qcom_cpufreq_kryo_match_list[] __initconst 
> = {
> { .compatible = "qcom,apq8096", },
> { .compatible = "qcom,msm8996", },
> +   {}
>  };
>
>  /*
> --
> 2.7.0
>
>

Acked-by: Ilia Lin 


Re: [PATCH v11 2/2] dt: qcom: Add qcom-cpufreq-kryo driver configuration

2018-07-10 Thread Ilia Lin
Hi Niklas,

The frequency list in the DT is correct, but the initial frequency for
the CPUs 0,1 is configured by the XBL, while the CPUs 2,3 stay at XO
rate. Both rates are unlisted in the DT and that's OK.

BR,
Ilia Lin

On Tue, Jul 10, 2018 at 12:29 PM Niklas Cassel  wrote:
>
> On Wed, May 23, 2018 at 04:11:31PM +0300, Ilia Lin wrote:
> > 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 
> > Acked-by: Viresh Kumar 
> > ---
> >  arch/arm64/boot/dts/qcom/apq8096-db820c.dts |   2 +-
> >  arch/arm64/boot/dts/qcom/msm8996.dtsi   | 281 
> > ++--
> >  2 files changed, 270 insertions(+), 13 deletions(-)
> >
>
> Hello Ilia, Viresh
>
>
> I tried this patch series (together with you cpu clock driver).
>
> The first problem is that the driver fails to create debugfs entries.
>
> The second problem appears to be that it runs on unlisted frequency.
> Is this simply because of missing entries in the opp table?
>
> [4.538513] cpu cpu1: opp_list_debug_create_link: Failed to create link
> [4.538567] cpu cpu1: _add_opp_dev: Failed to register opp debugfs (-12)
> [4.544514] cpufreq: cpufreq_online: CPU0: Running at unlisted freq: 
> 614400 KHz
> [4.551441] cpufreq: cpufreq_online: CPU0: Unlisted initial frequency 
> changed to: 652800 KHz
> [4.563219] cpu cpu3: opp_list_debug_create_link: Failed to create link
> [4.566937] cpu cpu3: _add_opp_dev: Failed to register opp debugfs (-12)
> [4.573489] cpufreq: cpufreq_online: CPU2: Running at unlisted freq: 19200 
> KHz
> [4.580368] cpufreq: cpufreq_online: CPU2: Unlisted initial frequency 
> changed to: 307200 KHz
>
>
> Kind regards,
> Niklas


Re: [PATCH v11 2/2] dt: qcom: Add qcom-cpufreq-kryo driver configuration

2018-07-10 Thread Ilia Lin
Hi Niklas,

The frequency list in the DT is correct, but the initial frequency for
the CPUs 0,1 is configured by the XBL, while the CPUs 2,3 stay at XO
rate. Both rates are unlisted in the DT and that's OK.

BR,
Ilia Lin

On Tue, Jul 10, 2018 at 12:29 PM Niklas Cassel  wrote:
>
> On Wed, May 23, 2018 at 04:11:31PM +0300, Ilia Lin wrote:
> > 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 
> > Acked-by: Viresh Kumar 
> > ---
> >  arch/arm64/boot/dts/qcom/apq8096-db820c.dts |   2 +-
> >  arch/arm64/boot/dts/qcom/msm8996.dtsi   | 281 
> > ++--
> >  2 files changed, 270 insertions(+), 13 deletions(-)
> >
>
> Hello Ilia, Viresh
>
>
> I tried this patch series (together with you cpu clock driver).
>
> The first problem is that the driver fails to create debugfs entries.
>
> The second problem appears to be that it runs on unlisted frequency.
> Is this simply because of missing entries in the opp table?
>
> [4.538513] cpu cpu1: opp_list_debug_create_link: Failed to create link
> [4.538567] cpu cpu1: _add_opp_dev: Failed to register opp debugfs (-12)
> [4.544514] cpufreq: cpufreq_online: CPU0: Running at unlisted freq: 
> 614400 KHz
> [4.551441] cpufreq: cpufreq_online: CPU0: Unlisted initial frequency 
> changed to: 652800 KHz
> [4.563219] cpu cpu3: opp_list_debug_create_link: Failed to create link
> [4.566937] cpu cpu3: _add_opp_dev: Failed to register opp debugfs (-12)
> [4.573489] cpufreq: cpufreq_online: CPU2: Running at unlisted freq: 19200 
> KHz
> [4.580368] cpufreq: cpufreq_online: CPU2: Unlisted initial frequency 
> changed to: 307200 KHz
>
>
> Kind regards,
> Niklas


[PATCH] MAINTAINERS: Update e-mail address for Ilia Lin

2018-06-18 Thread ilia . lin
From: Ilia Lin 

Change to the @kernel.org address

Signed-off-by: Ilia Lin 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 035973b23b8b..15a836eebe9a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11799,7 +11799,7 @@ F:  Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
 QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
-M:  Ilia Lin 
+M:  Ilia Lin 
 L:  linux...@vger.kernel.org
 S:  Maintained
 F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
-- 
2.11.0



[PATCH] MAINTAINERS: Update e-mail address for Ilia Lin

2018-06-18 Thread ilia . lin
From: Ilia Lin 

Change to the @kernel.org address

Signed-off-by: Ilia Lin 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 035973b23b8b..15a836eebe9a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11799,7 +11799,7 @@ F:  Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
 QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
-M:  Ilia Lin 
+M:  Ilia Lin 
 L:  linux...@vger.kernel.org
 S:  Maintained
 F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
-- 
2.11.0



[PATCH v3] cpufreq: kryo: Add module remove and exit

2018-06-17 Thread ilia . lin
From: Ilia Lin 

Add device remove and module exit code to make the driver
functioning as a loadable module.

Fixes: ac28927659be (cpufreq: kryo: allow building as a loadable module)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index 74b9b93d511b..01bddacf5c3b 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -42,6 +42,8 @@ enum _msm8996_version {
NUM_OF_MSM8996_VERSIONS,
 };
 
+struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
+
 static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
 {
size_t len;
@@ -74,7 +76,6 @@ static enum _msm8996_version __init 
qcom_cpufreq_kryo_get_msm_id(void)
 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
 {
struct opp_table *opp_tables[NR_CPUS] = {0};
-   struct platform_device *cpufreq_dt_pdev;
enum _msm8996_version msm8996_version;
struct nvmem_cell *speedbin_nvmem;
struct device_node *np;
@@ -165,8 +166,15 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
return ret;
 }
 
+static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
+{
+   platform_device_unregister(cpufreq_dt_pdev);
+   return 0;
+}
+
 static struct platform_driver qcom_cpufreq_kryo_driver = {
.probe = qcom_cpufreq_kryo_probe,
+   .remove = qcom_cpufreq_kryo_remove,
.driver = {
.name = "qcom-cpufreq-kryo",
},
@@ -201,8 +209,9 @@ static int __init qcom_cpufreq_kryo_init(void)
if (unlikely(ret < 0))
return ret;
 
-   ret = PTR_ERR_OR_ZERO(platform_device_register_simple(
-   "qcom-cpufreq-kryo", -1, NULL, 0));
+   kryo_cpufreq_pdev = platform_device_register_simple(
+   "qcom-cpufreq-kryo", -1, NULL, 0);
+   ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev);
if (0 == ret)
return 0;
 
@@ -211,5 +220,12 @@ static int __init qcom_cpufreq_kryo_init(void)
 }
 module_init(qcom_cpufreq_kryo_init);
 
+static void __init qcom_cpufreq_kryo_exit(void)
+{
+   platform_device_unregister(kryo_cpufreq_pdev);
+   platform_driver_unregister(_cpufreq_kryo_driver);
+}
+module_exit(qcom_cpufreq_kryo_exit);
+
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.11.0



[PATCH v3] cpufreq: kryo: Add module remove and exit

2018-06-17 Thread ilia . lin
From: Ilia Lin 

Add device remove and module exit code to make the driver
functioning as a loadable module.

Fixes: ac28927659be (cpufreq: kryo: allow building as a loadable module)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index 74b9b93d511b..01bddacf5c3b 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -42,6 +42,8 @@ enum _msm8996_version {
NUM_OF_MSM8996_VERSIONS,
 };
 
+struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
+
 static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
 {
size_t len;
@@ -74,7 +76,6 @@ static enum _msm8996_version __init 
qcom_cpufreq_kryo_get_msm_id(void)
 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
 {
struct opp_table *opp_tables[NR_CPUS] = {0};
-   struct platform_device *cpufreq_dt_pdev;
enum _msm8996_version msm8996_version;
struct nvmem_cell *speedbin_nvmem;
struct device_node *np;
@@ -165,8 +166,15 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
return ret;
 }
 
+static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
+{
+   platform_device_unregister(cpufreq_dt_pdev);
+   return 0;
+}
+
 static struct platform_driver qcom_cpufreq_kryo_driver = {
.probe = qcom_cpufreq_kryo_probe,
+   .remove = qcom_cpufreq_kryo_remove,
.driver = {
.name = "qcom-cpufreq-kryo",
},
@@ -201,8 +209,9 @@ static int __init qcom_cpufreq_kryo_init(void)
if (unlikely(ret < 0))
return ret;
 
-   ret = PTR_ERR_OR_ZERO(platform_device_register_simple(
-   "qcom-cpufreq-kryo", -1, NULL, 0));
+   kryo_cpufreq_pdev = platform_device_register_simple(
+   "qcom-cpufreq-kryo", -1, NULL, 0);
+   ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev);
if (0 == ret)
return 0;
 
@@ -211,5 +220,12 @@ static int __init qcom_cpufreq_kryo_init(void)
 }
 module_init(qcom_cpufreq_kryo_init);
 
+static void __init qcom_cpufreq_kryo_exit(void)
+{
+   platform_device_unregister(kryo_cpufreq_pdev);
+   platform_driver_unregister(_cpufreq_kryo_driver);
+}
+module_exit(qcom_cpufreq_kryo_exit);
+
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.11.0



[PATCH v2] cpufreq: kryo: Fix possible error code dereference

2018-06-17 Thread ilia . lin
From: Ilia Lin 

In event of error returned by the nvmem_cell_read() non-pointer value
may be dereferenced. Fix this with error handling.
Additionally free the allocated speedbin buffer, as per the API.

Fixes: 9ce36edd1a52 (cpufreq: Add Kryo CPU scaling driver)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index d049fe4b80c4..74b9b93d511b 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -115,6 +115,8 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
 
speedbin = nvmem_cell_read(speedbin_nvmem, );
nvmem_cell_put(speedbin_nvmem);
+   if (IS_ERR(speedbin))
+   return PTR_ERR(speedbin);
 
switch (msm8996_version) {
case MSM8996_V3:
@@ -127,6 +129,7 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
BUG();
break;
}
+   kfree(speedbin);
 
for_each_possible_cpu(cpu) {
cpu_dev = get_cpu_device(cpu);
-- 
2.11.0



[PATCH v2] cpufreq: kryo: Fix possible error code dereference

2018-06-17 Thread ilia . lin
From: Ilia Lin 

In event of error returned by the nvmem_cell_read() non-pointer value
may be dereferenced. Fix this with error handling.
Additionally free the allocated speedbin buffer, as per the API.

Fixes: 9ce36edd1a52 (cpufreq: Add Kryo CPU scaling driver)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index d049fe4b80c4..74b9b93d511b 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -115,6 +115,8 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
 
speedbin = nvmem_cell_read(speedbin_nvmem, );
nvmem_cell_put(speedbin_nvmem);
+   if (IS_ERR(speedbin))
+   return PTR_ERR(speedbin);
 
switch (msm8996_version) {
case MSM8996_V3:
@@ -127,6 +129,7 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
BUG();
break;
}
+   kfree(speedbin);
 
for_each_possible_cpu(cpu) {
cpu_dev = get_cpu_device(cpu);
-- 
2.11.0



[PATCH v13 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver

2018-06-14 Thread ilia . lin
From: Ilia Lin 

The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.

Signed-off-by: Ilia Lin 
Reviewed-by: Amit Kucheria 
Tested-by: Amit Kucheria 
---
 drivers/perf/Kconfig |  1 +
 drivers/perf/qcom_l2_pmu.c   | 90 ++--
 drivers/soc/qcom/Kconfig |  3 ++
 drivers/soc/qcom/Makefile|  1 +
 drivers/soc/qcom/kryo-l2-accessors.c | 56 ++
 include/soc/qcom/kryo-l2-accessors.h | 12 +
 6 files changed, 97 insertions(+), 66 deletions(-)
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 08ebaf7cca8b..5c3f07cd79f4 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -71,6 +71,7 @@ config HISI_PMU
 config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+   select QCOM_KRYO_L2_ACCESSORS
  help
  Provides support for the L2 cache performance monitor unit (PMU)
  in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135cf35a3..cc31f5162942 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_L2_CTRS 9
 
@@ -87,8 +88,6 @@
 #define L2_COUNTER_RELOAD   BIT_ULL(31)
 #define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
 
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1   sys_reg(3, 3, 15, 0, 7)
 
 #define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
 
@@ -107,48 +106,7 @@
 #define L2_EVENT_STREX 0x421
 #define L2_EVENT_CLREX 0x422
 
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
 
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   write_sysreg_s(val, L2CPUSRDR_EL1);
-   isb();
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
-   u64 val;
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   val = read_sysreg_s(L2CPUSRDR_EL1);
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-
-   return val;
-}
 
 struct cluster_pmu;
 
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
 static void cluster_pmu_reset(void)
 {
/* Reset all counters */
-   set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
-   set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+   kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
 }
 
 static inline void cluster_pmu_enable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
 }
 
 static inline void cluster_pmu_disable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
 }
 
 static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
 {
if (idx == l2_cycle_ctr_idx)
-   set_l2_indirect_reg(L2PMCCNTR, value);
+   kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
-   set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+   kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
 }
 
 static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
 
if (idx == l2_cycle_ctr_idx)
-   value = get_l2_indirect_reg(L2PMCCNTR);
+   value = kryo_l2_get_indirect_re

[PATCH v13 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver

2018-06-14 Thread ilia . lin
From: Ilia Lin 

The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.

Signed-off-by: Ilia Lin 
Reviewed-by: Amit Kucheria 
Tested-by: Amit Kucheria 
---
 drivers/perf/Kconfig |  1 +
 drivers/perf/qcom_l2_pmu.c   | 90 ++--
 drivers/soc/qcom/Kconfig |  3 ++
 drivers/soc/qcom/Makefile|  1 +
 drivers/soc/qcom/kryo-l2-accessors.c | 56 ++
 include/soc/qcom/kryo-l2-accessors.h | 12 +
 6 files changed, 97 insertions(+), 66 deletions(-)
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 08ebaf7cca8b..5c3f07cd79f4 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -71,6 +71,7 @@ config HISI_PMU
 config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+   select QCOM_KRYO_L2_ACCESSORS
  help
  Provides support for the L2 cache performance monitor unit (PMU)
  in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135cf35a3..cc31f5162942 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_L2_CTRS 9
 
@@ -87,8 +88,6 @@
 #define L2_COUNTER_RELOAD   BIT_ULL(31)
 #define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
 
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1   sys_reg(3, 3, 15, 0, 7)
 
 #define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
 
@@ -107,48 +106,7 @@
 #define L2_EVENT_STREX 0x421
 #define L2_EVENT_CLREX 0x422
 
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
 
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   write_sysreg_s(val, L2CPUSRDR_EL1);
-   isb();
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
-   u64 val;
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   val = read_sysreg_s(L2CPUSRDR_EL1);
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-
-   return val;
-}
 
 struct cluster_pmu;
 
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
 static void cluster_pmu_reset(void)
 {
/* Reset all counters */
-   set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
-   set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+   kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
 }
 
 static inline void cluster_pmu_enable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
 }
 
 static inline void cluster_pmu_disable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
 }
 
 static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
 {
if (idx == l2_cycle_ctr_idx)
-   set_l2_indirect_reg(L2PMCCNTR, value);
+   kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
-   set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+   kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
 }
 
 static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
 
if (idx == l2_cycle_ctr_idx)
-   value = get_l2_indirect_reg(L2PMCCNTR);
+   value = kryo_l2_get_indirect_re

[PATCH v13 4/8] clk: qcom: Add CPU clock driver for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.

ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/clk-alpha-pll.h |   6 +
 drivers/clk/qcom/clk-cpu-8996.c  | 403 +++
 4 files changed, 420 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480dcc38a..fe01df59f923 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,16 @@ config QCOM_CLK_APCS_MSM8916
  Say Y if you want to support CPU frequency scaling on devices
  such as msm8916.
 
+config QCOM_CLK_APCC_MSM8996
+   tristate "MSM8996 CPU Clock Controller"
+   depends on ARM64
+   depends on COMMON_CLK_QCOM
+   select QCOM_KRYO_L2_ACCESSORS
+   help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
+
 config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 762c01137c2f..d142778f6e92 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b486c468..9ce2a32f30ab 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -50,6 +50,12 @@ struct pll_vco {
u32 val;
 };
 
+#define VCO(a, b, c) { \
+   .val = a,\
+   .min_freq = b,\
+   .max_freq = c,\
+}
+
 /**
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index ..d92cad93af20
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown bel

[PATCH v13 5/8] dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

Signed-off-by: Ilia Lin 
Reviewed-by: Rob Herring 
Tested-by: Amit Kucheria 
---
 Documentation/devicetree/bindings/clock/qcom,kryocc.txt | 17 +
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index ..8458783c5a1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+   "qcom,msm8996-apcc"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+   kryocc: clock-controller@640 {
+   compatible = "qcom,msm8996-apcc";
+   reg = <0x640 0x9>;
+   #clock-cells = <1>;
+   };
-- 
2.11.0



[PATCH v13 4/8] clk: qcom: Add CPU clock driver for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.

ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/clk-alpha-pll.h |   6 +
 drivers/clk/qcom/clk-cpu-8996.c  | 403 +++
 4 files changed, 420 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480dcc38a..fe01df59f923 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,16 @@ config QCOM_CLK_APCS_MSM8916
  Say Y if you want to support CPU frequency scaling on devices
  such as msm8916.
 
+config QCOM_CLK_APCC_MSM8996
+   tristate "MSM8996 CPU Clock Controller"
+   depends on ARM64
+   depends on COMMON_CLK_QCOM
+   select QCOM_KRYO_L2_ACCESSORS
+   help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
+
 config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 762c01137c2f..d142778f6e92 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b486c468..9ce2a32f30ab 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -50,6 +50,12 @@ struct pll_vco {
u32 val;
 };
 
+#define VCO(a, b, c) { \
+   .val = a,\
+   .min_freq = b,\
+   .max_freq = c,\
+}
+
 /**
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index ..d92cad93af20
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown bel

[PATCH v13 5/8] dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

Signed-off-by: Ilia Lin 
Reviewed-by: Rob Herring 
Tested-by: Amit Kucheria 
---
 Documentation/devicetree/bindings/clock/qcom,kryocc.txt | 17 +
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index ..8458783c5a1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+   "qcom,msm8996-apcc"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+   kryocc: clock-controller@640 {
+   compatible = "qcom,msm8996-apcc";
+   reg = <0x640 0x9>;
+   #clock-cells = <1>;
+   };
-- 
2.11.0



[PATCH v13 7/8] clk: qcom: cpu-8996: Add support to switch below 600Mhz

2018-06-14 Thread ilia . lin
From: Rajendra Nayak 

The CPU clock controller's primary PLL operates on a single VCO range,
between 600MHz and 3GHz. However the CPUs do support OPPs with
frequencies between 300MHz and 600MHz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/clk-cpu-8996.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 620fdc2266ba..ff5c0a5740d2 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -68,6 +68,8 @@ enum _pmux_input {
NUM_OF_PMUX_INPUTS
 };
 
+#define DIV_2_THRESHOLD6
+
 static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
[PLL_OFF_ALPHA_VAL] = 0x08,
@@ -95,10 +97,11 @@ static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
 
 static const struct alpha_pll_config hfpll_config = {
.l = 60,
-   .config_ctl_val = 0x200d4828,
+   .config_ctl_val = 0x200d4aa8,
.config_ctl_hi_val = 0x006,
.pre_div_mask = BIT(12),
.post_div_mask = 0x3 << 8,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -140,7 +143,7 @@ static const struct alpha_pll_config altpll_config = {
.vco_mask = 0x3 << 20,
.config_ctl_val = 0x4001051b,
.post_div_mask = 0x3 << 8,
-   .post_div_val = 0x1,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -181,6 +184,7 @@ struct clk_cpu_8996_mux {
u8  width;
struct notifier_block nb;
struct clk_hw   *pll;
+   struct clk_hw   *pll_div_2;
struct clk_regmap clkr;
 };
 
@@ -226,6 +230,13 @@ clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct 
clk_rate_request *req)
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
struct clk_hw *parent = cpuclk->pll;
 
+   if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+   if (req->rate < (DIV_2_THRESHOLD / 2))
+   return -EINVAL;
+
+   parent = cpuclk->pll_div_2;
+   }
+
req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
req->best_parent_hw = parent;
 
@@ -237,13 +248,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, 
unsigned long event,
 {
int ret;
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+   struct clk_notifier_data *cnd = data;
 
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
break;
case POST_RATE_CHANGE:
-   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   if (cnd->new_rate < DIV_2_THRESHOLD)
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ DIV_2_INDEX);
+   else
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ PLL_INDEX);
break;
default:
ret = 0;
@@ -295,6 +312,7 @@ static struct clk_cpu_8996_mux pwrcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
@@ -315,6 +333,7 @@ static struct clk_cpu_8996_mux perfcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
-- 
2.11.0



[PATCH v13 7/8] clk: qcom: cpu-8996: Add support to switch below 600Mhz

2018-06-14 Thread ilia . lin
From: Rajendra Nayak 

The CPU clock controller's primary PLL operates on a single VCO range,
between 600MHz and 3GHz. However the CPUs do support OPPs with
frequencies between 300MHz and 600MHz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/clk-cpu-8996.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 620fdc2266ba..ff5c0a5740d2 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -68,6 +68,8 @@ enum _pmux_input {
NUM_OF_PMUX_INPUTS
 };
 
+#define DIV_2_THRESHOLD6
+
 static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
[PLL_OFF_ALPHA_VAL] = 0x08,
@@ -95,10 +97,11 @@ static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
 
 static const struct alpha_pll_config hfpll_config = {
.l = 60,
-   .config_ctl_val = 0x200d4828,
+   .config_ctl_val = 0x200d4aa8,
.config_ctl_hi_val = 0x006,
.pre_div_mask = BIT(12),
.post_div_mask = 0x3 << 8,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -140,7 +143,7 @@ static const struct alpha_pll_config altpll_config = {
.vco_mask = 0x3 << 20,
.config_ctl_val = 0x4001051b,
.post_div_mask = 0x3 << 8,
-   .post_div_val = 0x1,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -181,6 +184,7 @@ struct clk_cpu_8996_mux {
u8  width;
struct notifier_block nb;
struct clk_hw   *pll;
+   struct clk_hw   *pll_div_2;
struct clk_regmap clkr;
 };
 
@@ -226,6 +230,13 @@ clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct 
clk_rate_request *req)
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
struct clk_hw *parent = cpuclk->pll;
 
+   if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+   if (req->rate < (DIV_2_THRESHOLD / 2))
+   return -EINVAL;
+
+   parent = cpuclk->pll_div_2;
+   }
+
req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
req->best_parent_hw = parent;
 
@@ -237,13 +248,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, 
unsigned long event,
 {
int ret;
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+   struct clk_notifier_data *cnd = data;
 
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
break;
case POST_RATE_CHANGE:
-   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   if (cnd->new_rate < DIV_2_THRESHOLD)
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ DIV_2_INDEX);
+   else
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ PLL_INDEX);
break;
default:
ret = 0;
@@ -295,6 +312,7 @@ static struct clk_cpu_8996_mux pwrcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
@@ -315,6 +333,7 @@ static struct clk_cpu_8996_mux perfcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
-- 
2.11.0



[PATCH v13 2/8] clk: qcom: Make clk_alpha_pll_configure available to modules

2018-06-14 Thread ilia . lin
From: Rajendra Nayak 

Allow clk_alpha_pll_configure to be called from loadable
kernel modules.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/clk-alpha-pll.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 3c49a60072f1..a43f80ac94a4 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -228,6 +228,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, 
struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
 }
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
-- 
2.11.0



[PATCH v13 8/8] clk: qcom: Add ACD path to CPU clock driver for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

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 
Tested-by: Amit Kucheria 
---
 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 ff5c0a5740d2..0a908d849cda 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -53,9 +53,11 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 #include "clk-alpha-pll.h"
 #include "clk-regmap.h"
@@ -69,6 +71,11 @@ enum _pmux_input {
 };
 
 #define DIV_2_THRESHOLD6
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x8
+#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 @@ static const struct alpha_pll_config hfpll_config = {
 };
 
 static struct clk_alpha_pll perfcl_pll = {
-   .offset = 0x8,
+   .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 @@ static struct clk_alpha_pll perfcl_pll = {
 };
 
 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 @@ static const struct alpha_pll_config altpll_config = {
 };
 
 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 @@ static struct clk_alpha_pll perfcl_alt_pll = {
 };
 
 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 @@ static struct clk_alpha_pll pwrcl_alt_pll = {
},
 };
 
+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(>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(>clkr.hw,
- PLL_INDEX);
+ ACD_INDEX);
break;
default:
ret = 0;
@@ -276,7 +287,7 @@ const struct clk_ops clk_cpu_8996_mux_ops = {
 };
 
 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 @@ static struct clk_cpu_8996_mux pwrcl_smux = {
 };
 
 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 @@ static struct clk_cpu_8996_mux perfcl_smux = {
 };
 
 static struct clk_cpu_8996_mux pwrcl_pmux = {
-   .reg = 0x40,
+   .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
@@ -329,7 +340,7 @@ static struct clk_cpu_8996_mux pwrcl_pmux = {
 };
 
 static struct clk_cpu_8996_mux perfcl_pmux = {
-   .reg = 0x80040,
+   .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
@@ -393,6 +404,10 @@ qcom_cpu_clk_msm8996_register_clks(struct device *dev, 
struct regmap *regmap)
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll

[PATCH v13 2/8] clk: qcom: Make clk_alpha_pll_configure available to modules

2018-06-14 Thread ilia . lin
From: Rajendra Nayak 

Allow clk_alpha_pll_configure to be called from loadable
kernel modules.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/clk-alpha-pll.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 3c49a60072f1..a43f80ac94a4 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -228,6 +228,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, 
struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
 }
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
-- 
2.11.0



[PATCH v13 8/8] clk: qcom: Add ACD path to CPU clock driver for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

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 
Tested-by: Amit Kucheria 
---
 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 ff5c0a5740d2..0a908d849cda 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -53,9 +53,11 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 #include "clk-alpha-pll.h"
 #include "clk-regmap.h"
@@ -69,6 +71,11 @@ enum _pmux_input {
 };
 
 #define DIV_2_THRESHOLD6
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x8
+#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 @@ static const struct alpha_pll_config hfpll_config = {
 };
 
 static struct clk_alpha_pll perfcl_pll = {
-   .offset = 0x8,
+   .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 @@ static struct clk_alpha_pll perfcl_pll = {
 };
 
 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 @@ static const struct alpha_pll_config altpll_config = {
 };
 
 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 @@ static struct clk_alpha_pll perfcl_alt_pll = {
 };
 
 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 @@ static struct clk_alpha_pll pwrcl_alt_pll = {
},
 };
 
+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(>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(>clkr.hw,
- PLL_INDEX);
+ ACD_INDEX);
break;
default:
ret = 0;
@@ -276,7 +287,7 @@ const struct clk_ops clk_cpu_8996_mux_ops = {
 };
 
 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 @@ static struct clk_cpu_8996_mux pwrcl_smux = {
 };
 
 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 @@ static struct clk_cpu_8996_mux perfcl_smux = {
 };
 
 static struct clk_cpu_8996_mux pwrcl_pmux = {
-   .reg = 0x40,
+   .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
@@ -329,7 +340,7 @@ static struct clk_cpu_8996_mux pwrcl_pmux = {
 };
 
 static struct clk_cpu_8996_mux perfcl_pmux = {
-   .reg = 0x80040,
+   .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
@@ -393,6 +404,10 @@ qcom_cpu_clk_msm8996_register_clks(struct device *dev, 
struct regmap *regmap)
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll

[PATCH v13 3/8] clk: Use devm_ in the register fixed factor clock

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Use devm_clk_hw_register instead of clk_hw_register
to simplify the usage of this API. This way drivers that call
the clk_hw_register_fixed_factor won't need to maintain
a data structure for further cleanup.

Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/clk-fixed-factor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a5d402de5584..8e39bda8e596 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device 
*dev,
init.num_parents = 1;
 
hw = >hw;
-   ret = clk_hw_register(dev, hw);
+   ret = devm_clk_hw_register(dev, hw);
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);
-- 
2.11.0



[PATCH v13 6/8] clk: qcom: cpu-8996: Add support to switch to alternate PLL

2018-06-14 Thread ilia . lin
From: Rajendra Nayak 

Each of the CPU clusters on msm8996 are powered via a primary
PLL and a secondary PLL. The primary PLL is what drives the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/clk-cpu-8996.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index d92cad93af20..620fdc2266ba 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -52,6 +52,7 @@
  * detect voltage droops.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -178,10 +179,14 @@ struct clk_cpu_8996_mux {
u32 reg;
u8  shift;
u8  width;
+   struct notifier_block nb;
struct clk_hw   *pll;
struct clk_regmap clkr;
 };
 
+#define to_clk_cpu_8996_mux_nb(_nb) \
+   container_of(_nb, struct clk_cpu_8996_mux, nb)
+
 static inline
 struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
 {
@@ -227,6 +232,26 @@ clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct 
clk_rate_request *req)
return 0;
 }
 
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+   void *data)
+{
+   int ret;
+   struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+   switch (event) {
+   case PRE_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
+   break;
+   case POST_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   break;
+   default:
+   ret = 0;
+   break;
+   }
+
+   return notifier_from_errno(ret);
+};
 const struct clk_ops clk_cpu_8996_mux_ops = {
.set_parent = clk_cpu_8996_mux_set_parent,
.get_parent = clk_cpu_8996_mux_get_parent,
@@ -270,6 +295,7 @@ static struct clk_cpu_8996_mux pwrcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
.parent_names = (const char *[]){
@@ -289,6 +315,7 @@ static struct clk_cpu_8996_mux perfcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
.parent_names = (const char *[]){
@@ -347,6 +374,12 @@ qcom_cpu_clk_msm8996_register_clks(struct device *dev, 
struct regmap *regmap)
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll, regmap, _config);
 
+   ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, _pmux.nb);
+   if (ret)
+   return ret;
+
+   ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, _pmux.nb);
+
return ret;
 }
 
-- 
2.11.0



[PATCH v13 0/8] Clock for CPU scaling support for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

[v13]
 * Rebased

[v12]
 * Addressed the kbuild fail on arm architecture

[v11]
 * Split the series into domains

[v9]
 * Addressed comments from Viresh and Russel about the error handling

[v8]
 * Reordered the patch series into 4 groups
 * Addressed comments from Amit about the comments and commit messages
 * Addressed comments from Amit and Viresh about the resourses deallocation

[v7]
 * Addressed comments from Viresh about resourses deallocation and DT compatible

[v6]
 * Addressed comments from Viresh about:
  ** Comments style
  ** Kconfig bool instead of tristate
  ** DT and documentation style
  ** Resourses deallocation on an error
  ** Typos

[v5]
 * Rebased
 * Addressed comments from Bjorn about SPDX style, functions and parameters 
naming
 * Addressed comments from Viresh DT properties and style, comments style, 
resourses deallocation, documentation placement
 * Addressed comments from Sricharan about unnessesary include
 * Addressed comments from Nicolas
 * Addressed comments from Rob about the commit messages and acks
 * Addressed comments from Mark

[v4]
 * Adressed all comments from Stephen
 * Added CPU regulator support
 * Added qcom-cpufreq-kryo driver

[v3]
 * Rebased on top of the latest PLL driver changes
 * Addressed comment from Rob Herring for bindings

[v2]
 * Addressed comments from Rob Herring for bindings
 * Addressed comments from Mark Rutland for memory barrier
 * Addressed comments from Julien Thierry for clock reenabling condition
 * Tuned the HW configuration for clock frequencies below 600MHz

SOC (1/15):
Extracts the kryo l2 accessors driver from the QCOM PMU driver

Clocks (2/15-9/15):
This series adds support for the CPU clocks on msm8996 devices.
The driver uses the existing PLL drivers and is required to control
the CPU frequency scaling on the MSM8996.

Ilia Lin (5):
soc: qcom: Separate kryo l2 accessors from PMU driver
clk: Use devm_ in the register fixed factor clock
clk: qcom: Add CPU clock driver for msm8996
dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
clk: qcom: Add ACD path to CPU clock driver for msm8996

Rajendra Nayak (3):
clk: qcom: Make clk_alpha_pll_configure available to modules
clk: qcom: cpu-8996: Add support to switch to alternate PLL
clk: qcom: cpu-8996: Add support to switch below 600Mhz

.../devicetree/bindings/clock/qcom,kryocc.txt  |  17 +
drivers/clk/clk-fixed-factor.c |   2 +-
drivers/clk/qcom/Kconfig   |  10 +
drivers/clk/qcom/Makefile  |   1 +
drivers/clk/qcom/clk-alpha-pll.c   |   1 +
drivers/clk/qcom/clk-alpha-pll.h   |   6 +
drivers/clk/qcom/clk-cpu-8996.c| 510 +
drivers/perf/Kconfig   |   1 +
drivers/perf/qcom_l2_pmu.c |  90 +---
drivers/soc/qcom/Kconfig   |   3 +
drivers/soc/qcom/Makefile  |   1 +
drivers/soc/qcom/kryo-l2-accessors.c   |  56 +++
include/soc/qcom/kryo-l2-accessors.h   |  12 +
13 files changed, 643 insertions(+), 67 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
create mode 100644 include/soc/qcom/kryo-l2-accessors.h

-- 
2.11.0



[PATCH v13 3/8] clk: Use devm_ in the register fixed factor clock

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Use devm_clk_hw_register instead of clk_hw_register
to simplify the usage of this API. This way drivers that call
the clk_hw_register_fixed_factor won't need to maintain
a data structure for further cleanup.

Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/clk-fixed-factor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a5d402de5584..8e39bda8e596 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device 
*dev,
init.num_parents = 1;
 
hw = >hw;
-   ret = clk_hw_register(dev, hw);
+   ret = devm_clk_hw_register(dev, hw);
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);
-- 
2.11.0



[PATCH v13 6/8] clk: qcom: cpu-8996: Add support to switch to alternate PLL

2018-06-14 Thread ilia . lin
From: Rajendra Nayak 

Each of the CPU clusters on msm8996 are powered via a primary
PLL and a secondary PLL. The primary PLL is what drives the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
Tested-by: Amit Kucheria 
---
 drivers/clk/qcom/clk-cpu-8996.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index d92cad93af20..620fdc2266ba 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -52,6 +52,7 @@
  * detect voltage droops.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -178,10 +179,14 @@ struct clk_cpu_8996_mux {
u32 reg;
u8  shift;
u8  width;
+   struct notifier_block nb;
struct clk_hw   *pll;
struct clk_regmap clkr;
 };
 
+#define to_clk_cpu_8996_mux_nb(_nb) \
+   container_of(_nb, struct clk_cpu_8996_mux, nb)
+
 static inline
 struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
 {
@@ -227,6 +232,26 @@ clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct 
clk_rate_request *req)
return 0;
 }
 
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+   void *data)
+{
+   int ret;
+   struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+   switch (event) {
+   case PRE_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
+   break;
+   case POST_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   break;
+   default:
+   ret = 0;
+   break;
+   }
+
+   return notifier_from_errno(ret);
+};
 const struct clk_ops clk_cpu_8996_mux_ops = {
.set_parent = clk_cpu_8996_mux_set_parent,
.get_parent = clk_cpu_8996_mux_get_parent,
@@ -270,6 +295,7 @@ static struct clk_cpu_8996_mux pwrcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
.parent_names = (const char *[]){
@@ -289,6 +315,7 @@ static struct clk_cpu_8996_mux perfcl_pmux = {
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
.parent_names = (const char *[]){
@@ -347,6 +374,12 @@ qcom_cpu_clk_msm8996_register_clks(struct device *dev, 
struct regmap *regmap)
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll, regmap, _config);
 
+   ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, _pmux.nb);
+   if (ret)
+   return ret;
+
+   ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, _pmux.nb);
+
return ret;
 }
 
-- 
2.11.0



[PATCH v13 0/8] Clock for CPU scaling support for msm8996

2018-06-14 Thread ilia . lin
From: Ilia Lin 

[v13]
 * Rebased

[v12]
 * Addressed the kbuild fail on arm architecture

[v11]
 * Split the series into domains

[v9]
 * Addressed comments from Viresh and Russel about the error handling

[v8]
 * Reordered the patch series into 4 groups
 * Addressed comments from Amit about the comments and commit messages
 * Addressed comments from Amit and Viresh about the resourses deallocation

[v7]
 * Addressed comments from Viresh about resourses deallocation and DT compatible

[v6]
 * Addressed comments from Viresh about:
  ** Comments style
  ** Kconfig bool instead of tristate
  ** DT and documentation style
  ** Resourses deallocation on an error
  ** Typos

[v5]
 * Rebased
 * Addressed comments from Bjorn about SPDX style, functions and parameters 
naming
 * Addressed comments from Viresh DT properties and style, comments style, 
resourses deallocation, documentation placement
 * Addressed comments from Sricharan about unnessesary include
 * Addressed comments from Nicolas
 * Addressed comments from Rob about the commit messages and acks
 * Addressed comments from Mark

[v4]
 * Adressed all comments from Stephen
 * Added CPU regulator support
 * Added qcom-cpufreq-kryo driver

[v3]
 * Rebased on top of the latest PLL driver changes
 * Addressed comment from Rob Herring for bindings

[v2]
 * Addressed comments from Rob Herring for bindings
 * Addressed comments from Mark Rutland for memory barrier
 * Addressed comments from Julien Thierry for clock reenabling condition
 * Tuned the HW configuration for clock frequencies below 600MHz

SOC (1/15):
Extracts the kryo l2 accessors driver from the QCOM PMU driver

Clocks (2/15-9/15):
This series adds support for the CPU clocks on msm8996 devices.
The driver uses the existing PLL drivers and is required to control
the CPU frequency scaling on the MSM8996.

Ilia Lin (5):
soc: qcom: Separate kryo l2 accessors from PMU driver
clk: Use devm_ in the register fixed factor clock
clk: qcom: Add CPU clock driver for msm8996
dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
clk: qcom: Add ACD path to CPU clock driver for msm8996

Rajendra Nayak (3):
clk: qcom: Make clk_alpha_pll_configure available to modules
clk: qcom: cpu-8996: Add support to switch to alternate PLL
clk: qcom: cpu-8996: Add support to switch below 600Mhz

.../devicetree/bindings/clock/qcom,kryocc.txt  |  17 +
drivers/clk/clk-fixed-factor.c |   2 +-
drivers/clk/qcom/Kconfig   |  10 +
drivers/clk/qcom/Makefile  |   1 +
drivers/clk/qcom/clk-alpha-pll.c   |   1 +
drivers/clk/qcom/clk-alpha-pll.h   |   6 +
drivers/clk/qcom/clk-cpu-8996.c| 510 +
drivers/perf/Kconfig   |   1 +
drivers/perf/qcom_l2_pmu.c |  90 +---
drivers/soc/qcom/Kconfig   |   3 +
drivers/soc/qcom/Makefile  |   1 +
drivers/soc/qcom/kryo-l2-accessors.c   |  56 +++
include/soc/qcom/kryo-l2-accessors.h   |  12 +
13 files changed, 643 insertions(+), 67 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
create mode 100644 include/soc/qcom/kryo-l2-accessors.h

-- 
2.11.0



[PATCH v2] cpufreq: kryo: Add module remove and exit

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Add device remove and module exit code to make the driver
functioning as a loadable module.

Fixes: ac28927659be (cpufreq: kryo: allow building as a loadable module)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 23 ---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index 5e9511223ce9..01bddacf5c3b 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -42,6 +42,8 @@ enum _msm8996_version {
NUM_OF_MSM8996_VERSIONS,
 };
 
+struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
+
 static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
 {
size_t len;
@@ -74,7 +76,6 @@ static enum _msm8996_version __init 
qcom_cpufreq_kryo_get_msm_id(void)
 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
 {
struct opp_table *opp_tables[NR_CPUS] = {0};
-   struct platform_device *cpufreq_dt_pdev;
enum _msm8996_version msm8996_version;
struct nvmem_cell *speedbin_nvmem;
struct device_node *np;
@@ -129,6 +130,7 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
BUG();
break;
}
+   kfree(speedbin);
 
for_each_possible_cpu(cpu) {
cpu_dev = get_cpu_device(cpu);
@@ -164,8 +166,15 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
return ret;
 }
 
+static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
+{
+   platform_device_unregister(cpufreq_dt_pdev);
+   return 0;
+}
+
 static struct platform_driver qcom_cpufreq_kryo_driver = {
.probe = qcom_cpufreq_kryo_probe,
+   .remove = qcom_cpufreq_kryo_remove,
.driver = {
.name = "qcom-cpufreq-kryo",
},
@@ -200,8 +209,9 @@ static int __init qcom_cpufreq_kryo_init(void)
if (unlikely(ret < 0))
return ret;
 
-   ret = PTR_ERR_OR_ZERO(platform_device_register_simple(
-   "qcom-cpufreq-kryo", -1, NULL, 0));
+   kryo_cpufreq_pdev = platform_device_register_simple(
+   "qcom-cpufreq-kryo", -1, NULL, 0);
+   ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev);
if (0 == ret)
return 0;
 
@@ -210,5 +220,12 @@ static int __init qcom_cpufreq_kryo_init(void)
 }
 module_init(qcom_cpufreq_kryo_init);
 
+static void __init qcom_cpufreq_kryo_exit(void)
+{
+   platform_device_unregister(kryo_cpufreq_pdev);
+   platform_driver_unregister(_cpufreq_kryo_driver);
+}
+module_exit(qcom_cpufreq_kryo_exit);
+
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.11.0



[PATCH v2] cpufreq: kryo: Add module remove and exit

2018-06-14 Thread ilia . lin
From: Ilia Lin 

Add device remove and module exit code to make the driver
functioning as a loadable module.

Fixes: ac28927659be (cpufreq: kryo: allow building as a loadable module)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 23 ---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index 5e9511223ce9..01bddacf5c3b 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -42,6 +42,8 @@ enum _msm8996_version {
NUM_OF_MSM8996_VERSIONS,
 };
 
+struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
+
 static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
 {
size_t len;
@@ -74,7 +76,6 @@ static enum _msm8996_version __init 
qcom_cpufreq_kryo_get_msm_id(void)
 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
 {
struct opp_table *opp_tables[NR_CPUS] = {0};
-   struct platform_device *cpufreq_dt_pdev;
enum _msm8996_version msm8996_version;
struct nvmem_cell *speedbin_nvmem;
struct device_node *np;
@@ -129,6 +130,7 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
BUG();
break;
}
+   kfree(speedbin);
 
for_each_possible_cpu(cpu) {
cpu_dev = get_cpu_device(cpu);
@@ -164,8 +166,15 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
return ret;
 }
 
+static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
+{
+   platform_device_unregister(cpufreq_dt_pdev);
+   return 0;
+}
+
 static struct platform_driver qcom_cpufreq_kryo_driver = {
.probe = qcom_cpufreq_kryo_probe,
+   .remove = qcom_cpufreq_kryo_remove,
.driver = {
.name = "qcom-cpufreq-kryo",
},
@@ -200,8 +209,9 @@ static int __init qcom_cpufreq_kryo_init(void)
if (unlikely(ret < 0))
return ret;
 
-   ret = PTR_ERR_OR_ZERO(platform_device_register_simple(
-   "qcom-cpufreq-kryo", -1, NULL, 0));
+   kryo_cpufreq_pdev = platform_device_register_simple(
+   "qcom-cpufreq-kryo", -1, NULL, 0);
+   ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev);
if (0 == ret)
return 0;
 
@@ -210,5 +220,12 @@ static int __init qcom_cpufreq_kryo_init(void)
 }
 module_init(qcom_cpufreq_kryo_init);
 
+static void __init qcom_cpufreq_kryo_exit(void)
+{
+   platform_device_unregister(kryo_cpufreq_pdev);
+   platform_driver_unregister(_cpufreq_kryo_driver);
+}
+module_exit(qcom_cpufreq_kryo_exit);
+
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.11.0



[PATCH] cpufreq: kryo: Fix possible error code dereference

2018-06-14 Thread ilia . lin
From: Ilia Lin 

In event of error returned by the nvmem_cell_read() non-pointer value
may be dereferenced. Fix this with error handling.

Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index d049fe4b80c4..5e9511223ce9 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -115,6 +115,8 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
 
speedbin = nvmem_cell_read(speedbin_nvmem, );
nvmem_cell_put(speedbin_nvmem);
+   if (IS_ERR(speedbin))
+   return PTR_ERR(speedbin);
 
switch (msm8996_version) {
case MSM8996_V3:
-- 
2.11.0



[PATCH] cpufreq: kryo: Fix possible error code dereference

2018-06-14 Thread ilia . lin
From: Ilia Lin 

In event of error returned by the nvmem_cell_read() non-pointer value
may be dereferenced. Fix this with error handling.

Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index d049fe4b80c4..5e9511223ce9 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -115,6 +115,8 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
 
speedbin = nvmem_cell_read(speedbin_nvmem, );
nvmem_cell_put(speedbin_nvmem);
+   if (IS_ERR(speedbin))
+   return PTR_ERR(speedbin);
 
switch (msm8996_version) {
case MSM8996_V3:
-- 
2.11.0



[PATCH] cpufreq: kryo: Add module remove and exit

2018-06-07 Thread ilia . lin
From: Ilia Lin 

Add device remove and module exit code to make the driver
functioning as a loadable module.

Fixes: ac28927659be (cpufreq: kryo: allow building as a loadable module)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index d049fe4b80c4..a08de0253169 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -71,10 +71,10 @@ static enum _msm8996_version __init 
qcom_cpufreq_kryo_get_msm_id(void)
return version;
 }
 
+struct platform_device *cpufreq_dt_pdev;
 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
 {
struct opp_table *opp_tables[NR_CPUS] = {0};
-   struct platform_device *cpufreq_dt_pdev;
enum _msm8996_version msm8996_version;
struct nvmem_cell *speedbin_nvmem;
struct device_node *np;
@@ -115,6 +115,8 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
 
speedbin = nvmem_cell_read(speedbin_nvmem, );
nvmem_cell_put(speedbin_nvmem);
+   if (IS_ERR(speedbin))
+   return PTR_ERR(speedbin);
 
switch (msm8996_version) {
case MSM8996_V3:
@@ -162,8 +164,15 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
return ret;
 }
 
+static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
+{
+   platform_device_unregister(cpufreq_dt_pdev);
+   return 0;
+}
+
 static struct platform_driver qcom_cpufreq_kryo_driver = {
.probe = qcom_cpufreq_kryo_probe,
+   .remove = qcom_cpufreq_kryo_remove,
.driver = {
.name = "qcom-cpufreq-kryo",
},
@@ -174,6 +183,7 @@ static const struct of_device_id 
qcom_cpufreq_kryo_match_list[] __initconst = {
{ .compatible = "qcom,msm8996", },
 };
 
+struct platform_device *kryo_cpufreq_pdev;
 /*
  * Since the driver depends on smem and nvmem drivers, which may
  * return EPROBE_DEFER, all the real activity is done in the probe,
@@ -198,8 +208,9 @@ static int __init qcom_cpufreq_kryo_init(void)
if (unlikely(ret < 0))
return ret;
 
-   ret = PTR_ERR_OR_ZERO(platform_device_register_simple(
-   "qcom-cpufreq-kryo", -1, NULL, 0));
+   kryo_cpufreq_pdev = platform_device_register_simple(
+   "qcom-cpufreq-kryo", -1, NULL, 0);
+   ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev);
if (0 == ret)
return 0;
 
@@ -208,5 +219,12 @@ static int __init qcom_cpufreq_kryo_init(void)
 }
 module_init(qcom_cpufreq_kryo_init);
 
+static void __init qcom_cpufreq_kryo_exit(void)
+{
+   platform_device_unregister(kryo_cpufreq_pdev);
+   platform_driver_unregister(_cpufreq_kryo_driver);
+}
+module_exit(qcom_cpufreq_kryo_exit);
+
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.11.0



[PATCH] cpufreq: kryo: Add module remove and exit

2018-06-07 Thread ilia . lin
From: Ilia Lin 

Add device remove and module exit code to make the driver
functioning as a loadable module.

Fixes: ac28927659be (cpufreq: kryo: allow building as a loadable module)
Signed-off-by: Ilia Lin 
---
 drivers/cpufreq/qcom-cpufreq-kryo.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c 
b/drivers/cpufreq/qcom-cpufreq-kryo.c
index d049fe4b80c4..a08de0253169 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -71,10 +71,10 @@ static enum _msm8996_version __init 
qcom_cpufreq_kryo_get_msm_id(void)
return version;
 }
 
+struct platform_device *cpufreq_dt_pdev;
 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
 {
struct opp_table *opp_tables[NR_CPUS] = {0};
-   struct platform_device *cpufreq_dt_pdev;
enum _msm8996_version msm8996_version;
struct nvmem_cell *speedbin_nvmem;
struct device_node *np;
@@ -115,6 +115,8 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
 
speedbin = nvmem_cell_read(speedbin_nvmem, );
nvmem_cell_put(speedbin_nvmem);
+   if (IS_ERR(speedbin))
+   return PTR_ERR(speedbin);
 
switch (msm8996_version) {
case MSM8996_V3:
@@ -162,8 +164,15 @@ static int qcom_cpufreq_kryo_probe(struct platform_device 
*pdev)
return ret;
 }
 
+static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
+{
+   platform_device_unregister(cpufreq_dt_pdev);
+   return 0;
+}
+
 static struct platform_driver qcom_cpufreq_kryo_driver = {
.probe = qcom_cpufreq_kryo_probe,
+   .remove = qcom_cpufreq_kryo_remove,
.driver = {
.name = "qcom-cpufreq-kryo",
},
@@ -174,6 +183,7 @@ static const struct of_device_id 
qcom_cpufreq_kryo_match_list[] __initconst = {
{ .compatible = "qcom,msm8996", },
 };
 
+struct platform_device *kryo_cpufreq_pdev;
 /*
  * Since the driver depends on smem and nvmem drivers, which may
  * return EPROBE_DEFER, all the real activity is done in the probe,
@@ -198,8 +208,9 @@ static int __init qcom_cpufreq_kryo_init(void)
if (unlikely(ret < 0))
return ret;
 
-   ret = PTR_ERR_OR_ZERO(platform_device_register_simple(
-   "qcom-cpufreq-kryo", -1, NULL, 0));
+   kryo_cpufreq_pdev = platform_device_register_simple(
+   "qcom-cpufreq-kryo", -1, NULL, 0);
+   ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev);
if (0 == ret)
return 0;
 
@@ -208,5 +219,12 @@ static int __init qcom_cpufreq_kryo_init(void)
 }
 module_init(qcom_cpufreq_kryo_init);
 
+static void __init qcom_cpufreq_kryo_exit(void)
+{
+   platform_device_unregister(kryo_cpufreq_pdev);
+   platform_driver_unregister(_cpufreq_kryo_driver);
+}
+module_exit(qcom_cpufreq_kryo_exit);
+
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.11.0



Re: [PATCH] cpufreq: kryo: allow building as a loadable module

2018-06-05 Thread Ilia Lin
Viresh got ahead of my answer a bit. :)
Sure I'll post the module exit later.

On June 6, 2018 7:09:29 AM GMT+03:00, Viresh Kumar  
wrote:
>On 05-06-18, 13:44, Arnd Bergmann wrote:
>> Building the kryo cpufreq driver while QCOM_SMEM is a loadable module
>> results in a link error:
>> 
>> drivers/cpufreq/qcom-cpufreq-kryo.o: In function
>`qcom_cpufreq_kryo_probe':
>> qcom-cpufreq-kryo.c:(.text+0xbc): undefined reference to
>`qcom_smem_get'
>> 
>> The problem is that Kconfig ignores interprets the dependency as met
>> when the dependent symbol is a 'bool' one. By making it 'tristate',
>> it will be forced to be a module here, which builds successfully.
>> 
>> Fixes: 46e2856b8e18 ("cpufreq: Add Kryo CPU scaling driver")
>> Signed-off-by: Arnd Bergmann 
>> ---
>>  drivers/cpufreq/Kconfig.arm | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/drivers/cpufreq/Kconfig.arm
>b/drivers/cpufreq/Kconfig.arm
>> index c7ce928fbf1f..52f5f1a2040c 100644
>> --- a/drivers/cpufreq/Kconfig.arm
>> +++ b/drivers/cpufreq/Kconfig.arm
>> @@ -125,7 +125,7 @@ config ARM_OMAP2PLUS_CPUFREQ
>>  default ARCH_OMAP2PLUS
>>  
>>  config ARM_QCOM_CPUFREQ_KRYO
>> -bool "Qualcomm Kryo based CPUFreq"
>> +tristate "Qualcomm Kryo based CPUFreq"
>>  depends on ARM64
>>  depends on QCOM_QFPROM
>>  depends on QCOM_SMEM
>
>Okay, so we really need this to be a module. But the driver can't
>really work as
>a module right now if we do this: insmod, rmmod, insmod. Because it
>doesn't free
>resources at rmmmod and will fail on second insmod.
>
>Because what you are fixing is a critical build error, we better get it
>merged
>right now.
>
>Acked-by: Viresh Kumar 
>
>But Ilia needs to cook another patch to add the module removal code for
>the
>driver and mark your patch's commit id in the fixes tag.

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


Re: [PATCH] cpufreq: kryo: allow building as a loadable module

2018-06-05 Thread Ilia Lin
Viresh got ahead of my answer a bit. :)
Sure I'll post the module exit later.

On June 6, 2018 7:09:29 AM GMT+03:00, Viresh Kumar  
wrote:
>On 05-06-18, 13:44, Arnd Bergmann wrote:
>> Building the kryo cpufreq driver while QCOM_SMEM is a loadable module
>> results in a link error:
>> 
>> drivers/cpufreq/qcom-cpufreq-kryo.o: In function
>`qcom_cpufreq_kryo_probe':
>> qcom-cpufreq-kryo.c:(.text+0xbc): undefined reference to
>`qcom_smem_get'
>> 
>> The problem is that Kconfig ignores interprets the dependency as met
>> when the dependent symbol is a 'bool' one. By making it 'tristate',
>> it will be forced to be a module here, which builds successfully.
>> 
>> Fixes: 46e2856b8e18 ("cpufreq: Add Kryo CPU scaling driver")
>> Signed-off-by: Arnd Bergmann 
>> ---
>>  drivers/cpufreq/Kconfig.arm | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/drivers/cpufreq/Kconfig.arm
>b/drivers/cpufreq/Kconfig.arm
>> index c7ce928fbf1f..52f5f1a2040c 100644
>> --- a/drivers/cpufreq/Kconfig.arm
>> +++ b/drivers/cpufreq/Kconfig.arm
>> @@ -125,7 +125,7 @@ config ARM_OMAP2PLUS_CPUFREQ
>>  default ARCH_OMAP2PLUS
>>  
>>  config ARM_QCOM_CPUFREQ_KRYO
>> -bool "Qualcomm Kryo based CPUFreq"
>> +tristate "Qualcomm Kryo based CPUFreq"
>>  depends on ARM64
>>  depends on QCOM_QFPROM
>>  depends on QCOM_SMEM
>
>Okay, so we really need this to be a module. But the driver can't
>really work as
>a module right now if we do this: insmod, rmmod, insmod. Because it
>doesn't free
>resources at rmmmod and will fail on second insmod.
>
>Because what you are fixing is a critical build error, we better get it
>merged
>right now.
>
>Acked-by: Viresh Kumar 
>
>But Ilia needs to cook another patch to add the module removal code for
>the
>driver and mark your patch's commit id in the fixes tag.

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


Re: [PATCH v14 0/2] Kryo CPU scaling driver

2018-05-30 Thread Ilia Lin
Just like Viresh said, this is fixed in the v15.

On May 30, 2018 12:15:35 PM GMT+03:00, Viresh Kumar  
wrote:
>On 30-05-18, 10:08, Rafael J. Wysocki wrote:
>> On Fri, May 25, 2018 at 2:07 PM, Ilia Lin 
>wrote:
>> > [v14]
>> >  * Addressed comment from Sudeep about DT compatible
>> >  * Added MAINTAINERS entry
>> 
>> This causes a build issue to occur in my bleeding-edge branch.
>> 
>> Does it depend on anything new in arm-soc?
>
>He already sent a v15 and the changelog suggest he fixed that build
>issue.

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


Re: [PATCH v14 0/2] Kryo CPU scaling driver

2018-05-30 Thread Ilia Lin
Just like Viresh said, this is fixed in the v15.

On May 30, 2018 12:15:35 PM GMT+03:00, Viresh Kumar  
wrote:
>On 30-05-18, 10:08, Rafael J. Wysocki wrote:
>> On Fri, May 25, 2018 at 2:07 PM, Ilia Lin 
>wrote:
>> > [v14]
>> >  * Addressed comment from Sudeep about DT compatible
>> >  * Added MAINTAINERS entry
>> 
>> This causes a build issue to occur in my bleeding-edge branch.
>> 
>> Does it depend on anything new in arm-soc?
>
>He already sent a v15 and the changelog suggest he fixed that build
>issue.

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


[PATCH v15 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-29 Thread Ilia Lin
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 
Acked-by: Viresh Kumar 
Reviewed-by: Amit Kucheria 
Tested-by: Amit Kucheria 
---
 MAINTAINERS  |   7 ++
 drivers/cpufreq/Kconfig.arm  |  11 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 212 +++
 5 files changed, 234 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ba0adcb..648e0c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11687,6 +11687,13 @@ F: 
Documentation/devicetree/bindings/media/qcom,camss.txt
 F: Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
+QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
+M:  Ilia Lin 
+L:  linux...@vger.kernel.org
+S:  Maintained
+F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
+F:  drivers/cpufreq/qcom-cpufreq-kryo.c
+
 QUALCOMM EMAC GIGABIT ETHERNET DRIVER
 M: Timur Tabi 
 L: net...@vger.kernel.org
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de55c7d..86e87bb 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -124,6 +124,17 @@ config ARM_OMAP2PLUS_CPUFREQ
depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS
 
+config ARM_QCOM_CPUFREQ_KRYO
+   bool "Qualcomm Kryo based CPUFreq"
+   depends on ARM64
+   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 000..d049fe4
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,212 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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_sme

[PATCH v15 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-29 Thread Ilia Lin
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 
Acked-by: Viresh Kumar 
Reviewed-by: Amit Kucheria 
Tested-by: Amit Kucheria 
---
 MAINTAINERS  |   7 ++
 drivers/cpufreq/Kconfig.arm  |  11 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 212 +++
 5 files changed, 234 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ba0adcb..648e0c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11687,6 +11687,13 @@ F: 
Documentation/devicetree/bindings/media/qcom,camss.txt
 F: Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
+QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
+M:  Ilia Lin 
+L:  linux...@vger.kernel.org
+S:  Maintained
+F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
+F:  drivers/cpufreq/qcom-cpufreq-kryo.c
+
 QUALCOMM EMAC GIGABIT ETHERNET DRIVER
 M: Timur Tabi 
 L: net...@vger.kernel.org
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de55c7d..86e87bb 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -124,6 +124,17 @@ config ARM_OMAP2PLUS_CPUFREQ
depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS
 
+config ARM_QCOM_CPUFREQ_KRYO
+   bool "Qualcomm Kryo based CPUFreq"
+   depends on ARM64
+   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 000..d049fe4
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,212 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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_sme

[PATCH v15 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-29 Thread Ilia Lin
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 
Reviewed-by: Rob Herring 
Reviewed-by: Amit Kucheria 
Tested-by: Amit Kucheria 
Acked-by: Viresh Kumar 
---
 .../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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   CPU2: cpu@100 {
+  

[PATCH v15 0/2] Kryo CPU scaling driver

2018-05-29 Thread Ilia Lin
[v15]
 * Addressed the kbuild error

[v14]
 * Addressed comment from Sudeep about DT compatible
 * Added MAINTAINERS entry

[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10427315/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 MAINTAINERS|   7 +
 drivers/cpufreq/Kconfig.arm|  11 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 212 +++
 6 files changed, 914 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v15 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-29 Thread Ilia Lin
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 
Reviewed-by: Rob Herring 
Reviewed-by: Amit Kucheria 
Tested-by: Amit Kucheria 
Acked-by: Viresh Kumar 
---
 .../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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   CPU2: cpu@100 {
+  

[PATCH v15 0/2] Kryo CPU scaling driver

2018-05-29 Thread Ilia Lin
[v15]
 * Addressed the kbuild error

[v14]
 * Addressed comment from Sudeep about DT compatible
 * Added MAINTAINERS entry

[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10427315/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 MAINTAINERS|   7 +
 drivers/cpufreq/Kconfig.arm|  11 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 212 +++
 6 files changed, 914 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v14 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
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 <ilia...@codeaurora.org>
---
 MAINTAINERS  |   7 ++
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 212 +++
 5 files changed, 233 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ba0adcb..648e0c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11687,6 +11687,13 @@ F: 
Documentation/devicetree/bindings/media/qcom,camss.txt
 F: Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
+QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
+M:  Ilia Lin <ilia@gmail.com>
+L:  linux...@vger.kernel.org
+S:  Maintained
+F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
+F:  drivers/cpufreq/qcom-cpufreq-kryo.c
+
 QUALCOMM EMAC GIGABIT ETHERNET DRIVER
 M: Timur Tabi <ti...@codeaurora.org>
 L: net...@vger.kernel.org
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 000..d049fe4
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,212 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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_SME

[PATCH v14 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
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 
---
 MAINTAINERS  |   7 ++
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 212 +++
 5 files changed, 233 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ba0adcb..648e0c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11687,6 +11687,13 @@ F: 
Documentation/devicetree/bindings/media/qcom,camss.txt
 F: Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
+QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
+M:  Ilia Lin 
+L:  linux...@vger.kernel.org
+S:  Maintained
+F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
+F:  drivers/cpufreq/qcom-cpufreq-kryo.c
+
 QUALCOMM EMAC GIGABIT ETHERNET DRIVER
 M: Timur Tabi 
 L: net...@vger.kernel.org
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 000..d049fe4
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,212 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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, );
+   if (IS_ERR(msm_id))
+   return NUM_OF

[PATCH v14 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-25 Thread Ilia Lin
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 <ilia...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
Acked-by: Viresh Kumar <viresh.ku...@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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   C

[PATCH v14 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-25 Thread Ilia Lin
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 
Reviewed-by: Rob Herring 
Acked-by: Viresh Kumar 
---
 .../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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   CPU2: cpu@100 {
+   device_type = "cpu";
+

[PATCH v14 0/2] Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
[v14]
 * Addressed comment from Sudeep about DT compatible
 * Added MAINTAINERS entry

[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10424949/


Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 MAINTAINERS|   7 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 212 +++
 6 files changed, 913 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v14 0/2] Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
[v14]
 * Addressed comment from Sudeep about DT compatible
 * Added MAINTAINERS entry

[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10424949/


Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 MAINTAINERS|   7 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 212 +++
 6 files changed, 913 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v14 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-25 Thread Ilia Lin
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 <ilia...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
Acked-by: Viresh Kumar <viresh.ku...@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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   C

[PATCH v14 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-25 Thread Ilia Lin
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 
Reviewed-by: Rob Herring 
Acked-by: Viresh Kumar 
---
 .../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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   CPU2: cpu@100 {
+   device_type = "cpu";
+

[PATCH v14 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
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 <ilia...@codeaurora.org>
---
 MAINTAINERS  |   7 ++
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 206 +++
 5 files changed, 227 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ba0adcb..648e0c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11687,6 +11687,13 @@ F: 
Documentation/devicetree/bindings/media/qcom,camss.txt
 F: Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
+QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
+M:  Ilia Lin <ilia@gmail.com>
+L:  linux...@vger.kernel.org
+S:  Maintained
+F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
+F:  drivers/cpufreq/qcom-cpufreq-kryo.c
+
 QUALCOMM EMAC GIGABIT ETHERNET DRIVER
 M: Timur Tabi <ti...@codeaurora.org>
 L: net...@vger.kernel.org
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 000..bc2e885
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,206 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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_SME

[PATCH v14 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
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 
---
 MAINTAINERS  |   7 ++
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 206 +++
 5 files changed, 227 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ba0adcb..648e0c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11687,6 +11687,13 @@ F: 
Documentation/devicetree/bindings/media/qcom,camss.txt
 F: Documentation/media/v4l-drivers/qcom_camss.rst
 F: drivers/media/platform/qcom/camss-8x16/
 
+QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
+M:  Ilia Lin 
+L:  linux...@vger.kernel.org
+S:  Maintained
+F:  Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
+F:  drivers/cpufreq/qcom-cpufreq-kryo.c
+
 QUALCOMM EMAC GIGABIT ETHERNET DRIVER
 M: Timur Tabi 
 L: net...@vger.kernel.org
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 000..bc2e885
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,206 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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, );
+   if (IS_ERR(msm_id))
+   return NUM_OF

[PATCH v14 0/2] Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
[v14]
 * Addressed comment from Sudeep about DT compatible
 * Added MAINTAINERS entry

[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10424949/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 MAINTAINERS|   7 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 206 +++
 6 files changed, 907 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v14 0/2] Kryo CPU scaling driver

2018-05-25 Thread Ilia Lin
[v14]
 * Addressed comment from Sudeep about DT compatible
 * Added MAINTAINERS entry

[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10424949/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 MAINTAINERS|   7 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 206 +++
 6 files changed, 907 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v13 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-24 Thread Ilia Lin
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 <ilia...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
Acked-by: Viresh Kumar <viresh.ku...@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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   C

[PATCH v13 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-24 Thread Ilia Lin
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 
Reviewed-by: Rob Herring 
Acked-by: Viresh Kumar 
---
 .../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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   CPU2: cpu@100 {
+   device_type = "cpu";
+

[PATCH v13 0/2] Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10423137/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 206 +++
 5 files changed, 900 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v13 0/2] Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
[v13]
 * Addressed comment from Sudeep about DT compatible check on init

[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10423137/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 206 +++
 5 files changed, 900 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v13 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
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 <ilia...@codeaurora.org>
---
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 206 +++
 4 files changed, 220 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 000..bc2e885
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,206 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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, );
+   if (IS_ERR(msm_id))
+   return NUM_OF_MSM8996_VERSIONS;
+
+   /* 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 qcom_cpufreq_kryo_probe(struct platform_device *pdev)
+{
+   struct opp_table *opp_tables[NR_CPUS] = 

[PATCH v13 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
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 
---
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 206 +++
 4 files changed, 220 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 000..bc2e885
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,206 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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, );
+   if (IS_ERR(msm_id))
+   return NUM_OF_MSM8996_VERSIONS;
+
+   /* 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 qcom_cpufreq_kryo_probe(struct platform_device *pdev)
+{
+   struct opp_table *opp_tables[NR_CPUS] = {0};
+   struct platform_device *cp

[PATCH v12 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
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 <ilia...@codeaurora.org>
---
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 194 +++
 4 files changed, 208 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 000..9fe379c
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,194 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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, );
+   /* 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 qcom_cpufreq_kryo_probe(struct platform_device *pdev)
+{
+   struct opp_table *opp_tables[NR_CPUS] = {0};
+   struct platform_device *cpufreq_dt_pdev;
+   enum _msm8996_

[PATCH v12 1/2] cpufreq: Add Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
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 
---
 drivers/cpufreq/Kconfig.arm  |  10 ++
 drivers/cpufreq/Makefile |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 194 +++
 4 files changed, 208 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 000..9fe379c
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,194 @@
+// 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSM_ID_SMEM137
+
+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, );
+   /* 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 qcom_cpufreq_kryo_probe(struct platform_device *pdev)
+{
+   struct opp_table *opp_tables[NR_CPUS] = {0};
+   struct platform_device *cpufreq_dt_pdev;
+   enum _msm8996_version msm8996_version;
+   struc

[PATCH v12 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-24 Thread Ilia Lin
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 <ilia...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
Acked-by: Viresh Kumar <viresh.ku...@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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   C

[PATCH v12 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

2018-05-24 Thread Ilia Lin
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 
Reviewed-by: Rob Herring 
Acked-by: Viresh Kumar 
---
 .../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 000..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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_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 = < 0>;
+   cpu-supply = <_s11_saw>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
+   next-level-cache = <_0>;
+   };
+
+   CPU2: cpu@100 {
+   device_type = "cpu";
+

[PATCH v12 0/2] Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10421143/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 194 ++
 5 files changed, 888 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v12 0/2] Kryo CPU scaling driver

2018-05-24 Thread Ilia Lin
[v12]
 * Addressed comments from Sudeep and Viresh about the single init

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10421143/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt   | 680 +
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c| 194 ++
 5 files changed, 888 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1



[PATCH v12 5/8] dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996

2018-05-24 Thread Ilia Lin
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
---
 Documentation/devicetree/bindings/clock/qcom,kryocc.txt | 17 +
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index 000..8458783
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+   "qcom,msm8996-apcc"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+   kryocc: clock-controller@640 {
+   compatible = "qcom,msm8996-apcc";
+   reg = <0x640 0x9>;
+   #clock-cells = <1>;
+   };
-- 
1.9.1



[PATCH v12 5/8] dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996

2018-05-24 Thread Ilia Lin
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

Signed-off-by: Ilia Lin 
Reviewed-by: Rob Herring 
---
 Documentation/devicetree/bindings/clock/qcom,kryocc.txt | 17 +
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index 000..8458783
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+   "qcom,msm8996-apcc"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+   kryocc: clock-controller@640 {
+   compatible = "qcom,msm8996-apcc";
+   reg = <0x640 0x9>;
+   #clock-cells = <1>;
+   };
-- 
1.9.1



[PATCH v12 4/8] clk: qcom: Add CPU clock driver for msm8996

2018-05-24 Thread Ilia Lin
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.

ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops.

Signed-off-by: Rajendra Nayak <rna...@codeaurora.org>
Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
---
 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/clk-alpha-pll.h |   6 +
 drivers/clk/qcom/clk-cpu-8996.c  | 403 +++
 4 files changed, 420 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..42e84b5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,16 @@ config QCOM_CLK_APCS_MSM8916
  Say Y if you want to support CPU frequency scaling on devices
  such as msm8916.
 
+config QCOM_CLK_APCC_MSM8996
+   tristate "MSM8996 CPU Clock Controller"
+   depends on ARM64
+   depends on COMMON_CLK_QCOM
+   select QCOM_KRYO_L2_ACCESSORS
+   help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
+
 config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 7c09ab1..a822fc8 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b48..9ce2a32 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -50,6 +50,12 @@ struct pll_vco {
u32 val;
 };
 
+#define VCO(a, b, c) { \
+   .val = a,\
+   .min_freq = b,\
+   .max_freq = c,\
+}
+
 /**
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index 000..d92cad93
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown below
+ *
+ *  +-

[PATCH v12 3/8] clk: Use devm_ in the register fixed factor clock

2018-05-24 Thread Ilia Lin
Use devm_clk_hw_register instead of clk_hw_register
to simplify the usage of this API. This way drivers that call
the clk_hw_register_fixed_factor won't need to maintain
a data structure for further cleanup.

Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
---
 drivers/clk/clk-fixed-factor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a5d402d..8e39bda 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device 
*dev,
init.num_parents = 1;
 
hw = >hw;
-   ret = clk_hw_register(dev, hw);
+   ret = devm_clk_hw_register(dev, hw);
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);
-- 
1.9.1



[PATCH v12 0/8] Clock for CPU scaling support for msm8996

2018-05-24 Thread Ilia Lin
[v12]
 * Addressed the kbuild fail on arm architecture

[v11]
 * Split the series into domains

[v9]
 * Addressed comments from Viresh and Russel about the error handling

[v8]
 * Reordered the patch series into 4 groups
 * Addressed comments from Amit about the comments and commit messages
 * Addressed comments from Amit and Viresh about the resourses deallocation

[v7]
 * Addressed comments from Viresh about resourses deallocation
   and DT compatible

[v6]
 * Addressed comments from Viresh about:
 ** Comments style
 ** Kconfig bool instead of tristate
 ** DT and documentation style
 ** Resourses deallocation on an error
 ** Typos

[v5]
 * Rebased
 * Addressed comments from Bjorn about SPDX style,
   functions and parameters naming
 * Addressed comments from Viresh DT properties and style, comments style,
   resourses deallocation, documentation placement
 * Addressed comments from Sricharan about unnessesary include
 * Addressed comments from Nicolas
 * Addressed comments from Rob about the commit messages and acks
 * Addressed comments from Mark

[v4]
 * Adressed all comments from Stephen
 * Added CPU regulator support
 * Added qcom-cpufreq-kryo driver

[v3]
 * Rebased on top of the latest PLL driver changes
 * Addressed comment from Rob Herring for bindings

[v2]
 * Addressed comments from Rob Herring for bindings
 * Addressed comments from Mark Rutland for memory barrier
 * Addressed comments from Julien Thierry for clock reenabling condition
 * Tuned the HW configuration for clock frequencies below 600MHz

SOC (1/15):
Extracts the kryo l2 accessors driver from the QCOM PMU driver

Clocks (2/15-9/15):
This series adds support for the CPU clocks on msm8996 devices.
The driver uses the existing PLL drivers and is required to control
the CPU frequency scaling on the MSM8996.

Ilia Lin (6):
  soc: qcom: Separate kryo l2 accessors from PMU driver
  clk: Use devm_ in the register fixed factor clock
  clk: qcom: Add CPU clock driver for msm8996
  dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
  clk: qcom: cpu-8996: Add support to switch below 600Mhz
  clk: qcom: Add ACD path to CPU clock driver for msm8996

Rajendra Nayak (2):
  clk: qcom: Make clk_alpha_pll_configure available to modules
  clk: qcom: cpu-8996: Add support to switch to alternate PLL

 .../devicetree/bindings/clock/qcom,kryocc.txt  |  17 +
 drivers/clk/clk-fixed-factor.c |   2 +-
 drivers/clk/qcom/Kconfig   |  10 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/clk-alpha-pll.c   |   1 +
 drivers/clk/qcom/clk-alpha-pll.h   |   6 +
 drivers/clk/qcom/clk-cpu-8996.c| 510 +
 drivers/perf/Kconfig   |   1 +
 drivers/perf/qcom_l2_pmu.c |  90 +---
 drivers/soc/qcom/Kconfig   |   3 +
 drivers/soc/qcom/Makefile  |   1 +
 drivers/soc/qcom/kryo-l2-accessors.c   |  56 +++
 include/soc/qcom/kryo-l2-accessors.h   |  12 +
 13 files changed, 643 insertions(+), 67 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

-- 
1.9.1



[PATCH v12 3/8] clk: Use devm_ in the register fixed factor clock

2018-05-24 Thread Ilia Lin
Use devm_clk_hw_register instead of clk_hw_register
to simplify the usage of this API. This way drivers that call
the clk_hw_register_fixed_factor won't need to maintain
a data structure for further cleanup.

Signed-off-by: Ilia Lin 
---
 drivers/clk/clk-fixed-factor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a5d402d..8e39bda 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device 
*dev,
init.num_parents = 1;
 
hw = >hw;
-   ret = clk_hw_register(dev, hw);
+   ret = devm_clk_hw_register(dev, hw);
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);
-- 
1.9.1



[PATCH v12 0/8] Clock for CPU scaling support for msm8996

2018-05-24 Thread Ilia Lin
[v12]
 * Addressed the kbuild fail on arm architecture

[v11]
 * Split the series into domains

[v9]
 * Addressed comments from Viresh and Russel about the error handling

[v8]
 * Reordered the patch series into 4 groups
 * Addressed comments from Amit about the comments and commit messages
 * Addressed comments from Amit and Viresh about the resourses deallocation

[v7]
 * Addressed comments from Viresh about resourses deallocation
   and DT compatible

[v6]
 * Addressed comments from Viresh about:
 ** Comments style
 ** Kconfig bool instead of tristate
 ** DT and documentation style
 ** Resourses deallocation on an error
 ** Typos

[v5]
 * Rebased
 * Addressed comments from Bjorn about SPDX style,
   functions and parameters naming
 * Addressed comments from Viresh DT properties and style, comments style,
   resourses deallocation, documentation placement
 * Addressed comments from Sricharan about unnessesary include
 * Addressed comments from Nicolas
 * Addressed comments from Rob about the commit messages and acks
 * Addressed comments from Mark

[v4]
 * Adressed all comments from Stephen
 * Added CPU regulator support
 * Added qcom-cpufreq-kryo driver

[v3]
 * Rebased on top of the latest PLL driver changes
 * Addressed comment from Rob Herring for bindings

[v2]
 * Addressed comments from Rob Herring for bindings
 * Addressed comments from Mark Rutland for memory barrier
 * Addressed comments from Julien Thierry for clock reenabling condition
 * Tuned the HW configuration for clock frequencies below 600MHz

SOC (1/15):
Extracts the kryo l2 accessors driver from the QCOM PMU driver

Clocks (2/15-9/15):
This series adds support for the CPU clocks on msm8996 devices.
The driver uses the existing PLL drivers and is required to control
the CPU frequency scaling on the MSM8996.

Ilia Lin (6):
  soc: qcom: Separate kryo l2 accessors from PMU driver
  clk: Use devm_ in the register fixed factor clock
  clk: qcom: Add CPU clock driver for msm8996
  dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
  clk: qcom: cpu-8996: Add support to switch below 600Mhz
  clk: qcom: Add ACD path to CPU clock driver for msm8996

Rajendra Nayak (2):
  clk: qcom: Make clk_alpha_pll_configure available to modules
  clk: qcom: cpu-8996: Add support to switch to alternate PLL

 .../devicetree/bindings/clock/qcom,kryocc.txt  |  17 +
 drivers/clk/clk-fixed-factor.c |   2 +-
 drivers/clk/qcom/Kconfig   |  10 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/clk-alpha-pll.c   |   1 +
 drivers/clk/qcom/clk-alpha-pll.h   |   6 +
 drivers/clk/qcom/clk-cpu-8996.c| 510 +
 drivers/perf/Kconfig   |   1 +
 drivers/perf/qcom_l2_pmu.c |  90 +---
 drivers/soc/qcom/Kconfig   |   3 +
 drivers/soc/qcom/Makefile  |   1 +
 drivers/soc/qcom/kryo-l2-accessors.c   |  56 +++
 include/soc/qcom/kryo-l2-accessors.h   |  12 +
 13 files changed, 643 insertions(+), 67 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

-- 
1.9.1



[PATCH v12 4/8] clk: qcom: Add CPU clock driver for msm8996

2018-05-24 Thread Ilia Lin
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

 +---+
  XO |   |
  +-->0  |
 |   |
   PLL/2 | SMUX  ++
 +--->1  ||
 |   |   ||
 |   +---+|+---+
 |+>0  |
 | |   |
+---+| +--->1  | CPU clk
|Primary PLL++ PLL_EARLY   |   |   +-->
|   +--+---++-->2 PMUX |
+---+  ||  |   |
   |   +--+ |   +-->3  |
   +--^+  ACD +-+   |  +---+
+---+  +--+ |
|Alt PLL|   |
|   +---+
+---+ PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.

ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
---
 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/clk-alpha-pll.h |   6 +
 drivers/clk/qcom/clk-cpu-8996.c  | 403 +++
 4 files changed, 420 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..42e84b5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,16 @@ config QCOM_CLK_APCS_MSM8916
  Say Y if you want to support CPU frequency scaling on devices
  such as msm8916.
 
+config QCOM_CLK_APCC_MSM8996
+   tristate "MSM8996 CPU Clock Controller"
+   depends on ARM64
+   depends on COMMON_CLK_QCOM
+   select QCOM_KRYO_L2_ACCESSORS
+   help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
+
 config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 7c09ab1..a822fc8 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b48..9ce2a32 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -50,6 +50,12 @@ struct pll_vco {
u32 val;
 };
 
+#define VCO(a, b, c) { \
+   .val = a,\
+   .min_freq = b,\
+   .max_freq = c,\
+}
+
 /**
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index 000..d92cad93
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown below
+ *
+ *  +---+
+ * 

[PATCH v12 7/8] clk: qcom: cpu-8996: Add support to switch below 600Mhz

2018-05-24 Thread Ilia Lin
The CPU clock controller's primary PLL operates on a single VCO range,
between 600MHz and 3GHz. However the CPUs do support OPPs with
frequencies between 300MHz and 600MHz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk

Signed-off-by: Rajendra Nayak <rna...@codeaurora.org>
Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
---
 drivers/clk/qcom/clk-cpu-8996.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 620fdc2..ff5c0a5 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -68,6 +68,8 @@ enum _pmux_input {
NUM_OF_PMUX_INPUTS
 };
 
+#define DIV_2_THRESHOLD6
+
 static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
[PLL_OFF_ALPHA_VAL] = 0x08,
@@ -95,10 +97,11 @@ enum _pmux_input {
 
 static const struct alpha_pll_config hfpll_config = {
.l = 60,
-   .config_ctl_val = 0x200d4828,
+   .config_ctl_val = 0x200d4aa8,
.config_ctl_hi_val = 0x006,
.pre_div_mask = BIT(12),
.post_div_mask = 0x3 << 8,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -140,7 +143,7 @@ enum _pmux_input {
.vco_mask = 0x3 << 20,
.config_ctl_val = 0x4001051b,
.post_div_mask = 0x3 << 8,
-   .post_div_val = 0x1,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -181,6 +184,7 @@ struct clk_cpu_8996_mux {
u8  width;
struct notifier_block nb;
struct clk_hw   *pll;
+   struct clk_hw   *pll_div_2;
struct clk_regmap clkr;
 };
 
@@ -226,6 +230,13 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
struct clk_hw *parent = cpuclk->pll;
 
+   if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+   if (req->rate < (DIV_2_THRESHOLD / 2))
+   return -EINVAL;
+
+   parent = cpuclk->pll_div_2;
+   }
+
req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
req->best_parent_hw = parent;
 
@@ -237,13 +248,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, 
unsigned long event,
 {
int ret;
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+   struct clk_notifier_data *cnd = data;
 
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
break;
case POST_RATE_CHANGE:
-   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   if (cnd->new_rate < DIV_2_THRESHOLD)
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ DIV_2_INDEX);
+   else
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ PLL_INDEX);
break;
default:
ret = 0;
@@ -295,6 +312,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned 
long event,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
@@ -315,6 +333,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned 
long event,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
-- 
1.9.1



[PATCH v12 7/8] clk: qcom: cpu-8996: Add support to switch below 600Mhz

2018-05-24 Thread Ilia Lin
The CPU clock controller's primary PLL operates on a single VCO range,
between 600MHz and 3GHz. However the CPUs do support OPPs with
frequencies between 300MHz and 600MHz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
---
 drivers/clk/qcom/clk-cpu-8996.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 620fdc2..ff5c0a5 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -68,6 +68,8 @@ enum _pmux_input {
NUM_OF_PMUX_INPUTS
 };
 
+#define DIV_2_THRESHOLD6
+
 static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
[PLL_OFF_ALPHA_VAL] = 0x08,
@@ -95,10 +97,11 @@ enum _pmux_input {
 
 static const struct alpha_pll_config hfpll_config = {
.l = 60,
-   .config_ctl_val = 0x200d4828,
+   .config_ctl_val = 0x200d4aa8,
.config_ctl_hi_val = 0x006,
.pre_div_mask = BIT(12),
.post_div_mask = 0x3 << 8,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -140,7 +143,7 @@ enum _pmux_input {
.vco_mask = 0x3 << 20,
.config_ctl_val = 0x4001051b,
.post_div_mask = 0x3 << 8,
-   .post_div_val = 0x1,
+   .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
 };
@@ -181,6 +184,7 @@ struct clk_cpu_8996_mux {
u8  width;
struct notifier_block nb;
struct clk_hw   *pll;
+   struct clk_hw   *pll_div_2;
struct clk_regmap clkr;
 };
 
@@ -226,6 +230,13 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
struct clk_hw *parent = cpuclk->pll;
 
+   if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+   if (req->rate < (DIV_2_THRESHOLD / 2))
+   return -EINVAL;
+
+   parent = cpuclk->pll_div_2;
+   }
+
req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
req->best_parent_hw = parent;
 
@@ -237,13 +248,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, 
unsigned long event,
 {
int ret;
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+   struct clk_notifier_data *cnd = data;
 
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
break;
case POST_RATE_CHANGE:
-   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   if (cnd->new_rate < DIV_2_THRESHOLD)
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ DIV_2_INDEX);
+   else
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw,
+ PLL_INDEX);
break;
default:
ret = 0;
@@ -295,6 +312,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned 
long event,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
@@ -315,6 +333,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned 
long event,
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .pll_div_2 = _smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
-- 
1.9.1



[PATCH v12 6/8] clk: qcom: cpu-8996: Add support to switch to alternate PLL

2018-05-24 Thread Ilia Lin
From: Rajendra Nayak <rna...@codeaurora.org>

Each of the CPU clusters on msm8996 are powered via a primary
PLL and a secondary PLL. The primary PLL is what drives the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.

Signed-off-by: Rajendra Nayak <rna...@codeaurora.org>
Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
---
 drivers/clk/qcom/clk-cpu-8996.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index d92cad93..620fdc2 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -52,6 +52,7 @@
  * detect voltage droops.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -178,10 +179,14 @@ struct clk_cpu_8996_mux {
u32 reg;
u8  shift;
u8  width;
+   struct notifier_block nb;
struct clk_hw   *pll;
struct clk_regmap clkr;
 };
 
+#define to_clk_cpu_8996_mux_nb(_nb) \
+   container_of(_nb, struct clk_cpu_8996_mux, nb)
+
 static inline
 struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
 {
@@ -227,6 +232,26 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
return 0;
 }
 
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+   void *data)
+{
+   int ret;
+   struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+   switch (event) {
+   case PRE_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
+   break;
+   case POST_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   break;
+   default:
+   ret = 0;
+   break;
+   }
+
+   return notifier_from_errno(ret);
+};
 const struct clk_ops clk_cpu_8996_mux_ops = {
.set_parent = clk_cpu_8996_mux_set_parent,
.get_parent = clk_cpu_8996_mux_get_parent,
@@ -270,6 +295,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
.parent_names = (const char *[]){
@@ -289,6 +315,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
.parent_names = (const char *[]){
@@ -347,6 +374,12 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll, regmap, _config);
 
+   ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, _pmux.nb);
+   if (ret)
+   return ret;
+
+   ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, _pmux.nb);
+
return ret;
 }
 
-- 
1.9.1



[PATCH v12 6/8] clk: qcom: cpu-8996: Add support to switch to alternate PLL

2018-05-24 Thread Ilia Lin
From: Rajendra Nayak 

Each of the CPU clusters on msm8996 are powered via a primary
PLL and a secondary PLL. The primary PLL is what drives the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
---
 drivers/clk/qcom/clk-cpu-8996.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index d92cad93..620fdc2 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -52,6 +52,7 @@
  * detect voltage droops.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -178,10 +179,14 @@ struct clk_cpu_8996_mux {
u32 reg;
u8  shift;
u8  width;
+   struct notifier_block nb;
struct clk_hw   *pll;
struct clk_regmap clkr;
 };
 
+#define to_clk_cpu_8996_mux_nb(_nb) \
+   container_of(_nb, struct clk_cpu_8996_mux, nb)
+
 static inline
 struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
 {
@@ -227,6 +232,26 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
return 0;
 }
 
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+   void *data)
+{
+   int ret;
+   struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+   switch (event) {
+   case PRE_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, ALT_INDEX);
+   break;
+   case POST_RATE_CHANGE:
+   ret = clk_cpu_8996_mux_set_parent(>clkr.hw, PLL_INDEX);
+   break;
+   default:
+   ret = 0;
+   break;
+   }
+
+   return notifier_from_errno(ret);
+};
 const struct clk_ops clk_cpu_8996_mux_ops = {
.set_parent = clk_cpu_8996_mux_set_parent,
.get_parent = clk_cpu_8996_mux_get_parent,
@@ -270,6 +295,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
.parent_names = (const char *[]){
@@ -289,6 +315,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, 
u8 index)
.shift = 0,
.width = 2,
.pll = _pll.clkr.hw,
+   .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
.parent_names = (const char *[]){
@@ -347,6 +374,12 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll, regmap, _config);
 
+   ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, _pmux.nb);
+   if (ret)
+   return ret;
+
+   ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, _pmux.nb);
+
return ret;
 }
 
-- 
1.9.1



[PATCH v12 8/8] clk: qcom: Add ACD path to CPU clock driver for msm8996

2018-05-24 Thread Ilia Lin
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 <ilia...@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 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 #include "clk-alpha-pll.h"
 #include "clk-regmap.h"
@@ -69,6 +71,11 @@ enum _pmux_input {
 };
 
 #define DIV_2_THRESHOLD6
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x8
+#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 = 0x8,
+   .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(>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(>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 = _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 = _pll.clkr.hw,
@@ -393,6 +404,10 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll, regmap, _config);
 
+   /* Enable alt PLLs */
+   clk_prepare_enable(pwrcl_alt_pll.clkr.hw.clk);
+   clk_pre

[PATCH v12 8/8] clk: qcom: Add ACD path to CPU clock driver for msm8996

2018-05-24 Thread Ilia Lin
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 
---
 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 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 #include "clk-alpha-pll.h"
 #include "clk-regmap.h"
@@ -69,6 +71,11 @@ enum _pmux_input {
 };
 
 #define DIV_2_THRESHOLD6
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x8
+#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 = 0x8,
+   .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(>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(>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 = _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 = _pll.clkr.hw,
@@ -393,6 +404,10 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(_alt_pll, regmap, _config);
clk_alpha_pll_configure(_alt_pll, regmap, _config);
 
+   /* Enable alt PLLs */
+   clk_prepare_enable(pwrcl_alt_pll.clkr.hw.clk);
+   clk_prepare_enable(perfcl_alt_pll.clk

[PATCH v12 2/8] clk: qcom: Make clk_alpha_pll_configure available to modules

2018-05-24 Thread Ilia Lin
From: Rajendra Nayak <rna...@codeaurora.org>

Allow clk_alpha_pll_configure to be called from loadable
kernel modules.

Signed-off-by: Rajendra Nayak <rna...@codeaurora.org>
Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9722b70..57f2084 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -228,6 +228,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, 
struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
 }
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
-- 
1.9.1



[PATCH v12 2/8] clk: qcom: Make clk_alpha_pll_configure available to modules

2018-05-24 Thread Ilia Lin
From: Rajendra Nayak 

Allow clk_alpha_pll_configure to be called from loadable
kernel modules.

Signed-off-by: Rajendra Nayak 
Signed-off-by: Ilia Lin 
---
 drivers/clk/qcom/clk-alpha-pll.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9722b70..57f2084 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -228,6 +228,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, 
struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
 }
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
-- 
1.9.1



[PATCH v12 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver

2018-05-24 Thread Ilia Lin
The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.

Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
---
 drivers/perf/Kconfig |  1 +
 drivers/perf/qcom_l2_pmu.c   | 90 ++--
 drivers/soc/qcom/Kconfig |  3 ++
 drivers/soc/qcom/Makefile|  1 +
 drivers/soc/qcom/kryo-l2-accessors.c | 56 ++
 include/soc/qcom/kryo-l2-accessors.h | 12 +
 6 files changed, 97 insertions(+), 66 deletions(-)
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..561252a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -69,6 +69,7 @@ config HISI_PMU
 config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+   select QCOM_KRYO_L2_ACCESSORS
  help
  Provides support for the L2 cache performance monitor unit (PMU)
  in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..cc31f51 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_L2_CTRS 9
 
@@ -87,8 +88,6 @@
 #define L2_COUNTER_RELOAD   BIT_ULL(31)
 #define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
 
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1   sys_reg(3, 3, 15, 0, 7)
 
 #define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
 
@@ -107,48 +106,7 @@
 #define L2_EVENT_STREX 0x421
 #define L2_EVENT_CLREX 0x422
 
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
 
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   write_sysreg_s(val, L2CPUSRDR_EL1);
-   isb();
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
-   u64 val;
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   val = read_sysreg_s(L2CPUSRDR_EL1);
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-
-   return val;
-}
 
 struct cluster_pmu;
 
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
 static void cluster_pmu_reset(void)
 {
/* Reset all counters */
-   set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
-   set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+   kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
 }
 
 static inline void cluster_pmu_enable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
 }
 
 static inline void cluster_pmu_disable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
 }
 
 static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
 {
if (idx == l2_cycle_ctr_idx)
-   set_l2_indirect_reg(L2PMCCNTR, value);
+   kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
-   set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+   kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
 }
 
 static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
 
if (idx == l2_cycle_ctr_idx)
-   value = get_l2_indirect_reg(L2PMCCNTR);
+   value = kryo_l2_get_indirect_reg(L2PMCCNTR);
else
-   value = get_l2_indirect

[PATCH v12 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver

2018-05-24 Thread Ilia Lin
The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.

Signed-off-by: Ilia Lin 
---
 drivers/perf/Kconfig |  1 +
 drivers/perf/qcom_l2_pmu.c   | 90 ++--
 drivers/soc/qcom/Kconfig |  3 ++
 drivers/soc/qcom/Makefile|  1 +
 drivers/soc/qcom/kryo-l2-accessors.c | 56 ++
 include/soc/qcom/kryo-l2-accessors.h | 12 +
 6 files changed, 97 insertions(+), 66 deletions(-)
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..561252a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -69,6 +69,7 @@ config HISI_PMU
 config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+   select QCOM_KRYO_L2_ACCESSORS
  help
  Provides support for the L2 cache performance monitor unit (PMU)
  in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..cc31f51 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_L2_CTRS 9
 
@@ -87,8 +88,6 @@
 #define L2_COUNTER_RELOAD   BIT_ULL(31)
 #define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
 
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1   sys_reg(3, 3, 15, 0, 7)
 
 #define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
 
@@ -107,48 +106,7 @@
 #define L2_EVENT_STREX 0x421
 #define L2_EVENT_CLREX 0x422
 
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
 
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   write_sysreg_s(val, L2CPUSRDR_EL1);
-   isb();
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
-   u64 val;
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   val = read_sysreg_s(L2CPUSRDR_EL1);
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-
-   return val;
-}
 
 struct cluster_pmu;
 
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
 static void cluster_pmu_reset(void)
 {
/* Reset all counters */
-   set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
-   set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+   kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
 }
 
 static inline void cluster_pmu_enable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
 }
 
 static inline void cluster_pmu_disable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
 }
 
 static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
 {
if (idx == l2_cycle_ctr_idx)
-   set_l2_indirect_reg(L2PMCCNTR, value);
+   kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
-   set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+   kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
 }
 
 static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
 
if (idx == l2_cycle_ctr_idx)
-   value = get_l2_indirect_reg(L2PMCCNTR);
+   value = kryo_l2_get_indirect_reg(L2PMCCNTR);
else
-   value = get_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, id

[PATCH v11 2/2] dt: qcom: Add qcom-cpufreq-kryo driver configuration

2018-05-23 Thread Ilia Lin
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 <ilia...@codeaurora.org>
Acked-by: Viresh Kumar <viresh.ku...@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 
@@ -169,177 +162,436 @@
};
 
cluster0_opp: opp_table0 {
-   compatible = "operating-points-v2";
+   compatible = "operating-points-v2-kryo-cpu",
+   "operating-points-v2";
+   nvmem-cells = <_efuse>;
opp-shared;
 
opp-30720 {
opp-hz = /bits/ 64 <30720>;
+   opp-supported-hw = <0x77>;
+   clock-latency-ns = <20>;
+   };
+   opp-38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-42240 {
opp-hz = /bits/ 64 <42240>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-46080 {
+   opp-hz = /bits/ 64 <46080>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-48000 {
opp-hz = /bits/ 64 <48000>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-53760 {
+   opp-hz = /bits/ 64 <53760>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-55680 {
opp-hz = /bits/ 64 <55680>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-61440 {
+   opp-hz = /bits/ 64 <61440>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-65280 {
opp-hz = /bits/ 64 <65280>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-69120 {
+   opp-hz = /bits/ 64 <69120>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-72960 {
opp-hz = /bits/ 64 <72960>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-76800 {
+   opp-hz = /bits/ 64 <76800>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
   

[PATCH v11 2/2] dt: qcom: Add qcom-cpufreq-kryo driver configuration

2018-05-23 Thread Ilia Lin
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 
Acked-by: Viresh Kumar 
---
 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 
@@ -169,177 +162,436 @@
};
 
cluster0_opp: opp_table0 {
-   compatible = "operating-points-v2";
+   compatible = "operating-points-v2-kryo-cpu",
+   "operating-points-v2";
+   nvmem-cells = <_efuse>;
opp-shared;
 
opp-30720 {
opp-hz = /bits/ 64 <30720>;
+   opp-supported-hw = <0x77>;
+   clock-latency-ns = <20>;
+   };
+   opp-38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-42240 {
opp-hz = /bits/ 64 <42240>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-46080 {
+   opp-hz = /bits/ 64 <46080>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-48000 {
opp-hz = /bits/ 64 <48000>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-53760 {
+   opp-hz = /bits/ 64 <53760>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-55680 {
opp-hz = /bits/ 64 <55680>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-61440 {
+   opp-hz = /bits/ 64 <61440>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-65280 {
opp-hz = /bits/ 64 <65280>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-69120 {
+   opp-hz = /bits/ 64 <69120>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-72960 {
opp-hz = /bits/ 64 <72960>;
+   opp-supported-hw = <0x7>;
+   clock-latency-ns = <20>;
+   };
+   opp-76800 {
+   opp-hz = /bits/ 64 <76800>;
+   opp-supported-hw = <0x70>;
clock-latency-ns = <20>;
};
opp-84480 {
opp-hz = /bits/ 64 <

[PATCH v11 1/2] dt: qcom: Add opp and thermal to the msm8996

2018-05-23 Thread Ilia Lin
Signed-off-by: Ilia Lin <ilia...@codeaurora.org>
Acked-by: Viresh Kumar <viresh.ku...@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 
 #include 
 #include 
+#include 
 
 / {
model = "Qualcomm Technologies, Inc. MSM8996";
@@ -97,6 +98,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x0>;
enable-method = "psci";
+   clocks = < 0>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
next-level-cache = <_0>;
L2_0: l2-cache {
  compatible = "cache";
@@ -109,6 +113,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x1>;
enable-method = "psci";
+   clocks = < 0>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
next-level-cache = <_0>;
};
 
@@ -117,6 +124,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x100>;
enable-method = "psci";
+   clocks = < 1>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
next-level-cache = <_1>;
L2_1: l2-cache {
  compatible = "cache";
@@ -129,6 +139,9 @@
compatible = "qcom,kryo";
reg = <0x0 0x101>;
enable-method = "psci";
+   clocks = < 1>;
+   operating-points-v2 = <_opp>;
+   #cooling-cells = <2>;
next-level-cache = <_1>;
};
 
@@ -155,6 +168,182 @@
};
};
 
+   cluster0_opp: opp_table0 {
+   compatible = "operating-points-v2";
+   opp-shared;
+
+   opp-30720 {
+   opp-hz = /bits/ 64 <30720>;
+   clock-latency-ns = <20>;
+   };
+   opp-42240 {
+   opp-hz = /bits/ 64 <42240>;
+   clock-latency-ns = <20>;
+   };
+   opp-48000 {
+   opp-hz = /bits/ 64 <48000>;
+   clock-latency-ns = <20>;
+   };
+   opp-55680 {
+   opp-hz = /bits/ 64 <55680>;
+   clock-latency-ns = <20>;
+   };
+   opp-65280 {
+   opp-hz = /bits/ 64 <65280>;
+   clock-latency-ns = <20>;
+   };
+   opp-72960 {
+   opp-hz = /bits/ 64 <72960>;
+   clock-latency-ns = <20>;
+   };
+   opp-84480 {
+   opp-hz = /bits/ 64 <84480>;
+   clock-latency-ns = <20>;
+   };
+   opp-96000 {
+   opp-hz = /bits/ 64 <96000>;
+   clock-latency-ns = <20>;
+   };
+   opp-103680 {
+   opp-hz = /bits/ 64 <103680>;
+   clock-latency-ns = <20>;
+   };
+   opp-111360 {
+   opp-hz = /bits/ 64 <111360>;
+   clock-latency-ns = <20>;
+   };
+   opp-119040 {
+   opp-hz = /bits/ 64 <119040>;
+   clock-latency-ns = <20>;
+   };
+   opp-122880 {
+   opp-hz = /bits/ 64 <122880>;
+   clock-latency-ns = <20>;
+   };
+   opp-132480 {
+   opp-hz = /bits/ 64 <132480>;
+   clock-latency-ns = <20>;
+   };
+   opp-140160 {
+   opp-hz = /bits/ 64 <140160>;
+   clo

[PATCH v11 0/2] CPU scaling support for msm8996 DT

2018-05-23 Thread Ilia Lin
[v11]
 * Split the series into domains

The series adds OPP tables, thermal and CPU definitions in order to support
the CPU frequency scaling on msm8996 CPUs.

Ilia Lin (2):
  dt: qcom: Add opp and thermal to the msm8996
  dt: qcom: Add qcom-cpufreq-kryo driver configuration

 arch/arm64/boot/dts/qcom/apq8096-db820c.dts |   2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi   | 546 +++-
 2 files changed, 528 insertions(+), 20 deletions(-)

-- 
1.9.1



  1   2   3   4   >