Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cpufreq: Add Kryo CPU scaling driver
From: Ilia Lin @ 2018-05-19 11:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526555955-29960-11-git-send-email-ilialin@codeaurora.org>

In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
the CPU frequency subset and voltage value of each OPP varies
based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
defines the voltage and frequency value based on the msm-id in SMEM
and speedbin blown in the efuse combination.
The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
to provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each OPP of
operating-points-v2 table when it is parsed by the OPP framework.

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/Kconfig.arm          |  10 +++
 drivers/cpufreq/Makefile             |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 164 +++++++++++++++++++++++++++++++++++
 4 files changed, 178 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de55c7d..0bfd40e 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -124,6 +124,16 @@ config ARM_OMAP2PLUS_CPUFREQ
 	depends on ARCH_OMAP2PLUS
 	default ARCH_OMAP2PLUS
 
+config ARM_QCOM_CPUFREQ_KRYO
+	bool "Qualcomm Kryo based CPUFreq"
+	depends on QCOM_QFPROM
+	depends on QCOM_SMEM
+	select PM_OPP
+	help
+	  This adds the CPUFreq driver for Qualcomm Kryo SoC based boards.
+
+	  If in doubt, say N.
+
 config ARM_S3C_CPUFREQ
 	bool
 	help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 8d24ade..fb4a2ec 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_MVEBU_V7)		+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)	+= qcom-cpufreq-kryo.o
 obj-$(CONFIG_ARM_S3C2410_CPUFREQ)	+= s3c2410-cpufreq.o
 obj-$(CONFIG_ARM_S3C2412_CPUFREQ)	+= s3c2412-cpufreq.o
 obj-$(CONFIG_ARM_S3C2416_CPUFREQ)	+= s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 3b585e4..77d6ab8 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -118,6 +118,9 @@
 
 	{ .compatible = "nvidia,tegra124", },
 
+	{ .compatible = "qcom,apq8096", },
+	{ .compatible = "qcom,msm8996", },
+
 	{ .compatible = "st,stih407", },
 	{ .compatible = "st,stih410", },
 
diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c b/drivers/cpufreq/qcom-cpufreq-kryo.c
new file mode 100644
index 0000000..ae2d1b9
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
+ * the CPU frequency subset and voltage value of each OPP varies
+ * based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
+ * defines the voltage and frequency value based on the msm-id in SMEM
+ * and speedbin blown in the efuse combination.
+ * The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
+ * to provide the OPP framework with required information.
+ * This is used to determine the voltage and frequency value for each OPP of
+ * operating-points-v2 table when it is parsed by the OPP framework.
+ */
+
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem.h>
+
+#define MSM_ID_SMEM	137
+#define SILVER_LEAD	0
+#define GOLD_LEAD	2
+
+enum _msm_id {
+	MSM8996V3 = 0xF6ul,
+	APQ8096V3 = 0x123ul,
+	MSM8996SG = 0x131ul,
+	APQ8096SG = 0x138ul,
+};
+
+enum _msm8996_version {
+	MSM8996_V3,
+	MSM8996_SG,
+	NUM_OF_MSM8996_VERSIONS,
+};
+
+static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
+{
+	size_t len;
+	u32 *msm_id;
+	enum _msm8996_version version;
+
+	msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len);
+	/* The first 4 bytes are format, next to them is the actual msm-id */
+	msm_id++;
+
+	switch ((enum _msm_id)*msm_id) {
+	case MSM8996V3:
+	case APQ8096V3:
+		version = MSM8996_V3;
+		break;
+	case MSM8996SG:
+	case APQ8096SG:
+		version = MSM8996_SG;
+		break;
+	default:
+		version = NUM_OF_MSM8996_VERSIONS;
+	}
+
+	return version;
+}
+
+static int __init qcom_cpufreq_kryo_driver_init(void)
+{
+	struct device *cpu_dev_silver, *cpu_dev_gold;
+	struct opp_table *opp_silver, *opp_gold;
+	enum _msm8996_version msm8996_version;
+	struct nvmem_cell *speedbin_nvmem;
+	struct platform_device *pdev;
+	struct device_node *np;
+	u8 *speedbin;
+	u32 versions;
+	size_t len;
+	int ret;
+
+	cpu_dev_silver = get_cpu_device(SILVER_LEAD);
+	if (IS_ERR_OR_NULL(cpu_dev_silver))
+		return PTR_ERR(cpu_dev_silver);
+
+	cpu_dev_gold = get_cpu_device(SILVER_LEAD);
+	if (IS_ERR_OR_NULL(cpu_dev_gold))
+		return PTR_ERR(cpu_dev_gold);
+
+	msm8996_version = qcom_cpufreq_kryo_get_msm_id();
+	if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
+		dev_err(cpu_dev_silver, "Not Snapdragon 820/821!");
+		return -ENODEV;
+	}
+
+	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev_silver);
+	if (IS_ERR_OR_NULL(np))
+		return PTR_ERR(np);
+
+	if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
+		ret = -ENOENT;
+		goto free_np;
+	}
+
+	speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+	if (IS_ERR(speedbin_nvmem)) {
+		ret = PTR_ERR(speedbin_nvmem);
+		dev_err(cpu_dev_silver, "Could not get nvmem cell: %d\n", ret);
+		goto free_np;
+	}
+
+	speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+	nvmem_cell_put(speedbin_nvmem);
+
+	switch (msm8996_version) {
+	case MSM8996_V3:
+		versions = 1 << (unsigned int)(*speedbin);
+		break;
+	case MSM8996_SG:
+		versions = 1 << ((unsigned int)(*speedbin) + 4);
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	opp_silver = dev_pm_opp_set_supported_hw(cpu_dev_silver,&versions,1);
+	if (IS_ERR(opp_silver)) {
+		dev_err(cpu_dev_silver, "Failed to set supported hardware\n");
+		ret = PTR_ERR(opp_silver);
+		goto free_np;
+	}
+
+	opp_gold = dev_pm_opp_set_supported_hw(cpu_dev_gold,&versions,1);
+	if (IS_ERR(opp_gold)) {
+		dev_err(cpu_dev_gold, "Failed to set supported hardware\n");
+		ret = PTR_ERR(opp_gold);
+		goto free_opp_silver;
+	}
+
+	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+	if (!IS_ERR_OR_NULL(pdev))
+		return 0;
+
+	ret = PTR_ERR(pdev);
+	dev_err(cpu_dev_silver, "Failed to register platform device\n");
+	dev_pm_opp_put_supported_hw(opp_gold);
+
+free_opp_silver:
+	dev_pm_opp_put_supported_hw(opp_silver);
+
+free_np:
+	of_node_put(np);
+
+	return ret;
+}
+late_initcall(qcom_cpufreq_kryo_driver_init);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [PATCH v8 10/15] cpufreq: Add Kryo CPU scaling driver
From: ilialin at codeaurora.org @ 2018-05-19 11:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518014538.duphof6enscpm5vp@vireshk-i7>

commit 4abe2cd7176a43c77e9a462e4f6ec51aa7552e73
Author: Ilia Lin <ilialin@codeaurora.org>
Date:   Thu May 17 13:55:12 2018 +0300

    cpufreq: Add Kryo CPU scaling driver

    In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
    the CPU frequency subset and voltage value of each OPP varies
    based on the silicon variant in use. Qualcomm Process Voltage Scaling
Tables
    defines the voltage and frequency value based on the msm-id in SMEM
    and speedbin blown in the efuse combination.
    The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the
SoC
    to provide the OPP framework with required information.
    This is used to determine the voltage and frequency value for each OPP
of
    operating-points-v2 table when it is parsed by the OPP framework.

    Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
    Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de55c7d..0bfd40e 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -124,6 +124,16 @@ config ARM_OMAP2PLUS_CPUFREQ
        depends on ARCH_OMAP2PLUS
        default ARCH_OMAP2PLUS

+config ARM_QCOM_CPUFREQ_KRYO
+       bool "Qualcomm Kryo based CPUFreq"
+       depends on QCOM_QFPROM
+       depends on QCOM_SMEM
+       select PM_OPP
+       help
+         This adds the CPUFreq driver for Qualcomm Kryo SoC based boards.
+
+         If in doubt, say N.
+
 config ARM_S3C_CPUFREQ
        bool
        help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 8d24ade..fb4a2ec 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_MVEBU_V7)           += mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)    += omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)       += pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)                   += pxa3xx-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)    += qcom-cpufreq-kryo.o
 obj-$(CONFIG_ARM_S3C2410_CPUFREQ)      += s3c2410-cpufreq.o
 obj-$(CONFIG_ARM_S3C2412_CPUFREQ)      += s3c2412-cpufreq.o
 obj-$(CONFIG_ARM_S3C2416_CPUFREQ)      += s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c
b/drivers/cpufreq/cpufreq-dt-platdev.c
index 3b585e4..77d6ab8 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -118,6 +118,9 @@

        { .compatible = "nvidia,tegra124", },

+       { .compatible = "qcom,apq8096", },
+       { .compatible = "qcom,msm8996", },
+
        { .compatible = "st,stih407", },
        { .compatible = "st,stih410", },

diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c
b/drivers/cpufreq/qcom-cpufreq-kryo.c
new file mode 100644
index 0000000..b024b23
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
+ * the CPU frequency subset and voltage value of each OPP varies
+ * based on the silicon variant in use. Qualcomm Process Voltage Scaling
Tables
+ * defines the voltage and frequency value based on the msm-id in SMEM
+ * and speedbin blown in the efuse combination.
+ * The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the
SoC
+ * to provide the OPP framework with required information.
+ * This is used to determine the voltage and frequency value for each OPP
of
+ * operating-points-v2 table when it is parsed by the OPP framework.
+ */
+
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem.h>
+
+#define MSM_ID_SMEM    137
+#define SILVER_LEAD    0
+#define GOLD_LEAD      2
+
+enum _msm_id {
+       MSM8996V3 = 0xF6ul,
+       APQ8096V3 = 0x123ul,
+       MSM8996SG = 0x131ul,
+       APQ8096SG = 0x138ul,
+};
+
+enum _msm8996_version {
+       MSM8996_V3,
+       MSM8996_SG,
+       NUM_OF_MSM8996_VERSIONS,
+};
+
+static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
+{
+       size_t len;
+       u32 *msm_id;
+       enum _msm8996_version version;
+
+       msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len);
+       /* The first 4 bytes are format, next to them is the actual msm-id
*/
+       msm_id++;
+
+       switch ((enum _msm_id)*msm_id) {
+       case MSM8996V3:
+       case APQ8096V3:
+               version = MSM8996_V3;
+               break;
+       case MSM8996SG:
+       case APQ8096SG:
+               version = MSM8996_SG;
+               break;
+       default:
+               version = NUM_OF_MSM8996_VERSIONS;
+       }
+
+       return version;
+}
+
+static int __init qcom_cpufreq_kryo_driver_init(void)
+{
+       struct device *cpu_dev_silver, *cpu_dev_gold;
+       struct opp_table *opp_silver, *opp_gold;
+       enum _msm8996_version msm8996_version;
+       struct nvmem_cell *speedbin_nvmem;
+       struct platform_device *pdev;
+       struct device_node *np;
+       u8 *speedbin;
+       u32 versions;
+       size_t len;
+       int ret;
+
+       cpu_dev_silver = get_cpu_device(SILVER_LEAD);
+       if (IS_ERR_OR_NULL(cpu_dev_silver))
+               return PTR_ERR(cpu_dev_silver);
+
+       cpu_dev_gold = get_cpu_device(SILVER_LEAD);
+       if (IS_ERR_OR_NULL(cpu_dev_gold))
+               return PTR_ERR(cpu_dev_gold);
+
+       msm8996_version = qcom_cpufreq_kryo_get_msm_id();
+       if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
+               dev_err(cpu_dev_silver, "Not Snapdragon 820/821!");
+               return -ENODEV;
+       }
+
+       np = dev_pm_opp_of_get_opp_desc_node(cpu_dev_silver);
+       if (IS_ERR_OR_NULL(np))
+               return PTR_ERR(np);
+
+       if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
+               ret = -ENOENT;
+               goto free_np;
+       }
+
+       speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+       if (IS_ERR(speedbin_nvmem)) {
+               ret = PTR_ERR(speedbin_nvmem);
+               dev_err(cpu_dev_silver, "Could not get nvmem cell: %d\n",
ret);
+               goto free_np;
+       }
+
+       speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+       nvmem_cell_put(speedbin_nvmem);
+
+       switch (msm8996_version) {
+       case MSM8996_V3:
+               versions = 1 << (unsigned int)(*speedbin);
+               break;
+       case MSM8996_SG:
+               versions = 1 << ((unsigned int)(*speedbin) + 4);
+               break;
+       default:
+               BUG();
+               break;
+       }
+
+       opp_silver =
dev_pm_opp_set_supported_hw(cpu_dev_silver,&versions,1);
+       if (IS_ERR_OR_NULL(opp_silver)) {
+               dev_err(cpu_dev_silver, "Failed to set supported
hardware\n");
+               ret = PTR_ERR(opp_silver);
+               goto free_np;
+       }
+
+       opp_gold = dev_pm_opp_set_supported_hw(cpu_dev_gold,&versions,1);
+       if (IS_ERR_OR_NULL(opp_gold)) {
+               dev_err(cpu_dev_gold, "Failed to set supported hardware\n");
+               ret = PTR_ERR(opp_gold);
+               goto free_opp_silver;
+       }
+
+       pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+       if (!IS_ERR_OR_NULL(pdev))
+               return 0;
+
+       ret = PTR_ERR(pdev);
+       dev_err(cpu_dev_silver, "Failed to register platform device\n");
+       dev_pm_opp_put_supported_hw(opp_gold);
+
+free_opp_silver:
+       dev_pm_opp_put_supported_hw(opp_silver);
+
+free_np:
+       of_node_put(np);
+
+       return ret;
+}
+late_initcall(qcom_cpufreq_kryo_driver_init);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
+MODULE_LICENSE("GPL v2");

