* Re: [PATCH 2/3] arm64: dts: renesas: condor: specify EtherAVB PHY IRQ
From: Simon Horman @ 2018-06-04 10:33 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Mark Rutland, devicetree, Magnus Damm, Catalin Marinas,
Will Deacon, linux-renesas-soc, Rob Herring, linux-arm-kernel
In-Reply-To: <21578b79-7ba0-b3a6-ae45-7e9ffbb7c8db@cogentembedded.com>
On Fri, Jun 01, 2018 at 11:45:55PM +0300, Sergei Shtylyov wrote:
> Specify EtherAVB PHY IRQ in the Condor board's device tree, now that
> we have the GPIO support (previously phylib had to resort to polling).
>
> Based on the original (and large) patch by Vladimir Barinov.
>
> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> ---
> arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 2 ++
> 1 file changed, 2 insertions(+)
>
> Index: renesas/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
> ===================================================================
> --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
> +++ renesas/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
> @@ -59,6 +59,8 @@
> phy0: ethernet-phy@0 {
> rxc-skew-ps = <1500>;
> reg = <0>;
> + interrupt-parent = <&gpio1>;
> + interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
I don't see this documented. Perhaps I'm missing something obvious.
Or you have some extra information or newer documentation?
Also, given Olof Johansson's recent comments in ("Re: [GIT PULL] Renesas
ARM64 Based SoC DT Updates for v4.18") please consider squashing this patch
and the following one.
> };
> };
>
>
^ permalink raw reply
* Re: [PATCH 3/3] arm64: dts: renesas: v3hsk: specify GEther PHY IRQ
From: Simon Horman @ 2018-06-04 10:34 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Mark Rutland, devicetree, Magnus Damm, Catalin Marinas,
Will Deacon, linux-renesas-soc, Rob Herring, linux-arm-kernel
In-Reply-To: <9e6c40eb-71d0-d35b-1cf7-9179e093ed10@cogentembedded.com>
On Fri, Jun 01, 2018 at 11:47:14PM +0300, Sergei Shtylyov wrote:
> Specify GEther PHY IRQ in the V3H Starter Kit board's device tree, now
> that we have the GPIO support (previously phylib had to resort to polling).
>
> Based on the original (and large) patch by Vladimir Barinov.
>
> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Given Olof Johansson's recent comments in ("Re: [GIT PULL] Renesas
ARM64 Based SoC DT Updates for v4.18") please consider squashing this patch
and the previous one.
Other than that, this patch looks good to me.
^ permalink raw reply
* Re: [PATCH 1/3] arm64: dts: renesas: r8a77980: add GPIO support
From: Simon Horman @ 2018-06-04 10:34 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Mark Rutland, devicetree, Magnus Damm, Catalin Marinas,
Will Deacon, linux-renesas-soc, Rob Herring, linux-arm-kernel
In-Reply-To: <3c195d53-be0f-ad15-92e6-8ba43b14f076@cogentembedded.com>
On Fri, Jun 01, 2018 at 11:44:46PM +0300, Sergei Shtylyov wrote:
> Describe all 6 GPIO controllers in the R8A77980 device tree.
>
> Based on the original (and large) patch by Vladimir Barinov.
>
> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
This looks fine but I will wait to see if there are other reviews before
applying.
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
^ permalink raw reply
* Re: [RFC PATCH 2/8] coresight: Fix remote endpoint parsing
From: Suzuki K Poulose @ 2018-06-04 10:34 UTC (permalink / raw)
To: Mathieu Poirier
Cc: linux-arm-kernel, Sudeep Holla, Rob Herring, Mark Rutland,
Frank Rowand, Matt Sealey, Charles Garcia-Tobin, John Horley,
Mike Leach, coresight, Linux Kernel Mailing List, devicetree
In-Reply-To: <CANLsYkzY-1z4NBmZECczMisDixgPb2UkJL0k9_LmDNEiqUS1=g@mail.gmail.com>
On 06/01/2018 08:46 PM, Mathieu Poirier wrote:
> On 1 June 2018 at 13:38, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
>> On Fri, Jun 01, 2018 at 02:16:01PM +0100, Suzuki K Poulose wrote:
>>> When parsing the remote endpoint of an output port, we do :
>>> rport = of_graph_get_remote_port(ep);
>>> rparent = of_graph_get_remote_port_parent(ep);
>>>
>>> and then parse the "remote_port" as if it was the remote endpoint,
>>> which is wrong. The code worked fine because we used endpoint number
>>> as the port number. Let us fix it and optimise a bit as:
>>>
>>> remote_ep = of_graph_get_remote_endpoint(ep);
>>> if (remote_ep)
>>> remote_parent = of_graph_get_port_parent(remote_ep);
>>>
>>> and then, parse the remote_ep for the port/endpoint details.
>>>
>>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> ---
>>> drivers/hwtracing/coresight/of_coresight.c | 19 ++++++++++---------
>>> 1 file changed, 10 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
>>> index 7c37544..e0deab0 100644
>>> --- a/drivers/hwtracing/coresight/of_coresight.c
>>> +++ b/drivers/hwtracing/coresight/of_coresight.c
>>> @@ -128,7 +128,7 @@ of_get_coresight_platform_data(struct device *dev,
>>> struct device *rdev;
>>> struct device_node *ep = NULL;
>>> struct device_node *rparent = NULL;
>>> - struct device_node *rport = NULL;
>>> + struct device_node *rep = NULL;
>>>
>>> pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
>>> if (!pdata)
>>> @@ -169,16 +169,17 @@ of_get_coresight_platform_data(struct device *dev,
>>> pdata->outports[i] = endpoint.port;
>>>
>>> /*
>>> - * Get a handle on the remote port and parent
>>> - * attached to it.
>>> + * Get a handle on the remote endpoint and the device
>>> + * it is attached to.
>>> */
>>> - rparent = of_graph_get_remote_port_parent(ep);
>>> - rport = of_graph_get_remote_port(ep);
>>> -
>>> - if (!rparent || !rport)
>>> + rep = of_graph_get_remote_endpoint(ep);
>>> + if (!rep)
>>> + continue;
>>> + rparent = of_graph_get_port_parent(rep);
>>> + if (!rparent)
>>> continue;
>>>
>>> - if (of_graph_parse_endpoint(rport, &rendpoint))
>>> + if (of_graph_parse_endpoint(rep, &rendpoint))
>>> continue;
>>
>> You are correct and I'm out to lunch.
>>
>>>
>>> rdev = of_coresight_get_endpoint_device(rparent);
>>> @@ -186,7 +187,7 @@ of_get_coresight_platform_data(struct device *dev,
>>> return ERR_PTR(-EPROBE_DEFER);
>>>
>>> pdata->child_names[i] = dev_name(rdev);
>>> - pdata->child_ports[i] = rendpoint.id;
>>> + pdata->child_ports[i] = rendpoint.port;
>>
>> You need to do a of_node_put() here for both rep and rparent.
>
> Same thing for the "continue" and error condition above.
Mathieu,
Thanks for pointing that out. I see that we were missing them for the
existing code as well. I will clean all this up.
Cheers
Suzuki
^ permalink raw reply
* [PATCH v3 0/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver
From: Taniya Das @ 2018-06-04 10:46 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, linux-kernel, linux-pm,
Stephen Boyd, robh
Cc: Rajendra Nayak, devicetree, skannan, Taniya Das
[v3]
* Remove index check from 'qcom_cpufreq_fw_target_index'.
* Update the Documentation binding to add the platform specific properties in
the CPU nodes, node name "qcom,freq-domain".
* Update return value to '0' from -ENODEV from 'qcom_cpufreq_fw_get'.
* Update the logic for boost frequency to use local variables instead of
cpufreq driver data in 'qcom_read_lut'.
* Update the logic in 'qcom_get_related_cpus' to find the related cpus.
* Update the reg-names to remove "_base" and also update the binding with the
description of these registers.
* Update the logic in 'qcom_resources_init' to address the new device tree
notation of handling the frequency domain phandles.
[v2]
* Fixed the alignment issues in "qcom_cpufreq_fw_target_index" for dev_err and
also for "qcom_cpu_resources_init".
* Removed ret = 0 from qcom_get_related_cpus and added to check for
cpu_mask_empty to return -ENOENT.
* Fixes qcom_cpu_resources_init function
* Remove initialization of 'index'
* Check for valid 'c'
* Removed initialization of 'prev_cc' from 'qcom_read_lut'.
* Remove initialization of 'ret' from function qcom_resources_init and add
return -ENODEV based on 'of_get_available_child_count'.
* Removed initialization of 'rc' from qcom_cpufreq_fw_driver_probe
* Removed module_exit as this driver would not be used as module, also updated
the Kconfig to bool from tristate.
* Updated the subsystem in device tree bindings.
[v1]
* Fixed compilation reported by Amit K.
Taniya Das (2):
dt-bindings: cpufreq: Introduce QCOM CPUFREQ FW bindings
cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver
.../bindings/cpufreq/cpufreq-qcom-fw.txt | 173 +++++++++++
drivers/cpufreq/Kconfig.arm | 9 +
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/qcom-cpufreq-fw.c | 318 +++++++++++++++++++++
4 files changed, 501 insertions(+)
create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
create mode 100644 drivers/cpufreq/qcom-cpufreq-fw.c
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the Linux Foundation.
^ permalink raw reply
* [PATCH 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ FW bindings
From: Taniya Das @ 2018-06-04 10:46 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, linux-kernel, linux-pm,
Stephen Boyd, robh
Cc: Rajendra Nayak, devicetree, skannan, Taniya Das
In-Reply-To: <1528109194-16864-1-git-send-email-tdas@codeaurora.org>
Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
SoCs. This is required for managing the cpu frequency transitions which are
controlled by firmware.
Signed-off-by: Taniya Das <tdas@codeaurora.org>
---
.../bindings/cpufreq/cpufreq-qcom-fw.txt | 173 +++++++++++++++++++++
1 file changed, 173 insertions(+)
create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
new file mode 100644
index 0000000..e3087ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
@@ -0,0 +1,173 @@
+Qualcomm Technologies, Inc. CPUFREQ Bindings
+
+CPUFREQ FW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
+SoCs to manage frequency in hardware. It is capable of controlling frequency
+for multiple clusters.
+
+Properties:
+- compatible
+ Usage: required
+ Value type: <string>
+ Definition: must be "qcom,cpufreq-fw".
+
+* Property qcom,freq-domain
+Devices supporting freq-domain must set their "qcom,freq-domain" property with
+phandle to a freq_domain_table in their DT node.
+
+* Frequency Domain Table Node
+
+This describes the frequency domain belonging to a device.
+This node can have following properties:
+
+- reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Addresses and sizes for the memory of the perf
+ , lut and enable bases.
+ perf - indicates the base address for the desired
+ performance state to be set.
+ lut - indicates the look up table base address for the
+ cpufreq driver to read frequencies.
+ enable - indicates the enable register for firmware.
+- reg-names
+ Usage: required
+ Value type: <stringlist>
+ Definition: Address names. Must be "perf", "lut", "enable".
+ Must be specified in the same order as the reg property.
+
+Example:
+
+Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
+DCVS state together.
+
+/ {
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&L2_0>;
+ qcom,freq-domain = <&freq_domain_table0>;
+ L2_0: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ L3_0: l3-cache {
+ compatible = "cache";
+ };
+ };
+ };
+
+ CPU1: cpu@100 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ next-level-cache = <&L2_100>;
+ qcom,freq-domain = <&freq_domain_table0>;
+ L2_100: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ };
+ };
+
+ CPU2: cpu@200 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ next-level-cache = <&L2_200>;
+ qcom,freq-domain = <&freq_domain_table0>;
+ L2_200: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ };
+ };
+
+ CPU3: cpu@300 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ next-level-cache = <&L2_300>;
+ qcom,freq-domain = <&freq_domain_table0>;
+ L2_300: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ };
+ };
+
+ CPU4: cpu@400 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x400>;
+ enable-method = "psci";
+ next-level-cache = <&L2_400>;
+ qcom,freq-domain = <&freq_domain_table1>;
+ L2_400: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ };
+ };
+
+ CPU5: cpu@500 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x500>;
+ enable-method = "psci";
+ next-level-cache = <&L2_500>;
+ qcom,freq-domain = <&freq_domain_table1>;
+ L2_500: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ };
+ };
+
+ CPU6: cpu@600 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x600>;
+ enable-method = "psci";
+ next-level-cache = <&L2_600>;
+ qcom,freq-domain = <&freq_domain_table1>;
+ L2_600: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ };
+ };
+
+ CPU7: cpu@700 {
+ device_type = "cpu";
+ compatible = "qcom,kryo385";
+ reg = <0x0 0x700>;
+ enable-method = "psci";
+ next-level-cache = <&L2_700>;
+ qcom,freq-domain = <&freq_domain_table1>;
+ L2_700: l2-cache {
+ compatible = "cache";
+ next-level-cache = <&L3_0>;
+ };
+ };
+ };
+
+ qcom,cpufreq-fw {
+ compatible = "qcom,cpufreq-fw";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ freq_domain_table0 : freq_table0 {
+ reg = <0x17d43920 0x4>, <0x17d43110 0x500>,
+ <0x17d41000 0x4>;
+ reg-names = "perf", "lut", "enable";
+ };
+
+ freq_domain_table1 : freq_table1 {
+ reg = <0x17d46120 0x4>, <0x17d45910 0x500>,
+ <0x17d45800 0x4> ;
+ reg-names = "perf", "lut", "enable";
+ };
+ };
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the Linux Foundation.
^ permalink raw reply related
* [PATCH 2/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver
From: Taniya Das @ 2018-06-04 10:46 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, linux-kernel, linux-pm,
Stephen Boyd, robh
Cc: Rajendra Nayak, devicetree, skannan, Taniya Das
In-Reply-To: <1528109194-16864-1-git-send-email-tdas@codeaurora.org>
The CPUfreq FW present in some QCOM chipsets offloads the steps necessary
for changing the frequency of CPUs. The driver implements the cpufreq
driver interface for this firmware.
Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
Signed-off-by: Taniya Das <tdas@codeaurora.org>
---
drivers/cpufreq/Kconfig.arm | 9 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/qcom-cpufreq-fw.c | 316 ++++++++++++++++++++++++++++++++++++++
3 files changed, 326 insertions(+)
create mode 100644 drivers/cpufreq/qcom-cpufreq-fw.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index c7ce928..82c391e 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -312,3 +312,12 @@ config ARM_PXA2xx_CPUFREQ
This add the CPUFreq driver support for Intel PXA2xx SOCs.
If in doubt, say N.
+
+config ARM_QCOM_CPUFREQ_FW
+ bool "QCOM CPUFreq FW driver"
+ help
+ Support for the CPUFreq FW driver.
+ The CPUfreq FW preset in some QCOM chipsets offloads the steps
+ necessary for changing the frequency of CPUs. The driver
+ implements the cpufreq driver interface for this firmware.
+ Say Y if you want to support CPUFreq FW.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index fb4a2ec..34691a2 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o
obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o
obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_FW) += qcom-cpufreq-fw.o
##################################################################################
diff --git a/drivers/cpufreq/qcom-cpufreq-fw.c b/drivers/cpufreq/qcom-cpufreq-fw.c
new file mode 100644
index 0000000..2135a08
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-fw.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#define INIT_RATE 300000000UL
+#define XO_RATE 19200000UL
+#define LUT_MAX_ENTRIES 40U
+#define CORE_COUNT_VAL(val) (((val) & (GENMASK(18, 16))) >> 16)
+#define LUT_ROW_SIZE 32
+
+struct cpufreq_qcom {
+ struct cpufreq_frequency_table *table;
+ struct device *dev;
+ void __iomem *perf_base;
+ void __iomem *lut_base;
+ cpumask_t related_cpus;
+ unsigned int max_cores;
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int
+qcom_cpufreq_fw_target_index(struct cpufreq_policy *policy,
+ unsigned int index)
+{
+ struct cpufreq_qcom *c = policy->driver_data;
+
+ writel_relaxed(index, c->perf_base);
+
+ return 0;
+}
+
+static unsigned int qcom_cpufreq_fw_get(unsigned int cpu)
+{
+ struct cpufreq_qcom *c;
+ unsigned int index;
+
+ c = qcom_freq_domain_map[cpu];
+ if (!c)
+ return 0;
+
+ index = readl_relaxed(c->perf_base);
+ index = min(index, LUT_MAX_ENTRIES - 1);
+
+ return c->table[index].frequency;
+}
+
+static int qcom_cpufreq_fw_cpu_init(struct cpufreq_policy *policy)
+{
+ struct cpufreq_qcom *c;
+
+ c = qcom_freq_domain_map[policy->cpu];
+ if (!c) {
+ pr_err("No scaling support for CPU%d\n", policy->cpu);
+ return -ENODEV;
+ }
+
+ cpumask_copy(policy->cpus, &c->related_cpus);
+
+ policy->freq_table = c->table;
+ policy->driver_data = c;
+
+ return 0;
+}
+
+static struct freq_attr *qcom_cpufreq_fw_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ &cpufreq_freq_attr_scaling_boost_freqs,
+ NULL
+};
+
+static struct cpufreq_driver cpufreq_qcom_fw_driver = {
+ .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+ CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .target_index = qcom_cpufreq_fw_target_index,
+ .get = qcom_cpufreq_fw_get,
+ .init = qcom_cpufreq_fw_cpu_init,
+ .name = "qcom-cpufreq-fw",
+ .attr = qcom_cpufreq_fw_attr,
+ .boost_enabled = true,
+};
+
+static int qcom_read_lut(struct platform_device *pdev,
+ struct cpufreq_qcom *c)
+{
+ struct device *dev = &pdev->dev;
+ u32 data, src, lval, i, core_count, prev_cc, prev_freq, cur_freq;
+
+ c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
+ sizeof(*c->table), GFP_KERNEL);
+ if (!c->table)
+ return -ENOMEM;
+
+ for (i = 0; i < LUT_MAX_ENTRIES; i++) {
+ data = readl_relaxed(c->lut_base + i * LUT_ROW_SIZE);
+ src = ((data & GENMASK(31, 30)) >> 30);
+ lval = (data & GENMASK(7, 0));
+ core_count = CORE_COUNT_VAL(data);
+
+ if (!src)
+ c->table[i].frequency = INIT_RATE / 1000;
+ else
+ c->table[i].frequency = XO_RATE * lval / 1000;
+
+ cur_freq = c->table[i].frequency;
+
+ dev_dbg(dev, "index=%d freq=%d, core_count %d\n",
+ i, c->table[i].frequency, core_count);
+
+ if (core_count != c->max_cores)
+ cur_freq = CPUFREQ_ENTRY_INVALID;
+
+ /*
+ * Two of the same frequencies with the same core counts means
+ * end of table.
+ */
+ if (i > 0 && c->table[i - 1].frequency ==
+ c->table[i].frequency && prev_cc == core_count) {
+ struct cpufreq_frequency_table *prev = &c->table[i - 1];
+
+ if (prev_freq == CPUFREQ_ENTRY_INVALID)
+ prev->flags = CPUFREQ_BOOST_FREQ;
+ break;
+ }
+ prev_cc = core_count;
+ prev_freq = cur_freq;
+ }
+
+ c->table[i].frequency = CPUFREQ_TABLE_END;
+
+ return 0;
+}
+
+static int qcom_get_related_cpus(struct device_node *np, struct cpumask *m)
+{
+ struct device_node *cpu_dev;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ cpu_dev = of_cpu_device_node_get(cpu);
+ if (!cpu_dev)
+ continue;
+ cpu_dev = of_parse_phandle(cpu_dev, "qcom,freq-domain", 0);
+ if (!cpu_dev)
+ continue;
+ if (cpu_dev == np)
+ cpumask_set_cpu(cpu, m);
+ }
+
+ if (cpumask_empty(m))
+ return -ENOENT;
+
+ return 0;
+}
+
+static int qcom_cpu_resources_init(struct platform_device *pdev,
+ struct device_node *np)
+{
+ struct cpufreq_qcom *c;
+ struct resource res;
+ struct device *dev = &pdev->dev;
+ void __iomem *en_base;
+ int cpu, index, ret;
+
+ c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+ if (!c)
+ return -ENOMEM;
+
+ index = of_property_match_string(np, "reg-names", "enable");
+ if (index < 0)
+ return index;
+
+ if (of_address_to_resource(np, index, &res))
+ return -ENOMEM;
+
+ en_base = devm_ioremap(dev, res.start, resource_size(&res));
+ if (!en_base) {
+ dev_err(dev, "Unable to map %s enable-base\n", np->name);
+ return -ENOMEM;
+ }
+
+ /* FW should be in enabled state to proceed */
+ if (!(readl_relaxed(en_base) & 0x1)) {
+ dev_err(dev, "%s firmware not enabled\n", np->name);
+ return -ENODEV;
+ }
+ devm_iounmap(&pdev->dev, en_base);
+
+ index = of_property_match_string(np, "reg-names", "perf");
+ if (index < 0)
+ return index;
+
+ if (of_address_to_resource(np, index, &res))
+ return -ENOMEM;
+
+ c->perf_base = devm_ioremap(dev, res.start, resource_size(&res));
+ if (!c->perf_base) {
+ dev_err(dev, "Unable to map %s perf-base\n", np->name);
+ return -ENOMEM;
+ }
+
+ index = of_property_match_string(np, "reg-names", "lut");
+ if (index < 0)
+ return index;
+
+ if (of_address_to_resource(np, index, &res))
+ return -ENOMEM;
+
+ c->lut_base = devm_ioremap(dev, res.start, resource_size(&res));
+ if (!c->lut_base) {
+ dev_err(dev, "Unable to map %s lut-base\n", np->name);
+ return -ENOMEM;
+ }
+
+ ret = qcom_get_related_cpus(np, &c->related_cpus);
+ if (ret) {
+ dev_err(dev, "%s failed to get core phandles\n", np->name);
+ return ret;
+ }
+
+ c->max_cores = cpumask_weight(&c->related_cpus);
+
+ ret = qcom_read_lut(pdev, c);
+ if (ret) {
+ dev_err(dev, "%s failed to read LUT\n", np->name);
+ return ret;
+ }
+ for_each_cpu(cpu, &c->related_cpus)
+ qcom_freq_domain_map[cpu] = c;
+
+ return 0;
+}
+
+static int qcom_resources_init(struct platform_device *pdev)
+{
+ struct device_node *np, *cpu_dev;
+ unsigned int cpu;
+ int ret;
+
+ for_each_possible_cpu(cpu) {
+ cpu_dev = of_cpu_device_node_get(cpu);
+ if (!cpu_dev) {
+ dev_err(&pdev->dev, "Failed to get cpu %d device\n",
+ cpu);
+ continue;
+ }
+
+ np = of_parse_phandle(cpu_dev, "qcom,freq-domain", 0);
+ if (!np) {
+ dev_err(&pdev->dev, "Failed to get freq-domain device\n");
+ continue;
+ }
+
+ of_node_put(cpu_dev);
+
+ ret = qcom_cpu_resources_init(pdev, np);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int qcom_cpufreq_fw_driver_probe(struct platform_device *pdev)
+{
+ int rc;
+
+ /* Get the bases of cpufreq for domains */
+ rc = qcom_resources_init(pdev);
+ if (rc) {
+ dev_err(&pdev->dev, "CPUFreq resource init failed\n");
+ return rc;
+ }
+
+ rc = cpufreq_register_driver(&cpufreq_qcom_fw_driver);
+ if (rc) {
+ dev_err(&pdev->dev, "CPUFreq FW driver failed to register\n");
+ return rc;
+ }
+
+ dev_info(&pdev->dev, "QCOM CPUFreq FW driver inited\n");
+
+ return 0;
+}
+
+static const struct of_device_id match_table[] = {
+ { .compatible = "qcom,cpufreq-fw" },
+ {}
+};
+
+static struct platform_driver qcom_cpufreq_fw_driver = {
+ .probe = qcom_cpufreq_fw_driver_probe,
+ .driver = {
+ .name = "qcom-cpufreq-fw",
+ .of_match_table = match_table,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init qcom_cpufreq_fw_init(void)
+{
+ return platform_driver_register(&qcom_cpufreq_fw_driver);
+}
+subsys_initcall(qcom_cpufreq_fw_init);
+
+MODULE_DESCRIPTION("QCOM CPU Frequency FW");
+MODULE_LICENSE("GPL v2");
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the Linux Foundation.
^ permalink raw reply related
* Re: [PATCH 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ FW bindings
From: Sudeep Holla @ 2018-06-04 10:55 UTC (permalink / raw)
To: Taniya Das
Cc: Rafael J. Wysocki, Viresh Kumar, linux-kernel, linux-pm,
Stephen Boyd, robh, Rajendra Nayak, devicetree, skannan,
Sudeep Holla
In-Reply-To: <1528109194-16864-2-git-send-email-tdas@codeaurora.org>
On Mon, Jun 04, 2018 at 04:16:33PM +0530, Taniya Das wrote:
> Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
> SoCs. This is required for managing the cpu frequency transitions which are
> controlled by firmware.
>
> Signed-off-by: Taniya Das <tdas@codeaurora.org>
> ---
> .../bindings/cpufreq/cpufreq-qcom-fw.txt | 173 +++++++++++++++++++++
> 1 file changed, 173 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
>
> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
> new file mode 100644
> index 0000000..e3087ec
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
> @@ -0,0 +1,173 @@
> +Qualcomm Technologies, Inc. CPUFREQ Bindings
> +
> +CPUFREQ FW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
> +SoCs to manage frequency in hardware. It is capable of controlling frequency
> +for multiple clusters.
> +
> +Properties:
> +- compatible
> + Usage: required
> + Value type: <string>
> + Definition: must be "qcom,cpufreq-fw".
> +
> +* Property qcom,freq-domain
> +Devices supporting freq-domain must set their "qcom,freq-domain" property with
> +phandle to a freq_domain_table in their DT node.
> +
> +* Frequency Domain Table Node
> +
> +This describes the frequency domain belonging to a device.
> +This node can have following properties:
> +
> +- reg
> + Usage: required
> + Value type: <prop-encoded-array>
> + Definition: Addresses and sizes for the memory of the perf
> + , lut and enable bases.
> + perf - indicates the base address for the desired
> + performance state to be set.
> + lut - indicates the look up table base address for the
> + cpufreq driver to read frequencies.
> + enable - indicates the enable register for firmware.
> +- reg-names
> + Usage: required
> + Value type: <stringlist>
> + Definition: Address names. Must be "perf", "lut", "enable".
> + Must be specified in the same order as the reg property.
> +
[...]
> +
> + qcom,cpufreq-fw {
> + compatible = "qcom,cpufreq-fw";
> +
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + freq_domain_table0 : freq_table0 {
> + reg = <0x17d43920 0x4>, <0x17d43110 0x500>,
> + <0x17d41000 0x4>;
Are "perf", "lut", "enable" registers part of single IP block / share memory ?
I am just trying to understand the reason for separate entries in this fashion
as part of DT register property. I am wondering if there will be multiple
entries that fall with the page size.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH] drm/panel: simple: Add support for Innolux G070Y2-L01
From: Christoph Fritz @ 2018-06-04 11:16 UTC (permalink / raw)
To: Thierry Reding, Rob Herring; +Cc: David Airlie, devicetree, dri-devel
This patch adds support for Innolux G070Y2-L01 7" WVGA (800x480) TFT LCD
panel.
Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
.../bindings/display/panel/innolux,g070y2-l01.txt | 12 +++++++
drivers/gpu/drm/panel/panel-simple.c | 37 ++++++++++++++++++++--
2 files changed, 47 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/display/panel/innolux,g070y2-l01.txt
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,g070y2-l01.txt b/Documentation/devicetree/bindings/display/panel/innolux,g070y2-l01.txt
new file mode 100644
index 0000000..7c234cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/innolux,g070y2-l01.txt
@@ -0,0 +1,12 @@
+Innolux G070Y2-L01 7" WVGA (800x480) TFT LCD panel
+
+Required properties:
+- compatible: should be "innolux,g070y2-l01"
+- power-supply: as specified in the base binding
+
+Optional properties:
+- backlight: as specified in the base binding
+- enable-gpios: as specified in the base binding
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index cbf1ab4..c030ab2 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1086,6 +1086,36 @@ static const struct panel_desc innolux_at070tn92 = {
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
};
+static const struct display_timing innolux_g070y2_l01_timing = {
+ .pixelclock = { 28000000, 29500000, 32000000 },
+ .hactive = { 800, 800, 800 },
+ .hfront_porch = { 61, 91, 141 },
+ .hback_porch = { 60, 90, 140 },
+ .hsync_len = { 12, 12, 12 },
+ .vactive = { 480, 480, 480 },
+ .vfront_porch = { 4, 9, 30 },
+ .vback_porch = { 4, 8, 28 },
+ .vsync_len = { 2, 2, 2 },
+ .flags = DISPLAY_FLAGS_DE_HIGH,
+};
+
+static const struct panel_desc innolux_g070y2_l01 = {
+ .timings = &innolux_g070y2_l01_timing,
+ .num_timings = 1,
+ .bpc = 6,
+ .size = {
+ .width = 152,
+ .height = 91,
+ },
+ .delay = {
+ .prepare = 10,
+ .enable = 100,
+ .disable = 100,
+ .unprepare = 800,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+};
+
static const struct display_timing innolux_g101ice_l01_timing = {
.pixelclock = { 60400000, 71100000, 74700000 },
.hactive = { 1280, 1280, 1280 },
@@ -2155,10 +2185,13 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "innolux,at070tn92",
.data = &innolux_at070tn92,
}, {
- .compatible ="innolux,g101ice-l01",
+ .compatible = "innolux,g070y2-l01",
+ .data = &innolux_g070y2_l01,
+ }, {
+ .compatible = "innolux,g101ice-l01",
.data = &innolux_g101ice_l01
}, {
- .compatible ="innolux,g121i1-l01",
+ .compatible = "innolux,g121i1-l01",
.data = &innolux_g121i1_l01
}, {
.compatible = "innolux,g121x1-l03",
--
2.1.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* Re: [PATCH v4 01/10] i3c: Add core I3C infrastructure
From: Boris Brezillon @ 2018-06-04 11:24 UTC (permalink / raw)
To: Przemyslaw Gaj
Cc: Wolfram Sang, linux-i2c@vger.kernel.org, Jonathan Corbet,
linux-doc@vger.kernel.org, Greg Kroah-Hartman, Arnd Bergmann,
Przemyslaw Sroka, Arkadiusz Golec, Alan Douglas, Bartosz Folta,
Damian Kos, Alicja Jurasik-Urbaniak, Cyprian Wronka,
Suresh Punnoose, Rafal Ciepiela, Thomas Petazzoni, Nishanth Menon,
Rob Herring, Pawel Moll, Mark
In-Reply-To: <EFF070CA-9C6C-4E9C-9CEF-45AAD02745BB@cadence.com>
On Mon, 4 Jun 2018 09:11:25 +0000
Przemyslaw Gaj <pgaj@cadence.com> wrote:
> Hi Boris
>
> It looks great, just one comment to DEFSLVS command:
>
> On 6/4/18, 9:32 AM, "Boris Brezillon" <boris.brezillon@bootlin.com> wrote:
>
> +int i3c_master_defslvs_locked(struct i3c_master_controller *master)
> +{
> + struct i3c_ccc_cmd_dest dest = {
> + .addr = I3C_BROADCAST_ADDR,
> + };
> + struct i3c_ccc_cmd cmd = {
> + .id = I3C_CCC_DEFSLVS,
> + .dests = &dest,
> + .ndests = 1,
> + };
> + struct i3c_ccc_defslvs *defslvs;
> + struct i3c_ccc_dev_desc *desc;
> + struct i3c_device *i3cdev;
> + struct i2c_device *i2cdev;
> + struct i3c_bus *bus;
> + bool send = false;
> + int ndevs = 0, ret;
> +
> + if (!master)
> + return -EINVAL;
> +
> + bus = i3c_master_get_bus(master);
> + i3c_bus_for_each_i3cdev(bus, i3cdev) {
> + ndevs++;
> + if (I3C_BCR_DEVICE_ROLE(i3cdev->info.bcr) == I3C_BCR_I3C_MASTER)
> + send = true;
> + }
> +
> + /* No other master on the bus, skip DEFSLVS. */
> + if (!send)
> + return 0;
> +
> + i3c_bus_for_each_i2cdev(bus, i2cdev)
> + ndevs++;
> +
> + dest.payload.len = sizeof(*defslvs) +
> + ((ndevs - 1) * sizeof(struct i3c_ccc_dev_desc));
> + defslvs = kzalloc(dest.payload.len, GFP_KERNEL);
> + if (!defslvs)
> + return -ENOMEM;
> +
> + dest.payload.data = defslvs;
> +
> + defslvs->count = ndevs;
> + defslvs->master.bcr = master->this->info.bcr;
> + defslvs->master.dcr = master->this->info.dcr;
> + defslvs->master.dyn_addr = master->this->info.dyn_addr;
> + defslvs->master.static_addr = I3C_BROADCAST_ADDR;
> +
> + desc = defslvs->slaves;
> + i3c_bus_for_each_i2cdev(bus, i2cdev) {
> + desc->lvr = i2cdev->lvr;
> + desc->static_addr = i2cdev->info.addr;
> + desc++;
> + }
> +
> + i3c_bus_for_each_i3cdev(bus, i3cdev) {
> + /* Skip the I3C dev representing this master. */
> + if (i3cdev == master->this)
> + continue;
> +
> + desc->bcr = i3cdev->info.bcr;
> + desc->dcr = i3cdev->info.dcr;
> + desc->dyn_addr = i3cdev->info.dyn_addr;
> + desc->static_addr = i3cdev->info.static_addr;
> + desc++;
> + }
> +
> + ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
> + kfree(defslvs);
> +
> + return ret;
> +}
>
> You should shift all the addresses (dynamic and static) one bit left.
> Addresses are stored on bits [7:1], this is described in MIPI spec,
> section 5.1.9.3.7 Define List of Slaves (DEFSLVS)
Oops, indeed. I will fix that.
Thanks,
Boris
^ permalink raw reply
* Re: [PATCH v4 07/10] i3c: master: Add driver for Cadence IP
From: Boris Brezillon @ 2018-06-04 11:26 UTC (permalink / raw)
To: Przemyslaw Gaj
Cc: Wolfram Sang, linux-i2c@vger.kernel.org, Jonathan Corbet,
linux-doc@vger.kernel.org, Greg Kroah-Hartman, Arnd Bergmann,
Przemyslaw Sroka, Arkadiusz Golec, Alan Douglas, Bartosz Folta,
Damian Kos, Alicja Jurasik-Urbaniak, Cyprian Wronka,
Suresh Punnoose, Rafal Ciepiela, Thomas Petazzoni, Nishanth Menon,
Rob Herring, Pawel Moll, Mark
In-Reply-To: <9613475C-ECAE-4AD6-9C02-55C9214A6489@cadence.com>
Hi Przemek,
On Mon, 4 Jun 2018 09:24:51 +0000
Przemyslaw Gaj <pgaj@cadence.com> wrote:
> Hi Boris,
>
> Few things regarding Cadence IP driver:
>
> On 6/4/18, 9:31 AM, "Boris Brezillon" <boris.brezillon@bootlin.com> wrote:
>
> +static void cdns_i3c_master_handle_ibi(struct cdns_i3c_master *master,
> + u32 ibir)
> +{
> + struct cdns_i3c_i2c_dev_data *data;
> + bool data_consumed = false;
> + struct i3c_ibi_slot *slot;
> + u32 id = IBIR_SLVID(ibir);
> + struct i3c_device *dev;
> + int len, i, j;
> + u8 *buf;
> +
> + /*
> + * FIXME: maybe we should report the FIFO OVF errors to the upper
> + * layer.
> + */
> + if (id >= master->ibi.num_slots || (ibir & IBIR_ERROR))
> + goto out;
> +
> + dev = master->ibi.slots[id];
> + spin_lock(&master->ibi.lock);
> +
> + data = i3c_device_get_master_data(dev);
> + slot = i3c_generic_ibi_get_free_slot(data->ibi_pool);
> + if (!slot)
> + goto out_unlock;
> +
> + buf = slot->data;
> +
> + len = IBIR_XFER_BYTES(ibir);
> + for (i = 0; i < IBIR_XFER_BYTES(ibir); i += 4) {
> + u32 tmp = readl(master->regs + IBI_DATA_FIFO);
> +
> + for (j = 0; j < 4 && i + j < dev->ibi->max_payload_len; j++)
> + buf[i + j] = tmp >> (j * 8);
> +
> + }
> + slot->len = min_t(unsigned int, IBIR_XFER_BYTES(ibir),
> + dev->ibi->max_payload_len);
> + i3c_master_queue_ibi(dev, slot);
> + data_consumed = true;
> +
> +out_unlock:
> + spin_unlock(&master->ibi.lock);
> +
> +out:
> + /* Consume data from the FIFO if it's not been done already. */
> + if (!data_consumed) {
> + for (i = 0; i < IBIR_XFER_BYTES(ibir); i += 4)
> + readl(master->regs + IBI_DATA_FIFO);
> + }
> +}
>
> len variable is unneeded.
Will get rid of len.
> +
> + /* Device ID0 is reserved to describe this master. */
> + master->maxdevs = CONF_STATUS0_DEVS_NUM(val);
> + master->free_rr_slots = GENMASK(master->maxdevs, 1);
> +
> + val = readl(master->regs + CONF_STATUS1);
> + master->caps.cmdfifodepth = CONF_STATUS1_CMD_DEPTH(val);
> + master->caps.rxfifodepth = CONF_STATUS1_RX_DEPTH(val);
> + master->caps.txfifodepth = CONF_STATUS1_TX_DEPTH(val);
> + master->caps.ibirfifodepth = 16;
>
> IBI fifo depth is hardcoded. You can read this value from CONF_STATUS0 register.
>
> + master->caps.cmdrfifodepth = 16;
>
> CMDR fifo depth is hardcoded. You can read this value from CONF_STATUS0 register also.
Sure, I'll use the FIFO depth exposed in CONF_STATUS0.
Thanks,
Boris
^ permalink raw reply
* Re: [PATCH v4 2/6] mfd: bd71837: Devicetree bindings for ROHM BD71837 PMIC
From: Matti Vaittinen @ 2018-06-04 11:32 UTC (permalink / raw)
To: Rob Herring
Cc: Matti Vaittinen, Matti Vaittinen, Michael Turquette, Stephen Boyd,
Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown, linux-clk,
devicetree, linux-kernel@vger.kernel.org, mikko.mutanen,
heikki.haikola
In-Reply-To: <CAL_JsqJNMxR=zdwR41iLfWU=u3J_=_VkxVL+g3a12_4vvNwBtw@mail.gmail.com>
On Fri, Jun 01, 2018 at 12:32:16PM -0500, Rob Herring wrote:
> On Fri, Jun 1, 2018 at 1:25 AM, Matti Vaittinen
> <mazziesaccount@gmail.com> wrote:
> > On Thu, May 31, 2018 at 09:07:24AM -0500, Rob Herring wrote:
> >> On Thu, May 31, 2018 at 5:23 AM, Matti Vaittinen
> >> <mazziesaccount@gmail.com> wrote:
> >> > On Thu, May 31, 2018 at 10:17:17AM +0300, Matti Vaittinen wrote:
> >> >> On Wed, May 30, 2018 at 10:01:29PM -0500, Rob Herring wrote:
> >> >> > On Wed, May 30, 2018 at 11:42:03AM +0300, Matti Vaittinen wrote:
> >> >> > > Document devicetree bindings for ROHM BD71837 PMIC MFD.
> >> >> > > + - interrupts : The interrupt line the device is connected to.
> >> >> > > + - interrupt-controller : Marks the device node as an interrupt controller.
> >> >> >
> >> >> > What sub blocks have interrupts?
> >> >>
> >> >> The PMIC can generate interrupts from events which cause it to reset.
> >> >> Eg, irq from watchdog line change, power button pushes, reset request
> >> >> via register interface etc. I don't know any generic handling for these
> >> >> interrupts. In "normal" use-case this PMIC is powering the processor
> >> >> where driver is running and I do not see reasonable handling because
> >> >> power-reset is going to follow the irq.
> >> >>
> >> >
> >> > Oh, but when reading this I understand that the interrupt-controller
> >> > property should at least be optional.
> >>
> >> I don't think it should. The h/w either has an interrupt controller or
> >> it doesn't.
> >
> > I hope this explains why I did this interrupt controller - please tell
> > me if this is legitimate use-case and what you think of following:
> >
> > +Optional properties:
> > + - interrupt-controller : Marks the device node as an interrupt controller.
> > + BD71837MWV can report different power state change
> > + events to other devices. Different events can be seen
> > + as separate BD71837 domain interrupts.
>
> To what other devices?
Would it be better if I wrote "other drivers" instead? I think I've seen
examples where MFD driver is just providing the interrupts for other
drivers - like power-button input driver. Currently I have no such "irq
consumer" drivers written. Still I would like to expose these interrupts
so that they are ready for using if any platform using PMIC needs them.
I think there are other similar drivers in tree. For example TPS6591x
driver seems to be doing this. (Has MFD driver exposing the interrupts
but no driver handling those). Maybe explanation like this would help:
"The BD71837 driver only provides the infrastructure for the IRQs. The
users can write his own driver to convert the IRQ into the event they
wish. The IRQ can be used with the standard
request_irq/enable_irq/disable_irq API inside the kernel." (I found this
text from NXP forums and ruthlessly copied and modified it over here)
If this is not feasible, then I will remove the irq handling from MFD
(or leave code there but remove the binding information?) as I don't
know what the irq handles should do in generic case.
>
> > + - #interrupt-cells : The number of cells to describe an IRQ should be 1.
> > + The first cell is the IRQ number.
> > + masks from ../interrupt-controller/interrupts.txt.
Sorry this "masks from ../interrupt-controller/interrupts.txt." was
accidentally pasted here. I should have deleted it.
> I'm still not clear. Generally in a PMIC, you'd define an interrupt
> controller when there's a common set of registers to manage sub-block
> interrupts (typical mask/unmask, ack regs) and the subblocks
> themselves have control of masking/unmasking interrupts. If there's
> not a need to have these 2 levels of interrupt handling, then you
> don't really need to define an interrupt controller.
And to clarify - the PMIC can generate irq via one irq line. This is
typical ACTIVE_LOW irq with 8 bit "write 1 to clear" status register and
8 bit mask register. The role of interrupt-controller code here is just
to allow these 8 irq reasons to be seen as individual BD71837 domain
interrupts. I just don't have the driver(s) for handling these
interrupts.
> >> My concern is you added it but nothing uses it which tells
> >> me your binding is incomplete. I'd rather see complete bindings even
> >> if you don't have drivers.
> >
> > So this makes me wonder if my use-case for interrupt controller is
> > valid. I thought making this PMIC as interrupt controller is a nice way
> > of hiding the irq register and i2c access from other potential drivers
> > using these interrupts. But as I don't know what could be the potential
> > user for these irqs, I don't know how to complete binding. This is why I
> > also thought of making this optional, so that the potential for using
> > the interrupts would be there but it was not required when interrupts
> > are not needed.
>
> The only drivers getting these interrupts would be drivers for this
> PMIC. Interrupts are handled by the driver owning the h/w that
> generated the interrupt. I think that is the disconnect here.
>
> Take a power button. We don't create a generic power button interrupt
> and then have some generic power button interrupt handler. We have a
> handler for specifically for that device and then it generates a power
> button press event.
I think I understand this. Here we also have a 'power button' interrupt
from PMIC (as one of the interrupts) here. But what happens when button
is pressed depends on PMIC configuration. I guess we might want a power
button driver here - and this power button driver might be correct user
for the irq. So are you stating that I should write the power button
driver (or some other "IRQ consumer") before adding the
interrupt-controller property to bindings for MFD? Or should I just
somehow state that irq X in BD71837 is a "power button short push"
event and power button driver should be the consumer for it?
Rest of the interrupts are not so obvious. I have no idea how I should
handle rest of the interrupts. Those are interrupts which cause the PMIC
to reset and cut the powers from most of the regulators too. I can
easily think setup where one processor is controlling PMIC which powers
for the other processor. And getting IRQ if for example watchdog reset
the other processor would probably be very usefull. But doing any
'de-facto' handler for this is hard. Only generally usefull thing would
be notifying the user-space but I don't think I should invent any new
kernelspace - userspace interfaces for this. I believe that when such
are needed those should be implemented by ones knowing the platform.
So please bear with me but do you mean I should
a) document what conditions generate which IRQ
or
b) should I tell what kind of driver is needed for handling the IRQs
or
c) should I first write code using IRQs before addinf MFD binding?
a) I can do.
b) I think I can't do this for most of the irqs as in normal use-case
the processor won't catch these as it is going to be powered down.
c) I might be able to do this for power button IRQ but it might not be
what user wants in the end.
> >> My concern is you added it but nothing uses it which tells
> >> me your binding is incomplete. I'd rather see complete bindings even
> >> if you don't have drivers.
Can you please tell if I misunderstood this?
Br,
Matti Vaittinen
^ permalink raw reply
* Re: [PATCH 06/15] drm/sun4i: tcon: Add support for tcon-top
From: Maxime Ripard @ 2018-06-04 11:50 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Jernej Škrabec, Rob Herring, Mark Rutland, dri-devel,
devicetree, linux-arm-kernel, linux-kernel, linux-clk,
linux-sunxi
In-Reply-To: <CAGb2v667pdjfHXYpBk1ER5sC8vgpcaOFKEbEByWoD1zh9Z0cyg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 13141 bytes --]
On Fri, Jun 01, 2018 at 09:19:43AM -0700, Chen-Yu Tsai wrote:
> On Fri, Jun 1, 2018 at 8:29 AM, Maxime Ripard <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org> wrote:
> > On Thu, May 31, 2018 at 07:54:08PM +0200, Jernej Škrabec wrote:
> >> Dne četrtek, 31. maj 2018 ob 11:21:33 CEST je Maxime Ripard napisal(a):
> >> > On Thu, May 24, 2018 at 03:01:09PM -0700, Chen-Yu Tsai wrote:
> >> > > >> > > + if (tcon->quirks->needs_tcon_top) {
> >> > > >> > > + struct device_node *np;
> >> > > >> > > +
> >> > > >> > > + np = of_parse_phandle(dev->of_node, "allwinner,tcon-top",
> >> > > >> > > 0);
> >> > > >> > > + if (np) {
> >> > > >> > > + struct platform_device *pdev;
> >> > > >> > > +
> >> > > >> > > + pdev = of_find_device_by_node(np);
> >> > > >> > > + if (pdev)
> >> > > >> > > + tcon->tcon_top =
> >> > > >> > > platform_get_drvdata(pdev);
> >> > > >> > > + of_node_put(np);
> >> > > >> > > +
> >> > > >> > > + if (!tcon->tcon_top)
> >> > > >> > > + return -EPROBE_DEFER;
> >> > > >> > > + }
> >> > > >> > > + }
> >> > > >> > > +
> >> > > >> >
> >> > > >> > I might have missed it, but I've not seen the bindings additions for
> >> > > >> > that property. This shouldn't really be done that way anyway, instead
> >> > > >> > of using a direct phandle, you should be using the of-graph, with the
> >> > > >> > TCON-top sitting where it belongs in the flow of data.
> >> > > >>
> >> > > >> Just to answer to the first question, it did describe it in "[PATCH
> >> > > >> 07/15] dt- bindings: display: sun4i-drm: Add R40 HDMI pipeline".
> >> > > >>
> >> > > >> As why I designed it that way - HW representation could be described
> >> > > >> that way> >>
> >> > > >> (ASCII art makes sense when fixed width font is used to view it):
> >> > > >> / LCD0/LVDS0
> >> > > >>
> >> > > >> / TCON-LCD0
> >> > > >>
> >> > > >> | \ MIPI DSI
> >> > > >>
> >> > > >> mixer0 |
> >> > > >>
> >> > > >> \ / TCON-LCD1 - LCD1/LVDS1
> >> > > >>
> >> > > >> TCON-TOP
> >> > > >>
> >> > > >> / \ TCON-TV0 - TVE0/RGB
> >> > > >>
> >> > > >> mixer1 | \
> >> > > >>
> >> > > >> | TCON-TOP - HDMI
> >> > > >> |
> >> > > >> | /
> >> > > >>
> >> > > >> \ TCON-TV1 - TVE1/RGB
> >> > > >>
> >> > > >> This is a bit simplified, since there is also TVE-TOP, which is
> >> > > >> responsible
> >> > > >> for sharing 4 DACs between both TVE encoders. You can have two TV outs
> >> > > >> (PAL/ NTSC) or TVE0 as TV out and TVE1 as RGB or vice versa. It even
> >> > > >> seems that you can arbitrarly choose which DAC is responsible for
> >> > > >> which signal, so there is a ton of possible end combinations, but I'm
> >> > > >> not 100% sure.
> >> > > >>
> >> > > >> Even though I wrote TCON-TOP twice, this is same unit in HW. R40 manual
> >> > > >> suggest more possibilities, although some of them seem wrong, like RGB
> >> > > >> feeding from LCD TCON. That is confirmed to be wrong when checking BSP
> >> > > >> code.
> >> > > >>
> >> > > >> Additionally, TCON-TOP comes in the middle of TVE0 and LCD0, TVE1 and
> >> > > >> LCD1 for pin muxing, although I'm not sure why is that needed at all,
> >> > > >> since according to R40 datasheet, TVE0 and TVE1 pins are dedicated and
> >> > > >> not on PORT D and PORT H, respectively, as TCON-TOP documentation
> >> > > >> suggest. However, HSYNC and PSYNC lines might be shared between TVE
> >> > > >> (when it works in RGB mode) and LCD. But that is just my guess since
> >> > > >> I'm not really familiar with RGB and LCD interfaces.
> >> > > >>
> >> > > >> I'm really not sure what would be the best representation in OF-graph.
> >> > > >> Can you suggest one?
> >> > > >
> >> > > > Rob might disagree on this one, but I don't see anything wrong with
> >> > > > having loops in the graph. If the TCON-TOP can be both the input and
> >> > > > output of the TCONs, then so be it, and have it described that way in
> >> > > > the graph.
> >> > > >
> >> > > > The code is already able to filter out nodes that have already been
> >> > > > added to the list of devices we need to wait for in the component
> >> > > > framework, so that should work as well.
> >> > > >
> >> > > > And we'd need to describe TVE-TOP as well, even though we don't have a
> >> > > > driver for it yet. That will simplify the backward compatibility later
> >> > > > on.
> >> > >
> >> > > I'm getting the feeling that TCON-TOP / TVE-TOP is the glue layer that
> >> > > binds everything together, and provides signal routing, kind of like
> >> > > DE-TOP on A64. So the signal mux controls that were originally found
> >> > > in TCON0 and TVE0 were moved out.
> >> > >
> >> > > The driver needs to know about that, but the graph about doesn't make
> >> > > much sense directly. Without looking at the manual, I understand it to
> >> > > likely be one mux between the mixers and TCONs, and one between the
> >> > > TCON-TVs and HDMI. Would it make more sense to just have the graph
> >> > > connections between the muxed components, and remove TCON-TOP from
> >> > > it, like we had in the past? A phandle could be used to reference
> >> > > the TCON-TOP for mux controls, in addition to the clocks and resets.
> >> > >
> >> > > For TVE, we would need something to represent each of the output pins,
> >> > > so the device tree can actually describe what kind of signal, be it
> >> > > each component of RGB/YUV or composite video, is wanted on each pin,
> >> > > if any. This is also needed on the A20 for the Cubietruck, so we can
> >> > > describe which pins are tied to the VGA connector, and which one does
> >> > > R, G, or B.
> >> >
> >> > I guess we'll see how the DT maintainers feel about this, but my
> >> > impression is that the OF graph should model the flow of data between
> >> > the devices. If there's a mux somewhere, then the data is definitely
> >> > going through it, and as such it should be part of the graph.
> >>
> >> I concur, but I spent few days thinking how to represent this sanely in graph,
> >> but I didn't find any good solution. I'll represent here my idea and please
> >> tell your opinion before I start implementing it.
> >>
> >> First, let me be clear that mixer0 and mixer1 don't have same capabilities
> >> (different number of planes, mixer0 supports writeback, mixer1 does not,
> >> etc.). Thus, it does matter which mixer is connected to which TCON/encoder.
> >> mixer0 is meant to be connected to main display and mixer1 to auxiliary. That
> >> obviously depends on end system.
> >>
> >> So, TCON TOP has 3 muxes, which have to be represented in graph. Two of them
> >> are for mixer/TCON relationship (each of them 1 input and 4 possible outputs)
> >> and one for TV TCON/HDMI pair selection (2 possible inputs, 1 output).
> >>
> >> According to current practice in sun4i-drm driver, graph has to have port 0,
> >> representing input and port 1, representing output. This would mean that graph
> >> looks something like that:
> >>
> >> tcon_top: tcon-top@1c70000 {
> >> compatible = "allwinner,sun8i-r40-tcon-top";
> >> ...
> >> ports {
> >> #address-cells = <1>;
> >> #size-cells = <0>;
> >>
> >> tcon_top_in: port@0 {
> >> #address-cells = <1>;
> >> #size-cells = <0>;
> >> reg = <0>;
> >>
> >> tcon_top_in_mixer0: endpoint@0 {
> >> reg = <0>;
> >> remote-endpoint = <&mixer0_out_tcon_top>;
> >> };
> >>
> >> tcon_top_in_mixer1: endpoint@1 {
> >> reg = <1>;
> >> remote-endpoint = <&mixer1_out_tcon_top>;
> >> };
> >>
> >> tcon_top_in_tcon_tv: endpoint@2 {
> >> reg = <2>;
> >> // here is HDMI input connection, part of board DTS
> >> remote-endpoint = <board specific phandle to TV TCON output>;
> >> };
> >> };
> >>
> >> tcon_top_out: port@1 {
> >> #address-cells = <1>;
> >> #size-cells = <0>;
> >> reg = <1>;
> >>
> >> tcon_top_out_tcon0: endpoint@0 {
> >> reg = <0>;
> >> // here is mixer0 output connection, part of board DTS
> >> remote-endpoint = <board specific phandle to TCON>;
> >> };
> >>
> >> tcon_top_out_tcon1: endpoint@1 {
> >> reg = <1>;
> >> // here is mixer1 output connection, part of board DTS
> >> remote-endpoint = <board specific phandle to TCON>;
> >> };
> >>
> >> tcon_top_out_hdmi: endpoint@2 {
> >> reg = <2>;
> >> remote-endpoint = <&hdmi_in_tcon_top>;
> >> };
> >> };
> >> };
> >> };
> >
> > IIRC, each port is supposed to be one route for the data, so we would
> > have multiple ports, one for the mixers in input and for the tcon in
> > output, and one for the TCON in input and for the HDMI/TV in
> > output. Rob might correct me here.
> >
> >> tcon_tv0: lcd-controller@1c73000 {
> >> compatible = "allwinner,sun8i-r40-tcon-tv-0";
> >> ...
> >> ports {
> >> #address-cells = <1>;
> >> #size-cells = <0>;
> >>
> >> tcon_tv0_in: port@0 {
> >> reg = <0>;
> >>
> >> tcon_tv0_in_tcon_top: endpoint {
> >> // endpoint depends on board, part of board DTS
> >> remote-endpoint = <phandle to one of tcon_top_out_tcon>;
> >
> > Just curious, what would be there?
> >
> >> };
> >> };
> >>
> >> tcon_tv0_out: port@1 {
> >> #address-cells = <1>;
> >> #size-cells = <0>;
> >> reg = <1>;
> >>
> >> // endpoints to TV TOP and TCON TOP HDMI input
> >> ...
> >> };
> >> };
> >> };
> >>
> >> tcon_tv1: lcd-controller@1c74000 {
> >> compatible = "allwinner,sun8i-r40-tcon-tv-1";
> >> ...
> >> ports {
> >> #address-cells = <1>;
> >> #size-cells = <0>;
> >>
> >> tcon_tv1_in: port@0 {
> >> reg = <0>;
> >>
> >> tcon_tv1_in_tcon_top: endpoint {
> >> // endpoint depends on board, part of board DTS
> >> remote-endpoint = <phandle to one of tcon_top_out_tcon>;
> >> };
> >> };
> >>
> >> tcon_tv1_out: port@1 {
> >> #address-cells = <1>;
> >> #size-cells = <0>;
> >> reg = <1>;
> >>
> >> // endpoints to TV TOP and TCON TOP HDMI input
> >> ...
> >> };
> >> };
> >> };
> >>
> >> tcon_lcd0 and tcon_lcd1 would have similar connections, except that for
> >> outputs would be LCD or LVDS panels or MIPI DSI encoder.
> >>
> >> Please note that each TCON (there are 4 of them) would need to have unique
> >> compatible and have HW index stored in quirks data. It would be used by TCON
> >> TOP driver for configuring muxes.
> >
> > Can't we use the port/endpoint ID instead? If the mux is the only
> > thing that changes, the compatible has no reason to. It's the same IP,
> > and the only thing that changes is something that is not part of that
> > IP.
>
> I agree. Endpoint IDs should provide that information. I'm still not
> sure How to encode multiple in/out mux groups in a device node though.
I guess we can do that through different ports?
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v3 3/8] media: v4l2-fwnode: parse 'data-enable-active' prop
From: Niklas Söderlund @ 2018-06-04 12:08 UTC (permalink / raw)
To: Jacopo Mondi
Cc: devicetree, robh+dt, linux-renesas-soc, horms, hans.verkuil,
laurent.pinchart, sakari.ailus, geert, mchehab, linux-arm-kernel,
linux-media
In-Reply-To: <1527606359-19261-4-git-send-email-jacopo+renesas@jmondi.org>
Hi Jacopo,
Thanks for your patch.
On 2018-05-29 17:05:54 +0200, Jacopo Mondi wrote:
> Parse the newly defined 'data-enable-active' property in parallel endpoint
> parsing function.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
>
> ---
> v3:
> - new patch
> ---
> drivers/media/v4l2-core/v4l2-fwnode.c | 4 ++++
> include/media/v4l2-mediabus.h | 2 ++
> 2 files changed, 6 insertions(+)
>
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
> index 3f77aa3..6105191 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -154,6 +154,10 @@ static void v4l2_fwnode_endpoint_parse_parallel_bus(
> flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
> V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
>
> + if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v))
> + flags |= v ? V4L2_MBUS_DATA_ENABLE_HIGH :
> + V4L2_MBUS_DATA_ENABLE_LOW;
> +
> bus->flags = flags;
>
> }
> diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
> index 4d8626c..4bbb5f3 100644
> --- a/include/media/v4l2-mediabus.h
> +++ b/include/media/v4l2-mediabus.h
> @@ -45,6 +45,8 @@
> /* Active state of Sync-on-green (SoG) signal, 0/1 for LOW/HIGH respectively. */
> #define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH BIT(12)
> #define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW BIT(13)
> +#define V4L2_MBUS_DATA_ENABLE_HIGH BIT(14)
> +#define V4L2_MBUS_DATA_ENABLE_LOW BIT(15)
>
> /* Serial flags */
> /* How many lanes the client can use */
> --
> 2.7.4
>
--
Regards,
Niklas Söderlund
^ permalink raw reply
* Re: [PATCH v3 4/8] dt-bindings: media: rcar-vin: Add 'data-enable-active'
From: Niklas Söderlund @ 2018-06-04 12:10 UTC (permalink / raw)
To: Jacopo Mondi
Cc: devicetree, robh+dt, linux-renesas-soc, horms, hans.verkuil,
laurent.pinchart, sakari.ailus, geert, mchehab, linux-arm-kernel,
linux-media
In-Reply-To: <1527606359-19261-5-git-send-email-jacopo+renesas@jmondi.org>
Hi Jacopo,
Thanks for your patch.
On 2018-05-29 17:05:55 +0200, Jacopo Mondi wrote:
> Describe optional endpoint property 'data-enable-active' for R-Car VIN.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
> v3:
> - new patch
> ---
>
> Documentation/devicetree/bindings/media/rcar_vin.txt | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
> index 4d91a36..ff53226 100644
> --- a/Documentation/devicetree/bindings/media/rcar_vin.txt
> +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
> @@ -58,6 +58,8 @@ from local SoC CSI-2 receivers (port1) depending on SoC.
> - Optional properties for endpoint nodes of port@0:
> - hsync-active: see [1] for description. Default is active high.
> - vsync-active: see [1] for description. Default is active high.
> + - data-enable-active: polarity of CLKENB signal, see [1] for
> + description. Default is active high.
>
> If both HSYNC and VSYNC polarities are not specified, embedded
> synchronization is selected.
> --
> 2.7.4
>
--
Regards,
Niklas Söderlund
^ permalink raw reply
* Re: [PATCH v3 5/8] media: rcar-vin: Handle data-enable polarity
From: Niklas Söderlund @ 2018-06-04 12:13 UTC (permalink / raw)
To: Jacopo Mondi
Cc: devicetree, robh+dt, linux-renesas-soc, horms, hans.verkuil,
laurent.pinchart, sakari.ailus, geert, mchehab, linux-arm-kernel,
linux-media
In-Reply-To: <1527606359-19261-6-git-send-email-jacopo+renesas@jmondi.org>
Hi Jacopo,
Thanks for your work.
On 2018-05-29 17:05:56 +0200, Jacopo Mondi wrote:
> Handle data-enable signal polarity. If the polarity is not specifically
> requested to be active low, use the active high default.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
> v3:
> - use new property to set the CES bit
> ---
> drivers/media/platform/rcar-vin/rcar-dma.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
> index d2b7002..9145b56 100644
> --- a/drivers/media/platform/rcar-vin/rcar-dma.c
> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c
> @@ -123,6 +123,7 @@
> /* Video n Data Mode Register 2 bits */
> #define VNDMR2_VPS (1 << 30)
> #define VNDMR2_HPS (1 << 29)
> +#define VNDMR2_CES (1 << 28)
> #define VNDMR2_FTEV (1 << 17)
> #define VNDMR2_VLV(n) ((n & 0xf) << 12)
>
> @@ -698,6 +699,10 @@ static int rvin_setup(struct rvin_dev *vin)
> /* Vsync Signal Polarity Select */
> if (!(vin->parallel->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
> dmr2 |= VNDMR2_VPS;
> +
> + /* Data Enable Polarity Select */
> + if (vin->parallel->mbus_flags & V4L2_MBUS_DATA_ENABLE_LOW)
> + dmr2 |= VNDMR2_CES;
> }
>
> /*
> --
> 2.7.4
>
--
Regards,
Niklas Söderlund
^ permalink raw reply
* Re: [RFC v2 2/2] dt-bindings: mipi-dsi: Add dual-channel DSI related info
From: Heiko Stuebner @ 2018-06-04 12:17 UTC (permalink / raw)
To: dri-devel
Cc: devicetree, boris.brezillon, linux-arm-msm, tomi.valkeinen,
briannorris, philippe.cornu, nickey.yang, robh+dt, thierry.reding,
laurent.pinchart, maxime.ripard
In-Reply-To: <20180118045355.8858-3-architt@codeaurora.org>
Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> Add binding info for peripherals that support dual-channel DSI. Add
> corresponding optional bindings for DSI host controllers that may
> be configured in this mode. Add an example of an I2C controlled
> device operating in dual-channel DSI mode.
>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
Looks like a great solution for that problem, so
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
As I'm looking into that for my rk3399-scarlet device right now and
couldn't find this patchset in the kernel yet, is it planned to
merge or refresh these binding changes or were problems encountered.
At least an Ack/Review from Rob seems to be missing.
Heiko
> ---
> v2:
> - Specify that clock-master is a boolean property.
> - Drop/add unit-address and #*-cells where applicable.
>
> .../devicetree/bindings/display/mipi-dsi-bus.txt | 80 ++++++++++++++++++++++
> 1 file changed, 80 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> index 94fb72cb916f..7a3abbedb3fa 100644
> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> @@ -29,6 +29,13 @@ Required properties:
> - #size-cells: Should be 0. There are cases where it makes sense to use a
> different value here. See below.
>
> +Optional properties:
> +- clock-master: boolean. Should be enabled if the host is being used in
> + conjunction with another DSI host to drive the same peripheral. Hardware
> + supporting such a configuration generally requires the data on both the busses
> + to be driven by the same clock. Only the DSI host instance controlling this
> + clock should contain this property.
> +
> DSI peripheral
> ==============
>
> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI bus (mostly for the data
> path). Connections between such peripherals and a DSI host can be represented
> using the graph bindings [1], [2].
>
> +Peripherals that support dual channel DSI
> +-----------------------------------------
> +
> +Peripherals with higher bandwidth requirements can be connected to 2 DSI
> +busses. Each DSI bus/channel drives some portion of the pixel data (generally
> +left/right half of each line of the display, or even/odd lines of the display).
> +The graph bindings should be used to represent the multiple DSI busses that are
> +connected to this peripheral. Each DSI host's output endpoint can be linked to
> +an input endpoint of the DSI peripheral.
> +
> [1] Documentation/devicetree/bindings/graph.txt
> [2] Documentation/devicetree/bindings/media/video-interfaces.txt
>
> @@ -71,6 +88,8 @@ Examples
> with different virtual channel configurations.
> - (4) is an example of a peripheral on a I2C control bus connected with to
> a DSI host using of-graph bindings.
> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI peripheral,
> + which uses I2C as its primary control bus.
>
> 1)
> dsi-host {
> @@ -153,3 +172,64 @@ Examples
> };
> };
> };
> +
> +5)
> + i2c-host {
> + dsi-bridge@35 {
> + compatible = "...";
> + reg = <0x35>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> + dsi0_in: endpoint {
> + remote-endpoint = <&dsi0_out>;
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> + dsi1_in: endpoint {
> + remote-endpoint = <&dsi1_out>;
> + };
> + };
> + };
> + };
> + };
> +
> + dsi0-host {
> + ...
> +
> + /*
> + * this DSI instance drives the clock for both the host
> + * controllers
> + */
> + clock-master;
> +
> + ports {
> + ...
> +
> + port {
> + dsi0_out: endpoint {
> + remote-endpoint = <&dsi0_in>;
> + };
> + };
> + };
> + };
> +
> + dsi1-host {
> + ...
> +
> + ports {
> + ...
> +
> + port {
> + dsi1_out: endpoint {
> + remote-endpoint = <&dsi1_in>;
> + };
> + };
> + };
> + };
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v3 6/8] dt-bindings: rcar-vin: Add 'hsync-as-de' custom prop
From: Niklas Söderlund @ 2018-06-04 12:19 UTC (permalink / raw)
To: Jacopo Mondi
Cc: devicetree, robh+dt, linux-renesas-soc, horms, hans.verkuil,
laurent.pinchart, sakari.ailus, geert, mchehab, linux-arm-kernel,
linux-media
In-Reply-To: <1527606359-19261-7-git-send-email-jacopo+renesas@jmondi.org>
Hi Jacopo,
Thanks for your work.
On 2018-05-29 17:05:57 +0200, Jacopo Mondi wrote:
> Document the boolean custom property 'renesas,hsync-as-de' that indicates
> that the HSYNC signal is internally used as data-enable, when the
> CLKENB signal is not connected.
>
> As this is a VIN specificity create a custom property specific to the R-Car
> VIN driver.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> v3:
> - new patch
> ---
> Documentation/devicetree/bindings/media/rcar_vin.txt | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
> index ff53226..024c109 100644
> --- a/Documentation/devicetree/bindings/media/rcar_vin.txt
> +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
> @@ -60,6 +60,9 @@ from local SoC CSI-2 receivers (port1) depending on SoC.
> - vsync-active: see [1] for description. Default is active high.
> - data-enable-active: polarity of CLKENB signal, see [1] for
> description. Default is active high.
> + - renesas,hsync-as-de: a boolean property to indicate that HSYNC signal
> + is internally used as data-enable when the CLKENB signal is
> + not available.
I'm not sure I like this, is there really a need to add a custom
property for this? The datasheet states that when the CLKENB pin is not
connected the driver should enable 'Clock Enable Hsync Select (CHS)'.
With the new generic property 'data-enable-active' which describes the
polarity of the CLKENB pin we also gain the knowledge if the CLKENB pin
is connected or not.
I propose we drop this custom property and instead let the driver check
if the CLKENB polarity is described or not and use that to determine if
CHS bit should be set or not. IMHO that is much simpler then having two
properties describing the same pin.
>
> If both HSYNC and VSYNC polarities are not specified, embedded
> synchronization is selected.
> --
> 2.7.4
>
--
Regards,
Niklas Söderlund
^ permalink raw reply
* Re: [PATCH v3 8/8] ARM: dts: rcar-gen2: Remove unused VIN properties
From: Niklas Söderlund @ 2018-06-04 12:23 UTC (permalink / raw)
To: Jacopo Mondi
Cc: devicetree, robh+dt, linux-renesas-soc, horms, hans.verkuil,
laurent.pinchart, sakari.ailus, geert, mchehab, linux-arm-kernel,
linux-media
In-Reply-To: <1527606359-19261-9-git-send-email-jacopo+renesas@jmondi.org>
Hi Jacopo,
Thanks for your work.
On 2018-05-29 17:05:59 +0200, Jacopo Mondi wrote:
> The 'bus-width' and 'pclk-sample' properties are not parsed by the VIN
> driver and only confuse users. Remove them in all Gen2 SoC that use
> them.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
The more I think about this the more I lean towards that this patch
should be dropped. The properties accurately describes the hardware and
I think there is value in that. That the driver currently don't parse or
make use of them don't in my view reduce there value. Maybe you should
break out this patch to a separate series?
> ---
> v3:
> - remove bus-width from dt-bindings example
> ---
> Documentation/devicetree/bindings/media/rcar_vin.txt | 1 -
> arch/arm/boot/dts/r8a7790-lager.dts | 3 ---
> arch/arm/boot/dts/r8a7791-koelsch.dts | 3 ---
> arch/arm/boot/dts/r8a7791-porter.dts | 1 -
> arch/arm/boot/dts/r8a7793-gose.dts | 3 ---
> arch/arm/boot/dts/r8a7794-alt.dts | 1 -
> arch/arm/boot/dts/r8a7794-silk.dts | 1 -
> 7 files changed, 13 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
> index 024c109..c6d7f60 100644
> --- a/Documentation/devicetree/bindings/media/rcar_vin.txt
> +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
> @@ -128,7 +128,6 @@ Board setup example for Gen2 platforms (vin1 composite video input)
>
> vin1ep0: endpoint {
> remote-endpoint = <&adv7180>;
> - bus-width = <8>;
> };
> };
> };
> diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
> index 092610e..9cdabfcf 100644
> --- a/arch/arm/boot/dts/r8a7790-lager.dts
> +++ b/arch/arm/boot/dts/r8a7790-lager.dts
> @@ -885,10 +885,8 @@
> port {
> vin0ep2: endpoint {
> remote-endpoint = <&adv7612_out>;
> - bus-width = <24>;
> hsync-active = <0>;
> vsync-active = <0>;
> - pclk-sample = <1>;
> data-active = <1>;
> };
> };
> @@ -904,7 +902,6 @@
> port {
> vin1ep0: endpoint {
> remote-endpoint = <&adv7180>;
> - bus-width = <8>;
> };
> };
> };
> diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
> index 8ab793d..033c9e3 100644
> --- a/arch/arm/boot/dts/r8a7791-koelsch.dts
> +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
> @@ -857,10 +857,8 @@
> port {
> vin0ep2: endpoint {
> remote-endpoint = <&adv7612_out>;
> - bus-width = <24>;
> hsync-active = <0>;
> vsync-active = <0>;
> - pclk-sample = <1>;
> data-active = <1>;
> };
> };
> @@ -875,7 +873,6 @@
> port {
> vin1ep: endpoint {
> remote-endpoint = <&adv7180>;
> - bus-width = <8>;
> };
> };
> };
> diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts
> index a01101b..c16e870 100644
> --- a/arch/arm/boot/dts/r8a7791-porter.dts
> +++ b/arch/arm/boot/dts/r8a7791-porter.dts
> @@ -388,7 +388,6 @@
> port {
> vin0ep: endpoint {
> remote-endpoint = <&adv7180>;
> - bus-width = <8>;
> };
> };
> };
> diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts
> index aa209f6..60aaddb 100644
> --- a/arch/arm/boot/dts/r8a7793-gose.dts
> +++ b/arch/arm/boot/dts/r8a7793-gose.dts
> @@ -765,10 +765,8 @@
> port {
> vin0ep2: endpoint {
> remote-endpoint = <&adv7612_out>;
> - bus-width = <24>;
> hsync-active = <0>;
> vsync-active = <0>;
> - pclk-sample = <1>;
> data-active = <1>;
> };
> };
> @@ -784,7 +782,6 @@
> port {
> vin1ep: endpoint {
> remote-endpoint = <&adv7180_out>;
> - bus-width = <8>;
> };
> };
> };
> diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
> index e170275..8ed7a71 100644
> --- a/arch/arm/boot/dts/r8a7794-alt.dts
> +++ b/arch/arm/boot/dts/r8a7794-alt.dts
> @@ -388,7 +388,6 @@
> port {
> vin0ep: endpoint {
> remote-endpoint = <&adv7180>;
> - bus-width = <8>;
> };
> };
> };
> diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts
> index 7808aae..6adfcd6 100644
> --- a/arch/arm/boot/dts/r8a7794-silk.dts
> +++ b/arch/arm/boot/dts/r8a7794-silk.dts
> @@ -477,7 +477,6 @@
> port {
> vin0ep: endpoint {
> remote-endpoint = <&adv7180>;
> - bus-width = <8>;
> };
> };
> };
> --
> 2.7.4
>
--
Regards,
Niklas Söderlund
^ permalink raw reply
* Re: [PATCH v2 2/5] media: venus: add a routine to set venus state
From: Tomasz Figa @ 2018-06-04 12:54 UTC (permalink / raw)
To: vgarodia, Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Mark Rutland, andy.gross, bjorn.andersson, Stanimir Varbanov,
Linux Media Mailing List, Linux Kernel Mailing List,
linux-arm-msm, linux-soc, devicetree, Alexandre Courbot
In-Reply-To: <20180601212117.GD11565@jcrouse-lnx.qualcomm.com>
Hi Jordan, Vikash,
On Sat, Jun 2, 2018 at 6:21 AM Jordan Crouse <jcrouse@codeaurora.org> wrote:
>
> On Sat, Jun 02, 2018 at 01:56:05AM +0530, Vikash Garodia wrote:
[snip]
> > +int venus_set_hw_state(enum tzbsp_video_state state, struct venus_core *core)
> > +{
> > + int ret;
> > + struct device *dev = core->dev;
>
> If you get rid of the log message as you should, you don't need this.
>
> > + void __iomem *reg_base = core->base;
> > +
> > + switch (state) {
> > + case TZBSP_VIDEO_SUSPEND:
> > + if (qcom_scm_is_available())
> > + ret = qcom_scm_set_remote_state(TZBSP_VIDEO_SUSPEND, 0);
> > + else
> > + writel_relaxed(1, reg_base + WRAPPER_A9SS_SW_RESET);
>
> You can just use core->base here and not bother making a local variable for it.
>
> > + break;
> > + case TZBSP_VIDEO_RESUME:
> > + if (qcom_scm_is_available())
> > + ret = qcom_scm_set_remote_state(TZBSP_VIDEO_RESUME, 0);
> > + else
> > + venus_reset_hw(core);
> > + break;
> > + default:
> > + dev_err(dev, "invalid state\n");
>
> state is a enum - you are highly unlikely to be calling it in your own code with
> a random value. It is smart to have the default, but you don't need the log
> message - that is just wasted space in the binary.
>
> > + break;
> > + }
>
> There are three paths in the switch statement that could end up with 'ret' being
> uninitialized here. Set it to 0 when you declare it.
Does this actually compile? The compiler should detect that ret is
used uninitialized. Setting it to 0 at declaration time actually
prevents compiler from doing that and makes it impossible to catch
cases when the ret should actually be non-zero, e.g. the invalid enum
value case.
Given that this function is supposed to substitute existing calls into
qcom_scm_set_remote_state(), why not just do something like this:
if (qcom_scm_is_available())
return qcom_scm_set_remote_state(state, 0);
switch (state) {
case TZBSP_VIDEO_SUSPEND:
writel_relaxed(1, reg_base + WRAPPER_A9SS_SW_RESET);
break;
case TZBSP_VIDEO_RESUME:
venus_reset_hw(core);
break;
}
return 0;
Best regards,
Tomasz
^ permalink raw reply
* Re: [PATCH v2 3/5] venus: add check to make scm calls
From: Tomasz Figa @ 2018-06-04 12:58 UTC (permalink / raw)
To: vgarodia
Cc: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring, Mark Rutland,
andy.gross, bjorn.andersson, Stanimir Varbanov,
Linux Media Mailing List, Linux Kernel Mailing List,
linux-arm-msm, linux-soc, devicetree, Alexandre Courbot
In-Reply-To: <1527884768-22392-4-git-send-email-vgarodia@codeaurora.org>
Hi Vikash,
On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote:
[snip]
> +int venus_boot(struct venus_core *core)
> +{
> + phys_addr_t mem_phys;
> + size_t mem_size;
> + int ret;
> + struct device *dev;
> +
> + if (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER))
> + return -EPROBE_DEFER;
Why are we deferring probe here? The option will not magically become
enabled after probe is retried.
Best regards,
Tomasz
^ permalink raw reply
* Re: [PATCH v6 6/9] dt-bindings: counter: Document stm32 quadrature encoder
From: Benjamin Gaignard @ 2018-06-04 13:03 UTC (permalink / raw)
To: Rob Herring
Cc: William Breathitt Gray, Mark Rutland, devicetree,
Benjamin Gaignard, linux-iio, linux-kernel@vger.kernel.org,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Fabrice Gasnier, Jonathan Cameron
In-Reply-To: <20180518162815.GA24966@rob-hp-laptop>
2018-05-18 18:28 GMT+02:00 Rob Herring <robh@kernel.org>:
> On Thu, May 17, 2018 at 08:59:40PM +0200, Benjamin Gaignard wrote:
>> 2018-05-17 18:23 GMT+02:00 Rob Herring <robh+dt@kernel.org>:
>> > On Wed, May 16, 2018 at 12:51 PM, William Breathitt Gray
>> > <vilhelm.gray@gmail.com> wrote:
>> >> From: Benjamin Gaignard <benjamin.gaignard@st.com>
>> >
>> > v6? Where's v1-v5?
>> >
>> >> Add bindings for STM32 Timer quadrature encoder.
>> >> It is a sub-node of STM32 Timer which implement the
>> >> counter part of the hardware.
>> >>
>> >> Cc: Rob Herring <robh+dt@kernel.org>
>> >> Cc: Mark Rutland <mark.rutland@arm.com>
>> >> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>> >> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
>> >> ---
>> >> .../bindings/counter/stm32-timer-cnt.txt | 26 +++++++++++++++++++
>> >> .../devicetree/bindings/mfd/stm32-timers.txt | 7 +++++
>> >> 2 files changed, 33 insertions(+)
>> >> create mode 100644 Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>> >>
>> >> diff --git a/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>> >> new file mode 100644
>> >> index 000000000000..377728128bef
>> >> --- /dev/null
>> >> +++ b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>> >> @@ -0,0 +1,26 @@
>> >> +STMicroelectronics STM32 Timer quadrature encoder
>> >> +
>> >> +STM32 Timer provides quadrature encoder counter mode to detect
>> >
>> > 'mode' does not sound like a sub-block of the timers block.
>>
>> quadrature encoding is one of the counting modes of this hardware
>> block which is enable to count on other signals/triggers
>
> You don't need a child node and compatible to set a mode.
"mode" isn't the good word here because quadratic encoder enable a
sub-block of this hardware.
Timer internal counter input could be internal or external clocks,
some IIO triggers
or the output of the quadratic encoder sub-block.
It is a child like pwm or IIO trigger.
>
>> >> +angular position and direction of rotary elements,
>> >> +from IN1 and IN2 input signals.
>> >> +
>> >> +Must be a sub-node of an STM32 Timer device tree node.
>> >> +See ../mfd/stm32-timers.txt for details about the parent node.
>> >> +
>> >> +Required properties:
>> >> +- compatible: Must be "st,stm32-timer-counter".
>> >> +- pinctrl-names: Set to "default".
>> >> +- pinctrl-0: List of phandles pointing to pin configuration nodes,
>> >> + to set IN1/IN2 pins in mode of operation for Low-Power
>> >> + Timer input on external pin.
>> >> +
>> >> +Example:
>> >> + timers@40010000 {
>> >> + compatible = "st,stm32-timers";
>> >> + ...
>> >> + counter {
>> >> + compatible = "st,stm32-timer-counter";
>> >
>> > Is there only 1? How is the counter addressed?
>>
>> Yes there is only one counter per hardware block.
>> Counter is addressed like the two others sub-nodes and the details
>> about parent mode are describe in stm32-timers.txt
>> Should I add them here too ? so example will be like that:
>
> No, you should drop the child node and add pinctrl to the parent.
>
> Any other functions this block has that you plan on adding? Please make
> bindings as complete as possible, not what you currently have drivers
> for.
Counter framework didn't exist when I pushed timer node but thanks to
William's effort
it will allow us to use this kindf of hardware
Benjamin
>
>> timers@40010000 {
>> #address-cells = <1>;
>> #size-cells = <0>;
>> compatible = "st,stm32-timers";
>> reg = <0x40010000 0x400>;
>> clocks = <&rcc 0 160>;
>> clock-names = "int";
>> counter {
>> compatible = "st,stm32-timer-counter";
>> pinctrl-names = "default";
>> pinctrl-0 = <&tim1_in_pins>;
>> };
>> };
>>
>> Benjamin
>> >
>> > _______________________________________________
>> > linux-arm-kernel mailing list
>> > linux-arm-kernel@lists.infradead.org
>> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Benjamin Gaignard
Graphic Study Group
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v2 4/5] media: venus: add no TZ boot and shutdown routine
From: Tomasz Figa @ 2018-06-04 13:09 UTC (permalink / raw)
To: vgarodia
Cc: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring, Mark Rutland,
andy.gross, bjorn.andersson, Stanimir Varbanov,
Linux Media Mailing List, Linux Kernel Mailing List,
linux-arm-msm, linux-soc, devicetree, Alexandre Courbot,
Will Deacon, Robin Murphy
In-Reply-To: <1527884768-22392-5-git-send-email-vgarodia@codeaurora.org>
Hi Vikash,
On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote:
[snip]
> +int venus_boot_noTZ(struct venus_core *core, phys_addr_t mem_phys,
> + size_t mem_size)
> +{
> + struct iommu_domain *iommu;
> + struct device *dev;
> + int ret;
> +
> + if (!core->fw.dev)
> + return -EPROBE_DEFER;
Is it really possible that the device appears after the probe is retried?
> +
> + dev = core->fw.dev;
> +
> + iommu = iommu_domain_alloc(&platform_bus_type);
> + if (!iommu) {
> + dev_err(dev, "Failed to allocate iommu domain\n");
> + return -ENOMEM;
> + }
> +
> + ret = iommu_attach_device(iommu, dev);
> + if (ret) {
> + dev_err(dev, "could not attach device\n");
> + goto err_attach;
> + }
> +
> + ret = iommu_map(iommu, VENUS_FW_START_ADDR, mem_phys, mem_size,
> + IOMMU_READ|IOMMU_WRITE|IOMMU_PRIV);
> + if (ret) {
> + dev_err(dev, "could not map video firmware region\n");
> + goto err_map;
> + }
I'm not very familiar with translation capabilities of ARM SMMU, so
that might be an elementary question, but could you explain how this
works? Will this make the firmware device (transfers with firmware
PASID) use different page directory from the main device (all the
other PASIDs; used with DMA mapping API)?
+Will and Robin, just in case.
> + core->fw.iommu_domain = iommu;
> + venus_reset_hw(core);
> +
> + return 0;
> +
> +err_map:
> + iommu_detach_device(iommu, dev);
> +err_attach:
> + iommu_domain_free(iommu);
> + return ret;
> +}
[snip]
> diff --git a/drivers/media/platform/qcom/venus/firmware.h b/drivers/media/platform/qcom/venus/firmware.h
> index 0916826..67fdd89 100644
> --- a/drivers/media/platform/qcom/venus/firmware.h
> +++ b/drivers/media/platform/qcom/venus/firmware.h
> @@ -14,10 +14,15 @@
> #ifndef __VENUS_FIRMWARE_H__
> #define __VENUS_FIRMWARE_H__
>
> +#define VENUS_PAS_ID 9
Shouldn't this normally be given in DT?
Best regards,
Tomasz
^ permalink raw reply
* [PATCH v5 0/4] mfd/regulator/clk: bd71837: ROHM BD71837 PMIC driver
From: Matti Vaittinen @ 2018-06-04 13:17 UTC (permalink / raw)
To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
broonie, mazziesaccount
Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
heikki.haikola
Patch series adding support for ROHM BD71837 PMIC.
BD71837 is a programmable Power Management IC for powering single-core,
dual-core, and quad-core SoC’s such as NXP-i.MX 8M. It is optimized for
low BOM cost and compact solution footprint. It integrates 8 buck
regulators and 7 LDO’s to provide all the power rails required by the
SoC and the commonly used peripherals.
The driver aims to not limit the usage of PMIC. Thus the buck and LDO
naming is generic and not tied to any specific purposes. However there
is following limitations which make it mostly suitable for use cases
where the processor where PMIC driver is running is powered by the PMIC:
- The PMIC is not re-initialized if it resets. PMIC may reset as a
result of voltage monitoring (over/under voltage) or due to reset
request. Driver is only initializing PMIC at probe. This is not
problem as long as processor controlling PMIC is powered by PMIC.
- The PMIC internal state machine is ignored by driver. Driver assumes
the PMIC is wired so that it is always in "run" state when controlled
by the driver.
Changelog v5
- dropped regulator patches which are already applied to Mark's tree
Based on feedback from Rob Herring and Stephen Boyd
- mfd bindings: explain why this can be interrupt-controller
- mfd bindings: describe interrupts better
- mfd bindings: require one cell interrupt specifier
- mfd bindings: use generic node names in example
- mfd driver: ack masked interrupt once at init
- clk bindings: use generic node names in example
- clk driver: use devm
- clk driver: use of_clk_add_hw_provider
- clk driver: change severity of print and how prints are emitted at
probe error path.
- clk driver: dropped forward declared functions
- clk configs: drop unnecessary dependencies
- clk driver: other styling issues
- mfd/clk DT: drop clk node.
Changelog v4
- remove mutex from regulator state check as core prevents simultaneous
accesses
- allow voltage change for bucks 1 to 4 when regulator is enabled
- fix indentiation problems
- properly correct SPDX comments
Changelog v3
- kill unused variable
- kill unused definitions
- use REGMAP_IRQ_REG
Changelog v2
Based on feedback from Mark Brown
- Squashed code and buildfile changes to same patch
- Fixed some styling issues
- Changed SPDX comments to CPP style
- Error out if voltage is changed when regulator is enabled instead of
Disabling the regulator for duration of change
- Use devm_regulator_register
- Remove compatible usage from regulators - use parent dev for config
- Add a note about using regulator-boot-on for BUCK6 and 7
- fixed warnings from kbuild test robot
patch 1:
MFD driver and definitions bringing interrupt support and
enabling clk and regulator subsystems.
Patches 2 and 3
This patch series is based on for-mfd-next
---
Matti Vaittinen (4):
mfd: bd71837: mfd driver for ROHM BD71837 PMIC
mfd: bd71837: Devicetree bindings for ROHM BD71837 PMIC
clk: bd71837: Devicetree bindings for ROHM BD71837 PMIC
clk: bd71837: Add driver for BD71837 PMIC clock
.../bindings/clock/rohm,bd71837-clock.txt | 38 +++
.../devicetree/bindings/mfd/rohm,bd71837-pmic.txt | 76 ++++++
drivers/clk/Kconfig | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-bd71837.c | 146 +++++++++++
drivers/mfd/Kconfig | 13 +
drivers/mfd/Makefile | 1 +
drivers/mfd/bd71837.c | 223 ++++++++++++++++
include/linux/mfd/bd71837.h | 288 +++++++++++++++++++++
9 files changed, 793 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/rohm,bd71837-clock.txt
create mode 100644 Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
create mode 100644 drivers/clk/clk-bd71837.c
create mode 100644 drivers/mfd/bd71837.c
create mode 100644 include/linux/mfd/bd71837.h
--
2.14.3
^ permalink raw reply
* [PATCH v5 1/4] mfd: bd71837: mfd driver for ROHM BD71837 PMIC
From: Matti Vaittinen @ 2018-06-04 13:18 UTC (permalink / raw)
To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
broonie, mazziesaccount
Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
heikki.haikola
In-Reply-To: <cover.1528117485.git.matti.vaittinen@fi.rohmeurope.com>
ROHM BD71837 PMIC MFD driver providing interrupts and support
for two subsystems:
- clk
- Regulators
Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
drivers/mfd/Kconfig | 13 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/bd71837.c | 223 ++++++++++++++++++++++++++++++++++
include/linux/mfd/bd71837.h | 288 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 525 insertions(+)
create mode 100644 drivers/mfd/bd71837.c
create mode 100644 include/linux/mfd/bd71837.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..7aa05fc9ed8e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1787,6 +1787,19 @@ config MFD_STW481X
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.
+config MFD_BD71837
+ bool "BD71837 Power Management chip"
+ depends on I2C=y
+ depends on OF
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ select MFD_CORE
+ help
+ Select this option to get support for the ROHM BD71837
+ Power Management chips. BD71837 is designed to power processors like
+ NXP i.MX8. It contains 8 BUCK outputs and 7 LDOs, voltage monitoring
+ and emergency shut down as well as 32,768KHz clock output.
+
config MFD_STM32_LPTIMER
tristate "Support for STM32 Low-Power Timer"
depends on (ARCH_STM32 && OF) || COMPILE_TEST
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e9fd20dba18d..09dc9eb3782c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -227,4 +227,5 @@ obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o
obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
+obj-$(CONFIG_MFD_BD71837) += bd71837.o
diff --git a/drivers/mfd/bd71837.c b/drivers/mfd/bd71837.c
new file mode 100644
index 000000000000..93930f1f2893
--- /dev/null
+++ b/drivers/mfd/bd71837.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 ROHM Semiconductors
+// bd71837.c -- ROHM BD71837MWV mfd driver
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/gpio.h>
+#include <linux/regmap.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/bd71837.h>
+
+/* bd71837 multi function cells */
+static struct mfd_cell bd71837_mfd_cells[] = {
+ {
+ .name = "bd71837-clk",
+ .of_compatible = "rohm,bd71837-clk",
+ }, {
+ .name = "bd71837-pmic",
+ },
+};
+
+static const struct regmap_irq bd71837_irqs[] = {
+ REGMAP_IRQ_REG(BD71837_INT_SWRST, 0, BD71837_INT_SWRST_MASK),
+ REGMAP_IRQ_REG(BD71837_INT_PWRBTN_S, 0, BD71837_INT_PWRBTN_S_MASK),
+ REGMAP_IRQ_REG(BD71837_INT_PWRBTN_L, 0, BD71837_INT_PWRBTN_L_MASK),
+ REGMAP_IRQ_REG(BD71837_INT_PWRBTN, 0, BD71837_INT_PWRBTN_MASK),
+ REGMAP_IRQ_REG(BD71837_INT_WDOG, 0, BD71837_INT_WDOG_MASK),
+ REGMAP_IRQ_REG(BD71837_INT_ON_REQ, 0, BD71837_INT_ON_REQ_MASK),
+ REGMAP_IRQ_REG(BD71837_INT_STBY_REQ, 0, BD71837_INT_STBY_REQ_MASK),
+};
+
+static struct regmap_irq_chip bd71837_irq_chip = {
+ .name = "bd71837-irq",
+ .irqs = bd71837_irqs,
+ .num_irqs = ARRAY_SIZE(bd71837_irqs),
+ .num_regs = 1,
+ .irq_reg_stride = 1,
+ .status_base = BD71837_REG_IRQ,
+ .mask_base = BD71837_REG_MIRQ,
+ .init_ack_masked = true,
+ .mask_invert = false,
+};
+
+static int bd71837_irq_exit(struct bd71837 *bd71837)
+{
+ if (bd71837->chip_irq > 0)
+ regmap_del_irq_chip(bd71837->chip_irq, bd71837->irq_data);
+ return 0;
+}
+
+static const struct regmap_range pmic_status_range = {
+ .range_min = BD71837_REG_IRQ,
+ .range_max = BD71837_REG_POW_STATE,
+};
+
+static const struct regmap_access_table volatile_regs = {
+ .yes_ranges = &pmic_status_range,
+ .n_yes_ranges = 1,
+};
+
+static const struct regmap_config bd71837_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_table = &volatile_regs,
+ .max_register = BD71837_MAX_REGISTER - 1,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id bd71837_of_match[] = {
+ { .compatible = "rohm,bd71837", .data = (void *)0},
+ { },
+};
+MODULE_DEVICE_TABLE(of, bd71837_of_match);
+
+static int bd71837_parse_dt(struct i2c_client *client, struct bd71837_board **b)
+{
+ struct device_node *np = client->dev.of_node;
+ struct bd71837_board *board_info;
+ unsigned int prop;
+ int r;
+ int rv = -ENOMEM;
+
+ board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
+ GFP_KERNEL);
+ if (!board_info)
+ goto err_out;
+
+ if (client->irq) {
+ dev_dbg(&client->dev, "Got irq %d\n", client->irq);
+ board_info->gpio_intr = client->irq;
+ } else {
+ dev_err(&client->dev, "no pmic intr pin available\n");
+ rv = -ENOENT;
+ goto err_intr;
+ }
+ r = of_property_read_u32(np, "irq_base", &prop);
+ if (!r)
+ board_info->irq_base = prop;
+ else
+ board_info->irq_base = 0;
+
+ rv = 0;
+ *b = board_info;
+ if (0) {
+err_intr:
+ devm_kfree(&client->dev, board_info);
+err_out:
+ dev_err(&client->dev, "failed to parse device-tree (%d)\n", rv);
+ }
+ return rv;
+}
+#endif //CONFIG_OF
+
+static int bd71837_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct bd71837 *bd71837;
+ struct bd71837_board *pmic_plat_data;
+ int ret = -EINVAL;
+
+ pmic_plat_data = dev_get_platdata(&i2c->dev);
+
+ if (!pmic_plat_data && i2c->dev.of_node)
+ ret = bd71837_parse_dt(i2c, &pmic_plat_data);
+
+ if (!pmic_plat_data)
+ return ret;
+
+ bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
+ if (bd71837 == NULL)
+ return -ENOMEM;
+
+ bd71837->of_plat_data = pmic_plat_data;
+ i2c_set_clientdata(i2c, bd71837);
+ bd71837->dev = &i2c->dev;
+ bd71837->i2c_client = i2c;
+ bd71837->chip_irq = pmic_plat_data->gpio_intr;
+
+ bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config);
+ if (IS_ERR(bd71837->regmap)) {
+ ret = PTR_ERR(bd71837->regmap);
+ dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
+ goto err_out;
+ }
+
+ ret = bd71837_reg_read(bd71837, BD71837_REG_REV);
+ if (ret < 0) {
+ dev_err(bd71837->dev,
+ "%s(): Read BD71837_REG_DEVICE failed!\n", __func__);
+ goto err_out;
+ }
+
+ ret = regmap_add_irq_chip(bd71837->regmap, bd71837->chip_irq,
+ IRQF_ONESHOT, 0,
+ &bd71837_irq_chip, &bd71837->irq_data);
+ if (ret < 0) {
+ dev_err(bd71837->dev, "Failed to add irq_chip %d\n", ret);
+ goto err_out;
+ }
+
+ ret = mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
+ bd71837_mfd_cells, ARRAY_SIZE(bd71837_mfd_cells),
+ NULL, 0,
+ regmap_irq_get_domain(bd71837->irq_data));
+ if (ret)
+ regmap_del_irq_chip(bd71837->chip_irq, bd71837->irq_data);
+err_out:
+
+ return ret;
+}
+
+static int bd71837_i2c_remove(struct i2c_client *i2c)
+{
+ struct bd71837 *bd71837 = i2c_get_clientdata(i2c);
+
+ bd71837_irq_exit(bd71837);
+ mfd_remove_devices(bd71837->dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id bd71837_i2c_id[] = {
+ { .name = "bd71837", },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bd71837_i2c_id);
+
+static struct i2c_driver bd71837_i2c_driver = {
+ .driver = {
+ .name = "bd71837-mfd",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(bd71837_of_match),
+ },
+ .probe = bd71837_i2c_probe,
+ .remove = bd71837_i2c_remove,
+ .id_table = bd71837_i2c_id,
+};
+
+static int __init bd71837_i2c_init(void)
+{
+ return i2c_add_driver(&bd71837_i2c_driver);
+}
+/* init early so consumer devices can complete system boot */
+subsys_initcall(bd71837_i2c_init);
+
+static void __exit bd71837_i2c_exit(void)
+{
+ i2c_del_driver(&bd71837_i2c_driver);
+}
+module_exit(bd71837_i2c_exit);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD71837 chip multi-function driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/bd71837.h b/include/linux/mfd/bd71837.h
new file mode 100644
index 000000000000..641b7dba3076
--- /dev/null
+++ b/include/linux/mfd/bd71837.h
@@ -0,0 +1,288 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 ROHM Semiconductors */
+
+/*
+ * ROHM BD71837MWV header file
+ */
+
+#ifndef __LINUX_MFD_BD71837_H__
+#define __LINUX_MFD_BD71837_H__
+
+#include <linux/regmap.h>
+
+enum {
+ BD71837_BUCK1 = 0,
+ BD71837_BUCK2,
+ BD71837_BUCK3,
+ BD71837_BUCK4,
+ BD71837_BUCK5,
+ BD71837_BUCK6,
+ BD71837_BUCK7,
+ BD71837_BUCK8,
+ BD71837_LDO1,
+ BD71837_LDO2,
+ BD71837_LDO3,
+ BD71837_LDO4,
+ BD71837_LDO5,
+ BD71837_LDO6,
+ BD71837_LDO7,
+ BD71837_REGULATOR_CNT,
+};
+
+#define BD71837_BUCK1_VOLTAGE_NUM 0x40
+#define BD71837_BUCK2_VOLTAGE_NUM 0x40
+#define BD71837_BUCK3_VOLTAGE_NUM 0x40
+#define BD71837_BUCK4_VOLTAGE_NUM 0x40
+
+#define BD71837_BUCK5_VOLTAGE_NUM 0x08
+#define BD71837_BUCK6_VOLTAGE_NUM 0x04
+#define BD71837_BUCK7_VOLTAGE_NUM 0x08
+#define BD71837_BUCK8_VOLTAGE_NUM 0x40
+
+#define BD71837_LDO1_VOLTAGE_NUM 0x04
+#define BD71837_LDO2_VOLTAGE_NUM 0x02
+#define BD71837_LDO3_VOLTAGE_NUM 0x10
+#define BD71837_LDO4_VOLTAGE_NUM 0x10
+#define BD71837_LDO5_VOLTAGE_NUM 0x10
+#define BD71837_LDO6_VOLTAGE_NUM 0x10
+#define BD71837_LDO7_VOLTAGE_NUM 0x10
+
+enum {
+ BD71837_REG_REV = 0x00,
+ BD71837_REG_SWRESET = 0x01,
+ BD71837_REG_I2C_DEV = 0x02,
+ BD71837_REG_PWRCTRL0 = 0x03,
+ BD71837_REG_PWRCTRL1 = 0x04,
+ BD71837_REG_BUCK1_CTRL = 0x05,
+ BD71837_REG_BUCK2_CTRL = 0x06,
+ BD71837_REG_BUCK3_CTRL = 0x07,
+ BD71837_REG_BUCK4_CTRL = 0x08,
+ BD71837_REG_BUCK5_CTRL = 0x09,
+ BD71837_REG_BUCK6_CTRL = 0x0A,
+ BD71837_REG_BUCK7_CTRL = 0x0B,
+ BD71837_REG_BUCK8_CTRL = 0x0C,
+ BD71837_REG_BUCK1_VOLT_RUN = 0x0D,
+ BD71837_REG_BUCK1_VOLT_IDLE = 0x0E,
+ BD71837_REG_BUCK1_VOLT_SUSP = 0x0F,
+ BD71837_REG_BUCK2_VOLT_RUN = 0x10,
+ BD71837_REG_BUCK2_VOLT_IDLE = 0x11,
+ BD71837_REG_BUCK3_VOLT_RUN = 0x12,
+ BD71837_REG_BUCK4_VOLT_RUN = 0x13,
+ BD71837_REG_BUCK5_VOLT = 0x14,
+ BD71837_REG_BUCK6_VOLT = 0x15,
+ BD71837_REG_BUCK7_VOLT = 0x16,
+ BD71837_REG_BUCK8_VOLT = 0x17,
+ BD71837_REG_LDO1_VOLT = 0x18,
+ BD71837_REG_LDO2_VOLT = 0x19,
+ BD71837_REG_LDO3_VOLT = 0x1A,
+ BD71837_REG_LDO4_VOLT = 0x1B,
+ BD71837_REG_LDO5_VOLT = 0x1C,
+ BD71837_REG_LDO6_VOLT = 0x1D,
+ BD71837_REG_LDO7_VOLT = 0x1E,
+ BD71837_REG_TRANS_COND0 = 0x1F,
+ BD71837_REG_TRANS_COND1 = 0x20,
+ BD71837_REG_VRFAULTEN = 0x21,
+ BD71837_REG_MVRFLTMASK0 = 0x22,
+ BD71837_REG_MVRFLTMASK1 = 0x23,
+ BD71837_REG_MVRFLTMASK2 = 0x24,
+ BD71837_REG_RCVCFG = 0x25,
+ BD71837_REG_RCVNUM = 0x26,
+ BD71837_REG_PWRONCONFIG0 = 0x27,
+ BD71837_REG_PWRONCONFIG1 = 0x28,
+ BD71837_REG_RESETSRC = 0x29,
+ BD71837_REG_MIRQ = 0x2A,
+ BD71837_REG_IRQ = 0x2B,
+ BD71837_REG_IN_MON = 0x2C,
+ BD71837_REG_POW_STATE = 0x2D,
+ BD71837_REG_OUT32K = 0x2E,
+ BD71837_REG_REGLOCK = 0x2F,
+ BD71837_REG_OTPVER = 0xFF,
+ BD71837_MAX_REGISTER = 0x100,
+};
+
+#define REGLOCK_PWRSEQ 0x1
+#define REGLOCK_VREG 0x10
+
+/* Generic BUCK control masks */
+#define BD71837_BUCK_SEL 0x02
+#define BD71837_BUCK_EN 0x01
+#define BD71837_BUCK_RUN_ON 0x04
+
+/* Generic LDO masks */
+#define BD71837_LDO_SEL 0x80
+#define BD71837_LDO_EN 0x40
+
+/* BD71837 BUCK ramp rate CTRL reg bits */
+#define BUCK_RAMPRATE_MASK 0xC0
+#define BUCK_RAMPRATE_10P00MV 0x0
+#define BUCK_RAMPRATE_5P00MV 0x1
+#define BUCK_RAMPRATE_2P50MV 0x2
+#define BUCK_RAMPRATE_1P25MV 0x3
+
+/* BD71837_REG_BUCK1_VOLT_RUN bits */
+#define BUCK1_RUN_MASK 0x3F
+#define BUCK1_RUN_DEFAULT 0x14
+
+/* BD71837_REG_BUCK1_VOLT_SUSP bits */
+#define BUCK1_SUSP_MASK 0x3F
+#define BUCK1_SUSP_DEFAULT 0x14
+
+/* BD71837_REG_BUCK1_VOLT_IDLE bits */
+#define BUCK1_IDLE_MASK 0x3F
+#define BUCK1_IDLE_DEFAULT 0x14
+
+/* BD71837_REG_BUCK2_VOLT_RUN bits */
+#define BUCK2_RUN_MASK 0x3F
+#define BUCK2_RUN_DEFAULT 0x1E
+
+/* BD71837_REG_BUCK2_VOLT_IDLE bits */
+#define BUCK2_IDLE_MASK 0x3F
+#define BUCK2_IDLE_DEFAULT 0x14
+
+/* BD71837_REG_BUCK3_VOLT_RUN bits */
+#define BUCK3_RUN_MASK 0x3F
+#define BUCK3_RUN_DEFAULT 0x1E
+
+/* BD71837_REG_BUCK4_VOLT_RUN bits */
+#define BUCK4_RUN_MASK 0x3F
+#define BUCK4_RUN_DEFAULT 0x1E
+
+/* BD71837_REG_BUCK5_VOLT bits */
+#define BUCK5_MASK 0x07
+#define BUCK5_DEFAULT 0x02
+
+/* BD71837_REG_BUCK6_VOLT bits */
+#define BUCK6_MASK 0x03
+#define BUCK6_DEFAULT 0x03
+
+/* BD71837_REG_BUCK7_VOLT bits */
+#define BUCK7_MASK 0x07
+#define BUCK7_DEFAULT 0x03
+
+/* BD71837_REG_BUCK8_VOLT bits */
+#define BUCK8_MASK 0x3F
+#define BUCK8_DEFAULT 0x1E
+
+/* BD71837_REG_IRQ bits */
+#define IRQ_SWRST 0x40
+#define IRQ_PWRON_S 0x20
+#define IRQ_PWRON_L 0x10
+#define IRQ_PWRON 0x08
+#define IRQ_WDOG 0x04
+#define IRQ_ON_REQ 0x02
+#define IRQ_STBY_REQ 0x01
+
+/* BD71837_REG_OUT32K bits */
+#define BD71837_OUT32K_EN 0x01
+
+/* BD71837 gated clock rate */
+#define BD71837_CLK_RATE 32768
+
+/* BD71837 irqs */
+enum {
+ BD71837_INT_STBY_REQ,
+ BD71837_INT_ON_REQ,
+ BD71837_INT_WDOG,
+ BD71837_INT_PWRBTN,
+ BD71837_INT_PWRBTN_L,
+ BD71837_INT_PWRBTN_S,
+ BD71837_INT_SWRST
+};
+
+/* BD71837 interrupt masks */
+#define BD71837_INT_SWRST_MASK 0x40
+#define BD71837_INT_PWRBTN_S_MASK 0x20
+#define BD71837_INT_PWRBTN_L_MASK 0x10
+#define BD71837_INT_PWRBTN_MASK 0x8
+#define BD71837_INT_WDOG_MASK 0x4
+#define BD71837_INT_ON_REQ_MASK 0x2
+#define BD71837_INT_STBY_REQ_MASK 0x1
+
+/* BD71837_REG_LDO1_VOLT bits */
+#define LDO1_MASK 0x03
+
+/* BD71837_REG_LDO1_VOLT bits */
+#define LDO2_MASK 0x20
+
+/* BD71837_REG_LDO3_VOLT bits */
+#define LDO3_MASK 0x0F
+
+/* BD71837_REG_LDO4_VOLT bits */
+#define LDO4_MASK 0x0F
+
+/* BD71837_REG_LDO5_VOLT bits */
+#define LDO5_MASK 0x0F
+
+/* BD71837_REG_LDO6_VOLT bits */
+#define LDO6_MASK 0x0F
+
+/* BD71837_REG_LDO7_VOLT bits */
+#define LDO7_MASK 0x0F
+
+struct bd71837;
+struct bd71837_pmic;
+struct bd71837_clk;
+
+/*
+ * Board platform data may be used to initialize regulators.
+ */
+
+struct bd71837_board {
+ struct regulator_init_data *init_data[BD71837_REGULATOR_CNT];
+ int gpio_intr;
+ int irq_base;
+};
+
+struct bd71837 {
+ struct device *dev;
+ struct i2c_client *i2c_client;
+ struct regmap *regmap;
+ unsigned long int id;
+
+ int chip_irq;
+ struct regmap_irq_chip_data *irq_data;
+
+ struct bd71837_pmic *pmic;
+ struct bd71837_clk *clk;
+
+ struct bd71837_board *of_plat_data;
+};
+
+/*
+ * bd71837 sub-driver chip access routines
+ */
+
+static inline int bd71837_reg_read(struct bd71837 *bd71837, u8 reg)
+{
+ int r, val;
+
+ r = regmap_read(bd71837->regmap, reg, &val);
+ if (r < 0)
+ return r;
+ return val;
+}
+
+static inline int bd71837_reg_write(struct bd71837 *bd71837, u8 reg,
+ unsigned int val)
+{
+ return regmap_write(bd71837->regmap, reg, val);
+}
+
+static inline int bd71837_set_bits(struct bd71837 *bd71837, u8 reg, u8 mask)
+{
+ return regmap_update_bits(bd71837->regmap, reg, mask, mask);
+}
+
+static inline int bd71837_clear_bits(struct bd71837 *bd71837, u8 reg,
+ u8 mask)
+{
+ return regmap_update_bits(bd71837->regmap, reg, mask, 0);
+}
+
+static inline int bd71837_update_bits(struct bd71837 *bd71837, u8 reg,
+ u8 mask, u8 val)
+{
+ return regmap_update_bits(bd71837->regmap, reg, mask, val);
+}
+
+#endif /* __LINUX_MFD_BD71837_H__ */
--
2.14.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox