* Re: [PATCH v2] ARM: dts: da850: add the mstpri and ddrctl nodes
From: Bartosz Golaszewski @ 2016-11-23 10:27 UTC (permalink / raw)
To: David Lechner
Cc: Mark Rutland, linux-devicetree, Tomi Valkeinen, Kevin Hilman,
Michael Turquette, Sekhar Nori, Russell King, linux-drm, LKML,
Peter Ujfalusi, Rob Herring, Jyri Sarha, Frank Rowand, arm-soc,
Laurent Pinchart
In-Reply-To: <a39b9276-865b-6382-574e-a5ef040a452f@lechnology.com>
2016-11-22 23:23 GMT+01:00 David Lechner <david@lechnology.com>:
> On 11/15/2016 05:00 AM, Bartosz Golaszewski wrote:
>>
>> Add the nodes for the MSTPRI configuration and DDR2/mDDR memory
>> controller drivers to da850.dtsi.
>>
>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>> ---
>> v1 -> v2:
>> - moved the priority controller node above the cfgchip node
>> - renamed added nodes to better reflect their purpose
>>
>> arch/arm/boot/dts/da850.dtsi | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>> index 1bb1f6d..412eec6 100644
>> --- a/arch/arm/boot/dts/da850.dtsi
>> +++ b/arch/arm/boot/dts/da850.dtsi
>> @@ -210,6 +210,10 @@
>> };
>>
>> };
>> + prictrl: priority-controller@14110 {
>> + compatible = "ti,da850-mstpri";
>> + reg = <0x14110 0x0c>;
>
>
> I think we should add status = "disabled"; here and let boards opt in.
>
>> + };
>> cfgchip: chip-controller@1417c {
>> compatible = "ti,da830-cfgchip", "syscon",
>> "simple-mfd";
>> reg = <0x1417c 0x14>;
>> @@ -451,4 +455,8 @@
>> 1 0 0x68000000 0x00008000>;
>> status = "disabled";
>> };
>> + memctrl: memory-controller@b0000000 {
>> + compatible = "ti,da850-ddr-controller";
>> + reg = <0xb0000000 0xe8>;
>
>
> same here. status = "disabled";
>
>> + };
>> };
>>
Hi David,
I did that initially[1][2] and it was rejected by Kevin[3] and Laurent[4].
FYI this patch has already been queued by Sekhar.
Best regards,
Bartosz Golaszewski
[1] https://www.spinics.net/lists/arm-kernel/msg539638.html
[2] http://www.spinics.net/lists/devicetree/msg148575.html
[3] http://www.spinics.net/lists/devicetree/msg148667.html
[4] http://www.spinics.net/lists/devicetree/msg148655.html
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH 1/2] of: base: add support to get machine model name
From: Sudeep Holla @ 2016-11-23 10:25 UTC (permalink / raw)
To: Rob Herring
Cc: Frank Rowand, Sudeep Holla, linux-kernel@vger.kernel.org,
Arnd Bergmann, devicetree@vger.kernel.org
In-Reply-To: <CAL_JsqLsw6BNSDY8pGJ8x3XF21WdciLC7WC+z796pYtDk_kvxA@mail.gmail.com>
On 22/11/16 21:35, Rob Herring wrote:
> On Tue, Nov 22, 2016 at 12:44 PM, Frank Rowand <frowand.list@gmail.com> wrote:
[...]
>>
>> This patch adds a function that leads to conflating the "model" property
>> and the "compatible" property. This leads to opaque, confusing and unclear
>> code where ever it is used. I think it is not good for the device tree
>> framework to contribute to writing unclear code.
>>
>> Further, only two of the proposed users of this new function appear to
>> be proper usage. I do not think that the small amount of reduced lines
>> of code is a good trade off for the reduced code clarity and for the
>> potential for future mis-use of this function.
>>
>> Can I convince you to revert this patch?
>
> Yes, I will revert.
>
>> If not, will you accept a patch to change the function name to more
>> clearly indicate what it does? (One possible name would be
>> of_model_or_1st_compatible().)
>
> I took it as there's already the FDT equivalent function.
Yes it was mainly for non of_flat_* replacement for
of_flat_dt_get_machine_name
--
Regards,
Sudeep
^ permalink raw reply
* Re: [PATCH 1/2] of: base: add support to get machine model name
From: Sudeep Holla @ 2016-11-23 10:23 UTC (permalink / raw)
To: Frank Rowand
Cc: Rob Herring, Sudeep Holla, linux-kernel, Arnd Bergmann,
devicetree
In-Reply-To: <5834921F.2020809@gmail.com>
On 22/11/16 18:44, Frank Rowand wrote:
> Hi Rob,
[...]
>
> This patch adds a function that leads to conflating the "model"
> property and the "compatible" property. This leads to opaque,
> confusing and unclear code where ever it is used. I think it is
> not good for the device tree framework to contribute to writing
> unclear code.
>
I agree, the main intention of this patch initially was to have a non
flat_* version of of_flat_dt_get_machine_name
> Further, only two of the proposed users of this new function appear
> to be proper usage. I do not think that the small amount of reduced
> lines of code is a good trade off for the reduced code clarity and
> for the potential for future mis-use of this function.
>
OK, most of the place I found it used for logging/informational purpose
and hence I thought it could replace in places where even compatible is
used. If that's wrong or leads to misuse of this API, then fine we
should not have one.
--
Regards,
Sudeep
^ permalink raw reply
* Re: [PATCHv2 3/4] dt: bindings: add new dt entry for BTCOEX feature in qcom,ath10k.txt
From: Tamizh chelvam @ 2016-11-23 10:20 UTC (permalink / raw)
To: Rob Herring
Cc: c_traja-Rm6X0d1/PG5y9aJCnZT0Uw,
ath10k-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161118144406.3se7gnckhcmwqytp@rob-hp-laptop>
Thanks for the comments.
On 2016-11-18 20:14, Rob Herring wrote:
> On Thu, Nov 17, 2016 at 05:14:23PM +0530, c_traja-Rm6X0d1/PG5y9aJCnZT0Uw@public.gmane.org
> wrote:
>> From: Tamizh chelvam <tamizhchelvam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>>
>> There two things done in this patch.
>>
>> 1) 'btcoex_support' flag for BTCOEX feature support by the hardware.
>> 2) 'wlan_btcoex_gpio' is used to fill wlan priority pin number for
>> BTCOEX priority feature support.
>>
>> Signed-off-by: Tamizh chelvam <tamizhchelvam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>> ---
>> .../bindings/net/wireless/qcom,ath10k.txt | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git
>> a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> index 74d7f0a..08150e2d 100644
>> --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> @@ -46,6 +46,10 @@ Optional properties:
>> hw versions.
>> - qcom,ath10k-pre-calibration-data : pre calibration data as an
>> array,
>> the length can vary between hw versions.
>> +- btcoex_support : should contain eithr "0" or "1" to indicate
>> btcoex
>> + support by the hardware.
>
> This is BT coexistence? Make this boolean and n
Yes, this is BT coexistence. And I didn't get what are you trying to say
in this "Make this boolean and n"
>
>> +- btcoex_gpio_pin : btcoex gpio pin number for the device which
>> + supports BTCOEX.
>
> This is a pin number on the chip, not any pin number Linux GPIO subsys
> cares about, right? Is there a connection to the host too, or this is
> internal between BT and WiFi?
This is internal between BT and wifi.
>
> Do you really need 2 properties? Does supporting this feature require
> the GPIO? If so, then the first property is redundant.
>
Target/driver can hard copy this gpio pin for some chipsets and there we
will need btcoex_support flag to find the btcoex support.
> Needs vendor prefix and don't use '_'. Should be something like
> 'qcom,bt-coexist-gpio-pin'.
>
Sure I'll update this and send in v3 patch
^ permalink raw reply
* Re: [PATCH v2 1/5] ARM: memory: da8xx-ddrctl: new driver
From: Sudeep Holla @ 2016-11-23 10:16 UTC (permalink / raw)
To: Frank Rowand
Cc: Sekhar Nori, Bartosz Golaszewski, Kevin Hilman, Michael Turquette,
Rob Herring, Mark Rutland, Peter Ujfalusi, Russell King,
Sudeep Holla, LKML, arm-soc, linux-drm, linux-devicetree,
Jyri Sarha, Tomi Valkeinen, David Airlie, Laurent Pinchart
In-Reply-To: <5833A2DA.40701@gmail.com>
On 22/11/16 01:43, Frank Rowand wrote:
> Hi Sekhar,
>
> (And adding Sudeep since he becomes involved in this further
> down thread and at that point says he will re-work this
> proposed work around in a manner that is incorrect in a
> manner that is similar to this proposed work around.)
>
> On 11/21/16 08:33, Sekhar Nori wrote:
[...]
>> static int da8xx_ddrctl_probe(struct platform_device *pdev)
>> {
>> const struct da8xx_ddrctl_config_knob *knob;
>> @@ -118,7 +130,7 @@ static int da8xx_ddrctl_probe(struct platform_device *pdev)
>> setting = da8xx_ddrctl_get_board_settings();
>> if (!setting) {
>> dev_err(dev, "no settings for board '%s'\n",
>> - of_flat_dt_get_machine_name());
>
> da8xx_ddrctl_get_board_settings() tries to match based on the "compatible"
> property in the root node. The "model" property in the root node has
> nothing to do with the failure to match. So creating and then using
> da8xx_ddrctl_get_machine_name() to potentially report model is not useful.
>
> It should be sufficient to simply report that no compatible matched.
>
Agreed.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH] v4l: async: make v4l2 coexists with devicetree nodes in a dt overlay
From: Javi Merino @ 2016-11-23 10:09 UTC (permalink / raw)
To: linux-media
Cc: linux-kernel, devicetree, Pantelis Antoniou, Javi Merino,
Mauro Carvalho Chehab, Javier Martinez Canillas, Sakari Ailus
In asd's configured with V4L2_ASYNC_MATCH_OF, if the v4l2 subdev is in
a devicetree overlay, its of_node pointer will be different each time
the overlay is applied. We are not interested in matching the
pointer, what we want to match is that the path is the one we are
expecting. Change to use of_node_cmp() so that we continue matching
after the overlay has been removed and reapplied.
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Javier Martinez Canillas <javier@osg.samsung.com>
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Javi Merino <javi.merino@kernel.org>
---
Hi,
I feel it is a bit of a hack, but I couldn't think of anything better.
I'm ccing devicetree@ and Pantelis because there may be a simpler
solution.
drivers/media/v4l2-core/v4l2-async.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 5bada20..d33a17c 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -42,7 +42,8 @@ static bool match_devname(struct v4l2_subdev *sd,
static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
- return sd->of_node == asd->match.of.node;
+ return !of_node_cmp(of_node_full_name(sd->of_node),
+ of_node_full_name(asd->match.of.node));
}
static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
--
2.1.4
^ permalink raw reply related
* Re: [PATCH 1/3] of: base: add support to get machine compatible string
From: Sudeep Holla @ 2016-11-23 10:05 UTC (permalink / raw)
To: Sekhar Nori
Cc: Mark Rutland, linux-devicetree, Tomi Valkeinen, David Airlie,
Kevin Hilman, Michael Turquette, Russell King, linux-drm, LKML,
Bartosz Golaszewski, Rob Herring, Jyri Sarha, Sudeep Holla,
Robin Murphy, Frank Rowand, arm-soc, Laurent Pinchart
In-Reply-To: <ae92e013-b41b-6caa-b32f-284ffb6f5aa0@ti.com>
On 23/11/16 07:49, Sekhar Nori wrote:
> On Tuesday 22 November 2016 09:16 PM, Sudeep Holla wrote:
>> Hi Sekhar,
>>
>> On 22/11/16 15:06, Sekhar Nori wrote:
>>> Hi Sudeep,
>>>
>>> On Tuesday 22 November 2016 04:23 PM, Sudeep Holla wrote:
>>>>
>>>>
>>>> On 22/11/16 10:41, Bartosz Golaszewski wrote:
>>>>> Add a function allowing to retrieve the compatible string of the root
>>>>> node of the device tree.
>>>>>
>>>>
>>>> Rob has queued [1] and it's in -next today. You can reuse that if you
>>>> are planning to target this for v4.11 or just use open coding in your
>>>> driver for v4.10 and target this move for v4.11 to avoid cross tree
>>>> dependencies as I already mentioned in your previous thread.
>>>
>>> I dont have your original patch in my mailbox, but I wonder if
>>> returning a pointer to property string for a node whose reference has
>>> already been released is safe to do? Probably not an issue for the root
>>> node, but still feels counter-intuitive.
>>>
>>
>> I am not sure if I understand the issue here. Are you referring a case
>> where of_root is freed ?
>
> Yes, right, thats what I was hinting at. Since you are giving up the
> reference to the device node before the function returns, the user can
> be left with a dangling reference.
>
Yes I agree.
>> Also I have seen drivers today just using this pointer directly, but
>> it's better to copy the string(I just saw this done in one case)
>
> Hmm, the reference is given up before the API returns, so I doubt
> copying it later is any additional benefit.
>
True.
> I suspect this is a theoretical issue though since root device node is
> probably never freed.
>
Indeed, not sure if it's worth adding additional code to release the nod
at all call sites.
--
Regards,
Sudeep
^ permalink raw reply
* Re: [PATCH 7/7] add stm32 multi-functions timer driver in DT
From: Lee Jones @ 2016-11-23 9:53 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: mark.rutland, devicetree, lars, alexandre.torgue, linux-pwm,
linux-iio, linus.walleij, arnaud.pouliquen, linux-kernel, robh+dt,
thierry.reding, linux-arm-kernel, pmeerw, knaack.h, gerald.baeza,
fabrice.gasnier, linaro-kernel, jic23, Benjamin Gaignard
In-Reply-To: <1479831207-32699-8-git-send-email-benjamin.gaignard@st.com>
On Tue, 22 Nov 2016, Benjamin Gaignard wrote:
> Add timers MFD and childs into DT for stm32f4.
> Define and enable pwm1 and pwm3 for stm32f469 discovery board
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> ---
> arch/arm/boot/dts/stm32f429.dtsi | 246 ++++++++++++++++++++++++++++++++++
> arch/arm/boot/dts/stm32f469-disco.dts | 29 ++++
> 2 files changed, 275 insertions(+)
>
> diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
> index bca491d..28a0fe9 100644
> --- a/arch/arm/boot/dts/stm32f429.dtsi
> +++ b/arch/arm/boot/dts/stm32f429.dtsi
> @@ -355,6 +355,21 @@
> slew-rate = <2>;
> };
> };
> +
> + pwm1_pins: pwm@1 {
> + pins {
> + pinmux = <STM32F429_PA8_FUNC_TIM1_CH1>,
> + <STM32F429_PB13_FUNC_TIM1_CH1N>,
> + <STM32F429_PB12_FUNC_TIM1_BKIN>;
> + };
> + };
> +
> + pwm3_pins: pwm@3 {
> + pins {
> + pinmux = <STM32F429_PB4_FUNC_TIM3_CH1>,
> + <STM32F429_PB5_FUNC_TIM3_CH2>;
> + };
> + };
> };
>
> rcc: rcc@40023810 {
> @@ -426,6 +441,237 @@
> interrupts = <80>;
> clocks = <&rcc 0 38>;
> };
> +
> + mfd_timer1: mfdtimer1@40010000 {
Do you reference this node?
If not, it should read:
advanced-control@40010000
> + compatible = "st,stm32-mfd-timer1";
"st,stm32-advanced-control"
> + reg = <0x40010000 0x400>;
> + clocks = <&rcc 0 160>;
> + clock-names = "mfd_timer_clk";
"clk_int"
> + interrupts = <27>;
This is a timer property.
Also move the associated registration C code into the timer driver.
> + status = "disabled";
> +
> + pwm1: pwm1@40010000 {
pwm@0 {
> + compatible = "st,stm32-pwm1";
st,stm32-advanced-control-pwm
> + status = "disabled";
> + };
> +
> + iiotimer1: iiotimer1@40010000 {
Same here:
timer@0
> + compatible = "st,stm32-iio-timer1";
st,stm32-advanced-control-timer
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer2: mfdtimer2@40000000 {
> + compatible = "st,stm32-mfd-timer2";
> + reg = <0x40000000 0x400>;
> + clocks = <&rcc 0 128>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <28>;
> + status = "disabled";
> +
> + pwm2: pwm2@40000000 {
> + compatible = "st,stm32-pwm2";
> + status = "disabled";
> + };
> + iiotimer2: iiotimer2@40000000 {
> + compatible = "st,stm32-iio-timer2";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer3: mfdtimer3@40000400 {
> + compatible = "st,stm32-mfd-timer3";
> + reg = <0x40000400 0x400>;
> + clocks = <&rcc 0 129>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <29>;
> + status = "disabled";
> +
> + pwm3: pwm3@40000400 {
> + compatible = "st,stm32-pwm3";
> + status = "disabled";
> + };
> + iiotimer3: iiotimer3@40000400 {
> + compatible = "st,stm32-iio-timer3";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer4: mfdtimer4@40000800 {
> + compatible = "st,stm32-mfd-timer4";
> + reg = <0x40000800 0x400>;
> + clocks = <&rcc 0 130>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <30>;
> + status = "disabled";
> +
> + pwm4: pwm4@40000800 {
> + compatible = "st,stm32-pwm4";
> + status = "disabled";
> + };
> + iiotimer4: iiotimer4@40000800 {
> + compatible = "st,stm32-iio-timer4";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer5: mfdtimer5@40000C00 {
> + compatible = "st,stm32-mfd-timer5";
> + reg = <0x40000C00 0x400>;
> + clocks = <&rcc 0 131>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <50>;
> + status = "disabled";
> +
> + pwm5: pwm5@40000C00 {
> + compatible = "st,stm32-pwm5";
> + status = "disabled";
> + };
> + iiotimer5: iiotimer5@40000800 {
> + compatible = "st,stm32-iio-timer5";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer6: mfdtimer6@40001000 {
> + compatible = "st,stm32-mfd-timer6";
> + reg = <0x40001000 0x400>;
> + clocks = <&rcc 0 132>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <54>;
> + status = "disabled";
> +
> + iiotimer6: iiotimer6@40001000 {
> + compatible = "st,stm32-iio-timer6";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer7: mfdtimer7@40001400 {
> + compatible = "st,stm32-mfd-timer7";
> + reg = <0x40001400 0x400>;
> + clocks = <&rcc 0 133>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <55>;
> + status = "disabled";
> +
> + iiotimer7: iiotimer7@40001400 {
> + compatible = "st,stm32-iio-timer7";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer8: mfdtimer8@40010400 {
> + compatible = "st,stm32-mfd-timer8";
> + reg = <0x40010400 0x400>;
> + clocks = <&rcc 0 161>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <46>;
> + status = "disabled";
> +
> + pwm8: pwm8@40010400 {
> + compatible = "st,stm32-pwm8";
> + status = "disabled";
> + };
> +
> + iiotimer8: iiotimer7@40010400 {
> + compatible = "st,stm32-iio-timer8";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer9: mfdtimer9@40014000 {
> + compatible = "st,stm32-mfd-timer9";
> + reg = <0x40014000 0x400>;
> + clocks = <&rcc 0 176>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <24>;
> + status = "disabled";
> +
> + pwm9: pwm9@40014000 {
> + compatible = "st,stm32-pwm9";
> + status = "disabled";
> + };
> +
> + iiotimer9: iiotimer9@40014000 {
> + compatible = "st,stm32-iio-timer9";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer10: mfdtimer10@40014400 {
> + compatible = "st,stm32-mfd-timer10";
> + reg = <0x40014400 0x400>;
> + clocks = <&rcc 0 177>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <25>;
> + status = "disabled";
> +
> + pwm10: pwm10@40014400 {
> + compatible = "st,stm32-pwm10";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer11: mfdtimer11@40014800 {
> + compatible = "st,stm32-mfd-timer11";
> + reg = <0x40014800 0x400>;
> + clocks = <&rcc 0 178>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <26>;
> + status = "disabled";
> +
> + pwm11: pwm11@40014800 {
> + compatible = "st,stm32-pwm11";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer12: mfdtimer12@40001800 {
> + compatible = "st,stm32-mfd-timer12";
> + reg = <0x40001800 0x400>;
> + clocks = <&rcc 0 134>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <43>;
> + status = "disabled";
> +
> + pwm12: pwm12@40001800 {
> + compatible = "st,stm32-pwm12";
> + status = "disabled";
> + };
> + iiotimer12: iiotimer12@40001800 {
> + compatible = "st,stm32-iio-timer12";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer13: mfdtimer13@40001C00 {
> + compatible = "st,stm32-mfd-timer13";
> + reg = <0x40001C00 0x400>;
> + clocks = <&rcc 0 135>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <44>;
> + status = "disabled";
> +
> + pwm13: pwm13@40001C00 {
> + compatible = "st,stm32-pwm13";
> + status = "disabled";
> + };
> + };
> +
> + mfd_timer14: mfdtimer14@40002000 {
> + compatible = "st,stm32-mfd-timer14";
> + reg = <0x40002000 0x400>;
> + clocks = <&rcc 0 136>;
> + clock-names = "mfd_timer_clk";
> + interrupts = <45>;
> + status = "disabled";
> +
> + pwm14: pwm14@40002000 {
> + compatible = "st,stm32-pwm14";
> + status = "disabled";
> + };
> + };
> };
> };
>
> diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
> index 8a163d7..a8f1788 100644
> --- a/arch/arm/boot/dts/stm32f469-disco.dts
> +++ b/arch/arm/boot/dts/stm32f469-disco.dts
> @@ -81,3 +81,32 @@
> &usart3 {
> status = "okay";
> };
> +
> +&mfd_timer1 {
> + status = "okay";
> +};
> +
> +&pwm1 {
> + pinctrl-0 = <&pwm1_pins>;
> + pinctrl-names = "default";
> + st,breakinput-polarity = <0>;
Is this documented?
I'm sure we have generic polarity properties somewhere already?
> + status = "okay";
> +};
> +
> +&iiotimer1 {
> + status = "okay";
> +};
> +
> +&mfd_timer3 {
> + status = "okay";
> +};
> +
> +&pwm3 {
> + pinctrl-0 = <&pwm3_pins>;
> + pinctrl-names = "default";
> + status = "okay";
> +};
> +
> +&iiotimer3 {
> + status = "okay";
> +};
I've always disliked this way of referencing nodes!
Any chance we can represent them in a hierarchy, so we don't lose that
information and we can get rid of all those horrible labels?
I'm happy to do the work.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6 3/3] arm: dts: mt2701: Add node for Mediatek JPEG Decoder
From: Rick Chang @ 2016-11-23 9:43 UTC (permalink / raw)
To: Hans Verkuil
Cc: Hans Verkuil, Laurent Pinchart, Mauro Carvalho Chehab,
Matthias Brugger, Rob Herring, linux-kernel, linux-media,
srv_heupstream, linux-mediatek, linux-arm-kernel, devicetree,
Minghsiu Tsai
In-Reply-To: <1479866054.8964.21.camel@mtksdaap41>
On Wed, 2016-11-23 at 09:54 +0800, Rick Chang wrote:
> Hi Hans,
>
> On Tue, 2016-11-22 at 13:43 +0100, Hans Verkuil wrote:
> > On 22/11/16 04:21, Rick Chang wrote:
> > > Hi Hans,
> > >
> > > On Mon, 2016-11-21 at 15:51 +0100, Hans Verkuil wrote:
> > >> On 17/11/16 04:38, Rick Chang wrote:
> > >>> Signed-off-by: Rick Chang <rick.chang@mediatek.com>
> > >>> Signed-off-by: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
> > >>> ---
> > >>> This patch depends on:
> > >>> CCF "Add clock support for Mediatek MT2701"[1]
> > >>> iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
> > >>>
> > >>> [1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
> > >>> [2] https://patchwork.kernel.org/patch/9164013/
> > >>
> > >> I assume that 1 & 2 will appear in 4.10? So this patch needs to go in
> > >> after the
> > >> other two are merged in 4.10?
> > >>
> > >> Regards,
> > >>
> > >> Hans
> > >
> > > [1] will appear in 4.10, but [2] will appear latter than 4.10.So this
> > > patch needs to go in after [1] & [2] will be merged in 4.11.
> >
> > So what should I do? Merge the driver for 4.11 and wait with this patch
> > until [2] is merged in 4.11? Does that sound reasonable?
> >
> > Regards,
> >
> > Hans
>
> What do you think about this? You merge the driver first and I send this
> patch again after [1] & [2] is merged.
BTW, to prevent merging conflict, the dtsi should be merged by mediatek
SoC maintainer, Matthias.I think we can only take care on the driver
part at this moment.
^ permalink raw reply
* Re: [PATCH v2 2/3] ARM: dts: sunxi: add support for Orange Pi Zero board
From: Andre Przywara @ 2016-11-23 9:23 UTC (permalink / raw)
To: Maxime Ripard, Icenowy Zheng
Cc: Mark Rutland, devicetree, Vishnu Patekar, Arnd Bergmann,
Jonathan Corbet, linux-doc, Russell King, linux-kernel,
Hans de Goede, Chen-Yu Tsai, linux-arm-kernel
In-Reply-To: <20161123075713.ks6gmud3rszjbdsh@lukather>
Hi Maxime,
On 23/11/16 07:57, Maxime Ripard wrote:
> On Tue, Nov 22, 2016 at 12:24:20AM +0800, Icenowy Zheng wrote:
>> Orange Pi Zero is a board that came with the new Allwinner H2+ SoC.
>>
>> Add a device tree file for it.
>>
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
>> ---
>> Changes since v2:
>> - Use generic pinconf binding instead of legacy allwinner pinctrl binding.
>> - removed uart3, which is not accessible on Orange Pi Zero.
>> - Removed sun8i-h2plus.dtsi and make Orange Pi Zero dts directly include
>> sun8i-h3.dtsi.
>> - Removed allwinner,sun8i-h3 compatible.
>>
>> arch/arm/boot/dts/Makefile | 1 +
>> arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts | 137 +++++++++++++++++++++++
>
> Ditto, h2-plus-orangepi-zero.
>
>> 2 files changed, 138 insertions(+)
>> create mode 100644 arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index 802a10d..51a1dd7 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -834,6 +834,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
>> sun8i-a33-sinlinx-sina33.dtb \
>> sun8i-a83t-allwinner-h8homlet-v2.dtb \
>> sun8i-a83t-cubietruck-plus.dtb \
>> + sun8i-h2plus-orangepi-zero.dtb \
>> sun8i-h3-bananapi-m2-plus.dtb \
>> sun8i-h3-nanopi-neo.dtb \
>> sun8i-h3-orangepi-2.dtb \
>> diff --git a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>> new file mode 100644
>> index 0000000..b428e47
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>> @@ -0,0 +1,137 @@
>> +/*
>> + * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
>> + *
>> + * Based on sun8i-h3-orangepi-one.dts, which is:
>> + * Copyright (C) 2016 Hans de Goede <hdegoede@redhat.com>
>> + *
>> + * This file is dual-licensed: you can use it either under the terms
>> + * of the GPL or the X11 license, at your option. Note that this dual
>> + * licensing only applies to this file, and not this project as a
>> + * whole.
>> + *
>> + * a) This file is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of the
>> + * License, or (at your option) any later version.
>> + *
>> + * This file is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * Or, alternatively,
>> + *
>> + * b) Permission is hereby granted, free of charge, to any person
>> + * obtaining a copy of this software and associated documentation
>> + * files (the "Software"), to deal in the Software without
>> + * restriction, including without limitation the rights to use,
>> + * copy, modify, merge, publish, distribute, sublicense, and/or
>> + * sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following
>> + * conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be
>> + * included in all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
>> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>> + * OTHER DEALINGS IN THE SOFTWARE.
>> + */
>> +
>> +/dts-v1/;
>> +#include "sun8i-h3.dtsi"
>> +#include "sunxi-common-regulators.dtsi"
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/input/input.h>
>> +#include <dt-bindings/pinctrl/sun4i-a10.h>
>> +
>> +/ {
>> + model = "Xunlong Orange Pi Zero";
>> + compatible = "xunlong,orangepi-zero", "allwinner,sun8i-h2plus";
>> +
>> + aliases {
>> + serial0 = &uart0;
>> + };
>> +
>> + chosen {
>> + stdout-path = "serial0:115200n8";
>> + };
>> +
>> + leds {
>> + compatible = "gpio-leds";
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&leds_opi0>, <&leds_r_opi0>;
>> +
>> + pwr_led {
>> + label = "orangepi:green:pwr";
>> + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
>> + default-state = "on";
>> + };
>> +
>> + status_led {
>> + label = "orangepi:red:status";
>> + gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>;
>> + };
>> + };
>> +};
>> +
>> +&ehci1 {
>> + status = "okay";
>> +};
>> +
>> +&mmc0 {
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
>> + vmmc-supply = <®_vcc3v3>;
>> + bus-width = <4>;
>> + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
>> + cd-inverted;
>> + status = "okay";
>> +};
>> +
>> +&ohci1 {
>> + status = "okay";
>> +};
>> +
>> +&pio {
>> + leds_opi0: led_pins@0 {
>> + pins = "PA17";
>> + function = "gpio_out";
>> + };
>> +};
>> +
>> +&r_pio {
>> + leds_r_opi0: led_pins@0 {
>> + pins = "PL10";
>> + function = "gpio_out";
>> + };
>> +};
>> +
>> +&uart0 {
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&uart0_pins_a>;
>> + status = "okay";
>> +};
>> +
>> +&uart1 {
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&uart1_pins>;
>> + status = "disabled";
>> +};
>> +
>> +&uart2 {
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&uart2_pins>;
>> + status = "disabled";
>> +};
>
> I'm not sure you answered me on this one. Are those exposed on the
> headers? why did you put them as disabled here?
So they are on headers, though you have to solder the actual header pins
yourself [1]. But also these are the normal pins multiplexed with GPIOs
and other peripherals, so keeping them disabled is in line with the
existing policy, if I got this correctly.
I agree that the status="disabled" is redundant, since we have that
exact line already in the .dtsi. But I saw it in other DTs as well, most
prominently in the sun8i-h3-orangepi-one.dts.
So I think we should remove the "status=" lines here, dtc will generate
an identical dtb out of it. But we should keep the uart descriptions in
to make it easier for users to see which SoC pins are used for these
pins labeled UART[012] in the board description and schematic. Also all
it takes to enable those is to overwrite the status property, which can
easily be done inline (without resizing the dtb).
Cheers,
Andre.
[1] http://linux-sunxi.org/Xunlong_Orange_Pi_Zero
^ permalink raw reply
* Re: [PATCH 1/7] add binding for stm32 multifunctions timer driver
From: Lee Jones @ 2016-11-23 9:21 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: robh+dt, Mark Rutland, alexandre.torgue, devicetree,
Linux Kernel Mailing List, Thierry Reding, linux-pwm, jic23,
knaack.h, Lars-Peter Clausen, Peter Meerwald-Stadler, linux-iio,
linux-arm-kernel, Fabrice Gasnier, Gerald Baeza, Arnaud Pouliquen,
Linus Walleij, Linaro Kernel Mailman List, Benjamin Gaignard
In-Reply-To: <CA+M3ks4cVLtVe4zSvSiDUz6jKy0Wbw8j24VuStf_31D5ntwfvw@mail.gmail.com>
On Wed, 23 Nov 2016, Benjamin Gaignard wrote:
> 2016-11-22 17:52 GMT+01:00 Lee Jones <lee.jones@linaro.org>:
> > On Tue, 22 Nov 2016, Benjamin Gaignard wrote:
> >
> >> Add bindings information for stm32 timer MFD
> >>
> >> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> >> ---
> >> .../devicetree/bindings/mfd/stm32-timer.txt | 53 ++++++++++++++++++++++
> >> 1 file changed, 53 insertions(+)
> >> create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timer.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/mfd/stm32-timer.txt b/Documentation/devicetree/bindings/mfd/stm32-timer.txt
> >> new file mode 100644
> >> index 0000000..3cefce1
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/mfd/stm32-timer.txt
> >> @@ -0,0 +1,53 @@
> >> +STM32 multifunctions timer driver
> >
> > "STM32 Multi-Function Timer/PWM device bindings"
> >
> > Doesn't this shared device have a better name?
>
> In SoC documentation those hardware blocks are named "advanced-control
> timers", "general purpose timers" or "basic timers"
> "stm32-timer" name is already used for clock source driver, that why I
> have prefix it with mfd
MFD is a Linuxisum and has no place in hardware description.
Please used one of the names you mentioned above.
Hopefully the one that best fits.
> >> +stm32 timer MFD allow to handle at the same time pwm and IIO timer devices
> >
> > No need for this sentence.
> >
> OK
>
> >> +Required parameters:
> >> +- compatible: must be one of the follow value:
> >> + "st,stm32-mfd-timer1"
> >> + "st,stm32-mfd-timer2"
> >> + "st,stm32-mfd-timer3"
> >> + "st,stm32-mfd-timer4"
> >> + "st,stm32-mfd-timer5"
> >> + "st,stm32-mfd-timer6"
> >> + "st,stm32-mfd-timer7"
> >> + "st,stm32-mfd-timer8"
> >> + "st,stm32-mfd-timer9"
> >> + "st,stm32-mfd-timer10"
> >> + "st,stm32-mfd-timer11"
> >> + "st,stm32-mfd-timer12"
> >> + "st,stm32-mfd-timer13"
> >> + "st,stm32-mfd-timer14"
> >
> > We don't normally number devices.
> >
> > What's stopping you from simply doing:
> >
> > pwm1: pwm1@40010000 {
> > compatible = "st,stm32-pwm";
> > };
> > pwm2: pwm1@40020000 {
> > compatible = "st,stm32-pwm";
> > };
> > pwm3: pwm1@40030000 {
> > compatible = "st,stm32-pwm";
> > };
> >
>
> Because each instance of the hardware is slightly different: number of
> pwm channels, triggers capabilities, etc ..
> so I need to distinguish them.
> Since it look to be a problem I will follow your suggestion and add a
> property this driver to be able to identify each instance.
> Do you think that "id" parameter (integer for 1 to 14) is acceptable ?
Unfortunately not. IDs aren't allowed in DT.
What about "pwm-chans" and "trigger"?
pwm-chans : Number of available channels available
trigger : Boolean value specifying whether a timer is present
Why can't you let of_platform_populate() register the devices for you?
Then you can get rid of all of the meaningless numbers all over the place.
> >> +- reg : Physical base address and length of the controller's
> >> + registers.
> >> +- clock-names: Set to "mfd_timer_clk".
> >
> Only one but I use devm_regmap_init_mmio_clk() to avoid calling
> clk_{enable/disable}
> everywhere in the drivers when reading/writing regsister.
> devm_regmap_init_mmio_clk() find the clock by it name that why I have
> put it here
> In the doc this clock in named "clk_int" I will use this name.
Please reply *below* the quote.
But okay, "clk_int" sounds like a more suitable name.
> > How many clocks are there?
> >
> > If only 1, you don't need this property.
> >
> > "mfd_timer_clk" is not the correct name.
> >
> > What is it called in the datasheet?
> >
> >> +- clocks: Phandle of the clock used by the timer module.
> >
> > "Phandle to the clock ..."
> >
> >> + For Clk properties, please refer to [1].
> >> +- interrupts : Reference to the timer interrupt
> >
> > Reference to?
> >
> > See how other binding documents describe this property.
> >
> >> +Optional parameters:
> >> +- resets : Reference to a reset controller asserting the timer
> >
> > As above.
> >
> >> +Optional subnodes:
> >
> > Either use ":" or " :" or "<tab>:", but keep it consistent.
> >
> >> +- pwm: See Documentation/devicetree/bindings/pwm/pwm-stm32.txt
> >> +- iiotimer: See Documentation/devicetree/bindings/iio/timer/stm32-iio-timer.txt
> >> +
> >> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> >
> > Use the relative paths "../clock/", "../pwm/", "../iio/".
> >
> OK
>
> >> +Example:
> >> + mfd_timer1: mfdtimer1@40010000 {
> >
> > This is not an "MFD timer". MFD is a Linuxisum.
> >
> >> + compatible = "st,stm32-mfd-timer1";
> >
> > Better description required.
> >
> >> + reg = <0x40010000 0x400>;
> >> + clocks = <&rcc 0 160>;
> >> + clock-names = "mfd_timer_clk";
> >> + interrupts = <27>;
> >> +
> >> + pwm1: pwm1@40010000 {
> >> + compatible = "st,stm32-pwm1";
> >> + };
> >> +
> >> + iiotimer1: iiotimer1@40010000 {
> >> + compatible = "st,stm32-iio-timer1";
> >> + };
> >> + };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: sunxi: enable EHCI1, OHCI1 and USB PHY nodes in Pine64
From: Maxime Ripard @ 2016-11-23 9:20 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Mark Rutland, devicetree, Catalin Marinas, Will Deacon,
linux-kernel, Chen-Yu Tsai, Rob Herring, linux-arm-kernel
In-Reply-To: <20161122155831.8724-3-icenowy@aosc.xyz>
[-- Attachment #1.1: Type: text/plain, Size: 476 bytes --]
On Tue, Nov 22, 2016 at 11:58:31PM +0800, Icenowy Zheng wrote:
> Pine64 have two USB Type-A ports, which are wired to the two ports of
> A64 USB PHY, and the lower port is the EHCI/OHCI1 port.
>
> Enable the necessary nodes to enable the lower USB port to work.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
Fixed the prefix and applied, thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 2/3] arm64: dts: sunxi: sort the nodes in sun50i-a64-pine64.dts
From: Maxime Ripard @ 2016-11-23 9:19 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Mark Rutland, devicetree, Catalin Marinas, Will Deacon,
linux-kernel, Chen-Yu Tsai, Rob Herring, linux-arm-kernel
In-Reply-To: <20161122155831.8724-2-icenowy@aosc.xyz>
[-- Attachment #1.1: Type: text/plain, Size: 393 bytes --]
On Tue, Nov 22, 2016 at 11:58:30PM +0800, Icenowy Zheng wrote:
> In this dts file, uart0 node is put before i2c1.
>
> Move the uart0 node to the end to satisfy alphebetical order.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
Fixed the prefix and applied. Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 3/3] ARM: dts: gose: add composite video input
From: Laurent Pinchart @ 2016-11-23 8:56 UTC (permalink / raw)
To: Ulrich Hecht
Cc: horms, linux-media, linux-renesas-soc, magnus.damm, hans.verkuil,
niklas.soderlund, geert, sergei.shtylyov, devicetree
In-Reply-To: <2343930.U8AiEBNJBl@avalon>
Hello device tree maintainers,
On Tuesday 18 Oct 2016 18:50:39 Laurent Pinchart wrote:
> On Tuesday 18 Oct 2016 17:02:23 Ulrich Hecht wrote:
> > Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
> > ---
> >
> > arch/arm/boot/dts/r8a7793-gose.dts | 36 +++++++++++++++++++++++++++++++
> > 1 file changed, 36 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/r8a7793-gose.dts
> > b/arch/arm/boot/dts/r8a7793-gose.dts index a47ea4b..2606021 100644
> > --- a/arch/arm/boot/dts/r8a7793-gose.dts
> > +++ b/arch/arm/boot/dts/r8a7793-gose.dts
[snip]
> > + composite-in@20 {
> > + compatible = "adi,adv7180";
> > + reg = <0x20>;
> > + remote = <&vin1>;
> > +
> > + port {
> > + adv7180: endpoint {
> > + bus-width = <8>;
> > + remote-endpoint = <&vin1ep>;
> > + };
> > + };
>
> As explained before, you need to update the ADV7180 DT bindings first to
> document ports. I've discussed this with Hans last week, and we agreed that
> DT should model physical ports. Unfortunately the ADV7180 comes in four
> different packages with different feature sets that affect ports.
>
> ADV7180 K CP32 Z 32-Lead Lead Frame Chip Scale Package
> ADV7180 B CP32 Z 32-Lead Lead Frame Chip Scale Package
> ADV7180 WB CP32 Z 32-Lead Lead Frame Chip Scale Package
>
> ADV7180 B CP Z 40-Lead Lead Frame Chip Scale Package
> ADV7180 WB CP Z 40-Lead Lead Frame Chip Scale Package
>
> ADV7180 K ST48 Z 48-Lead Low Profile Quad Flat Package
> ADV7180 B ST48 Z 48-Lead Low Profile Quad Flat Package
> ADV7180 WB ST48 Z 48-Lead Low Profile Quad Flat Package
>
> ADV7180 B ST Z 64-Lead Low Profile Quad Flat Package
> ADV7180 WB ST Z 64-Lead Low Profile Quad Flat Package
>
> W tells whether the part is qualified for automotive applications. It has no
> impact from a software point of view. K and B indicate the temperature
> range, and also have no software impact. The Z suffix indicates that the
> part is RoHS compliant (they all are) and also has no impact.
>
> Unfortunately the W and K/B qualifiers come before the package qualifier.
> I'm not sure whether we could simply drop W, K/B and W and specify the
> following compatible strings
>
> - adv7180cp32
> - adv7180cp
> - adv7180st48
> - adv7180st
>
> or if we need more compatible strings that would match the full chip name.
> Feedback on that from the device tree maintainers would be appreciated.
Your input would be appreciated on this.
> Regardless of what compatible strings end up being used, the bindings should
> document 3 or 6 input ports depending on the model, and one output port.
> You can number the input ports from 0 to 2 or 0 to 5 depending on the model
> and the output port 3 or 6. Another option would be to number the output
> port 0 and the input ports 1 to 3 or 1 to 6 depending on the model. That
> would give a fixed number for the output port across all models, but might
> be a bit consuming as most bindings number input ports before output ports.
>
> For the Gose board you should then add one composite connector to the device
> tree ("composite-video-connector") and connect it to port 0 of the
> ADV7180WBCP32.
>
> > + };
> > +
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v4 3/4] drm/bridge: Add ti-tfp410 DVI transmitter driver
From: Jyri Sarha @ 2016-11-23 8:43 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: khilman, bgolaszewski, tomi.valkeinen, laurent.pinchart
In-Reply-To: <2943f3cb3ea913686bc63e8496df63c82ce0f334.1479825908.git.jsarha@ti.com>
On 11/22/16 16:49, Jyri Sarha wrote:
> Add very basic ti-tfp410 DVI transmitter driver. The only feature
> separating this from a completely dummy bridge is the EDID read
> support trough DDC I2C. Even that functionality should be in a
> separate generic connector driver. However, because of missing DRM
> infrastructure support the connector is implemented within the bridge
> driver. Some tfp410 HW specific features may be added later if needed,
> because there is a set of registers behind i2c if it is connected.
>
> This implementation is tested against my new tilcdc bridge support
> and it works with BeagleBone DVI-D Cape Rev A3. A DT binding document
> is also updated.
>
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
> .../bindings/display/bridge/ti,tfp410.txt | 9 +-
> drivers/gpu/drm/bridge/Kconfig | 7 +
> drivers/gpu/drm/bridge/Makefile | 1 +
> drivers/gpu/drm/bridge/ti-tfp410.c | 311 +++++++++++++++++++++
> 4 files changed, 326 insertions(+), 2 deletions(-)
> create mode 100644 drivers/gpu/drm/bridge/ti-tfp410.c
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
> index 2cbe32a..54d7e31 100644
> --- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
> @@ -6,10 +6,15 @@ Required properties:
>
> Optional properties:
> - powerdown-gpios: power-down gpio
> +- reg: I2C address. If and only if present the device node
> + should be placed into the i2c controller node where the
> + tfp410 i2c is connected to.
>
> Required nodes:
> -- Video port 0 for DPI input
> -- Video port 1 for DVI output
> +- Video port 0 for DPI input [1].
> +- Video port 1 for DVI output [1].
> +
> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>
> Example
> -------
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index bd6acc8..a424e03 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -81,6 +81,13 @@ config DRM_TOSHIBA_TC358767
> ---help---
> Toshiba TC358767 eDP bridge chip driver.
>
> +config DRM_TI_TFP410
> + tristate "TI TFP410 DVI/HDMI bridge"
> + depends on OF
> + select DRM_KMS_HELPER
> + ---help---
> + Texas Instruments TFP410 DVI/HDMI Transmitter driver
> +
> source "drivers/gpu/drm/bridge/analogix/Kconfig"
>
> source "drivers/gpu/drm/bridge/adv7511/Kconfig"
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 97ed1a5..8b065d9 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_DRM_SII902X) += sii902x.o
> obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
> obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
> obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
> +obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
> diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
> new file mode 100644
> index 0000000..58e26cc
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/ti-tfp410.c
> @@ -0,0 +1,311 @@
> +/*
> + * Copyright (C) 2016 Texas Instruments
> + * Author: Jyri Sarha <jsarha@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +#include <linux/i2c.h>
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_crtc_helper.h>
> +
> +struct tfp410 {
> + struct drm_bridge bridge;
> + struct drm_connector connector;
> +
> + struct i2c_adapter *ddc;
> +
> + struct device *dev;
> +};
> +
> +static inline struct tfp410 *
> +drm_bridge_to_tfp410(struct drm_bridge *bridge)
> +{
> + return container_of(bridge, struct tfp410, bridge);
> +}
> +
> +static inline struct tfp410 *
> +drm_connector_to_tfp410(struct drm_connector *connector)
> +{
> + return container_of(connector, struct tfp410, connector);
> +}
> +
> +static int tfp410_get_modes(struct drm_connector *connector)
> +{
> + struct tfp410 *dvi = drm_connector_to_tfp410(connector);
> + struct edid *edid;
> + int ret;
> +
> + if (!dvi->ddc)
> + goto fallback;
> +
> + edid = drm_get_edid(connector, dvi->ddc);
> + if (!edid) {
> + DRM_INFO("EDID read failed. Fallback to standard modes\n");
> + goto fallback;
> + }
> +
> + drm_mode_connector_update_edid_property(connector, edid);
> +
> + return drm_add_edid_modes(connector, edid);
> +fallback:
> + /* No EDID, fallback on the XGA standard modes */
> + ret = drm_add_modes_noedid(connector, 1920, 1200);
> +
> + /* And prefer a mode pretty much anything can handle */
> + drm_set_preferred_mode(connector, 1024, 768);
> +
> + return ret;
> +}
> +
> +static const struct drm_connector_helper_funcs tfp410_con_helper_funcs = {
> + .get_modes = tfp410_get_modes,
> +};
> +
> +static enum drm_connector_status
> +tfp410_connector_detect(struct drm_connector *connector, bool force)
> +{
> + struct tfp410 *dvi = drm_connector_to_tfp410(connector);
> +
> + if (dvi->ddc) {
> + if (drm_probe_ddc(dvi->ddc))
> + return connector_status_connected;
> + else
> + return connector_status_disconnected;
> + }
> +
> + return connector_status_unknown;
> +}
> +
> +static const struct drm_connector_funcs tfp410_con_funcs = {
> + .dpms = drm_atomic_helper_connector_dpms,
> + .detect = tfp410_connector_detect,
> + .fill_modes = drm_helper_probe_single_connector_modes,
> + .destroy = drm_connector_cleanup,
> + .reset = drm_atomic_helper_connector_reset,
> + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static int tfp410_attach(struct drm_bridge *bridge)
> +{
> + struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
> + int ret;
> +
> + if (!bridge->encoder) {
> + dev_err(dvi->dev, "Missing encoder\n");
> + return -ENODEV;
> + }
> +
> + drm_connector_helper_add(&dvi->connector,
> + &tfp410_con_helper_funcs);
> + ret = drm_connector_init(bridge->dev, &dvi->connector,
> + &tfp410_con_funcs, DRM_MODE_CONNECTOR_HDMIA);
> + if (ret) {
> + dev_err(dvi->dev, "drm_connector_init() failed: %d\n", ret);
> + return ret;
> + }
> +
> + drm_mode_connector_attach_encoder(&dvi->connector,
> + bridge->encoder);
> +
> + return 0;
> +}
> +
> +static const struct drm_bridge_funcs tfp410_bridge_funcs = {
> + .attach = tfp410_attach,
> +};
> +
> +static int tfp410_get_connector_ddc(struct tfp410 *dvi)
> +{
> + struct device_node *ep = NULL, *connector_node = NULL;
> + struct device_node *ddc_phandle = NULL;
> + int ret = 0;
> +
> + /* port@1 is the connector node */
> + ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 1, -1);
> + if (!ep)
> + goto fail;
> +
> + connector_node = of_graph_get_remote_port_parent(ep);
> + if (!connector_node)
> + goto fail;
> +
> + ddc_phandle = of_parse_phandle(connector_node, "ddc-i2c-bus", 0);
> + if (!ddc_phandle)
> + goto fail;
> +
> + dvi->ddc = of_get_i2c_adapter_by_node(ddc_phandle);
> + if (dvi->ddc)
> + dev_info(dvi->dev, "Connector's ddc i2c bus found\n");
> + else
> + ret = -EPROBE_DEFER;
> +
> +fail:
> + of_node_put(ep);
> + of_node_put(connector_node);
> + of_node_put(ddc_phandle);
> + return ret;
> +}
> +
> +static int tfp410_init(struct device *dev)
> +{
> + struct tfp410 *dvi;
> + int ret;
> +
> + if (!dev->of_node) {
> + dev_err(dev, "device-tree data is missing\n");
> + return -ENXIO;
> + }
> +
> + dvi = devm_kzalloc(dev, sizeof(*dvi), GFP_KERNEL);
> + if (!dvi)
> + return -ENOMEM;
> + dev_set_drvdata(dev, dvi);
> +
> + dvi->bridge.funcs = &tfp410_bridge_funcs;
> + dvi->bridge.of_node = dev->of_node;
> + dvi->dev = dev;
> +
> + ret = tfp410_get_connector_ddc(dvi);
> + if (ret)
> + goto fail;
> +
> + ret = drm_bridge_add(&dvi->bridge);
> + if (ret) {
> + dev_err(dev, "drm_bridge_add() failed: %d\n", ret);
> + goto fail;
> + }
> +
> + return 0;
> +fail:
> + i2c_put_adapter(dvi->ddc);
> + return ret;
> +}
> +
> +static int tfp410_fini(struct device *dev)
> +{
> + struct tfp410 *dvi = dev_get_drvdata(dev);
> +
> + drm_bridge_remove(&dvi->bridge);
> +
> + if (dvi->ddc)
> + i2c_put_adapter(dvi->ddc);
> +
> + return 0;
> +}
> +
> +static int tfp410_probe(struct platform_device *pdev)
> +{
> + return tfp410_init(&pdev->dev);
> +}
> +
> +static int tfp410_remove(struct platform_device *pdev)
> +{
> + return tfp410_fini(&pdev->dev);
> +}
> +
Argh... I think I should still put all i2c code between
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#endif
Otherwise I think this is now finally ready.
> +/* There is currently no i2c functionality. */
> +static int tfp410_i2c_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + int reg;
> +
> + if (!client->dev.of_node ||
> + of_property_read_u32(client->dev.of_node, "reg", ®)) {
> + dev_err(&client->dev,
> + "Can't get i2c reg property from device-tree\n");
> + return -ENXIO;
> + }
> +
> + return tfp410_init(&client->dev);
> +}
> +
> +static int tfp410_i2c_remove(struct i2c_client *client)
> +{
> + return tfp410_fini(&client->dev);
> +}
> +
> +static const struct of_device_id tfp410_match[] = {
> + { .compatible = "ti,tfp410" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, tfp410_match);
> +
> +struct platform_driver tfp410_platform_driver = {
> + .probe = tfp410_probe,
> + .remove = tfp410_remove,
> + .driver = {
> + .name = "tfp410-bridge",
> + .of_match_table = tfp410_match,
> + },
> +};
> +
> +static const struct i2c_device_id tfp410_i2c_ids[] = {
> + { "tfp410", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, tfp410_i2c_ids);
> +
> +static struct i2c_driver tfp410_i2c_driver = {
> + .driver = {
> + .name = "tfp410",
> + .of_match_table = of_match_ptr(tfp410_match),
> + },
> + .id_table = tfp410_i2c_ids,
> + .probe = tfp410_i2c_probe,
> + .remove = tfp410_i2c_remove,
> +};
> +
> +static struct {
> + uint i2c:1;
> + uint platform:1;
> +} tfp410_registered_driver;
> +
> +static int __init tfp410_module_init(void)
> +{
> + int ret;
> +
> + ret = i2c_add_driver(&tfp410_i2c_driver);
> + if (ret)
> + pr_err("%s: registering i2c driver failed: %d",
> + __func__, ret);
> + else
> + tfp410_registered_driver.i2c = 1;
> +
> + ret = platform_driver_register(&tfp410_platform_driver);
> + if (ret)
> + pr_err("%s: registering platform driver failed: %d",
> + __func__, ret);
> + else
> + tfp410_registered_driver.platform = 1;
> +
> + if (tfp410_registered_driver.i2c ||
> + tfp410_registered_driver.platform)
> + return 0;
> +
> + return ret;
> +}
> +module_init(tfp410_module_init);
> +
> +static void __exit tfp410_module_exit(void)
> +{
> + if (tfp410_registered_driver.i2c)
> + i2c_del_driver(&tfp410_i2c_driver);
> + if (tfp410_registered_driver.platform)
> + platform_driver_unregister(&tfp410_platform_driver);
> +}
> +module_exit(tfp410_module_exit);
> +
> +MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
> +MODULE_DESCRIPTION("TI TFP410 DVI bridge driver");
> +MODULE_LICENSE("GPL");
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [PATCH v17 4/4] soc: mediatek: Add Mediatek CMDQ helper
From: HS Liao @ 2016-11-23 8:39 UTC (permalink / raw)
To: Rob Herring, Matthias Brugger, Jassi Brar
Cc: Monica Wang, Jiaguang Zhang, Nicolas Boichat, cawa cheng, HS Liao,
Bibby Hsieh, YT Shen, Damon Chu,
devicetree-u79uwXL29TY76Z2rM5mHXA, Sascha Hauer, Daoyuan Huang,
Sascha Hauer, Glory Hung, CK HU,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Josh-YC Liu,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Dennis-YC Hsieh,
Philipp Zabel
In-Reply-To: <1479890343-4979-1-git-send-email-hs.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
Signed-off-by: HS Liao <hs.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
drivers/soc/mediatek/Kconfig | 11 ++
drivers/soc/mediatek/Makefile | 1 +
drivers/soc/mediatek/mtk-cmdq-helper.c | 310 +++++++++++++++++++++++++++++++++
include/linux/soc/mediatek/mtk-cmdq.h | 174 ++++++++++++++++++
4 files changed, 496 insertions(+)
create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..94651ed 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,17 @@
#
# MediaTek SoC drivers
#
+config MTK_CMDQ
+ bool "MediaTek CMDQ Support"
+ depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
+ select MTK_CMDQ_MBOX
+ select MTK_INFRACFG
+ help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 0000000..7809e65
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/errno.h>
+#include <linux/of_address.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#define CMDQ_SUBSYS_SHIFT 16
+#define CMDQ_ARG_A_WRITE_MASK 0xffff
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_EN BIT(0)
+#define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+ << 32 | CMDQ_EOC_IRQ_EN)
+
+struct cmdq_subsys {
+ u32 base;
+ int id;
+};
+
+static const struct cmdq_subsys gce_subsys[] = {
+ {0x1400, 1},
+ {0x1401, 2},
+ {0x1402, 3},
+};
+
+static int cmdq_subsys_base_to_id(u32 base)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(gce_subsys); i++)
+ if (gce_subsys[i].base == base)
+ return gce_subsys[i].id;
+ return -EFAULT;
+}
+
+static int cmdq_pkt_realloc_cmd_buffer(struct cmdq_pkt *pkt, size_t size)
+{
+ void *new_buf;
+
+ new_buf = krealloc(pkt->va_base, size, GFP_KERNEL | __GFP_ZERO);
+ if (!new_buf)
+ return -ENOMEM;
+ pkt->va_base = new_buf;
+ pkt->buf_size = size;
+ return 0;
+}
+
+struct cmdq_base *cmdq_register_device(struct device *dev)
+{
+ struct cmdq_base *cmdq_base;
+ struct resource res;
+ int subsys;
+ u32 base;
+
+ if (of_address_to_resource(dev->of_node, 0, &res))
+ return NULL;
+ base = (u32)res.start;
+
+ subsys = cmdq_subsys_base_to_id(base >> 16);
+ if (subsys < 0)
+ return NULL;
+
+ cmdq_base = devm_kmalloc(dev, sizeof(*cmdq_base), GFP_KERNEL);
+ if (!cmdq_base)
+ return NULL;
+ cmdq_base->subsys = subsys;
+ cmdq_base->base = base;
+
+ return cmdq_base;
+}
+EXPORT_SYMBOL(cmdq_register_device);
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index)
+{
+ struct cmdq_client *client;
+
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
+ client->client.dev = dev;
+ client->client.tx_block = false;
+ client->chan = mbox_request_channel(&client->client, index);
+ return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+ mbox_free_channel(client->chan);
+ kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+int cmdq_pkt_create(struct cmdq_pkt **pkt_ptr)
+{
+ struct cmdq_pkt *pkt;
+ int err;
+
+ pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+ if (!pkt)
+ return -ENOMEM;
+ err = cmdq_pkt_realloc_cmd_buffer(pkt, PAGE_SIZE);
+ if (err < 0) {
+ kfree(pkt);
+ return err;
+ }
+ *pkt_ptr = pkt;
+ return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+{
+ kfree(pkt->va_base);
+ kfree(pkt);
+}
+EXPORT_SYMBOL(cmdq_pkt_destroy);
+
+static bool cmdq_pkt_is_finalized(struct cmdq_pkt *pkt)
+{
+ u64 *expect_eoc;
+
+ if (pkt->cmd_buf_size < CMDQ_INST_SIZE << 1)
+ return false;
+
+ expect_eoc = pkt->va_base + pkt->cmd_buf_size - (CMDQ_INST_SIZE << 1);
+ if (*expect_eoc == CMDQ_EOC_CMD)
+ return true;
+
+ return false;
+}
+
+static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
+ u32 arg_a, u32 arg_b)
+{
+ u64 *cmd_ptr;
+ int err;
+
+ if (WARN_ON(cmdq_pkt_is_finalized(pkt)))
+ return -EBUSY;
+ if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
+ err = cmdq_pkt_realloc_cmd_buffer(pkt, pkt->buf_size << 1);
+ if (err < 0)
+ return err;
+ }
+ cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
+ (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
+ pkt->cmd_buf_size += CMDQ_INST_SIZE;
+ return 0;
+}
+
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, struct cmdq_base *base,
+ u32 offset)
+{
+ u32 arg_a = ((base->base + offset) & CMDQ_ARG_A_WRITE_MASK) |
+ (base->subsys << CMDQ_SUBSYS_SHIFT);
+ return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
+}
+EXPORT_SYMBOL(cmdq_pkt_write);
+
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
+ struct cmdq_base *base, u32 offset, u32 mask)
+{
+ u32 offset_mask = offset;
+ int err;
+
+ if (mask != 0xffffffff) {
+ err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
+ if (err < 0)
+ return err;
+ offset_mask |= CMDQ_WRITE_ENABLE_MASK;
+ }
+ return cmdq_pkt_write(pkt, value, base, offset_mask);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_mask);
+
+static const u32 cmdq_event_value[CMDQ_MAX_EVENT] = {
+ /* Display start of frame(SOF) events */
+ [CMDQ_EVENT_DISP_OVL0_SOF] = 11,
+ [CMDQ_EVENT_DISP_OVL1_SOF] = 12,
+ [CMDQ_EVENT_DISP_RDMA0_SOF] = 13,
+ [CMDQ_EVENT_DISP_RDMA1_SOF] = 14,
+ [CMDQ_EVENT_DISP_RDMA2_SOF] = 15,
+ [CMDQ_EVENT_DISP_WDMA0_SOF] = 16,
+ [CMDQ_EVENT_DISP_WDMA1_SOF] = 17,
+ /* Display end of frame(EOF) events */
+ [CMDQ_EVENT_DISP_OVL0_EOF] = 39,
+ [CMDQ_EVENT_DISP_OVL1_EOF] = 40,
+ [CMDQ_EVENT_DISP_RDMA0_EOF] = 41,
+ [CMDQ_EVENT_DISP_RDMA1_EOF] = 42,
+ [CMDQ_EVENT_DISP_RDMA2_EOF] = 43,
+ [CMDQ_EVENT_DISP_WDMA0_EOF] = 44,
+ [CMDQ_EVENT_DISP_WDMA1_EOF] = 45,
+ /* Mutex end of frame(EOF) events */
+ [CMDQ_EVENT_MUTEX0_STREAM_EOF] = 53,
+ [CMDQ_EVENT_MUTEX1_STREAM_EOF] = 54,
+ [CMDQ_EVENT_MUTEX2_STREAM_EOF] = 55,
+ [CMDQ_EVENT_MUTEX3_STREAM_EOF] = 56,
+ [CMDQ_EVENT_MUTEX4_STREAM_EOF] = 57,
+ /* Display underrun events */
+ [CMDQ_EVENT_DISP_RDMA0_UNDERRUN] = 63,
+ [CMDQ_EVENT_DISP_RDMA1_UNDERRUN] = 64,
+ [CMDQ_EVENT_DISP_RDMA2_UNDERRUN] = 65,
+};
+
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, enum cmdq_event event)
+{
+ u32 arg_b;
+
+ if (event >= CMDQ_MAX_EVENT || event < 0)
+ return -EINVAL;
+
+ /*
+ * WFE arg_b
+ * bit 0-11: wait value
+ * bit 15: 1 - wait, 0 - no wait
+ * bit 16-27: update value
+ * bit 31: 1 - update, 0 - no update
+ */
+ arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
+ return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE,
+ cmdq_event_value[event], arg_b);
+}
+EXPORT_SYMBOL(cmdq_pkt_wfe);
+
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, enum cmdq_event event)
+{
+ if (event >= CMDQ_MAX_EVENT || event < 0)
+ return -EINVAL;
+
+ return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE,
+ cmdq_event_value[event], CMDQ_WFE_UPDATE);
+}
+EXPORT_SYMBOL(cmdq_pkt_clear_event);
+
+static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
+{
+ int err;
+
+ if (cmdq_pkt_is_finalized(pkt))
+ return 0;
+
+ /* insert EOC and generate IRQ for each command iteration */
+ err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN);
+ if (err < 0)
+ return err;
+
+ /* JUMP to end */
+ err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+int cmdq_pkt_flush_async(struct cmdq_client *client, struct cmdq_pkt *pkt,
+ cmdq_async_flush_cb cb, void *data)
+{
+ int err;
+
+ err = cmdq_pkt_finalize(pkt);
+ if (err < 0)
+ return err;
+
+ pkt->cb.cb = cb;
+ pkt->cb.data = data;
+
+ mbox_send_message(client->chan, pkt);
+ /* We can send next packet immediately, so just call txdone. */
+ mbox_client_txdone(client->chan, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_flush_async);
+
+struct cmdq_flush_completion {
+ struct completion cmplt;
+ bool err;
+};
+
+static void cmdq_pkt_flush_cb(struct cmdq_cb_data data)
+{
+ struct cmdq_flush_completion *cmplt = data.data;
+
+ cmplt->err = data.err;
+ complete(&cmplt->cmplt);
+}
+
+int cmdq_pkt_flush(struct cmdq_client *client, struct cmdq_pkt *pkt)
+{
+ struct cmdq_flush_completion cmplt;
+ int err;
+
+ init_completion(&cmplt.cmplt);
+ err = cmdq_pkt_flush_async(client, pkt, cmdq_pkt_flush_cb, &cmplt);
+ if (err < 0)
+ return err;
+ wait_for_completion(&cmplt.cmplt);
+ return cmplt.err ? -EFAULT : 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_flush);
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
new file mode 100644
index 0000000..5b35d73
--- /dev/null
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_CMDQ_H__
+#define __MTK_CMDQ_H__
+
+#include <linux/mailbox_client.h>
+#include <linux/mailbox/mtk-cmdq-mailbox.h>
+
+/* display events in command queue(CMDQ) */
+enum cmdq_event {
+ /* Display start of frame(SOF) events */
+ CMDQ_EVENT_DISP_OVL0_SOF,
+ CMDQ_EVENT_DISP_OVL1_SOF,
+ CMDQ_EVENT_DISP_RDMA0_SOF,
+ CMDQ_EVENT_DISP_RDMA1_SOF,
+ CMDQ_EVENT_DISP_RDMA2_SOF,
+ CMDQ_EVENT_DISP_WDMA0_SOF,
+ CMDQ_EVENT_DISP_WDMA1_SOF,
+ /* Display end of frame(EOF) events */
+ CMDQ_EVENT_DISP_OVL0_EOF,
+ CMDQ_EVENT_DISP_OVL1_EOF,
+ CMDQ_EVENT_DISP_RDMA0_EOF,
+ CMDQ_EVENT_DISP_RDMA1_EOF,
+ CMDQ_EVENT_DISP_RDMA2_EOF,
+ CMDQ_EVENT_DISP_WDMA0_EOF,
+ CMDQ_EVENT_DISP_WDMA1_EOF,
+ /* Mutex end of frame(EOF) events */
+ CMDQ_EVENT_MUTEX0_STREAM_EOF,
+ CMDQ_EVENT_MUTEX1_STREAM_EOF,
+ CMDQ_EVENT_MUTEX2_STREAM_EOF,
+ CMDQ_EVENT_MUTEX3_STREAM_EOF,
+ CMDQ_EVENT_MUTEX4_STREAM_EOF,
+ /* Display underrun events */
+ CMDQ_EVENT_DISP_RDMA0_UNDERRUN,
+ CMDQ_EVENT_DISP_RDMA1_UNDERRUN,
+ CMDQ_EVENT_DISP_RDMA2_UNDERRUN,
+ /* Keep this at the end */
+ CMDQ_MAX_EVENT,
+};
+
+struct cmdq_pkt;
+
+struct cmdq_base {
+ int subsys;
+ u32 base;
+};
+
+struct cmdq_client {
+ struct mbox_client client;
+ struct mbox_chan *chan;
+};
+
+/**
+ * cmdq_register_device() - register device which needs CMDQ
+ * @dev: device for CMDQ to access its registers
+ *
+ * Return: cmdq_base pointer or NULL for failed
+ */
+struct cmdq_base *cmdq_register_device(struct device *dev);
+
+/**
+ * cmdq_mbox_create() - create CMDQ mailbox client and channel
+ * @dev: device of CMDQ mailbox client
+ * @index: index of CMDQ mailbox channel
+ *
+ * Return: CMDQ mailbox client pointer
+ */
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index);
+
+/**
+ * cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel
+ * @client: the CMDQ mailbox client
+ */
+void cmdq_mbox_destroy(struct cmdq_client *client);
+
+/**
+ * cmdq_pkt_create() - create a CMDQ packet
+ * @pkt_ptr: CMDQ packet pointer to retrieve cmdq_pkt
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_create(struct cmdq_pkt **pkt_ptr);
+
+/**
+ * cmdq_pkt_destroy() - destroy the CMDQ packet
+ * @pkt: the CMDQ packet
+ */
+void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
+
+/**
+ * cmdq_pkt_write() - append write command to the CMDQ packet
+ * @pkt: the CMDQ packet
+ * @value: the specified target register value
+ * @base: the CMDQ base
+ * @offset: register offset from module base
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value,
+ struct cmdq_base *base, u32 offset);
+
+/**
+ * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
+ * @pkt: the CMDQ packet
+ * @value: the specified target register value
+ * @base: the CMDQ base
+ * @offset: register offset from module base
+ * @mask: the specified target register mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
+ struct cmdq_base *base, u32 offset, u32 mask);
+
+/**
+ * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
+ * @pkt: the CMDQ packet
+ * @event: the desired event type to "wait and CLEAR"
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, enum cmdq_event event);
+
+/**
+ * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
+ * @pkt: the CMDQ packet
+ * @event: the desired event to be cleared
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, enum cmdq_event event);
+
+/**
+ * cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet
+ * @client: the CMDQ mailbox client
+ * @pkt: the CMDQ packet
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Trigger CMDQ to execute the CMDQ packet. Note that this is a
+ * synchronous flush function. When the function returned, the recorded
+ * commands have been done.
+ */
+int cmdq_pkt_flush(struct cmdq_client *client, struct cmdq_pkt *pkt);
+
+/**
+ * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
+ * packet and call back at the end of done packet
+ * @client: the CMDQ mailbox client
+ * @pkt: the CMDQ packet
+ * @cb: called at the end of done packet
+ * @data: this data will pass back to cb
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Trigger CMDQ to asynchronously execute the CMDQ packet and call back
+ * at the end of done packet. Note that this is an ASYNC function. When the
+ * function returned, it may or may not be finished.
+ */
+int cmdq_pkt_flush_async(struct cmdq_client *client, struct cmdq_pkt *pkt,
+ cmdq_async_flush_cb cb, void *data);
+
+#endif /* __MTK_CMDQ_H__ */
--
1.9.1
^ permalink raw reply related
* [PATCH v17 3/4] arm64: dts: mt8173: Add GCE node
From: HS Liao @ 2016-11-23 8:39 UTC (permalink / raw)
To: Rob Herring, Matthias Brugger, Jassi Brar
Cc: Daniel Kurtz, Monica Wang, Jiaguang Zhang, Nicolas Boichat,
cawa cheng, HS Liao, Bibby Hsieh, YT Shen, Damon Chu, devicetree,
Sascha Hauer, Daoyuan Huang, Sascha Hauer, Glory Hung, CK HU,
linux-mediatek, linux-arm-kernel, srv_heupstream, Josh-YC Liu,
linux-kernel, Dennis-YC Hsieh, Philipp Zabel
In-Reply-To: <1479890343-4979-1-git-send-email-hs.liao@mediatek.com>
This patch adds the device node of the GCE hardware for CMDQ module.
Signed-off-by: HS Liao <hs.liao@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 1c71e25..d50c044 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -414,6 +414,16 @@
status = "disabled";
};
+ gce: gce@10212000 {
+ compatible = "mediatek,mt8173-gce";
+ reg = <0 0x10212000 0 0x1000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_GCE>;
+ clock-names = "gce";
+
+ #mbox-cells = <2>;
+ };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
--
1.9.1
^ permalink raw reply related
* [PATCH v17 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
From: HS Liao @ 2016-11-23 8:39 UTC (permalink / raw)
To: Rob Herring, Matthias Brugger, Jassi Brar
Cc: Monica Wang, Jiaguang Zhang, Nicolas Boichat, cawa cheng, HS Liao,
Bibby Hsieh, YT Shen, Damon Chu,
devicetree-u79uwXL29TY76Z2rM5mHXA, Sascha Hauer, Daoyuan Huang,
Sascha Hauer, Glory Hung, CK HU,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Josh-YC Liu,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Dennis-YC Hsieh,
Philipp Zabel
In-Reply-To: <1479890343-4979-1-git-send-email-hs.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.
Signed-off-by: HS Liao <hs.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Signed-off-by: CK Hu <ck.hu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
drivers/mailbox/Kconfig | 10 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mtk-cmdq-mailbox.c | 632 +++++++++++++++++++++++++++++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 75 ++++
4 files changed, 719 insertions(+)
create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 11eebfe..5a4af2d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -143,4 +143,14 @@ config BCM_PDC_MBOX
Mailbox implementation for the Broadcom PDC ring manager,
which provides access to various offload engines on Broadcom
SoCs. Say Y here if you want to use the Broadcom PDC.
+
+config MTK_CMDQ_MBOX
+ bool "MediaTek CMDQ Mailbox Support"
+ depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
+ select MTK_INFRACFG
+ help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ mailbox driver. The CMDQ is used to help read/write registers with
+ critical time limitation, such as updating display configuration
+ during the vblank.
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index ace6fed..b904bed 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -29,3 +29,5 @@ obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o
obj-$(CONFIG_HI6220_MBOX) += hi6220-mailbox.o
obj-$(CONFIG_BCM_PDC_MBOX) += bcm-pdc-mailbox.o
+
+obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
new file mode 100644
index 0000000..8771e57
--- /dev/null
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox/mtk-cmdq-mailbox.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+
+#define CMDQ_THR_MAX_COUNT 3 /* main, sub, general(misc) */
+#define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT)
+#define CMDQ_TIMEOUT_MS 1000
+#define CMDQ_IRQ_MASK 0xffff
+#define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE)
+
+#define CMDQ_CURR_IRQ_STATUS 0x10
+#define CMDQ_THR_SLOT_CYCLES 0x30
+
+#define CMDQ_THR_BASE 0x100
+#define CMDQ_THR_SIZE 0x80
+#define CMDQ_THR_WARM_RESET 0x00
+#define CMDQ_THR_ENABLE_TASK 0x04
+#define CMDQ_THR_SUSPEND_TASK 0x08
+#define CMDQ_THR_CURR_STATUS 0x0c
+#define CMDQ_THR_IRQ_STATUS 0x10
+#define CMDQ_THR_IRQ_ENABLE 0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR 0x24
+#define CMDQ_THR_WAIT_TOKEN 0x30
+
+#define CMDQ_THR_ENABLED 0x1
+#define CMDQ_THR_DISABLED 0x0
+#define CMDQ_THR_SUSPEND 0x1
+#define CMDQ_THR_RESUME 0x0
+#define CMDQ_THR_STATUS_SUSPENDED BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES 0x3200
+#define CMDQ_THR_IRQ_DONE 0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | CMDQ_THR_IRQ_DONE)
+#define CMDQ_THR_IS_WAITING BIT(31)
+
+#define CMDQ_JUMP_BY_OFFSET 0x10000000
+#define CMDQ_JUMP_BY_PA 0x10000001
+
+struct cmdq_thread {
+ struct mbox_chan *chan;
+ void __iomem *base;
+ struct list_head task_busy_list;
+ struct timer_list timeout;
+ bool atomic_exec;
+};
+
+struct cmdq_task {
+ struct cmdq *cmdq;
+ struct list_head list_entry;
+ dma_addr_t pa_base;
+ struct cmdq_thread *thread;
+ struct cmdq_pkt *pkt; /* the packet sent from mailbox client */
+};
+
+struct cmdq_clk_release {
+ struct cmdq *cmdq;
+ struct work_struct release_work;
+};
+
+struct cmdq {
+ struct mbox_controller mbox;
+ void __iomem *base;
+ u32 irq;
+ struct workqueue_struct *clk_release_wq;
+ struct cmdq_thread thread[CMDQ_THR_MAX_COUNT];
+ struct clk *clock;
+ bool suspended;
+};
+
+static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+ u32 status;
+
+ writel(CMDQ_THR_SUSPEND, thread->base + CMDQ_THR_SUSPEND_TASK);
+
+ /* If already disabled, treat as suspended successful. */
+ if (!(readl(thread->base + CMDQ_THR_ENABLE_TASK) & CMDQ_THR_ENABLED))
+ return 0;
+
+ if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_CURR_STATUS,
+ status, status & CMDQ_THR_STATUS_SUSPENDED, 0, 10)) {
+ dev_err(cmdq->mbox.dev, "suspend GCE thread 0x%x failed\n",
+ (u32)(thread->base - cmdq->base));
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void cmdq_thread_resume(struct cmdq_thread *thread)
+{
+ writel(CMDQ_THR_RESUME, thread->base + CMDQ_THR_SUSPEND_TASK);
+}
+
+static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+ u32 warm_reset;
+
+ writel(CMDQ_THR_DO_WARM_RESET, thread->base + CMDQ_THR_WARM_RESET);
+ if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_WARM_RESET,
+ warm_reset, !(warm_reset & CMDQ_THR_DO_WARM_RESET),
+ 0, 10)) {
+ dev_err(cmdq->mbox.dev, "reset GCE thread 0x%x failed\n",
+ (u32)(thread->base - cmdq->base));
+ return -EFAULT;
+ }
+ writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
+ return 0;
+}
+
+static void cmdq_thread_disable(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+ cmdq_thread_reset(cmdq, thread);
+ writel(CMDQ_THR_DISABLED, thread->base + CMDQ_THR_ENABLE_TASK);
+}
+
+/* notify GCE to re-fetch commands by setting GCE thread PC */
+static void cmdq_thread_invalidate_fetched_data(struct cmdq_thread *thread)
+{
+ writel(readl(thread->base + CMDQ_THR_CURR_ADDR),
+ thread->base + CMDQ_THR_CURR_ADDR);
+}
+
+static void cmdq_task_insert_into_thread(struct cmdq_task *task)
+{
+ struct device *dev = task->cmdq->mbox.dev;
+ struct cmdq_thread *thread = task->thread;
+ struct cmdq_task *prev_task = list_last_entry(
+ &thread->task_busy_list, typeof(*task), list_entry);
+ u64 *prev_task_base = prev_task->pkt->va_base;
+
+ /* let previous task jump to this task */
+ dma_sync_single_for_cpu(dev, prev_task->pa_base,
+ prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+ prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
+ (u64)CMDQ_JUMP_BY_PA << 32 | task->pa_base;
+ dma_sync_single_for_device(dev, prev_task->pa_base,
+ prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+
+ cmdq_thread_invalidate_fetched_data(thread);
+}
+
+static bool cmdq_command_is_wfe(u64 cmd)
+{
+ u64 wfe_option = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
+ u64 wfe_op = (u64)(CMDQ_CODE_WFE << CMDQ_OP_CODE_SHIFT) << 32;
+ u64 wfe_mask = (u64)CMDQ_OP_CODE_MASK << 32 | 0xffffffff;
+
+ return ((cmd & wfe_mask) == (wfe_op | wfe_option));
+}
+
+/* we assume tasks in the same display GCE thread are waiting the same event. */
+static void cmdq_task_remove_wfe(struct cmdq_task *task)
+{
+ struct device *dev = task->cmdq->mbox.dev;
+ u64 *base = task->pkt->va_base;
+ int i;
+
+ dma_sync_single_for_cpu(dev, task->pa_base, task->pkt->cmd_buf_size,
+ DMA_TO_DEVICE);
+ for (i = 0; i < CMDQ_NUM_CMD(task->pkt); i++)
+ if (cmdq_command_is_wfe(base[i]))
+ base[i] = (u64)CMDQ_JUMP_BY_OFFSET << 32 |
+ CMDQ_JUMP_PASS;
+ dma_sync_single_for_device(dev, task->pa_base, task->pkt->cmd_buf_size,
+ DMA_TO_DEVICE);
+}
+
+static bool cmdq_thread_is_in_wfe(struct cmdq_thread *thread)
+{
+ return readl(thread->base + CMDQ_THR_WAIT_TOKEN) & CMDQ_THR_IS_WAITING;
+}
+
+static void cmdq_thread_wait_end(struct cmdq_thread *thread,
+ unsigned long end_pa)
+{
+ struct device *dev = thread->chan->mbox->dev;
+ unsigned long curr_pa;
+
+ if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_CURR_ADDR,
+ curr_pa, curr_pa == end_pa, 1, 20))
+ dev_err(dev, "GCE thread cannot run to end.\n");
+}
+
+static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread *thread)
+{
+ struct cmdq *cmdq;
+ struct cmdq_task *task;
+ unsigned long curr_pa, end_pa, flags;
+
+ cmdq = dev_get_drvdata(thread->chan->mbox->dev);
+
+ /* Client should not flush new tasks if suspended. */
+ WARN_ON(cmdq->suspended);
+
+ task = kzalloc(sizeof(*task), GFP_ATOMIC);
+ task->cmdq = cmdq;
+ INIT_LIST_HEAD(&task->list_entry);
+ task->pa_base = dma_map_single(cmdq->mbox.dev, pkt->va_base,
+ pkt->cmd_buf_size, DMA_TO_DEVICE);
+ task->thread = thread;
+ task->pkt = pkt;
+
+ if (list_empty(&thread->task_busy_list)) {
+ /*
+ * Unlock for clk prepare (sleeping function).
+ * This is safe since clk_prepare_enable has internal locks.
+ */
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+ WARN_ON(clk_prepare_enable(cmdq->clock) < 0);
+ spin_lock_irqsave(&thread->chan->lock, flags);
+
+ WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
+
+ writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+ writel(task->pa_base + pkt->cmd_buf_size,
+ thread->base + CMDQ_THR_END_ADDR);
+ writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
+ writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
+
+ mod_timer(&thread->timeout,
+ jiffies + msecs_to_jiffies(CMDQ_TIMEOUT_MS));
+ } else {
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+ curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+ end_pa = readl(thread->base + CMDQ_THR_END_ADDR);
+
+ /*
+ * Atomic execution should remove the following wfe, i.e. only
+ * wait event at first task, and prevent to pause when running.
+ */
+ if (thread->atomic_exec) {
+ /* GCE is executing if command is not WFE */
+ if (!cmdq_thread_is_in_wfe(thread)) {
+ cmdq_thread_resume(thread);
+ cmdq_thread_wait_end(thread, end_pa);
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+ /* set to this task directly */
+ writel(task->pa_base,
+ thread->base + CMDQ_THR_CURR_ADDR);
+ } else {
+ cmdq_task_insert_into_thread(task);
+ cmdq_task_remove_wfe(task);
+ smp_mb(); /* modify jump before enable thread */
+ }
+ } else {
+ /* check boundary */
+ if (curr_pa == end_pa - CMDQ_INST_SIZE ||
+ curr_pa == end_pa) {
+ /* set to this task directly */
+ writel(task->pa_base,
+ thread->base + CMDQ_THR_CURR_ADDR);
+ } else {
+ cmdq_task_insert_into_thread(task);
+ smp_mb(); /* modify jump before enable thread */
+ }
+ }
+ writel(task->pa_base + pkt->cmd_buf_size,
+ thread->base + CMDQ_THR_END_ADDR);
+ cmdq_thread_resume(thread);
+ }
+ list_move_tail(&task->list_entry, &thread->task_busy_list);
+}
+
+static void cmdq_task_exec_done(struct cmdq_task *task, bool err)
+{
+ struct device *dev = task->cmdq->mbox.dev;
+ struct cmdq_cb_data cmdq_cb_data;
+
+ dma_unmap_single(dev, task->pa_base, task->pkt->cmd_buf_size,
+ DMA_TO_DEVICE);
+ if (task->pkt->cb.cb) {
+ cmdq_cb_data.err = err;
+ cmdq_cb_data.data = task->pkt->cb.data;
+ task->pkt->cb.cb(cmdq_cb_data);
+ }
+ list_del(&task->list_entry);
+}
+
+static void cmdq_task_handle_error(struct cmdq_task *task)
+{
+ struct cmdq_thread *thread = task->thread;
+ struct cmdq_task *next_task;
+
+ dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
+ WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
+ next_task = list_first_entry_or_null(&thread->task_busy_list,
+ struct cmdq_task, list_entry);
+ if (next_task)
+ writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+ cmdq_thread_resume(thread);
+}
+
+static void cmdq_clk_release_work(struct work_struct *work_item)
+{
+ struct cmdq_clk_release *clk_release = container_of(work_item,
+ struct cmdq_clk_release, release_work);
+ struct cmdq *cmdq = clk_release->cmdq;
+
+ clk_disable_unprepare(cmdq->clock);
+ kfree(clk_release);
+}
+
+static void cmdq_clk_release_schedule(struct cmdq *cmdq)
+{
+ struct cmdq_clk_release *clk_release;
+
+ clk_release = kmalloc(sizeof(*clk_release), GFP_ATOMIC);
+ clk_release->cmdq = cmdq;
+ INIT_WORK(&clk_release->release_work, cmdq_clk_release_work);
+ queue_work(cmdq->clk_release_wq, &clk_release->release_work);
+}
+
+static void cmdq_thread_irq_handler(struct cmdq *cmdq,
+ struct cmdq_thread *thread)
+{
+ struct cmdq_task *task, *tmp, *curr_task = NULL;
+ u32 curr_pa, irq_flag, task_end_pa;
+ bool err;
+
+ irq_flag = readl(thread->base + CMDQ_THR_IRQ_STATUS);
+ writel(~irq_flag, thread->base + CMDQ_THR_IRQ_STATUS);
+
+ /*
+ * When ISR call this function, another CPU core could run
+ * "release task" right before we acquire the spin lock, and thus
+ * reset / disable this GCE thread, so we need to check the enable
+ * bit of this GCE thread.
+ */
+ if (!(readl(thread->base + CMDQ_THR_ENABLE_TASK) & CMDQ_THR_ENABLED))
+ return;
+
+ if (irq_flag & CMDQ_THR_IRQ_ERROR)
+ err = true;
+ else if (irq_flag & CMDQ_THR_IRQ_DONE)
+ err = false;
+ else
+ return;
+
+ curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+
+ list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+ list_entry) {
+ task_end_pa = task->pa_base + task->pkt->cmd_buf_size;
+ if (curr_pa >= task->pa_base && curr_pa < task_end_pa)
+ curr_task = task;
+
+ if (!curr_task || curr_pa == task_end_pa - CMDQ_INST_SIZE) {
+ cmdq_task_exec_done(task, false);
+ kfree(task);
+ } else if (err) {
+ cmdq_task_exec_done(task, true);
+ cmdq_task_handle_error(curr_task);
+ kfree(task);
+ }
+
+ if (curr_task)
+ break;
+ }
+
+ if (list_empty(&thread->task_busy_list)) {
+ cmdq_thread_disable(cmdq, thread);
+ cmdq_clk_release_schedule(cmdq);
+ } else {
+ mod_timer(&thread->timeout,
+ jiffies + msecs_to_jiffies(CMDQ_TIMEOUT_MS));
+ }
+}
+
+static irqreturn_t cmdq_irq_handler(int irq, void *dev)
+{
+ struct cmdq *cmdq = dev;
+ unsigned long irq_status, flags = 0L;
+ int bit;
+
+ irq_status = readl(cmdq->base + CMDQ_CURR_IRQ_STATUS) & CMDQ_IRQ_MASK;
+ if (!(irq_status ^ CMDQ_IRQ_MASK))
+ return IRQ_NONE;
+
+ for_each_clear_bit(bit, &irq_status, fls(CMDQ_IRQ_MASK)) {
+ struct cmdq_thread *thread = &cmdq->thread[bit];
+
+ spin_lock_irqsave(&thread->chan->lock, flags);
+ cmdq_thread_irq_handler(cmdq, thread);
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+ }
+ return IRQ_HANDLED;
+}
+
+static void cmdq_thread_handle_timeout(unsigned long data)
+{
+ struct cmdq_thread *thread = (struct cmdq_thread *)data;
+ struct cmdq *cmdq = container_of(thread->chan->mbox, struct cmdq, mbox);
+ struct cmdq_task *task, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&thread->chan->lock, flags);
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+
+ /*
+ * Although IRQ is disabled, GCE continues to execute.
+ * It may have pending IRQ before GCE thread is suspended,
+ * so check this condition again.
+ */
+ cmdq_thread_irq_handler(cmdq, thread);
+
+ if (list_empty(&thread->task_busy_list)) {
+ cmdq_thread_resume(thread);
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+ return;
+ }
+
+ dev_err(cmdq->mbox.dev, "timeout\n");
+ list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+ list_entry) {
+ cmdq_task_exec_done(task, true);
+ kfree(task);
+ }
+
+ cmdq_thread_resume(thread);
+ cmdq_thread_disable(cmdq, thread);
+ cmdq_clk_release_schedule(cmdq);
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+}
+
+static int cmdq_suspend(struct device *dev)
+{
+ struct cmdq *cmdq = dev_get_drvdata(dev);
+ struct cmdq_thread *thread;
+ int i;
+ bool task_running = false;
+
+ cmdq->suspended = true;
+
+ for (i = 0; i < ARRAY_SIZE(cmdq->thread); i++) {
+ thread = &cmdq->thread[i];
+ if (!list_empty(&thread->task_busy_list)) {
+ task_running = true;
+ break;
+ }
+ }
+
+ if (task_running)
+ dev_warn(dev, "exist running task(s) in suspend\n");
+
+ flush_workqueue(cmdq->clk_release_wq);
+ return 0;
+}
+
+static int cmdq_resume(struct device *dev)
+{
+ struct cmdq *cmdq = dev_get_drvdata(dev);
+
+ cmdq->suspended = false;
+ return 0;
+}
+
+static int cmdq_remove(struct platform_device *pdev)
+{
+ struct cmdq *cmdq = platform_get_drvdata(pdev);
+
+ destroy_workqueue(cmdq->clk_release_wq);
+ mbox_controller_unregister(&cmdq->mbox);
+ return 0;
+}
+
+static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+ cmdq_task_exec(data, chan->con_priv);
+ return 0;
+}
+
+static int cmdq_mbox_startup(struct mbox_chan *chan)
+{
+ return 0;
+}
+
+static void cmdq_mbox_shutdown(struct mbox_chan *chan)
+{
+}
+
+static bool cmdq_mbox_last_tx_done(struct mbox_chan *chan)
+{
+ return true;
+}
+
+static const struct mbox_chan_ops cmdq_mbox_chan_ops = {
+ .send_data = cmdq_mbox_send_data,
+ .startup = cmdq_mbox_startup,
+ .shutdown = cmdq_mbox_shutdown,
+ .last_tx_done = cmdq_mbox_last_tx_done,
+};
+
+static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox,
+ const struct of_phandle_args *sp)
+{
+ int ind = sp->args[0];
+ struct cmdq_thread *thread;
+
+ if (ind >= mbox->num_chans)
+ return ERR_PTR(-EINVAL);
+
+ thread = mbox->chans[ind].con_priv;
+ thread->atomic_exec = (sp->args[1] != 0);
+ thread->chan = &mbox->chans[ind];
+
+ return &mbox->chans[ind];
+}
+
+static int cmdq_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct cmdq *cmdq;
+ int err, i;
+
+ cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
+ if (!cmdq)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ cmdq->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(cmdq->base)) {
+ dev_err(dev, "failed to ioremap gce\n");
+ return PTR_ERR(cmdq->base);
+ }
+
+ cmdq->irq = platform_get_irq(pdev, 0);
+ if (!cmdq->irq) {
+ dev_err(dev, "failed to get irq\n");
+ return -EINVAL;
+ }
+ err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
+ "mtk_cmdq", cmdq);
+ if (err < 0) {
+ dev_err(dev, "failed to register ISR (%d)\n", err);
+ return err;
+ }
+
+ dev_dbg(dev, "cmdq device: addr:0x%p, va:0x%p, irq:%d\n",
+ dev, cmdq->base, cmdq->irq);
+
+ cmdq->clock = devm_clk_get(dev, "gce");
+ if (IS_ERR(cmdq->clock)) {
+ dev_err(dev, "failed to get gce clk\n");
+ return PTR_ERR(cmdq->clock);
+ }
+
+ cmdq->mbox.dev = dev;
+ cmdq->mbox.chans = devm_kcalloc(dev, CMDQ_THR_MAX_COUNT,
+ sizeof(*cmdq->mbox.chans), GFP_KERNEL);
+ if (!cmdq->mbox.chans)
+ return -ENOMEM;
+
+ cmdq->mbox.num_chans = CMDQ_THR_MAX_COUNT;
+ cmdq->mbox.ops = &cmdq_mbox_chan_ops;
+ cmdq->mbox.of_xlate = cmdq_xlate;
+
+ /* make use of TXDONE_BY_ACK */
+ cmdq->mbox.txdone_irq = false;
+ cmdq->mbox.txdone_poll = false;
+
+ for (i = 0; i < ARRAY_SIZE(cmdq->thread); i++) {
+ cmdq->thread[i].base = cmdq->base + CMDQ_THR_BASE +
+ CMDQ_THR_SIZE * i;
+ INIT_LIST_HEAD(&cmdq->thread[i].task_busy_list);
+ init_timer(&cmdq->thread[i].timeout);
+ cmdq->thread[i].timeout.function = cmdq_thread_handle_timeout;
+ cmdq->thread[i].timeout.data = (unsigned long)&cmdq->thread[i];
+ cmdq->mbox.chans[i].con_priv = &cmdq->thread[i];
+ }
+
+ err = mbox_controller_register(&cmdq->mbox);
+ if (err < 0) {
+ dev_err(dev, "failed to register mailbox: %d\n", err);
+ return err;
+ }
+
+ cmdq->clk_release_wq = alloc_ordered_workqueue(
+ "%s", WQ_MEM_RECLAIM | WQ_HIGHPRI,
+ "cmdq_clk_release");
+
+ platform_set_drvdata(pdev, cmdq);
+
+ return 0;
+}
+
+static const struct dev_pm_ops cmdq_pm_ops = {
+ .suspend = cmdq_suspend,
+ .resume = cmdq_resume,
+};
+
+static const struct of_device_id cmdq_of_ids[] = {
+ {.compatible = "mediatek,mt8173-gce",},
+ {}
+};
+
+static struct platform_driver cmdq_drv = {
+ .probe = cmdq_probe,
+ .remove = cmdq_remove,
+ .driver = {
+ .name = "mtk_cmdq",
+ .pm = &cmdq_pm_ops,
+ .of_match_table = cmdq_of_ids,
+ }
+};
+
+builtin_platform_driver(cmdq_drv);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
new file mode 100644
index 0000000..3433c64
--- /dev/null
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_CMDQ_MAILBOX_H__
+#define __MTK_CMDQ_MAILBOX_H__
+
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_OP_CODE_SHIFT 24
+#define CMDQ_JUMP_PASS CMDQ_INST_SIZE
+
+#define CMDQ_WFE_UPDATE BIT(31)
+#define CMDQ_WFE_WAIT BIT(15)
+#define CMDQ_WFE_WAIT_VALUE 0x1
+
+/*
+ * CMDQ_CODE_MASK:
+ * set write mask
+ * format: op mask
+ * CMDQ_CODE_WRITE:
+ * write value into target register
+ * format: op subsys address value
+ * CMDQ_CODE_JUMP:
+ * jump by offset
+ * format: op offset
+ * CMDQ_CODE_WFE:
+ * wait for event and clear
+ * it is just clear if no wait
+ * format: [wait] op event update:1 to_wait:1 wait:1
+ * [clear] op event update:1 to_wait:0 wait:0
+ * CMDQ_CODE_EOC:
+ * end of command
+ * format: op irq_flag
+ */
+enum cmdq_code {
+ CMDQ_CODE_MASK = 0x02,
+ CMDQ_CODE_WRITE = 0x04,
+ CMDQ_CODE_JUMP = 0x10,
+ CMDQ_CODE_WFE = 0x20,
+ CMDQ_CODE_EOC = 0x40,
+};
+
+struct cmdq_cb_data {
+ bool err;
+ void *data;
+};
+
+typedef void (*cmdq_async_flush_cb)(struct cmdq_cb_data data);
+
+struct cmdq_task_cb {
+ cmdq_async_flush_cb cb;
+ void *data;
+};
+
+struct cmdq_pkt {
+ void *va_base;
+ size_t cmd_buf_size; /* command occupied size */
+ size_t buf_size; /* real buffer size */
+ struct cmdq_task_cb cb;
+};
+
+#endif /* __MTK_CMDQ_MAILBOX_H__ */
--
1.9.1
^ permalink raw reply related
* [PATCH v17 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit
From: HS Liao @ 2016-11-23 8:39 UTC (permalink / raw)
To: Rob Herring, Matthias Brugger, Jassi Brar
Cc: Monica Wang, Jiaguang Zhang, Nicolas Boichat, cawa cheng, HS Liao,
Bibby Hsieh, YT Shen, Damon Chu,
devicetree-u79uwXL29TY76Z2rM5mHXA, Sascha Hauer, Daoyuan Huang,
Sascha Hauer, Glory Hung, CK HU,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Josh-YC Liu,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Dennis-YC Hsieh,
Philipp Zabel
In-Reply-To: <1479890343-4979-1-git-send-email-hs.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
This adds documentation for the MediaTek Global Command Engine (GCE) unit
found in MT8173 SoCs.
Signed-off-by: HS Liao <hs.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
.../devicetree/bindings/mailbox/mtk-gce.txt | 43 ++++++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
new file mode 100644
index 0000000..d2d3ccb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -0,0 +1,43 @@
+MediaTek GCE
+===============
+
+The Global Command Engine (GCE) is used to help read/write registers with
+critical time limitation, such as updating display configuration during the
+vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
+
+CMDQ driver uses mailbox framework for communication. Please refer to
+mailbox.txt for generic information about mailbox device-tree bindings.
+
+Required properties:
+- compatible: Must be "mediatek,mt8173-gce"
+- reg: Address range of the GCE unit
+- interrupts: The interrupt signal from the GCE block
+- clock: Clocks according to the common clock binding
+- clock-names: Must be "gce" to stand for GCE clock
+- #mbox-cells: Should be 2
+
+Required properties for a client device:
+- mboxes: client use mailbox to communicate with GCE, it should have this
+ property and list of phandle, mailbox channel specifiers, and atomic
+ execution flag.
+
+Example:
+
+ gce: gce@10212000 {
+ compatible = "mediatek,mt8173-gce";
+ reg = <0 0x10212000 0 0x1000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_GCE>;
+ clock-names = "gce";
+
+ #mbox-cells = <2>;
+ };
+
+Example for a client device:
+
+ mmsys: clock-controller@14000000 {
+ compatible = "mediatek,mt8173-mmsys";
+ mboxes = <&gce 0 1 /* main display with atomic execution */
+ &gce 1 1>; /* sub display with atomic execution */
+ ...
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v17 0/4] Mediatek MT8173 CMDQ support
From: HS Liao @ 2016-11-23 8:38 UTC (permalink / raw)
To: Rob Herring, Matthias Brugger, Jassi Brar
Cc: Monica Wang, Jiaguang Zhang, Nicolas Boichat, cawa cheng, HS Liao,
Bibby Hsieh, YT Shen, Damon Chu,
devicetree-u79uwXL29TY76Z2rM5mHXA, Sascha Hauer, Daoyuan Huang,
Sascha Hauer, Glory Hung, CK HU,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Josh-YC Liu,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Dennis-YC Hsieh,
Philipp Zabel
Hi,
This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.
These patches have a build dependency on top of v4.9-rc1.
Changes since v16:
- merge suspend/resume patch into cmdq driver patch
- merge power saving patch into cmdq driver patch
- split cmdq mailbox controller and cmdq helper into two different patches
Best regards,
HS Liao
HS Liao (4):
dt-bindings: soc: Add documentation for the MediaTek GCE unit
mailbox: mediatek: Add Mediatek CMDQ driver
arm64: dts: mt8173: Add GCE node
soc: mediatek: Add Mediatek CMDQ helper
.../devicetree/bindings/mailbox/mtk-gce.txt | 43 ++
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 10 +
drivers/mailbox/Kconfig | 10 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mtk-cmdq-mailbox.c | 632 +++++++++++++++++++++
drivers/soc/mediatek/Kconfig | 11 +
drivers/soc/mediatek/Makefile | 1 +
drivers/soc/mediatek/mtk-cmdq-helper.c | 310 ++++++++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 75 +++
include/linux/soc/mediatek/mtk-cmdq.h | 174 ++++++
10 files changed, 1268 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
--
1.9.1
^ permalink raw reply
* Re: [PATCH v2 4/5] arm: dts: am57xx-beagle-x15-common: Add overide powerhold property
From: Lee Jones @ 2016-11-23 8:33 UTC (permalink / raw)
To: Keerthy
Cc: Tony Lindgren, robh+dt, linux-omap, linux-kernel, devicetree,
linux-gpio, nm, t-kristo
In-Reply-To: <6ac3b28e-4891-83bc-a2f7-c903541acc18@ti.com>
On Wed, 23 Nov 2016, Keerthy wrote:
>
>
> On Tuesday 15 November 2016 05:38 AM, Tony Lindgren wrote:
> > * Keerthy <j-keerthy@ti.com> [161109 21:10]:
> > > The PMICs have POWERHOLD set by default which prevents PMIC shutdown
> > > even on DEV_CTRL On bit set to 0 as the Powerhold has higher priority.
> > > So to enable pmic power off this property lets one over ride the default
> > > value and enable pmic power off.
> >
> > This should not cause merge conflicts so probably best to merge along
> > with the driver changes:
> >
> > Acked-by: Tony Lindgren <tony@atomide.com>
> >
> > If you guys want me to pick up this separately let me know.
>
> Hi Lee Jones,
>
> Are you planning to pull DT and Documentation patches as well?
No need. They can be safely applied to their own subsystems.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v2 4/5] arm: dts: am57xx-beagle-x15-common: Add overide powerhold property
From: Keerthy @ 2016-11-23 8:32 UTC (permalink / raw)
To: Lee Jones, Tony Lindgren
Cc: robh+dt, linux-omap, linux-kernel, devicetree, linux-gpio, nm,
t-kristo
In-Reply-To: <20161123083327.GM10134@dell.home>
On Wednesday 23 November 2016 02:03 PM, Lee Jones wrote:
> On Wed, 23 Nov 2016, Keerthy wrote:
>
>>
>>
>> On Tuesday 15 November 2016 05:38 AM, Tony Lindgren wrote:
>>> * Keerthy <j-keerthy@ti.com> [161109 21:10]:
>>>> The PMICs have POWERHOLD set by default which prevents PMIC shutdown
>>>> even on DEV_CTRL On bit set to 0 as the Powerhold has higher priority.
>>>> So to enable pmic power off this property lets one over ride the default
>>>> value and enable pmic power off.
>>>
>>> This should not cause merge conflicts so probably best to merge along
>>> with the driver changes:
>>>
>>> Acked-by: Tony Lindgren <tony@atomide.com>
>>>
>>> If you guys want me to pick up this separately let me know.
>>
>> Hi Lee Jones,
>>
>> Are you planning to pull DT and Documentation patches as well?
>
> No need. They can be safely applied to their own subsystems.
Okay. Thanks for the response.
Tony,
Hope you can pull the DT patches.
>
^ permalink raw reply
* Re: [PATCH v9 00/16] mmc: sdhci-msm: Add clk-rates, DDR, HS400 support
From: Ulf Hansson @ 2016-11-23 8:32 UTC (permalink / raw)
To: Andy Gross
Cc: Ritesh Harjani, linux-mmc, Adrian Hunter, Stephen Boyd, Shawn Lin,
devicetree@vger.kernel.org, linux-clk, David Brown,
linux-arm-msm@vger.kernel.org, Georgi Djakov, Alex Lemberg,
Mateusz Nowak, Yuliy Izrailov, Asutosh Das, David Griego,
Sahitya Tummala, Venkat Gopalakrishnan, Rajendra Nayak
In-Reply-To: <20161123050038.GD16531@hector.attlocal.net>
On 23 November 2016 at 06:00, Andy Gross <andy.gross@linaro.org> wrote:
> On Mon, Nov 21, 2016 at 11:06:13AM +0100, Ulf Hansson wrote:
>> On 21 November 2016 at 07:37, Ritesh Harjani <riteshh@codeaurora.org> wrote:
>> > Hi,
>> >
>> > This is v9 version of the patch series which adds support for MSM8996.
>> > Adds HS400 driver support as well.
>> > These are tested on internal msm8996 & db410c HW.
>> >
>> > The patch series is ready. Do we think we can apply these
>> > patches for next now?
>>
>> I guess the DTS changes can be picked up by Andy, so they can go via arm-soc?
>
> Yeah I'll pick up the DTS change and the Documentation change.
Andy, I would rather like to pick the DT Documentation change via my
mmc tree. Just because I normally do that.
This one:
[PATCH v9 05/16] dt-bindings: sdhci-msm: Add xo value
Kind regards
Uffe
^ permalink raw reply
* Re: [PATCH 0/10] mmc: Add support to Marvell Xenon SD Host Controller
From: Gregory CLEMENT @ 2016-11-23 8:30 UTC (permalink / raw)
To: Ulf Hansson
Cc: Hilbert Zhang, Andrew Lunn, Romain Perier, Liuliu Zhao, Peng Zhu,
linux-kernel, Nadav Haklai, Ziji Hu, Victor Gu, Doug Jones,
Jisheng Zhang, Yehu da Yitschak, Marcin Wojtas, Xueping Liu,
Shiwu Zhang, Yu Cao, Sebastian Hesselbarth, devicetree,
Jason Cooper, Hanna Hawa, Kostya Porotchkin, Rob Herring,
Ryan Gao, Wei(SOCP) Liu, linux-arm-kernel
In-Reply-To: <cover.86006f271b60cf7c0b4c5a51762a9dacca4c4718.1477911954.git-series.gregory.clement@free-electrons.com>
Hi Ulf,
On lun., oct. 31 2016, Gregory CLEMENT <gregory.clement@free-electrons.com> wrote:
> Hello,
>
> This the second version of the series adding support for the SDHCI
> Xenon controller. It can be currently found on the Armada 37xx and the
> Armada 7K/8K but will be also used in more Marvell SoC (and not only
> the mvebu ones actually).
>
> Some of the remarks had been taking into account since the first
> version, according to Ziji Hu, here are the following chcanges:
> "Changes in V2:
> rebase on v4.9-rc2.
> Re-write Xenon bindings. Ajust Xenon DT property naming.
> Add a new DT property to indicate eMMC card type, instead of using
> variable card_candidate.
> Clear quirks SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 in Xenon platform data
> Add support to HS400 retuning."
>
> I think the main open point which remains is about issuing commands
> from the ->set_ios() callback (in patch 7).
> Ulf, could you comment about it?
This part is the last thing missing, we are about to solve the last
issues about the binding, but we still didn't have your opinion about
issuing commands from the ->set_ios() callback and Adrian required it to
take this series.
To have more context you can have a look on:
http://marc.info/?l=linux-mmc&m=147618996414673&w=2
it is the original email where Adrian wanted your agreement.
Thanks,
Gregory
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: [RFC PATCH] ARM: dts: Add support for Turris Omnia
From: Uwe Kleine-König @ 2016-11-23 8:19 UTC (permalink / raw)
To: Tomas Hlavacek
Cc: Rob Herring, Mark Rutland, Russell King, Jason Cooper,
Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1479859770-9375-1-git-send-email-tmshlvck-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 10076 bytes --]
Hello Tomas,
calling it v4 would be nice.
On Wed, Nov 23, 2016 at 01:09:20AM +0100, Tomas Hlavacek wrote:
> Turris Omnia board by CZ.NIC:
>
> * Marvell Armada 385 SoC
> * 1 or 2 GB DDR3
> * eMMC
> * 8 MB SPI flash (U-Boot and rescue Linux image)
> * 88E1514 PHY
> * 88E6176 Ethernet switch (not supported)
>
> Supported board revision: CZ11NIC13 (production board).
>
> Signed-off-by: Tomas Hlavacek <tmshlvck-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
As you picked my v3, you should keep my S-o-b.
> ---
> Changes since Uwe's version:
>
> - add MBUS regions (needed for Marvell CESA)
> - remove rtc disable (WFM with CZ11NIC13 = production board)
If I do
mw 0xf10184a0 0xfd4d4cfa
in the boot loader, it seems to work for me, too. You don't need that?
> - cleanup comments
>
> Unsupported peripherals:
> - MV88E7176 switch
> - SFP
> - LEDs
LEDs is not that bad IMHO, because they work. You just cannot change
their function, but they blink according to their default trigger.
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/armada-385-turris-omnia.dts | 279 ++++++++++++++++++++++++++
> 2 files changed, 280 insertions(+)
> create mode 100644 arch/arm/boot/dts/armada-385-turris-omnia.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index befcd26..f1d3b9ff 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -920,6 +920,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
> armada-385-db-ap.dtb \
> armada-385-linksys-caiman.dtb \
> armada-385-linksys-cobra.dtb \
> + armada-385-turris-omnia.dtb \
> armada-388-clearfog.dtb \
> armada-388-db.dtb \
> armada-388-gp.dtb \
> diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
> new file mode 100644
> index 0000000..5ef3d62
> --- /dev/null
> +++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
> @@ -0,0 +1,279 @@
> +/*
> + * Device Tree file for the Turris Omnia
> + * Schematic available at https://www.turris.cz/doc/_media/rtrom01-schema.pdf
> + *
> + * Copyright (C) 2016 Uwe Kleine-König <uwe-rXY34ruvC2xidJT2blvkqNi2O/JbrIOy@public.gmane.org>
> + * Copyright (C) 2016 Tomas Hlavacek <tmshlvkc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + * a) This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without
> + * any warranty of any kind, whether express or implied.
> + *
> + * Or, alternatively,
> + *
> + * b) Permission is hereby granted, free of charge, to any person
> + * obtaining a copy of this software and associated documentation
> + * files (the "Software"), to deal in the Software without
> + * restriction, including without limitation the rights to use,
> + * copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following
> + * conditions:
> + *
> + * The above copyright notice and this permission notice shall be
> + * included in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include "armada-385.dtsi"
> +
> +/ {
> + model = "Turris Omnia";
> + compatible = "cznic,turris-omnia", "marvell,armada385", \
> + "marvell,armada380";
You don't need a \ here AFAIK.
> +
> + chosen {
> + stdout-path = &uart0;
> + };
> +
> + memory {
> + device_type = "memory";
> + reg = <0x00000000 0x40000000>; /* 1024 MB */
> + };
> +
> + soc {
> + ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
> + MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
> + MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
> + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
> +
> + internal-regs {
> +
> + /* USB part of the PCIe2/USB 2.0 port */
> + usb@58000 {
> + status = "okay";
> + };
> +
> + sata@a8000 {
> + status = "okay";
> + };
> +
> + sdhci@d8000 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&sdhci_pins>;
> + status = "okay";
> +
> + bus-width = <8>;
> + no-1-8-v;
> + non-removable;
> + };
> +
> + usb3@f0000 {
> + status = "okay";
> + };
> +
> + usb3@f8000 {
> + status = "okay";
> + };
> + };
> +
> + pcie-controller {
> + status = "okay";
> +
> + pcie@1,0 {
> + /* Port 0, Lane 0 */
> + status = "okay";
> + };
> +
> + pcie@2,0 {
> + /* Port 1, Lane 0 */
> + status = "okay";
> + };
> +
> + pcie@3,0 {
> + /* Port 2, Lane 0 */
> + status = "okay";
> + };
> + };
> + };
> +};
> +
> +/* Connected to 88E6176 switch, port 6 */
> +ð0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&ge0_rgmii_pins>;
> + status = "okay";
> + phy-mode = "rgmii-id";
> +
> + fixed-link {
> + speed = <1000>;
> + full-duplex;
> + };
> +};
> +
> +/* Connected to 88E6176 switch, port 5 */
> +ð1 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&ge1_rgmii_pins>;
> + status = "okay";
> + phy-mode = "rgmii-id";
> +
> + fixed-link {
> + speed = <1000>;
> + full-duplex;
> + };
> +};
> +
> +/* WAN port */
> +ð2 {
> + status = "okay";
> + phy-mode = "sgmii";
> + phy = <&phy1>;
> +};
> +
> +&i2c0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c0_pins>;
> + status = "okay";
> +
> + i2cmux@70 {
> + compatible = "nxp,pca9547";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x70>;
> + status = "okay";
> +
> + i2c@0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>;
> + status = "okay";
> +
> + /* STM32F0 command interface at address 0x2a.
> + * STM32F0 LED interface at address 0x2b.
> + */
Should this better be:
/*
* STM32F0 command interface at address 0x2a.
* STM32F0 LED interface at address 0x2b.
*/
As is recommended for comments in .c?
> +
> + eeprom@54 {
> + compatible = "at,24c64";
> + reg = <0x54>;
> +
> + /* The EEPROM contains data for bootloader.
> + * Contents:
> + * struct omnia_eeprom {
> + * u32 magic; (=0x0341a034)
> + * u32 ramsize;
ramsize in GiB?
> + * char region[4] (=0x0);
This is for the WLAN regdomain, right?
> + * u32 crc32;
> + * };
> + */
ditto for the comment format.
> + };
> + };
> +
> + /* Channel 1: Routed to PCIe0/mSATA connector (CN7A).
> + * Channel 2: Routed to PCIe1/USB2 connector (CN61A).
> + * Channel 3: Routed to PCIe2 connector (CN62A).
> + * Channel 4: Routed to SFP+.
> + * Channel 5: ATSHA204A at address 0x64.
> + * Channel 6: Routed to user pin header CN11.
> + */
I'd like to keep the busses as Andrew already pointed out. For example
this might make it possible to use i2c-tools to read out the mac address
from the ATSHA.
> + i2c@7 {
> + /* GPIO expander for SFP+ signals */
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <7>;
> +
> + wangpio: gpio@71 {
> + compatible = "nxp,pca9538";
> + reg = <0x71>;
> + interrupt-parent = <&gpio1>;
> + interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
> + gpio-controller;
> + #gpio-cells = <2>;
> + };
> + };
> + };
> +};
> +
> +&mdio {
> + pinctrl-names = "default";
> + pinctrl-0 = <&mdio_pins>;
> + status = "okay";
> +
> + phy1: phy@1 {
> + status = "okay";
> + compatible = "ethernet-phy-id0141.0DD1", \
> + "ethernet-phy-ieee802.3-c22";
Drop the \
> + reg = <1>;
> + /* IRQ is connected to PCA9538 pin 7. Currently it
> + * can not be utilized.
> + */
> + };
> +
> + /* Switch MV88E7176 at address 0x10. */
> +};
> +
> +&pinctrl {
> + spi0cs1_pins: spi0-pins-0cs1 {
> + marvell,pins = "mpp26";
> + marvell,function = "spi0";
> + };
Why did you drop the pcawan pinctrl?
> +};
> +
> +&spi0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&spi0_pins &spi0cs1_pins>;
Oh, this is wrong (already in my patch): this is cs0 not cs1.
> + status = "okay";
> +
> + spi-nor@0 {
> + compatible = "spansion,s25fl164k", "jedec,spi-nor";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0>;
> + spi-max-frequency = <40000000>;
> +
> + partition@0 {
> + reg = <0x0 0x00100000>;
> + label = "U-Boot";
> + };
> +
> + partition@1 {
> + reg = <0x00100000 0x00700000>;
> + label = "Rescue system";
> + };
> + };
> +
> + /* SPI0 + CS1 (MPP26) is routed to a pin header CN11. */
Looks strange. What about
/* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */
Maybe also add the node for this pin to &pinctrl, but don't use it in
&spi0.pinctrl-0? This would nicely document the MPP26 part.
> +};
> +
> +&uart0 {
> + /* Pin header CN10. */
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart0_pins>;
> + status = "okay";
> +};
> +
> +&uart1 {
> + /* Pin header CN11. */
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart1_pins>;
> + status = "okay";
> +};
> +
Trailing new line
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
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