> -----Original Message-----
> From: Viresh Kumar <viresh.kumar@linaro.org>
> Sent: Friday, May 18, 2018 04:46
> To: Ilia Lin <ilialin@codeaurora.org>
> Cc: mturquette at baylibre.com; sboyd at kernel.org; robh at kernel.org;
> mark.rutland at arm.com; nm at ti.com; lgirdwood at gmail.com;
> broonie at kernel.org; andy.gross at linaro.org; david.brown at linaro.org;
> catalin.marinas at arm.com; will.deacon at arm.com; rjw at rjwysocki.net; linux-
> clk at vger.kernel.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-pm at vger.kernel.org; linux-arm-
> msm at vger.kernel.org; linux-soc at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; rnayak at codeaurora.org;
> amit.kucheria at linaro.org; nicolas.dechesne at linaro.org;
> celster at codeaurora.org; tfinkel at codeaurora.org
> Subject: Re: [PATCH v8 10/15] cpufreq: Add Kryo CPU scaling driver
> 
> On 17-05-18, 14:19, Ilia Lin wrote:
> > +static int __init qcom_cpufreq_kryo_driver_init(void)
> > +{
> > +	size_t len;
> > +	int ret = 0;
> > +	u32 versions;
> > +	enum _msm8996_version msm8996_version;
> > +	u8 *speedbin;
> > +	struct device *cpu_dev_silver, *cpu_dev_gold;
> > +	struct device_node *np;
> > +	struct nvmem_cell *speedbin_nvmem;
> > +	struct platform_device *pdev;
> > +	struct opp_table *opp_silver = NULL;
> > +	struct opp_table *opp_gold = NULL;
> 
> No need to initialize them and you may want to arrange all above in
> decreasing order of their length.
> 
> > +
> > +	cpu_dev_silver = get_cpu_device(SILVER_LEAD);
> > +	if (IS_ERR_OR_NULL(cpu_dev_silver))
> > +		return PTR_ERR(cpu_dev_silver);
> > +
> > +	cpu_dev_gold = get_cpu_device(SILVER_LEAD);
> > +	if (IS_ERR_OR_NULL(cpu_dev_gold))
> > +		return PTR_ERR(cpu_dev_gold);
> > +
> > +	msm8996_version = qcom_cpufreq_kryo_get_msm_id();
> > +	if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
> > +		dev_err(cpu_dev_silver, "Not Snapdragon 820/821!");
> > +		return -ENODEV;
> > +	}
> > +
> > +	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev_silver);
> > +	if (IS_ERR_OR_NULL(np))
> > +		return PTR_ERR(np);
> > +
> > +	if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
> > +		ret = -ENOENT;
> > +		goto free_np;
> > +	}
> > +
> > +	speedbin_nvmem = of_nvmem_cell_get(np, NULL);
> > +	if (IS_ERR(speedbin_nvmem)) {
> > +		ret = PTR_ERR(speedbin_nvmem);
> > +		dev_err(cpu_dev_silver, "Could not get nvmem cell: %d\n",
> ret);
> > +		goto free_np;
> > +	}
> > +
> > +	speedbin = nvmem_cell_read(speedbin_nvmem, &len);
> > +	nvmem_cell_put(speedbin_nvmem);
> > +
> > +	switch (msm8996_version) {
> > +	case MSM8996_V3:
> > +		versions = 1 << (unsigned int)(*speedbin);
> > +		break;
> > +	case MSM8996_SG:
> > +		versions = 1 << ((unsigned int)(*speedbin) + 4);
> > +		break;
> > +	default:
> > +		BUG();
> > +		break;
> > +	}
> > +
> > +	opp_silver =
> dev_pm_opp_set_supported_hw(cpu_dev_silver,&versions,1);
> > +	if (IS_ERR_OR_NULL(opp_silver)) {
> 
> This API doesn't return NULL and so IS_ERR() would be sufficient.
> 
> > +		dev_err(cpu_dev_silver, "Failed to set supported
> hardware\n");
> > +		ret = PTR_ERR(opp_silver);
> > +		goto free_np;
> > +	}
> > +
> > +	opp_gold =
> dev_pm_opp_set_supported_hw(cpu_dev_gold,&versions,1);
> > +	if (IS_ERR_OR_NULL(opp_gold)) {
> 
> same here.
> 
> > +		dev_err(cpu_dev_gold, "Failed to set supported
> hardware\n");
> > +		ret = PTR_ERR(opp_gold);
> > +		goto free_opp_silver;
> > +	}
> > +
> > +	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> > +	if (!IS_ERR_OR_NULL(pdev))
> > +		goto out;
> 
> Simply return from here and remove the useless label out.
> 
> > +
> > +	ret = PTR_ERR(pdev);
> > +	dev_err(cpu_dev_silver, "Failed to register platform device\n");
> > +	dev_pm_opp_put_supported_hw(opp_gold);
> > +
> > +free_opp_silver:
> > +	dev_pm_opp_put_supported_hw(opp_silver);
> > +
> > +free_np:
> > +	of_node_put(np);
> > +
> > +out:
> > +	return ret;
> > +}
> > +late_initcall(qcom_cpufreq_kryo_driver_init);
> 
> Please resend only this patch now or just paste the new code in a mail
here
> so that I can review it quickly and then you can resend the final version.
Most
> of the patches aren't changing anyway.
> 
> --
> viresh

^ permalink raw reply related

* [PATCH] arm64: kvm: use -fno-jump-tables with clang
From: Marc Zyngier @ 2018-05-19 10:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKwvOdk+=JKcQP1ieLEkZftRGf-pqCTTzEuYvT_45YNMkEw_wA@mail.gmail.com>

On Fri, 18 May 2018 19:31:50 +0100,
Nick Desaulniers wrote:
> 
> On Fri, May 18, 2018 at 11:13 AM Marc Zyngier <marc.zyngier@arm.com> wrote:
> > What I'd really like is to apply that patch knowing that:
> 
> > - you have checked that with a released version of the compiler, you
> > don't observe any absolute address in any of the objects that are going
> > to be executed at EL2 on a mainline kernel,
> 
> To verify, we should disassemble objects from arch/arm64/kvm/hyp/*.o and
> make sure we don't see absolute addresses?  I can work with Sami to get a
> sense of what the before and after of this patch looks like in disassembly,
> then verify those changes are pervasive.

That seems sensible. You definitely want to look for things stored in
constant pools and subsequently used as an address. Also, you may have
to look at the .hyp.text section of the vmlinux binary, rather than
the individual *.o files, as the linker will likely rewrite things
(the compiler doesn't know about the kernel link address).

> > - you have successfully run guests with a mainline kernel,
> 
> I believe Andrey has already done this.  If he can verify (maybe
> during working hours next week), then maybe we can add his Tested-by
> to this patches commit message?

That would definitely be the right thing to do. Make sure you (or
Andrey tests with the latest released mainline kernel (4.16 for now)
or (even better) the tip of Linus' tree.

> > - it works for a reasonable set of common kernel configurations
> > (defconfig and some of the most useful debug options),
> 
> It's easy for us to test our kernel configs for Android, ChromeOS,
> and defconfig.  I'd be curious to know the shortlist of "most useful
> debug options" just to be a better kernel developer, personally.

Activate the various sanitizers, and all the tracing options, for a
start. They are the most likely to do weird things...

> > - I can reproduce your findings with the same released compiler.
> 
> Lets wait for Andrey to confirm his test setup.  On the Android side, I
> think you should be able to get by with a released version, but I'd be
> curious to hear from Andrey.

Android has all kind of additional patches, and I'm solely concerned
with mainline. If it is what Andrey runs, that's great.

> > Is that the case? I don't think any of the above is completely outlandish.
> 
> These are all reasonable. Thanks for the feedback.

Cheers,

	M.

-- 
Jazz is not dead, it just smell funny.

^ permalink raw reply

* [PATCH 03/14] ARM: bugs: hook processor bug checking into SMP and suspend paths
From: Russell King - ARM Linux @ 2018-05-19 10:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <01094c0d-af69-7e4c-65ec-7acddc778b5e@gmail.com>

On Wed, May 16, 2018 at 09:23:01AM -0700, Florian Fainelli wrote:
> On 05/16/2018 04:00 AM, Russell King wrote:
> > diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> > index 2da087926ebe..5ad0b67b9e33 100644
> > --- a/arch/arm/kernel/smp.c
> > +++ b/arch/arm/kernel/smp.c
> > @@ -31,6 +31,7 @@
> >  #include <linux/irq_work.h>
> >  
> >  #include <linux/atomic.h>
> > +#include <asm/bugs.h>
> >  #include <asm/smp.h>
> >  #include <asm/cacheflush.h>
> >  #include <asm/cpu.h>
> > @@ -405,6 +406,9 @@ asmlinkage void secondary_start_kernel(void)
> >  	 * before we continue - which happens after __cpu_up returns.
> >  	 */
> >  	set_cpu_online(cpu, true);
> > +
> > +	check_other_bugs();
> 
> Given what is currently implemented, I don't think the location of
> check_other_bugs() matters too much, but we might have to move this
> after the local_irq_enable() at some point if we need to check for e.g:
> a bogus local timer or whatever?

We could move it later if we need to.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
From: Manivannan Sadhasivam @ 2018-05-19 10:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <12834501.5lBvNSZm06@debian64>

Hi Christian,

On Sat, May 19, 2018 at 11:18:53AM +0200, Christian Lamparter wrote:
> On Friday, May 18, 2018 4:30:55 AM CEST Manivannan Sadhasivam wrote:
> > Add gpio support to pinctrl driver for Actions Semi S900 SoC.
> > 
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > ---
> > [...]
> > +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> > +{
> > +	struct gpio_chip *chip;
> > +	int ret;
> > +
> > +	chip = &pctrl->chip;
> > +	chip->base = -1;
> > +	chip->ngpio = pctrl->soc->ngpios;
> > +	chip->label = dev_name(pctrl->dev);
> > +	chip->parent = pctrl->dev;
> > +	chip->owner = THIS_MODULE;
> > +	chip->of_node = pctrl->dev->of_node;
> > +
> > +	ret = gpiochip_add_data(&pctrl->chip, pctrl);
> > +	if (ret) {
> > +		dev_err(pctrl->dev, "failed to register gpiochip\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> > +							0, 0, chip->ngpio);
> > +	if (ret) {
> > +		dev_err(pctrl->dev, "failed to add pin range\n");
> > +		gpiochip_remove(&pctrl->chip);
> > +		return ret;
> > +	}
> > +
> gpiochip_add_pin_range()? That's not going to work with gpio-hogs. 
> 

Hmmm. Just looked into the gpio-hog mechanism and the patch you have
implemented for MSM driver. I agree with you on replacing
gpiochip_add_pin_range() with gpio-ranges property. But I'm curious
whether we should document it somewhere or not (probably in [1]).

Anyway I will send the v2 incorporating your suggestion.

Thanks,
Mani

[1] Documentation/devicetree/bindings/gpio/gpio.txt

> But, you can easily test this. Just add a gpio-hog [0] 
> ( Section 2. gpio-controller nodes) into the Devicetree's
> pinctrl node.
> 
> something like: (No idea if GPIO1 is already used, but any free
> gpio will do)
> | 		[...]
> |		pinctrl at e01b0000 {
> |			compatible = "actions,s900-pinctrl";
> |			reg = <0x0 0xe01b0000 0x0 0x1000>;
> |			clocks = <&cmu CLK_GPIO>;
> |			gpio-controller;
> |			#gpio-cells = <2>;
> |
> |			line_b {
> |				gpio-hog;
> |				gpios = <1 GPIO_ACTIVE_HIGH>;
> |				output-low;
> |				line-name = "foo-bar-gpio";
> |			};
> |		};
> 
> The pinctrl probe will fail. You can fix this by
> replacing the gpiochip_add_pin_range() and use
> the gpio-ranges [0] property to define the range.
> 
> [0] <https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt>
> 
> 
> 

^ permalink raw reply

* [PATCH v3 4/4] arm64: dts: Add Mediatek SoC MT8183 and evaluation board dts and Makefile
From: kbuild test robot @ 2018-05-19 10:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526538126-51497-5-git-send-email-erin.lo@mediatek.com>

Hi Ben,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.17-rc5 next-20180517]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Erin-Lo/Add-basic-support-for-Mediatek-MT8183-SoC/20180519-160349
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm64-alldefconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm64 

All errors (new ones prefixed by >>):

>> Error: arch/arm64/boot/dts/mediatek/mt8183.dtsi:137.9-10 syntax error
   FATAL ERROR: Unable to parse input tree

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

^ permalink raw reply

* [PATCH v4] pinctrl: msm: fix gpio-hog related boot issues
From: Christian Lamparter @ 2018-05-19  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518051826.GO14924@minitux>

On Friday, May 18, 2018 7:18:26 AM CEST Bjorn Andersson wrote:
> On Thu 12 Apr 12:01 PDT 2018, Christian Lamparter wrote:
> > diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> > index 0a6f7952bbb1..18511e782cbd 100644
> > --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> > @@ -530,6 +530,7 @@
> >  			reg = <0x01010000 0x300000>;
> >  			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
> >  			gpio-controller;
> > +			gpio-ranges = <&msmgpio 0 0 150>;
> 
> I'm still confused to why this information is in DT at all, it feels
> like an implementation detail, not a system configuration thing.

I did look at the commits and code from back in 2013. From what 
I can gather "this implementation detail" was realized the way
it is now, because "devicetree was the new thing" and it seemed
like a good idea to make it as extendable/generic as possible.

You should definitely check out the gpio/gpio.txt [0] file from section
"2.1) gpio- and pin-controller interaction" onwards. (there are way more
bindings in there)


Maybe Linus has the full story.

> 
> >  			#gpio-cells = <2>;
> >  			interrupt-controller;
> >  			#interrupt-cells = <2>;
> > diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
> > index e7abc8ba222b..ed889553f01c 100644
> > --- a/drivers/pinctrl/qcom/pinctrl-msm.c
> > +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
> > @@ -890,11 +890,24 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
> >  		return ret;
> >  	}
> >  
> > -	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
> > -	if (ret) {
> > -		dev_err(pctrl->dev, "Failed to add pin range\n");
> > -		gpiochip_remove(&pctrl->chip);
> > -		return ret;
> > +	/*
> > +	 * For DeviceTree-supported systems, the gpio core checks the
> > +	 * pinctrl's device node for the "gpio-ranges" property.
> > +	 * If it is present, it takes care of adding the pin ranges
> > +	 * for the driver. In this case the driver can skip ahead.
> > +	 *
> > +	 * In order to remain compatible with older, existing DeviceTree
> > +	 * files which don't set the "gpio-ranges" property or systems that
> > +	 * utilize ACPI the driver has to call gpiochip_add_pin_range().
> > +	 */
> > +	if (!of_property_read_bool(pctrl->dev->of_node, "gpio-ranges")) {
> > +		ret = gpiochip_add_pin_range(&pctrl->chip,
> > +			dev_name(pctrl->dev), 0, 0, chip->ngpio);
> > +		if (ret) {
> > +			dev_err(pctrl->dev, "Failed to add pin range\n");
> > +			gpiochip_remove(&pctrl->chip);
> > +			return ret;
> > +		}
> >  	}
> 
> The patch looks good, but I would like you to split it in DT and pinctrl
> parts, to make it less likely to collide and to allow Andy to inject the
> missing change of sdm845.dtsi (which is now in linux-next) 
> 
> Please split it and add my
> 
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> 
> to both patches.
Ok, thanks. 

Regards,
Christian

[0] <https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt>

^ permalink raw reply

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
From: Christian Lamparter @ 2018-05-19  9:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518023056.7869-5-manivannan.sadhasivam@linaro.org>

On Friday, May 18, 2018 4:30:55 AM CEST Manivannan Sadhasivam wrote:
> Add gpio support to pinctrl driver for Actions Semi S900 SoC.
> 
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
> [...]
> +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> +{
> +	struct gpio_chip *chip;
> +	int ret;
> +
> +	chip = &pctrl->chip;
> +	chip->base = -1;
> +	chip->ngpio = pctrl->soc->ngpios;
> +	chip->label = dev_name(pctrl->dev);
> +	chip->parent = pctrl->dev;
> +	chip->owner = THIS_MODULE;
> +	chip->of_node = pctrl->dev->of_node;
> +
> +	ret = gpiochip_add_data(&pctrl->chip, pctrl);
> +	if (ret) {
> +		dev_err(pctrl->dev, "failed to register gpiochip\n");
> +		return ret;
> +	}
> +
> +	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> +							0, 0, chip->ngpio);
> +	if (ret) {
> +		dev_err(pctrl->dev, "failed to add pin range\n");
> +		gpiochip_remove(&pctrl->chip);
> +		return ret;
> +	}
> +
gpiochip_add_pin_range()? That's not going to work with gpio-hogs. 

But, you can easily test this. Just add a gpio-hog [0] 
( Section 2. gpio-controller nodes) into the Devicetree's
pinctrl node.

something like: (No idea if GPIO1 is already used, but any free
gpio will do)
| 		[...]
|		pinctrl at e01b0000 {
|			compatible = "actions,s900-pinctrl";
|			reg = <0x0 0xe01b0000 0x0 0x1000>;
|			clocks = <&cmu CLK_GPIO>;
|			gpio-controller;
|			#gpio-cells = <2>;
|
|			line_b {
|				gpio-hog;
|				gpios = <1 GPIO_ACTIVE_HIGH>;
|				output-low;
|				line-name = "foo-bar-gpio";
|			};
|		};

The pinctrl probe will fail. You can fix this by
replacing the gpiochip_add_pin_range() and use
the gpio-ranges [0] property to define the range.

[0] <https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt>

^ permalink raw reply

* [PATCH v2 12/26] drm/sun4i: Add support for multiple DW HDMI PHY clock parents
From: Jernej Škrabec @ 2018-05-19  7:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518152651.lfymc3kj7npj5tww@flea>

Hi,

Dne petek, 18. maj 2018 ob 17:26:51 CEST je Maxime Ripard napisal(a):
> On Fri, May 18, 2018 at 04:46:41PM +0200, Jernej ?krabec wrote:
> > > And this is a bit sloppy, since if phy_clk_num == 3, you won't try to
> > > lookup pll-2 either.
> > 
> > It is highly unlikely this will be higher than 2, at least for this HDMI
> > PHY, since it has only 1 bit reserved for parent selection. But since I
> > have to fix it, I'll add ">= 2"
> 
> If we're only going to have two parents at most, ever, why don't we
> had just a single other boolean. This would be less intrusive, and we
> wouldn't have to check for those corner cases.

It seems that usage of "bool" data type in structures is not wanted anymore 
according to checkpatch and this: https://lkml.org/lkml/2017/11/21/384

I guess I'll use "unsigned int" as recommended by Linus and named it 
"has_second_parent" to be unambigous that it's boolean in reality.

Best regards,
Jernej

> 
> > BTW, I'll resend fixed version of this patch for my R40 HDMI series, since
> > there is nothing to hold it back, unlike for this.
> 
> Awesome, thanks!
> Maxime
> 
> --
> Maxime Ripard, Bootlin (formerly Free Electrons)
> Embedded Linux and Kernel engineering
> https://bootlin.com

^ permalink raw reply

* [PATCH v3 2/6] mfd: at91-usart: added mfd driver for usart
From: Alexandre Belloni @ 2018-05-19  7:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518221949.GA13443@rob-hp-laptop>

On 18/05/2018 17:19:49-0500, Rob Herring wrote:
> On Fri, May 11, 2018 at 01:38:18PM +0300, Radu Pirea wrote:
> > This mfd driver is just a wrapper over atmel_serial driver and
> > spi-at91-usart driver. Selection of one of the drivers is based on a
> > property from device tree. If the property is not specified, the default
> > driver is atmel_serial.
> > 
> > Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
> > ---
> >  drivers/mfd/Kconfig                  | 10 ++++
> >  drivers/mfd/Makefile                 |  1 +
> >  drivers/mfd/at91-usart.c             | 75 ++++++++++++++++++++++++++++
> >  include/dt-bindings/mfd/at91-usart.h | 17 +++++++
> >  4 files changed, 103 insertions(+)
> >  create mode 100644 drivers/mfd/at91-usart.c
> >  create mode 100644 include/dt-bindings/mfd/at91-usart.h
> > 
> 
> > +#ifndef __DT_BINDINGS_AT91_USART_H__
> > +#define __DT_BINDINGS_AT91_USART_H__
> > +
> > +#define AT91_USART_MODE_SERIAL	1
> > +#define AT91_USART_MODE_SPI	2
> 
> Won't this require a DT update for serial mode to add the mode property? 
> That breaks compatibility.
> 

If the mode property is not present, it defaults to serial to keep
compatibility.


-- 
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* [PATCH 02/20] dma-mapping: provide a generic dma-noncoherent implementation
From: hch at lst.de @ 2018-05-19  6:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0c5d27e9-2799-eb38-8b09-47a04c48b5c7@gmx.de>

On Fri, May 18, 2018 at 10:05:51PM +0200, Helge Deller wrote:
> This patch seems to fix the dma issues I faced on my 32bit B160L parisc box.
> 
> So it leaves only one open issue on parisc:
> Now every 32 bit parisc system is unnecessarily non-coherent.

I diagree with those comments, let me resend the refactored patch
to make it more clear.

^ permalink raw reply

* [PATCH] firmware: arm_scmi: remove some unnecessary checks
From: Dan Carpenter @ 2018-05-19  6:37 UTC (permalink / raw)
  To: linux-arm-kernel

The "pi->dom_info" buffer is allocated in init() and it can't be NULL
here.  These tests are sort of weird as well because if "pi->dom_info"
was NULL but "domain" was non-zero then it would lead to an Oops.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 2a219b1261b1..721e6c57beae 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -363,8 +363,6 @@ static int scmi_dvfs_device_opps_add(const struct scmi_handle *handle,
 		return domain;
 
 	dom = pi->dom_info + domain;
-	if (!dom)
-		return -EIO;
 
 	for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) {
 		freq = opp->perf * dom->mult_factor;
@@ -394,9 +392,6 @@ static int scmi_dvfs_transition_latency_get(const struct scmi_handle *handle,
 		return domain;
 
 	dom = pi->dom_info + domain;
-	if (!dom)
-		return -EIO;
-
 	/* uS to nS */
 	return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
 }

^ permalink raw reply related

* [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: David Collins @ 2018-05-19  0:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAD=FV=U-QOQekUHj=ck57YJbTFdFjCAWr4t2A92x+fCNf+yV9A@mail.gmail.com>

On 05/17/2018 06:01 PM, Doug Anderson wrote:
> On Thu, May 17, 2018 at 5:16 PM, David Collins <collinsd@codeaurora.org> wrote:
>> On 05/17/2018 02:22 PM, Doug Anderson wrote:
>>> On Fri, May 11, 2018 at 7:28 PM, David Collins <collinsd@codeaurora.org> wrote:
>>>> +- qcom,regulator-initial-microvolt
>>>> +       Usage:      optional; VRM regulators only
>>>> +       Value type: <u32>
>>>> +       Definition: Specifies the initial voltage in microvolts to request for a
>>>> +                   VRM regulator.
>>>
>>> Now that Mark has landed the patch adding support for the
>>> -ENOTRECOVERABLE error code from get_voltage() / get_voltage_sel(), do
>>> we still need the qcom,regulator-initial-microvolt property?
>>
>> Yes, this is still needed.  The -ENOTRECOVERABLE patch ensures that
>> qcom-rpmh-regulator devices can be registered even if
>> qcom,regulator-initial-microvolt is not specified.  However, that will
>> result in the regulators being configured for the minimum voltage
>> supported in the DT specified min/max range.  The
>> qcom,regulator-initial-microvolt property allows us to set a specific
>> voltage that is larger than the min constraint.
> 
> Ah, OK.  In the device tree fragment I saw the initial was always
> equal to the min, so I wasn't sure if this was really needed in
> practice.  I presume it would only be important if a voltage was left
> high by the bootloader for some peripheral that needs to continue to
> function (and use the existing higher voltage) until a real device
> claims it.  For all other voltages, it should be fine if it's set to
> the min until a real device claims it.  Do you have real examples of
> devices like this in boards using sdm845?

Something to keep in mind about the downstream rpmh-regulator driver is
that it caches the initial voltages specified in device tree and only
sends them after a consumer driver makes a regulator framework call.  This
saves time during boot and ensures that requests are not made for
regulators that no Linux consumer cares about.

It is generally not safe to request all regulators to be set to the
minimum allowed voltage.  Special care will be needed with the upstream
qcom-rpmh-regulator driver to avoid disrupting the boot up state of
regulators that are needed by other subsystems.  Therefore, I would like
to keep the initial voltage feature supported.


>>>> +- regulator-initial-mode
>>>> +       Usage:      optional; VRM regulators only
>>>> +       Value type: <u32>
>>>> +       Definition: Specifies the initial mode to request for a VRM regulator.
>>>> +                   Supported values are RPMH_REGULATOR_MODE_* which are defined
>>>> +                   in [1] (i.e. 0 to 3).  This property may be specified even
>>>> +                   if the regulator-allow-set-load property is not specified.
>>>
>>> Every time I read the above I wonder why you're documenting a standard
>>> regulator regulator property in your bindings.  ...then I realize it's
>>> because you're doing it because you want to explicitly document what
>>> the valid modes are.  I wonder if it makes sense to just put a
>>> reference somewhere else in this document to go look at the header
>>> file where these are all nicely documented.
>>
>> Isn't that what the [1] in the above snippet is currently doing.  Further
>> down in qcom,rpmh-regulator.txt is this line:
>>
>> +[1] include/dt-bindings/regulator/qcom,rpmh-regulator.h
> 
> Right, but I want to move it so it doesn't look like you're defining a
> property that's already defined in the common bindings.  AKA get rid
> of the "regulator-initial-mode" property description.  Then add above
> Examples:
> 
> ========================
> Regulator Modes
> ========================
> 
> RPMh regulators are designed to work with the standard regulator mode
> bindings, using properties like "regulator-initial-mode".  See
> include/dt-bindings/regulator/qcom,rpmh-regulator.h for information on
> the modes relevant to RPMh regulators.
> 
> Some RPMh regulators (BOB regulators only) also support bypass using
> the standard "regulator-allow-bypass" binding.
> 
> 
> ...feel fee to reword, but basically the idea is to document it but
> not make it look like you're defining a novel property.

Ok, I'll try rewording the mode explanation and move it into another
section of the binding doc.


>>> Speaking of documenting things like that, it might be worth finding
>>> somewhere in this doc to mention that the "bob" regulator on PMI8998
>>> can support "regulator-allow-bypass".  That tidbit got lost when we
>>> moved to the standard regulator bindings for bypass.
>>
>> I suppose that I could add something like this:
>>
>> +- regulator-allow-bypass
>> +       Usage:      optional; BOB type VRM regulators only
>> +       Value type: <empty>
>> +       Definition: See [2] for details.
>> ...
>> +[2]: Documentation/devicetree/bindings/regulator.txt
>>
>> However, I don't want the patch to get NACKed because it is defining a
>> property that is already defined in the common regulator.txt file.
> 
> See above for my suggestion.

Ok.


>>>> +- qcom,allowed-drms-modes
>>>> +       Usage:      required if regulator-allow-set-load is specified;
>>>> +                   VRM regulators only
>>>> +       Value type: <prop-encoded-array>
>>>> +       Definition: A list of integers specifying the PMIC regulator modes which
>>>> +                   can be configured at runtime based upon consumer load needs.
>>>> +                   Supported values are RPMH_REGULATOR_MODE_* which are defined
>>>> +                   in [1] (i.e. 0 to 3).
>>>
>>> Why is this still here?  You moved it to the core regulator framework,
>>> right?  It's still in your examples too.  Shouldn't this be removed?
>>> It looks like the driver still needs this and it needs to be an exact
>>> duplicate of the common binding.  That doesn't seem right...
>>
>> The qcom,allowed-drms-modes property supports a different feature than the
>> regulator-allowed-modes property accepted in [2].  The latter specifies
>> the modes that may be used at all (e.g. in regulator_set_mode() calls) and
>> it lists the mode values in an unordered fashion.
>>
>> qcom,allowed-drms-modes defines a specific subset of the possible allowed
>> modes that should be set based on DRMS (e.g. in regulator_set_load()
>> calls).  Its values are listed in a specific order and must match 1-to-1
>> with qcom,drms-mode-max-microamps entries.
>>
>> It would probably be good to change the name of the property from
>> qcom,allowed-drms-modes to qcom,regulator-drms-modes.
> 
> Ah, I see.  It's unfortunate that now we need to effectively list all
> modes twice.  Have you seen real-life examples where these sets of
> modes need to be different, or is this just theoretical?  If not can
> we start with one property (that controls both things) and if we
> really see that we need to specify different sets of modes for the two
> cases we can add a separate property?  ...actually, even if you do
> have real-life examples of where these need to be different, if 90% of
> the time they are the same it would still be nice to just have one
> property apply to both cases.

I plan to keep qcom,regulator-drms-modes (and
qcom,drms-mode-max-microamps) around as a property specifically handled
for qcom-rpmh-regulator.  It serves a purpose that is distinct from that
of the generic regulator-allowed-modes.  Without it, there will not be a
way to utilize regulator_set_load() to configure the regulator modes.


>>>> +- qcom,drms-mode-max-microamps
>>>> +       Usage:      required if regulator-allow-set-load is specified;
>>>> +                   VRM regulators only
>>>> +       Value type: <prop-encoded-array>
>>>> +       Definition: A list of integers specifying the maximum allowed load
>>>> +                   current in microamps for each of the modes listed in
>>>> +                   qcom,allowed-drms-modes (matched 1-to-1 in order).  Elements
>>>> +                   must be specified in order from lowest to highest value.
>>>
>>> Any reason this can't go into the regulator core?  You'd basically
>>> just take the existing concept of rpmh_regulator_vrm_set_load() and
>>> put it in the core.
>>
>> This could be implemented in the core via new constraint elements parsed
>> in of_regulator and a helper function to specify in regulator_ops.
>> However, I'm not sure about the wide-spread applicability of this feature.
>>  I'd prefer to leave it in the driver unless Mark would like me to add it
>> into the core.
> 
> You're already using pre-existing APIs around specifying the current
> and having the regulator core call you to map the total current into a
> mode.  That implies that this is applicable to others.  Adding this
> tiny amount of code to the core makes the pre-existing APIs generally
> useful.

I don't see the benefit of making struct regulation_constraints more
complicated with DRMS mode and current arrays that would only every be
used by the qcom-rpmh-regulator driver.  Other regulator drivers are able
to hard code this information in the driver code using get_optimum_mode()
callbacks.

As a side note, changing qcom-rpmh-regulator to use a get_optimum_mode()
callback instead of a set_load() callback would probably be a good idea too.


>>>> +- qcom,headroom-microvolt
>>>> +       Usage:      optional; VRM regulators only
>>>> +       Value type: <u32>
>>>> +       Definition: Specifies the headroom voltage in microvolts to request for
>>>> +                   a VRM regulator.  RPMh hardware automatically ensures that
>>>> +                   the parent of this regulator outputs a voltage high enough
>>>> +                   to satisfy the requested headroom.  Supported values are
>>>> +                   0 to 511000.
>>>
>>> I'm curious: is this a voted-for value, or a global value?
>>>
>>> Said another way: the whole point of RPMh is that there may be more
>>> than one processor that needs the same rails, right?  So the AP might
>>> request 1.1 V for a rail and the modem might request 1.3 V.  RPMh
>>> would decide to pick the higher of those two (1.3 V), but if the modem
>>> said it no longer needs the rail it will drop down to 1.1 V.
>>>
>>> ...and as an example of why the headroom needs to be in hardware, if
>>> the source voltage was normally 1.4 V and the headroom was 200 mV then
>>> the hardware would need to know to bump up the source voltage to 1.5V
>>> during the period of of time that the modem wants the rail at 1.3V.
>>>
>>> So my question is: do the AP and modem in the above situation
>>> separately vote for headroom?  How is it aggregated?  ...or is it a
>>> global value and this sets the headroom for all clients of RPMh?  It
>>> would be interesting to document this as it might help with figuring
>>> out how this value should be set.
>>
>> The headroom voltage voting is supported in hardware per-regulator and
>> per-master (AP, modem, etc).  The headroom voltage and output voltage are
>> each aggregated (using max) per-regulator across masters.  If the
>> aggregated enable state for a regulator is on, then the aggregated output
>> voltage and headroom voltage are added together and applied as a min
>> constraint on the parent's output voltage (if there is a parent).
> 
> Ah, interesting.  I'm not 100% convinced that the RPMh API is at the
> right abstraction level here.  I guess you increase the headroom
> voltage if you expect a lot of current and need the regulator to still
> give a clean signal?  If you truly wanted to aggregate then if both
> the modem and AP wanted to draw a lot of current they would both need
> to increase the headroom and then the headroom should maybe not be the
> max but something slightly more (you wouldn't want to add, but ...)
> 
> Since it's just a max, in theory it seems like you get 99% of the way
> there by just using the Linux APIs to deal with dropout voltage.  If
> Linux was managing it in software then if it needed to account for
> extra headroom it would just increase the supply voltage.  That should
> play just fine with the modem (which might be using the hardware
> headroom feature) since it will be making its own completely separate
> requests and they should be aggregated OK.
> 
> In another thread you said you'd be OK dropping the headroom voltage
> since it wasn't needed on SDM845.  Maybe we should do that?  ...and if
> someone later needs to account for a larger dropout they can figure
> out how to hookup the standard linux min_dropout_uV?

I will remove qcom,headroom-microvolt.

Take care,
David

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

^ permalink raw reply

* [linux-sunxi] Re: [PATCH v4 3/3] ARM: dts: sun7i: Add support for the Ainol AW1 tablet
From: Brüns, Stefan @ 2018-05-19  0:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518071436.3vvyllghrdxptsxg@flea>

On Freitag, 18. Mai 2018 09:14:36 CEST Maxime Ripard wrote:
> On Mon, May 14, 2018 at 10:36:08PM +0200, Paul Kocialkowski wrote:
> > > > +	backlight: backlight {
> > > > +		compatible = "pwm-backlight";
> > > > +		pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
> > > > +		brightness-levels = <  0   1   1   1   1   2   2   2
> > > > +				       2   3   3   3   3   4   4   4
> > > > +				       5   5   5   6   6   6   7   7
> > > > +				       8   8   8   9   9   9  10  10
> > > > +				      10  11  11  12  12  12  13  13
> > > > +				      14  14  14  15  15  16  16  17
> > > > +				      17  17  18  18  19  19  20  20
> > > > +				      21  21  21  22  22  23  23  24
> > > > +				      24  25  25  26  26  27  27  28
> > > > +				      28  29  30  30  31  31  32  32
> > > > +				      33  33  34  35  35  36  36  37
> > > > +				      38  38  39  39  40  41  41  42
> > > > +				      43  43  44  44  45  46  47  47
> > > > +				      48  49  49  50  51  51  52  53
> > > > +				      54  54  55  56  57  57  58  59
> > > > +				      60  61  61  62  63  64  65  65
> > > > +				      66  67  68  69  70  71  71  72
> > > > +				      73  74  75  76  77  78  79  80
> > > > +				      81  82  83  84  85  86  87  88
> > > > +				      89  90  91  92  93  94  95  96
> > > > +				      97  98  99 101 102 103 104 105
> > > > +				     106 108 109 110 111 112 114 115
> > > > +				     116 117 119 120 121 123 124 125
> > > > +				     127 128 129 131 132 133 135 136
> > > > +				     138 139 141 142 144 145 147 148
> > > > +				     150 151 153 154 156 157 159 161
> > > > +				     162 164 166 167 169 171 173 174
> > > > +				     176 178 180 181 183 185 187 189
> > > > +				     191 192 194 196 198 200 202 204
> > > > +				     206 208 210 212 214 216 219 221
> > > > +				     223 225 227 229 232 234 236 238
> > > > +				     241 242 244 246 248 250 253 255>;
> > > 
> > > You kind of overdid it here :)
> > > 
> > > What I meant to say before was that if you have 10 elements (and you
> > > really should have something in that magnitude) each step should
> > > increase the perceived brightness by 10%.
> > 
> > Mhh I think 10 elements would fall too short to really depict the curve
> > with appropriate precision. Given the usual size for brightness cursors
> > in e.g. gnome-shell, it feels like a bigger number would be more
> > appropriate. Let's make it to 100 with values from 0 to 255!
> > 
> > > In this particular case, I really think having something close to <0 4
> > > 8 16 32 64 128 255> would be enough.
> > > 
> > > And in general, that kind of odd looking table without any more
> > > context is just screaming for a comment :)
> > 
> > Noted, I will explain the idea, but probably without the exact formula
> > that's really a nasty hack written down on a piece of paper sitting in
> > my garbage at this point.
> 
> So no one will ever be able to understand where this sequence comes
> from (yourself-in-two-years included). That sounds like a pretty bad
> idea.
> 
> Maxime

The following formula yields practically the same table:

out = ceil(255 * (0.245 * in/255  +  0.755 * pow(in/255, 2.6) ))

Maximum error: 4, maximum relative error: 0.33 

Kind regards,

Stefan

^ permalink raw reply

* [PATCH 5/6] mtd: rawnand: ams-delta: use GPIO lookup table
From: Janusz Krzysztofik @ 2018-05-18 23:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHp75VdNUW6KoM6oupyQ80A1WVRk7vewwDt6WEZOyjrAUifqRg@mail.gmail.com>

On Friday, May 18, 2018 11:21:14 PM CEST Andy Shevchenko wrote:
> On Sat, May 19, 2018 at 12:09 AM, Janusz Krzysztofik
> 
> <jmkrzyszt@gmail.com> wrote:
> > +       gpiod_rdy = devm_gpiod_get_optional(&pdev->dev, "rdy", GPIOD_IN);
> > +       if (!IS_ERR_OR_NULL(gpiod_rdy)) {
> 
> So, is it optional or not at the end?
> If it is, why do we check for NULL?

As far as I can understand, nand_chip->dev_ready() callback is optional. 
That's why I decided to use the _optional variant of devm_gpiod_get(). In case 
of ams-delta, the dev_ready() callback depends on availability of the 'rdy' 
GPIO pin. As a consequence, I'm checking for both NULL and ERR in order to 
decide if dev_ready() will be supported.

I can pretty well replace it with the standard form and check for ERR only if 
the purpose of the _optional form is different.

> >                 this->dev_ready = ams_delta_nand_ready;
> >         
> >         } else {
> >         
> >                 this->dev_ready = NULL;
> >                 pr_notice("Couldn't request gpio for Delta NAND
> >                 ready.\n");
> 
> dev_notice() ?

Sure, but maybe in a separate patch? That's not a new code just being added 
but an existing one, not the merit of the change.

> >         }
> > 
> > +err_gpiod:
> > +       if (err == -ENODEV || err == -ENOENT)
> > +               err = -EPROBE_DEFER;
> 
> Hmm...

Amstrad Delta uses gpio-mmio driver. Unfortunatelty that driver is not 
availble before device init phase, unlike other crucial GPIO drivers which are 
initialized earlier, e.g. during the postcore or at latetst the subsys phase. 
Hence, devices which depend on GPIO pins provided by gpio-mmio must either be 
declared late or fail softly so they get another chance of being probed 
succesfully.

I thought of replacing the gpio-mmio platform driver with bgpio functions it 
exports but for now I haven't implemented it, not even shared the idea.

Does it really hurt to return -EPROBE_DEFER if a GPIO pin can't be obtained?

Thanks,
Janusz

^ permalink raw reply

* [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: Rob Herring @ 2018-05-18 22:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <869aad59-1cc5-28ef-1fb5-4ef846696c40@codeaurora.org>

On Thu, May 17, 2018 at 05:16:13PM -0700, David Collins wrote:
> On 05/17/2018 02:22 PM, Doug Anderson wrote:
> > On Fri, May 11, 2018 at 7:28 PM, David Collins <collinsd@codeaurora.org> wrote:
> >> +- qcom,regulator-initial-microvolt
> >> +       Usage:      optional; VRM regulators only
> >> +       Value type: <u32>
> >> +       Definition: Specifies the initial voltage in microvolts to request for a
> >> +                   VRM regulator.
> > 
> > Now that Mark has landed the patch adding support for the
> > -ENOTRECOVERABLE error code from get_voltage() / get_voltage_sel(), do
> > we still need the qcom,regulator-initial-microvolt property?
> 
> Yes, this is still needed.  The -ENOTRECOVERABLE patch ensures that
> qcom-rpmh-regulator devices can be registered even if
> qcom,regulator-initial-microvolt is not specified.  However, that will
> result in the regulators being configured for the minimum voltage
> supported in the DT specified min/max range.  The
> qcom,regulator-initial-microvolt property allows us to set a specific
> voltage that is larger than the min constraint.
> 
> > If this is really still needed, can it be moved to the regulator core?
> 
> I'm not opposed to the idea, but I think that Mark is [1]:
> 
> >> Do you have a preference for qcom,regulator-initial-microvolt vs a generic
> >> framework supported regulator-initial-microvolt property for configuring a
> >> specific voltage at registration time?  We'll need to have support for one
> >> or the other in order for the qcom_rpmh-regulator driver to be functional.
> > 
> > This is basically specific to Qualcomm, I can't off hand think of any
> > other devices with similar issues.
> 
> 
> >> +- regulator-initial-mode
> >> +       Usage:      optional; VRM regulators only
> >> +       Value type: <u32>
> >> +       Definition: Specifies the initial mode to request for a VRM regulator.
> >> +                   Supported values are RPMH_REGULATOR_MODE_* which are defined
> >> +                   in [1] (i.e. 0 to 3).  This property may be specified even
> >> +                   if the regulator-allow-set-load property is not specified.
> > 
> > Every time I read the above I wonder why you're documenting a standard
> > regulator regulator property in your bindings.  ...then I realize it's
> > because you're doing it because you want to explicitly document what
> > the valid modes are.  I wonder if it makes sense to just put a
> > reference somewhere else in this document to go look at the header
> > file where these are all nicely documented.
> 
> Isn't that what the [1] in the above snippet is currently doing.  Further
> down in qcom,rpmh-regulator.txt is this line:
> 
> +[1] include/dt-bindings/regulator/qcom,rpmh-regulator.h
> 
> 
> > Speaking of documenting things like that, it might be worth finding
> > somewhere in this doc to mention that the "bob" regulator on PMI8998
> > can support "regulator-allow-bypass".  That tidbit got lost when we
> > moved to the standard regulator bindings for bypass.
> 
> I suppose that I could add something like this:
> 
> +- regulator-allow-bypass
> +	Usage:      optional; BOB type VRM regulators only
> +	Value type: <empty>
> +	Definition: See [2] for details.
> ...
> +[2]: Documentation/devicetree/bindings/regulator.txt
> 
> However, I don't want the patch to get NACKed because it is defining a
> property that is already defined in the common regulator.txt file.

If all constraints are defined in the common doc, just "see 
regulator.txt" is fine. You just need to say what properties this 
binding uses.

Rob

^ permalink raw reply

* [PATCH v3 2/6] mfd: at91-usart: added mfd driver for usart
From: Rob Herring @ 2018-05-18 22:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180511103822.31698-3-radu.pirea@microchip.com>

On Fri, May 11, 2018 at 01:38:18PM +0300, Radu Pirea wrote:
> This mfd driver is just a wrapper over atmel_serial driver and
> spi-at91-usart driver. Selection of one of the drivers is based on a
> property from device tree. If the property is not specified, the default
> driver is atmel_serial.
> 
> Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
> ---
>  drivers/mfd/Kconfig                  | 10 ++++
>  drivers/mfd/Makefile                 |  1 +
>  drivers/mfd/at91-usart.c             | 75 ++++++++++++++++++++++++++++
>  include/dt-bindings/mfd/at91-usart.h | 17 +++++++
>  4 files changed, 103 insertions(+)
>  create mode 100644 drivers/mfd/at91-usart.c
>  create mode 100644 include/dt-bindings/mfd/at91-usart.h
> 

> +#ifndef __DT_BINDINGS_AT91_USART_H__
> +#define __DT_BINDINGS_AT91_USART_H__
> +
> +#define AT91_USART_MODE_SERIAL	1
> +#define AT91_USART_MODE_SPI	2

Won't this require a DT update for serial mode to add the mode property? 
That breaks compatibility.

Rob

^ permalink raw reply

* [PATCH 2/2] pwm: stm32: initialize raw local variables
From: Thierry Reding @ 2018-05-18 22:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526657044-14879-3-git-send-email-fabrice.gasnier@st.com>

On Fri, May 18, 2018 at 05:24:04PM +0200, Fabrice Gasnier wrote:
> This removes build warning when COMPILE_TEST=y and MFD_STM32_TIMERS=n
> in drivers/pwm/pwm-stm32.c. In function 'stm32_pwm_capture' 'raw_prd' and
> 'raw_dty' may be used uninitialized in this function
> [-Wmaybe-uninitialized]
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> ---
>  drivers/pwm/pwm-stm32.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Hi Lee,

I assume you'll pick this up into your branch where you applied the
initial patches along with 1/2 in this series?

Acked-by: Thierry Reding <thierry.reding@gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180519/a4364ea1/attachment-0001.sig>

^ permalink raw reply

* [PATCH 3/3] mmc: sdhci-iproc: add SDHCI_QUIRK2_HOST_OFF_CARD_ON for cygnus
From: Scott Branden @ 2018-05-18 22:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526681037-2074-1-git-send-email-scott.branden@broadcom.com>

From: Corneliu Doban <corneliu.doban@broadcom.com>

The SDHCI_QUIRK2_HOST_OFF_CARD_ON is needed for the driver to
properly reset the host controller (reset all) on initialization
after exiting deep sleep.

Signed-off-by: Corneliu Doban <corneliu.doban@broadcom.com>
Signed-off-by: Scott Branden <scott.branden@broadcom.com>
Reviewed-by: Ray Jui <ray.jui@broadcom.com>
Reviewed-by: Srinath Mannam <srinath.mannam@broadcom.com>
---
 drivers/mmc/host/sdhci-iproc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 1f0ab08..d0e83db 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -186,7 +186,7 @@ static const struct sdhci_ops sdhci_iproc_32only_ops = {
 
 static const struct sdhci_pltfm_data sdhci_iproc_cygnus_pltfm_data = {
 	.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK,
-	.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN,
+	.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | SDHCI_QUIRK2_HOST_OFF_CARD_ON,
 	.ops = &sdhci_iproc_32only_ops,
 };
 
-- 
2.5.0

^ permalink raw reply related

* [PATCH 2/3] mmc: sdhci-iproc: fix 32bit writes for TRANSFER_MODE register
From: Scott Branden @ 2018-05-18 22:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526681037-2074-1-git-send-email-scott.branden@broadcom.com>

From: Corneliu Doban <corneliu.doban@broadcom.com>

When the host controller accepts only 32bit writes, the value of the
16bit TRANSFER_MODE register, that has the same 32bit address as the
16bit COMMAND register, needs to be saved and it will be written
in a 32bit write together with the command as this will trigger the
host to send the command on the SD interface.
When sending the tuning command, TRANSFER_MODE is written and then
sdhci_set_transfer_mode reads it back to clear AUTO_CMD12 bit and
write it again resulting in wrong value to be written because the
initial write value was saved in a shadow and the read-back returned
a wrong value, from the register.
Fix sdhci_iproc_readw to return the saved value of TRANSFER_MODE
when a saved value exist.
Same fix for read of BLOCK_SIZE and BLOCK_COUNT registers, that are
saved for a different reason, although a scenario that will cause the
mentioned problem on this registers is not probable.

Fixes: b580c52d58d9 ("mmc: sdhci-iproc: add IPROC SDHCI driver")
Signed-off-by: Corneliu Doban <corneliu.doban@broadcom.com>
Signed-off-by: Scott Branden <scott.branden@broadcom.com>
---
 drivers/mmc/host/sdhci-iproc.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 6f430da..1f0ab08 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -33,6 +33,8 @@ struct sdhci_iproc_host {
 	const struct sdhci_iproc_data *data;
 	u32 shadow_cmd;
 	u32 shadow_blk;
+	bool is_cmd_shadowed;
+	bool is_blk_shadowed;
 };
 
 #define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18)
@@ -48,8 +50,22 @@ static inline u32 sdhci_iproc_readl(struct sdhci_host *host, int reg)
 
 static u16 sdhci_iproc_readw(struct sdhci_host *host, int reg)
 {
-	u32 val = sdhci_iproc_readl(host, (reg & ~3));
-	u16 word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_iproc_host *iproc_host = sdhci_pltfm_priv(pltfm_host);
+	u32 val;
+	u16 word;
+
+	if ((reg == SDHCI_TRANSFER_MODE) && iproc_host->is_cmd_shadowed) {
+		/* Get the saved transfer mode */
+		val = iproc_host->shadow_cmd;
+	} else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
+		   iproc_host->is_blk_shadowed) {
+		/* Get the saved block info */
+		val = iproc_host->shadow_blk;
+	} else {
+		val = sdhci_iproc_readl(host, (reg & ~3));
+	}
+	word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff;
 	return word;
 }
 
@@ -105,13 +121,15 @@ static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg)
 
 	if (reg == SDHCI_COMMAND) {
 		/* Write the block now as we are issuing a command */
-		if (iproc_host->shadow_blk != 0) {
+		if (iproc_host->is_blk_shadowed) {
 			sdhci_iproc_writel(host, iproc_host->shadow_blk,
 				SDHCI_BLOCK_SIZE);
-			iproc_host->shadow_blk = 0;
+			iproc_host->is_blk_shadowed = false;
 		}
 		oldval = iproc_host->shadow_cmd;
-	} else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) {
+		iproc_host->is_cmd_shadowed = false;
+	} else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
+		   iproc_host->is_blk_shadowed) {
 		/* Block size and count are stored in shadow reg */
 		oldval = iproc_host->shadow_blk;
 	} else {
@@ -123,9 +141,11 @@ static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg)
 	if (reg == SDHCI_TRANSFER_MODE) {
 		/* Save the transfer mode until the command is issued */
 		iproc_host->shadow_cmd = newval;
+		iproc_host->is_cmd_shadowed = true;
 	} else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) {
 		/* Save the block info until the command is issued */
 		iproc_host->shadow_blk = newval;
+		iproc_host->is_blk_shadowed = true;
 	} else {
 		/* Command or other regular 32-bit write */
 		sdhci_iproc_writel(host, newval, reg & ~3);
-- 
2.5.0

^ permalink raw reply related

* [PATCH 1/3] mmc: sdhci-iproc: remove hard coded mmc cap 1.8v
From: Scott Branden @ 2018-05-18 22:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526681037-2074-1-git-send-email-scott.branden@broadcom.com>

From: Srinath Mannam <srinath.mannam@broadcom.com>

Remove hard coded mmc cap 1.8v from platform data as it is board specific.
The 1.8v DDR mmc caps can be enabled using DTS property for those
boards that support it.

Fixes: b17b4ab8ce38 ("mmc: sdhci-iproc: define MMC caps in platform data")
Signed-off-by: Srinath Mannam <srinath.mannam@broadcom.com>
Signed-off-by: Scott Branden <scott.branden@broadcom.com>
Reviewed-by: Ray Jui <ray.jui@broadcom.com>
---
 drivers/mmc/host/sdhci-iproc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 0ef741b..6f430da 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -206,7 +206,6 @@ static const struct sdhci_iproc_data iproc_data = {
 	.caps1 = SDHCI_DRIVER_TYPE_C |
 		 SDHCI_DRIVER_TYPE_D |
 		 SDHCI_SUPPORT_DDR50,
-	.mmc_caps = MMC_CAP_1_8V_DDR,
 };
 
 static const struct sdhci_pltfm_data sdhci_bcm2835_pltfm_data = {
-- 
2.5.0

^ permalink raw reply related

* [PATCH 0/3] mmc: sdhci-iproc: UHS and 32bit access fixes
From: Scott Branden @ 2018-05-18 22:03 UTC (permalink / raw)
  To: linux-arm-kernel

Collection of bug fixes for sdhci-iproc driver.
- fix for 32bit writes for TRANSFER_MODE register by correcting shadow
register logic
- fix for deep sleep mode by adding SDHCI_QUIRK2_HOST_OFF_CARD_ON
- remove hard coded mmc capability of 1.8V to allow boards to be supported
that do support 1.8V.


Corneliu Doban (2):
  mmc: sdhci-iproc: fix 32bit writes for TRANSFER_MODE register
  mmc: sdhci-iproc: add SDHCI_QUIRK2_HOST_OFF_CARD_ON for cygnus

Srinath Mannam (1):
  mmc: sdhci-iproc: remove hard coded mmc cap 1.8v

 drivers/mmc/host/sdhci-iproc.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

-- 
2.5.0

^ permalink raw reply

* [GIT PULL v2 2/5] memory: tegra: Changes for v4.18-rc1
From: Thierry Reding @ 2018-05-18 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-2-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-memory-v2

for you to fetch changes up to a1be3cfdfb81cc55c1b2feb73aca6945f61acddb:

  dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions (2018-05-18 22:45:01 +0200)

This contains the same patches as the previous pull request with the exception
that the final two are reordered to keep the set bisectible.

Thanks,
Thierry

----------------------------------------------------------------
memory: tegra: Changes for v4.18-rc1

This contains some cleanup of the memory controller driver as well as
unification work to share more code between Tegra20 and later SoC
generations. Also included are an implementation for the hot resets
functionality by the memory controller which is required to properly
reset busy hardware.

----------------------------------------------------------------
Dmitry Osipenko (14):
      dt-bindings: memory: tegra: Add hot resets definitions
      memory: tegra: Do not handle spurious interrupts
      memory: tegra: Setup interrupts mask before requesting IRQ
      memory: tegra: Apply interrupts mask per SoC
      memory: tegra: Remove unused headers inclusions
      memory: tegra: Squash tegra20-mc into common tegra-mc driver
      memory: tegra: Introduce memory client hot reset
      memory: tegra: Add Tegra20 memory controller hot resets
      memory: tegra: Add Tegra30 memory controller hot resets
      memory: tegra: Add Tegra114 memory controller hot resets
      memory: tegra: Add Tegra124 memory controller hot resets
      memory: tegra: Register SMMU after MC driver became ready
      memory: tegra: Remove Tegra114 SATA and AFI reset definitions
      dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions

Thierry Reding (1):
      memory: tegra: Add Tegra210 memory controller hot resets

 drivers/memory/Kconfig                   |  10 -
 drivers/memory/Makefile                  |   1 -
 drivers/memory/tegra/Makefile            |   1 +
 drivers/memory/tegra/mc.c                | 362 +++++++++++++++++++++++++++----
 drivers/memory/tegra/mc.h                |  22 ++
 drivers/memory/tegra/tegra114.c          |  33 +++
 drivers/memory/tegra/tegra124.c          |  48 ++++
 drivers/memory/tegra/tegra20.c           | 296 +++++++++++++++++++++++++
 drivers/memory/tegra/tegra210.c          |  53 ++++-
 drivers/memory/tegra/tegra30.c           |  35 +++
 drivers/memory/tegra20-mc.c              | 254 ----------------------
 include/dt-bindings/memory/tegra114-mc.h |  17 ++
 include/dt-bindings/memory/tegra124-mc.h |  25 +++
 include/dt-bindings/memory/tegra20-mc.h  |  21 ++
 include/dt-bindings/memory/tegra210-mc.h |  31 +++
 include/dt-bindings/memory/tegra30-mc.h  |  19 ++
 include/soc/tegra/mc.h                   |  37 +++-
 17 files changed, 956 insertions(+), 309 deletions(-)
 create mode 100644 drivers/memory/tegra/tegra20.c
 delete mode 100644 drivers/memory/tegra20-mc.c
 create mode 100644 include/dt-bindings/memory/tegra20-mc.h

^ permalink raw reply

* dma_sync_*_for_cpu and direction=TO_DEVICE (was Re: [PATCH 02/20] dma-mapping: provide a generic dma-noncoherent implementation)
From: Russell King - ARM Linux @ 2018-05-18 21:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cecfe6bd-ef1f-1e25-bfcf-992d1f828efb@synopsys.com>

On Fri, May 18, 2018 at 01:35:08PM -0700, Vineet Gupta wrote:
> On 05/18/2018 10:50 AM, Russell King - ARM Linux wrote:
> >On Fri, May 18, 2018 at 10:20:02AM -0700, Vineet Gupta wrote:
> >>I never understood the need for this direction. And if memory serves me
> >>right, at that time I was seeing twice the amount of cache flushing !
> >It's necessary.  Take a moment to think carefully about this:
> >
> >	dma_map_single(, dir)
> >
> >	dma_sync_single_for_cpu(, dir)
> >
> >	dma_sync_single_for_device(, dir)
> >
> >	dma_unmap_single(, dir)
> 
> As an aside, do these imply a state machine of sorts - does a driver needs
> to always call map_single first ?

Kind-of, but some drivers do omit some of the dma_sync_*() calls.
For example, if a buffer is written to, then mapped with TO_DEVICE,
and then the CPU wishes to write to it, it's fairly common that a
driver omits the dma_sync_single_for_cpu() call.  If you think about
the cases I gave and what cache operations happen, such a scenario
practically turns out to be safe.

> My original point of contention/confusion is the specific combinations of
> API and direction, specifically for_cpu(TO_DEV) and for_device(TO_CPU)

Remember that it is expected that all calls for a mapping use the
same direction argument while that mapping exists.  In other words,
if you call dma_map_single(TO_DEVICE) and then use any of the other
functions, the other functions will also use TO_DEVICE.  The DMA
direction argument describes the direction of the DMA operation
being performed on the buffer, not on the individual dma_* operation.

What isn't expected at arch level is for drivers to do:

	dma_map_single(TO_DEVICE)
	dma_sync_single_for_cpu(FROM_DEVICE)

or vice versa.

> Semantically what does dma_sync_single_for_cpu(TO_DEV) even imply for a non
> dma coherent arch.
> 
> Your tables below have "none" for both, implying it is unlikely to be a real
> combination (for ARM and ARC atleast).

Very little for the cases that I've stated (and as I mentioned
above, some drivers do omit the call in that case.)

> The other case, actually @dir TO_CPU, independent of for_{cpu, device}?
> implies driver intends to touch it after the call, so it would invalidate
> any stray lines, unconditionally (and not just for speculative prefetch
> case).

If you don't have a CPU that speculatively prefetches, and you've
already had to invalidate the cache lines (to avoid write-backs
corrupting DMA'd data) then there's no need for the architecture
to do any work at the for_cpu(TO_CPU) case - the CPU shouldn't
be touching cache lines that are part of the buffer while it is
mapped, which means a non-speculating CPU won't pull in any
cache lines without an explicit access.

Speculating CPUs are different.  The action of the speculation is
to try and guess what data the program wants to access ahead of
the program flow.  That causes the CPU to prefetch data into the
cache.  The point in the program flow that this happens is not
really determinant to the programmer.  This means that if you try
to read from the DMA buffer after the DMA operation has complete
without invalidating the cache between the DMA completing and the
CPU reading, you have no guarantee that you're reading the data
that the DMA operation has been written.  The cache may have
loaded itself with data before the DMA operation completed, and
the CPU may see that stale data.

The difference between non-speculating CPUs and speculating CPUs
is that for non-speculating CPUs, caches work according to explicit
accesses by the program, and the program is stalled while the data
is fetched from external memory.  Speculating CPUs try to predict
ahead of time what data the program will require in the future,
and attempt to load that data into the caches _before_ the program
requires it - which means that the program suffers fewer stalls.

> >In the case of a DMA-incoherent architecture, the operations done at each
> >stage depend on the direction argument:
> >
> >	map		for_cpu		for_device	unmap
> >TO_DEV	writeback	none		writeback	none
> >TO_CPU	invalidate	invalidate*	invalidate	invalidate*
> >BIDIR	writeback	invalidate	writeback	invalidate
> >
> >* - only necessary if the CPU speculatively prefetches.
> >
> >The multiple invalidations for the TO_CPU case handles different
> >conditions that can result in data corruption, and for some CPUs, all
> >four are necessary.
> 
> Can you please explain in some more detail, TO_CPU row, why invalidate is
> conditional sometimes.

See above - I hope my explanation above is sufficient.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* [PATCH v9 02/12] drivers: base: cacheinfo: setup DT cache properties early
From: Andy Shevchenko @ 2018-05-18 21:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180517154701.GA20281@e107155-lin>

On Thu, May 17, 2018 at 6:47 PM, Sudeep Holla <sudeep.holla@arm.com> wrote:

> Is below patch does what you were looking for ?

Somewhat.
See below for some minors.

> of_property_read_u64 searches for a property in a device node and read
> a 64-bit value from it. Instead of using of_get_property to get the
> property and then read 64-bit value using of_read_number, we can make
> use of of_property_read_u64.

Suggested-by?

> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>


> -       cache_size = of_get_property(np, propname, NULL);
> -       if (cache_size)
> -               this_leaf->size = of_read_number(cache_size, 1);
> +       if (!of_property_read_u64(np, propname, &cache_size))
> +               this_leaf->size = cache_size;

I suppose it's something like this

ret = of_property_...(..., &this_leaf->VAR);
if (ret)
 warning / set default / etc

>                 propname = cache_type_info[ct_idx].line_size_props[i];
> -               line_size = of_get_property(np, propname, NULL);
> -               if (line_size)
> +               line_size = of_property_read_u64(np, propname, &line_size);
> +               if (line_size) {

ret = ...
if (ret) {

> +                       this_leaf->coherency_line_size = line_size;
>                         break;
> +               }

> +       if (!of_property_read_u64(np, propname, &nr_sets))
> +               this_leaf->number_of_sets = nr_sets;

As in first case.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply


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