* [PATCH RFC v2 4/4] ARM: dts: imx6*-hummingboard2: convert to more conventional vmmc-supply
From: Russell King @ 2017-01-13 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144449.GQ14217@n2100.armlinux.org.uk>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
index 88aaed26dd77..f19d30b34ac4 100644
--- a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
@@ -56,11 +56,6 @@
linux,rc-map-name = "rc-rc6-mce";
};
- usdhc2_pwrseq: usdhc2-pwrseq {
- compatible = "mmc-pwrseq-simple";
- reset-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>;
- };
-
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "3P3V";
@@ -123,6 +118,18 @@
regulator-boot-on;
};
+ reg_usdhc2_vmmc: reg-usdhc2-vmmc {
+ compatible = "regulator-fixed";
+ gpio = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_vmmc>;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "usdhc2_vmmc";
+ startup-delay-us = <1000>;
+ };
+
sound-sgtl5000 {
audio-codec = <&sgtl5000>;
audio-routing =
@@ -393,7 +400,6 @@
pinctrl_hummingboard2_usdhc2_aux: hummingboard2-usdhc2-aux {
fsl,pins = <
- MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x1b071
MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x1b0b0
>;
@@ -432,6 +438,12 @@
>;
};
+ pinctrl_hummingboard2_vmmc: hummingboard2-vmmc {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
+ >;
+ };
+
pinctrl_hummingboard2_usdhc3: hummingboard2-usdhc3 {
fsl,pins = <
MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
@@ -519,7 +531,7 @@
&pinctrl_hummingboard2_usdhc2_aux
&pinctrl_hummingboard2_usdhc2_200mhz
>;
- mmc-pwrseq = <&usdhc2_pwrseq>;
+ vmmc-supply = <®_usdhc2_vmmc>;
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
status = "okay";
};
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Mark Rutland @ 2017-01-13 14:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113123612.GA31994@cbox>
On Fri, Jan 13, 2017 at 01:36:12PM +0100, Christoffer Dall wrote:
> On Fri, Jan 13, 2017 at 11:31:32AM +0000, Marc Zyngier wrote:
> Further, are we guaranteed that the static branch gets compiled into
> something that doesn't actually look at cpu_hwcap_keys, which is not
> mapped in hyp mode?
The fact that this might happen silently seems to be a larger problem.
Can we do something like the EFI stub, and ensure that (unintentional)
references to symbols outside of the hyp-stub will fail to link? That's
ensrue by some symbol mangling in drivers/firmware/efi/libstub/Makefile.
I think this may have come up before; I can't recall if there was some
reason that was problematic.
Thanks,
Mark.
^ permalink raw reply
* [PATCH] i2c: i2c-cadence: Don't register the adapter until it's ready
From: Mike Looijmans @ 2017-01-13 14:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113083727.GB1446@katana>
?On 13-01-17 09:37, Wolfram Sang wrote:
>
>> I would argue that the "info" message means "the I2C adapter is ready for
>> transaction now, and we'll start initializing devices on the bus". That is
>> the case before it calls i2c_add_adapter().
>
> I know what you mean, but i2c_add_adapter does more, and it can fail
> because the adapter is *not* ready to transfer. Seeing the success
> message before is also confusing.
>
>> When i2c_add_adapter() runs, it will start probing devices on the bus. This
>> yields very confusing output, as it will output things in a reversed order:
>>
>> - device X on I2C bus
>> - device Y on I2C bus
>> - cdns-i2c ff030000.i2c: 100 kHz mmio ff030000 irq 197
>
> I agree. That being said, somewhen I started working on moving such
> messages into the core to save string space and have consistent output.
> Then, we can print at the proper time.
>
> So, until then, we should be consistent with the other driver, I'd say.
Makes sense.
I'll create a v2 patch to just move the i2c_add_adapter to after writing the
configuration registers, and leave the dmesg output as is.
Thanks for reviewing,
Mike.
Kind regards,
Mike Looijmans
System Expert
TOPIC Products
Materiaalweg 4, NL-5681 RJ Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans at topicproducts.com
Website: www.topicproducts.com
Please consider the environment before printing this e-mail
^ permalink raw reply
* [PATCH v4 5/5] ARM: dts: mt2701: add iommu/smi dtsi node for mt2701
From: Matthias Brugger @ 2017-01-13 14:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <577A1794.5040509@gmail.com>
On 04/07/16 10:00, Matthias Brugger wrote:
>
>
> On 04/07/16 03:32, Honghui Zhang wrote:
>> On Sun, 2016-07-03 at 21:12 +0200, Matthias Brugger wrote:
>>>
>>> On 07/03/2016 08:24 AM, Matthias Brugger wrote:
>>>>
>>>>
>>>> On 06/08/2016 11:51 AM, honghui.zhang at mediatek.com wrote:
>>>>> From: Honghui Zhang <honghui.zhang@mediatek.com>
>>>>>
>>>>> Add the dtsi node of iommu and smi for mt2701.
>>>>>
>>>>> Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
>>>>> ---
>>>>> arch/arm/boot/dts/mt2701.dtsi | 51
>>>>> +++++++++++++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 51 insertions(+)
>>>>>
>>>>
>>>> Applied,
>>>
>>> Please resend the patch including the infracfg and mmsys node.
>>>
>>
>> Hi, Matthias,
>>
>> Please hold this one.
>> This one is based on CCF "arm: dts: mt2701: Add clock controller device
>> nodes"[1] and power domain patch "Mediatek MT2701 SCPSYS power domain
>> support v7"[2],
>> But these two patchset are still being reviewed now.
>>
>> Do you think it's better that I send this one later after ccf and power
>> domain patch got merged? I will send this patch later if it's OK with
>> you.
>>
>
> Sounds good.
Applied now to v4.10-next/dts32
Thanks.
>
> Thanks a lot,
> Matthias
>
>> Thanks.
>> [1] https://patchwork.kernel.org/patch/9109081
>> [2]
>> http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005429.html
>>
>>> Regards,
>>> Matthias
>>>
>>>>
>>>> Thanks.
>>>>
>>>>> diff --git a/arch/arm/boot/dts/mt2701.dtsi
>>>>> b/arch/arm/boot/dts/mt2701.dtsi
>>>>> index 42d5a37..363de0d 100644
>>>>> --- a/arch/arm/boot/dts/mt2701.dtsi
>>>>> +++ b/arch/arm/boot/dts/mt2701.dtsi
>>>>> @@ -16,6 +16,7 @@
>>>>> #include <dt-bindings/power/mt2701-power.h>
>>>>> #include <dt-bindings/interrupt-controller/irq.h>
>>>>> #include <dt-bindings/interrupt-controller/arm-gic.h>
>>>>> +#include <dt-bindings/memory/mt2701-larb-port.h>
>>>>> #include "skeleton64.dtsi"
>>>>> #include "mt2701-pinfunc.h"
>>>>>
>>>>> @@ -160,6 +161,16 @@
>>>>> clock-names = "system-clk", "rtc-clk";
>>>>> };
>>>>>
>>>>> + smi_common: smi at 1000c000 {
>>>>> + compatible = "mediatek,mt2701-smi-common";
>>>>> + reg = <0 0x1000c000 0 0x1000>;
>>>>> + clocks = <&infracfg CLK_INFRA_SMI>,
>>>>> + <&mmsys CLK_MM_SMI_COMMON>,
>>>>> + <&infracfg CLK_INFRA_SMI>;
>>>>> + clock-names = "apb", "smi", "async";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
>>>>> + };
>>>>> +
>>>>> sysirq: interrupt-controller at 10200100 {
>>>>> compatible = "mediatek,mt2701-sysirq",
>>>>> "mediatek,mt6577-sysirq";
>>>>> @@ -169,6 +180,16 @@
>>>>> reg = <0 0x10200100 0 0x1c>;
>>>>> };
>>>>>
>>>>> + iommu: mmsys_iommu at 10205000 {
>>>>> + compatible = "mediatek,mt2701-m4u";
>>>>> + reg = <0 0x10205000 0 0x1000>;
>>>>> + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>;
>>>>> + clocks = <&infracfg CLK_INFRA_M4U>;
>>>>> + clock-names = "bclk";
>>>>> + mediatek,larbs = <&larb0 &larb1 &larb2>;
>>>>> + #iommu-cells = <1>;
>>>>> + };
>>>>> +
>>>>> apmixedsys: syscon at 10209000 {
>>>>> compatible = "mediatek,mt2701-apmixedsys", "syscon";
>>>>> reg = <0 0x10209000 0 0x1000>;
>>>>> @@ -234,6 +255,16 @@
>>>>> status = "disabled";
>>>>> };
>>>>>
>>>>> + larb0: larb at 14010000 {
>>>>> + compatible = "mediatek,mt2701-smi-larb";
>>>>> + reg = <0 0x14010000 0 0x1000>;
>>>>> + mediatek,smi = <&smi_common>;
>>>>> + clocks = <&mmsys CLK_MM_SMI_LARB0>,
>>>>> + <&mmsys CLK_MM_SMI_LARB0>;
>>>>> + clock-names = "apb", "smi";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
>>>>> + };
>>>>> +
>>>>> imgsys: syscon at 15000000 {
>>>>> compatible = "mediatek,mt2701-imgsys", "syscon";
>>>>> reg = <0 0x15000000 0 0x1000>;
>>>>> @@ -241,6 +272,16 @@
>>>>> status = "disabled";
>>>>> };
>>>>>
>>>>> + larb2: larb at 15001000 {
>>>>> + compatible = "mediatek,mt2701-smi-larb";
>>>>> + reg = <0 0x15001000 0 0x1000>;
>>>>> + mediatek,smi = <&smi_common>;
>>>>> + clocks = <&imgsys CLK_IMG_SMI_COMM>,
>>>>> + <&imgsys CLK_IMG_SMI_COMM>;
>>>>> + clock-names = "apb", "smi";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
>>>>> + };
>>>>> +
>>>>> vdecsys: syscon at 16000000 {
>>>>> compatible = "mediatek,mt2701-vdecsys", "syscon";
>>>>> reg = <0 0x16000000 0 0x1000>;
>>>>> @@ -248,6 +289,16 @@
>>>>> status = "disabled";
>>>>> };
>>>>>
>>>>> + larb1: larb at 16010000 {
>>>>> + compatible = "mediatek,mt2701-smi-larb";
>>>>> + reg = <0 0x16010000 0 0x1000>;
>>>>> + mediatek,smi = <&smi_common>;
>>>>> + clocks = <&vdecsys CLK_VDEC_CKGEN>,
>>>>> + <&vdecsys CLK_VDEC_LARB>;
>>>>> + clock-names = "apb", "smi";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>;
>>>>> + };
>>>>> +
>>>>> hifsys: syscon at 1a000000 {
>>>>> compatible = "mediatek,mt2701-hifsys", "syscon";
>>>>> reg = <0 0x1a000000 0 0x1000>;
>>>>>
>>
>>
^ permalink raw reply
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Mark Rutland @ 2017-01-13 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144204.GB2472@leverpostej>
On Fri, Jan 13, 2017 at 02:42:04PM +0000, Mark Rutland wrote:
> On Fri, Jan 13, 2017 at 01:30:29PM +0000, Marc Zyngier wrote:
> > On 13/01/17 12:36, Christoffer Dall wrote:
> > > Further, are we guaranteed that the static branch gets compiled into
> > > something that doesn't actually look at cpu_hwcap_keys, which is not
> > > mapped in hyp mode?
>
> If I disable CONFIG_JUMP_LABEL (which lives under "General setup", with
> teh title "Optimize very unlikely/likely branches"), I see adrp; add;
> ldr sequences accessing cpu_hwcap_keys when using cpus_have_const_cap()
> in hyp code, even with the patch below.
Looking again, that's the same sequence Marc mentioned, as it falls in
the BSS. I just happened to be looking at the unlinked .o file rather
than the vmlinux.
Sorry for the noise.
Thanks,
Mark.
^ permalink raw reply
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Suzuki K Poulose @ 2017-01-13 14:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d496020c-a097-ffd5-adb7-7edb7c1a214e@arm.com>
On 13/01/17 13:30, Marc Zyngier wrote:
> [+ Suzuki, who wrote the whole cpus_have_const_cap thing]
>
> On 13/01/17 12:36, Christoffer Dall wrote:
>> On Fri, Jan 13, 2017 at 11:31:32AM +0000, Marc Zyngier wrote:
>>> From: Jintack Lim <jintack@cs.columbia.edu>
>>>
...
>>> /*
>>> * __boot_cpu_mode records what mode CPUs were booted in.
>>> @@ -80,6 +81,14 @@ static inline bool is_kernel_in_hyp_mode(void)
>>> return read_sysreg(CurrentEL) == CurrentEL_EL2;
>>> }
>>>
>>> +static inline bool has_vhe(void)
>>> +{
>>> + if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
>>> + return true;
>>> +
>>> + return false;
>>> +}
>>> +
>>
>> I was experimenting with using has_vhe for some of the optimization code
>> I was writing, and I saw a hyp crash as a result. That made me wonder
>> if this is really safe in Hyp mode?
>>
>> Specifically, there is no guarantee that this will actually be inlined
>> in the caller, right? At least that's what I can gather from trying to
>> understand the semantics of the inline keyword in the GCC manual.
>
> Indeed, there is no strict guarantee that this is enforced. We should
> probably have __always_inline instead. But having checked the generated
> code for __timer_restore_state, the function is definitely inlined
> (gcc 6.2). Happy to queue an extra patch changing that.
>
>> Further, are we guaranteed that the static branch gets compiled into
>> something that doesn't actually look at cpu_hwcap_keys, which is not
>> mapped in hyp mode?
>
> Here's the disassembly:
>
> ffff000008ad01d0 <__timer_restore_state>:
> ffff000008ad01d0: f9400001 ldr x1, [x0]
> ffff000008ad01d4: 9240bc21 and x1, x1, #0xffffffffffff
> ffff000008ad01d8: d503201f nop
> ffff000008ad01dc: d503201f nop
> ffff000008ad01e0: d53ce102 mrs x2, cnthctl_el2
> ffff000008ad01e4: 927ef842 and x2, x2, #0xfffffffffffffffd
> ffff000008ad01e8: b2400042 orr x2, x2, #0x1
> ffff000008ad01ec: d51ce102 msr cnthctl_el2, x2
> ffff000008ad01f0: d2834002 mov x2, #0x1a00 // #6656
> ffff000008ad01f4: 8b020000 add x0, x0, x2
> ffff000008ad01f8: 91038002 add x2, x0, #0xe0
> ffff000008ad01fc: 39425443 ldrb w3, [x2,#149]
> ffff000008ad0200: 34000103 cbz w3, ffff000008ad0220 <__timer_restore_state+0x50>
> ffff000008ad0204: f945a821 ldr x1, [x1,#2896]
> ffff000008ad0208: d51ce061 msr cntvoff_el2, x1
> ffff000008ad020c: f9400441 ldr x1, [x2,#8]
> ffff000008ad0210: d51be341 msr cntv_cval_el0, x1
> ffff000008ad0214: d5033fdf isb
> ffff000008ad0218: b940e000 ldr w0, [x0,#224]
> ffff000008ad021c: d51be320 msr cntv_ctl_el0, x0
> ffff000008ad0220: d65f03c0 ret
>
> The static branch resolves as such when VHE is enabled (taken from
> a running model):
>
> ffff000008ad01d0 <__timer_restore_state>:
> ffff000008ad01d0: f9400001 ldr x1, [x0]
> ffff000008ad01d4: 9240bc21 nop
> ffff000008ad01d8: d503201f nop
> ffff000008ad01dc: d503201f b ffff000008ad01f0
> ffff000008ad01e0: d53ce102 mrs x2, cnthctl_el2
> [...]
>
> That's using a toolchain that supports the "asm goto" feature that is used
> to implement static branches (and that's guaranteed not to generate any
> memory access other than the code patching itself).
>
> Now, with a toolchain that doesn't support this, such as gcc 4.8:
>
> ffff000008aa5168 <__timer_restore_state>:
> ffff000008aa5168: f9400001 ldr x1, [x0]
> ffff000008aa516c: 9240bc21 and x1, x1, #0xffffffffffff
> ffff000008aa5170: d503201f nop
> ffff000008aa5174: f00038a2 adrp x2, ffff0000091bc000 <reset_devices>
> ffff000008aa5178: 9113e042 add x2, x2, #0x4f8
> ffff000008aa517c: b9402c42 ldr w2, [x2,#44]
> ffff000008aa5180: 6b1f005f cmp w2, wzr
> ffff000008aa5184: 540000ac b.gt ffff000008aa5198 <__timer_restore_state+0x30>
> ffff000008aa5188: d53ce102 mrs x2, cnthctl_el2
> ffff000008aa518c: 927ef842 and x2, x2, #0xfffffffffffffffd
> ffff000008aa5190: b2400042 orr x2, x2, #0x1
> ffff000008aa5194: d51ce102 msr cnthctl_el2, x2
> ffff000008aa5198: 91400402 add x2, x0, #0x1, lsl #12
> ffff000008aa519c: 396dd443 ldrb w3, [x2,#2933]
> ffff000008aa51a0: 34000103 cbz w3, ffff000008aa51c0 <__timer_restore_state+0x58>
> ffff000008aa51a4: f945a821 ldr x1, [x1,#2896]
> ffff000008aa51a8: d51ce061 msr cntvoff_el2, x1
> ffff000008aa51ac: f9457441 ldr x1, [x2,#2792]
> ffff000008aa51b0: d51be341 msr cntv_cval_el0, x1
> ffff000008aa51b4: d5033fdf isb
> ffff000008aa51b8: b95ae000 ldr w0, [x0,#6880]
> ffff000008aa51bc: d51be320 msr cntv_ctl_el0, x0
> ffff000008aa51c0: d65f03c0 ret
>
> This is now controlled by some date located at FFFF0000091BC524:
>
> maz at approximate:~/Work/arm-platforms$ aarch64-linux-gnu-objdump -h vmlinux
>
> vmlinux: file format elf64-littleaarch64
>
> Sections:
> Idx Name Size VMA LMA File off Algn
> [...]
> 23 .bss 000da348 ffff0000091b8000 ffff0000091b8000 01147a00 2**12
> ALLOC
>
> That's the BSS, which we do map in HYP (fairly recent).
>
> But maybe we should have have some stronger guarantees that we'll
> always get things inlined, and that the "const" side is enforced:
Agreed.
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index b4989df..4710469 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -105,10 +105,11 @@ static inline bool cpu_have_feature(unsigned int num)
> }
>
> /* System capability check for constant caps */
> -static inline bool cpus_have_const_cap(int num)
> +static __always_inline bool cpus_have_const_cap(int num)
I think we should have the above change and make it inline always.
> {
> - if (num >= ARM64_NCAPS)
> - return false;
> + BUILD_BUG_ON(!__builtin_constant_p(num));
This is not needed, as the compilation would fail if num is not a constant with
static key code.
> + BUILD_BUG_ON(num >= ARM64_NCAPS);
> +
Also, I think it would be good to return false for caps > the ARM64_NCAPS, in sync
with the non-const version.
> return static_branch_unlikely(&cpu_hwcap_keys[num]);
> }
>
> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
> index 439f6b5..1257701 100644
> --- a/arch/arm64/include/asm/virt.h
> +++ b/arch/arm64/include/asm/virt.h
> @@ -81,7 +81,7 @@ static inline bool is_kernel_in_hyp_mode(void)
> return read_sysreg(CurrentEL) == CurrentEL_EL2;
> }
>
> -static inline bool has_vhe(void)
> +static __always_inline bool has_vhe(void)
> {
> if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
> return true;
>
>
> But that's probably another patch or two. Thoughts?
With the above changes, please feel free to add :
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
^ permalink raw reply
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Marc Zyngier @ 2017-01-13 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144622.GC2472@leverpostej>
On 13/01/17 14:46, Mark Rutland wrote:
> On Fri, Jan 13, 2017 at 01:36:12PM +0100, Christoffer Dall wrote:
>> On Fri, Jan 13, 2017 at 11:31:32AM +0000, Marc Zyngier wrote:
>
>> Further, are we guaranteed that the static branch gets compiled into
>> something that doesn't actually look at cpu_hwcap_keys, which is not
>> mapped in hyp mode?
>
> The fact that this might happen silently seems to be a larger problem.
>
> Can we do something like the EFI stub, and ensure that (unintentional)
> references to symbols outside of the hyp-stub will fail to link? That's
> ensrue by some symbol mangling in drivers/firmware/efi/libstub/Makefile.
>
> I think this may have come up before; I can't recall if there was some
> reason that was problematic.
>From what I remember, this was a gigantic mess... We could revisit it
though (after all, it's been a whole year since we did turn the whole
thing upside down -- time for a rewrite!).
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v6 3/3] arm: dts: mt2701: Add node for Mediatek JPEG Decoder
From: Matthias Brugger @ 2017-01-13 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484011718.10361.7.camel@mtksdaap41>
Hi James,
On 10/01/17 02:28, Eddie Huang wrote:
> Hi Matthias,
>
> On Mon, 2017-01-09 at 19:45 +0100, Matthias Brugger wrote:
>>
>> On 09/01/17 12:29, Hans Verkuil wrote:
>>> Hi Rick,
>>>
>>> On 01/06/2017 03:34 AM, Rick Chang wrote:
>>>> Hi Hans,
>>>>
>>>> The dependence on [1] has been merged in 4.10, but [2] has not.Do you have
>>>> any idea about this patch series? Should we wait for [2] or we could merge
>>>> the source code and dt-binding first?
>>>
>>> Looking at [2] I noticed that the last comment was July 4th. What is the reason
>>> it hasn't been merged yet?
>>>
>>> If I know [2] will be merged for 4.11, then I am fine with merging this media
>>> patch series. The dependency of this patch on [2] is something Mauro can handle.
>>>
>>> If [2] is not merged for 4.11, then I think it is better to wait until it is
>>> merged.
>>>
>>
>> I can't take [2] because there is no scpsys in the dts present. It seems
>> that it got never posted.
>>
>> Rick can you please follow-up with James and provide a patch which adds
>> a scpsys node to the mt2701.dtsi?
>>
>
> James sent three MT2701 dts patches [1] two weeks ago, these three
> patches include scpsys node. Please take a reference. And We will send
> new MT2701 ionmmu/smi dtsi node patch base on [1] later, thus you can
> accept and merge to 4.11.
>
Thanks for the clarification. I pulled all this patches into
v4.10-next/dts32
Hans will you take v9 of this patch set?
Then I'll take the dts patch.
Regards,
Matthias
> [1]
> https://patchwork.kernel.org/patch/9489991/
> https://patchwork.kernel.org/patch/9489985/
> https://patchwork.kernel.org/patch/9489989/
>
> Thanks,
> Eddie
>
>
^ permalink raw reply
* [PATCH v2 2/6] arm: dts: mt2701: Add iommu/smi device node
From: Matthias Brugger @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484296978-18572-3-git-send-email-erin.lo@mediatek.com>
Hi Erin,
I just took the patch from Honghui he send in june.
Please see my comment inline.
On 13/01/17 09:42, Erin Lo wrote:
> From: Honghui Zhang <honghui.zhang@mediatek.com>
>
> Add the device node of iommu and smi for MT2701.
>
> Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
> Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> ---
> arch/arm/boot/dts/mt2701.dtsi | 54 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index eb4c6fd..87be52c 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -17,6 +17,7 @@
> #include <dt-bindings/interrupt-controller/irq.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> #include <dt-bindings/reset/mt2701-resets.h>
> +#include <dt-bindings/memory/mt2701-larb-port.h>
> #include "skeleton64.dtsi"
> #include "mt2701-pinfunc.h"
>
> @@ -161,6 +162,16 @@
> clock-names = "system-clk", "rtc-clk";
> };
>
> + smi_common: smi at 1000c000 {
> + compatible = "mediatek,mt2701-smi-common";
> + reg = <0 0x1000c000 0 0x1000>;
> + clocks = <&infracfg CLK_INFRA_SMI>,
> + <&mmsys CLK_MM_SMI_COMMON>,
> + <&infracfg CLK_INFRA_SMI>;
> + clock-names = "apb", "smi", "async";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
> + };
> +
> sysirq: interrupt-controller at 10200100 {
> compatible = "mediatek,mt2701-sysirq",
> "mediatek,mt6577-sysirq";
> @@ -170,6 +181,16 @@
> reg = <0 0x10200100 0 0x1c>;
> };
>
> + iommu: mmsys_iommu at 10205000 {
> + compatible = "mediatek,mt2701-m4u";
> + reg = <0 0x10205000 0 0x1000>;
> + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&infracfg CLK_INFRA_M4U>;
> + clock-names = "bclk";
> + mediatek,larbs = <&larb0 &larb1 &larb2>;
> + #iommu-cells = <1>;
> + };
> +
> apmixedsys: syscon at 10209000 {
> compatible = "mediatek,mt2701-apmixedsys", "syscon";
> reg = <0 0x10209000 0 0x1000>;
> @@ -272,18 +293,51 @@
> #clock-cells = <1>;
> };
>
> + larb0: larb at 14010000 {
> + compatible = "mediatek,mt2701-smi-larb";
> + reg = <0 0x14010000 0 0x1000>;
> + mediatek,smi = <&smi_common>;
> + mediatek,larbidx = <0>;
Did I miss something? 'mediatek,larbidx' does not sound familiar to me.
Regards,
Matthias
> + clocks = <&mmsys CLK_MM_SMI_LARB0>,
> + <&mmsys CLK_MM_SMI_LARB0>;
> + clock-names = "apb", "smi";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
> + };
> +
> imgsys: syscon at 15000000 {
> compatible = "mediatek,mt2701-imgsys", "syscon";
> reg = <0 0x15000000 0 0x1000>;
> #clock-cells = <1>;
> };
>
> + larb2: larb at 15001000 {
> + compatible = "mediatek,mt2701-smi-larb";
> + reg = <0 0x15001000 0 0x1000>;
> + mediatek,smi = <&smi_common>;
> + mediatek,larbidx = <2>;
> + clocks = <&imgsys CLK_IMG_SMI_COMM>,
> + <&imgsys CLK_IMG_SMI_COMM>;
> + clock-names = "apb", "smi";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
> + };
> +
> vdecsys: syscon at 16000000 {
> compatible = "mediatek,mt2701-vdecsys", "syscon";
> reg = <0 0x16000000 0 0x1000>;
> #clock-cells = <1>;
> };
>
> + larb1: larb at 16010000 {
> + compatible = "mediatek,mt2701-smi-larb";
> + reg = <0 0x16010000 0 0x1000>;
> + mediatek,smi = <&smi_common>;
> + mediatek,larbidx = <1>;
> + clocks = <&vdecsys CLK_VDEC_CKGEN>,
> + <&vdecsys CLK_VDEC_LARB>;
> + clock-names = "apb", "smi";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>;
> + };
> +
> hifsys: syscon at 1a000000 {
> compatible = "mediatek,mt2701-hifsys", "syscon";
> reg = <0 0x1a000000 0 0x1000>;
>
^ permalink raw reply
* [PATCH v3 0/2] mmc: host: s3cmci: add device tree support
From: Sergio Prado @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
This series adds support for configuring Samsung's S3C24XX MMC/SD/SDIO
controller via device tree.
Tested on FriendlyARM mini2440, based on s3c2440 SoC.
Changes since v2:
- struct "s3cmci_drv_data" and flag "is2440" renamed
- copying the whole driver data struct instead of only its member so
it will be easier to extend the information in the future
- using mmc_of_parse() to read "cd-gpios" and "wp-gpios" properties
from device tree
Changes since v1:
- pinctrl description removed from DT binding
- unit and label on DT binding renamed to mmc
Sergio Prado (2):
dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
mmc: host: s3cmci: allow probing from device tree
.../devicetree/bindings/mmc/samsung,s3cmci.txt | 34 +++
drivers/mmc/host/s3cmci.c | 298 +++++++++++----------
drivers/mmc/host/s3cmci.h | 3 +-
3 files changed, 192 insertions(+), 143 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
--
1.9.1
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
From: Sergio Prado @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484319953-6479-1-git-send-email-sergio.prado@e-labworks.com>
Adds the device tree bindings description for Samsung S3C24XX
MMC/SD/SDIO controller, used as a connectivity interface with external
MMC, SD and SDIO storage mediums.
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
.../devicetree/bindings/mmc/samsung,s3cmci.txt | 34 ++++++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
diff --git a/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
new file mode 100644
index 000000000000..d09dbf4b3824
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
@@ -0,0 +1,34 @@
+* Samsung's S3C24XX MMC/SD/SDIO controller device tree bindings
+
+Samsung's S3C24XX MMC/SD/SDIO controller is used as a connectivity interface
+with external MMC, SD and SDIO storage mediums.
+
+This file documents differences between the core mmc properties described by
+mmc.txt and the properties used by the Samsung S3C24XX MMC/SD/SDIO controller
+implementation.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+ - "samsung,s3c2410-sdi": for controllers compatible with s3c2410
+ - "samsung,s3c2412-sdi": for controllers compatible with s3c2412
+ - "samsung,s3c2440-sdi": for controllers compatible with s3c2440
+- clocks: Should reference the controller clock
+- clock-names: Should contain "sdi"
+
+Example:
+ mmc0: mmc at 5a000000 {
+ compatible = "samsung,s3c2440-sdi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdi_pins>;
+ reg = <0x5a000000 0x100000>;
+ interrupts = <0 0 21 3>;
+ clocks = <&clocks PCLK_SDI>;
+ clock-names = "sdi";
+ bus-width = <4>;
+ cd-gpios = <&gpg 8 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gph 8 GPIO_ACTIVE_LOW>;
+ };
+
+ Note: This example shows both SoC specific and board specific properties
+ in a single device node. The properties can be actually be separated
+ into SoC specific node and board specific node.
--
1.9.1
^ permalink raw reply related
* [PATCH v3 2/2] mmc: host: s3cmci: allow probing from device tree
From: Sergio Prado @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484319953-6479-1-git-send-email-sergio.prado@e-labworks.com>
Allows configuring Samsung S3C24XX MMC/SD/SDIO controller using a device
tree.
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
drivers/mmc/host/s3cmci.c | 298 ++++++++++++++++++++++++----------------------
drivers/mmc/host/s3cmci.h | 3 +-
2 files changed, 158 insertions(+), 143 deletions(-)
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 932a4b1fed33..55535b65e0b3 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -23,6 +23,10 @@
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mmc/slot-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/dma.h>
@@ -127,6 +131,22 @@ enum dbg_channels {
dbg_conf = (1 << 8),
};
+struct s3cmci_variant_data {
+ int s3c2440_compatible;
+};
+
+static const struct s3cmci_variant_data s3c2410_s3cmci_variant_data = {
+ .s3c2440_compatible = 0,
+};
+
+static const struct s3cmci_variant_data s3c2412_s3cmci_variant_data = {
+ .s3c2440_compatible = 1,
+};
+
+static const struct s3cmci_variant_data s3c2440_s3cmci_variant_data = {
+ .s3c2440_compatible = 1,
+};
+
static const int dbgmap_err = dbg_fail;
static const int dbgmap_info = dbg_info | dbg_conf;
static const int dbgmap_debug = dbg_err | dbg_debug;
@@ -730,7 +750,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
goto clear_status_bits;
/* Check for FIFO failure */
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
dbg(host, dbg_err, "FIFO failure\n");
host->mrq->data->error = -EILSEQ;
@@ -806,21 +826,6 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
}
-/*
- * ISR for the CardDetect Pin
-*/
-
-static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
-{
- struct s3cmci_host *host = (struct s3cmci_host *)dev_id;
-
- dbg(host, dbg_irq, "card detect\n");
-
- mmc_detect_change(host->mmc, msecs_to_jiffies(500));
-
- return IRQ_HANDLED;
-}
-
static void s3cmci_dma_done_callback(void *arg)
{
struct s3cmci_host *host = arg;
@@ -912,7 +917,7 @@ static void finalize_request(struct s3cmci_host *host)
if (s3cmci_host_usedma(host))
dmaengine_terminate_all(host->dma);
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
/* Clear failure register and reset fifo. */
writel(S3C2440_SDIFSTA_FIFORESET |
S3C2440_SDIFSTA_FIFOFAIL,
@@ -1025,7 +1030,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
dcon |= S3C2410_SDIDCON_XFER_RXSTART;
}
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
dcon |= S3C2440_SDIDCON_DS_WORD;
dcon |= S3C2440_SDIDCON_DATSTART;
}
@@ -1044,7 +1049,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
/* write TIMER register */
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
writel(0x007FFFFF, host->base + S3C2410_SDITIMER);
} else {
writel(0x0000FFFF, host->base + S3C2410_SDITIMER);
@@ -1176,19 +1181,6 @@ static void s3cmci_send_request(struct mmc_host *mmc)
s3cmci_enable_irq(host, true);
}
-static int s3cmci_card_present(struct mmc_host *mmc)
-{
- struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pdata = host->pdata;
- int ret;
-
- if (pdata->no_detect)
- return -ENOSYS;
-
- ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
- return ret ^ pdata->detect_invert;
-}
-
static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct s3cmci_host *host = mmc_priv(mmc);
@@ -1197,7 +1189,7 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->cmd_is_stop = 0;
host->mrq = mrq;
- if (s3cmci_card_present(mmc) == 0) {
+ if (mmc_gpio_get_cd(mmc) == 0) {
dbg(host, dbg_err, "%s: no medium present\n", __func__);
host->mrq->cmd->error = -ENOMEDIUM;
mmc_request_done(mmc, mrq);
@@ -1241,22 +1233,24 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_ON:
case MMC_POWER_UP:
/* Configure GPE5...GPE10 pins in SD mode */
- s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
- S3C_GPIO_PULL_NONE);
+ if (!host->pdev->dev.of_node)
+ s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
+ S3C_GPIO_PULL_NONE);
if (host->pdata->set_power)
host->pdata->set_power(ios->power_mode, ios->vdd);
- if (!host->is2440)
+ if (!host->variant->s3c2440_compatible)
mci_con |= S3C2410_SDICON_FIFORESET;
break;
case MMC_POWER_OFF:
default:
- gpio_direction_output(S3C2410_GPE(5), 0);
+ if (!host->pdev->dev.of_node)
+ gpio_direction_output(S3C2410_GPE(5), 0);
- if (host->is2440)
+ if (host->variant->s3c2440_compatible)
mci_con |= S3C2440_SDICON_SDRESET;
if (host->pdata->set_power)
@@ -1294,21 +1288,6 @@ static void s3cmci_reset(struct s3cmci_host *host)
writel(con, host->base + S3C2410_SDICON);
}
-static int s3cmci_get_ro(struct mmc_host *mmc)
-{
- struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pdata = host->pdata;
- int ret;
-
- if (pdata->no_wprotect)
- return 0;
-
- ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0;
- ret ^= pdata->wprotect_invert;
-
- return ret;
-}
-
static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct s3cmci_host *host = mmc_priv(mmc);
@@ -1352,8 +1331,8 @@ static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
static struct mmc_host_ops s3cmci_ops = {
.request = s3cmci_request,
.set_ios = s3cmci_set_ios,
- .get_ro = s3cmci_get_ro,
- .get_cd = s3cmci_card_present,
+ .get_ro = mmc_gpio_get_ro,
+ .get_cd = mmc_gpio_get_cd,
.enable_sdio_irq = s3cmci_enable_sdio_irq,
};
@@ -1429,7 +1408,7 @@ static int s3cmci_state_show(struct seq_file *seq, void *v)
seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
seq_printf(seq, "Prescale = %d\n", host->prescaler);
- seq_printf(seq, "is2440 = %d\n", host->is2440);
+ seq_printf(seq, "S3C2440 compatible = %d\n", host->variant->s3c2440_compatible);
seq_printf(seq, "IRQ = %d\n", host->irq);
seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
@@ -1544,21 +1523,15 @@ static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
#endif /* CONFIG_DEBUG_FS */
-static int s3cmci_probe(struct platform_device *pdev)
+static int s3cmci_probe_pdata(struct s3cmci_host *host)
{
- struct s3cmci_host *host;
- struct mmc_host *mmc;
- int ret;
- int is2440;
- int i;
+ struct platform_device *pdev = host->pdev;
+ struct mmc_host *mmc = host->mmc;
+ struct s3c24xx_mci_pdata *pdata;
+ int i, ret;
- is2440 = platform_get_device_id(pdev)->driver_data;
-
- mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
- goto probe_out;
- }
+ host->variant = (const struct s3cmci_variant_data *)
+ platform_get_device_id(pdev)->driver_data;
for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
ret = gpio_request(i, dev_name(&pdev->dev));
@@ -1568,25 +1541,103 @@ static int s3cmci_probe(struct platform_device *pdev)
for (i--; i >= S3C2410_GPE(5); i--)
gpio_free(i);
- goto probe_free_host;
+ return ret;
}
}
+ if (!pdev->dev.platform_data)
+ pdev->dev.platform_data = &s3cmci_def_pdata;
+
+ pdata = pdev->dev.platform_data;
+
+ if (pdata->no_wprotect)
+ mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
+
+ if (pdata->no_detect)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+ if (pdata->wprotect_invert);
+ mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
+ if (pdata->detect_invert)
+ mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+
+ if (gpio_is_valid(pdata->gpio_detect)) {
+ ret = mmc_gpio_request_cd(mmc, pdata->gpio_detect, 0);
+ if (ret) {
+ dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ if (gpio_is_valid(pdata->gpio_wprotect)) {
+ ret = mmc_gpio_request_ro(mmc, pdata->gpio_wprotect);
+ if (ret) {
+ dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int s3cmci_probe_dt(struct s3cmci_host *host)
+{
+ struct platform_device *pdev = host->pdev;
+ struct s3c24xx_mci_pdata *pdata;
+ struct mmc_host *mmc = host->mmc;
+ int ret;
+
+ host->variant = of_device_get_match_data(&pdev->dev);
+ if (!host->variant)
+ return -ENODEV;
+
+ ret = mmc_of_parse(mmc);
+ if (ret)
+ return ret;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdev->dev.platform_data = pdata;
+
+ return 0;
+}
+
+static int s3cmci_probe(struct platform_device *pdev)
+{
+ struct s3cmci_host *host;
+ struct mmc_host *mmc;
+ int ret;
+ int i;
+
+ mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto probe_out;
+ }
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->pdev = pdev;
- host->is2440 = is2440;
+
+ if (pdev->dev.of_node)
+ ret = s3cmci_probe_dt(host);
+ else
+ ret = s3cmci_probe_pdata(host);
+
+ if (ret)
+ goto probe_free_host;
host->pdata = pdev->dev.platform_data;
- if (!host->pdata) {
- pdev->dev.platform_data = &s3cmci_def_pdata;
- host->pdata = &s3cmci_def_pdata;
- }
spin_lock_init(&host->complete_lock);
tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
- if (is2440) {
+ if (host->variant->s3c2440_compatible) {
host->sdiimsk = S3C2440_SDIIMSK;
host->sdidata = S3C2440_SDIDATA;
host->clk_div = 1;
@@ -1644,43 +1695,6 @@ static int s3cmci_probe(struct platform_device *pdev)
disable_irq(host->irq);
host->irq_state = false;
- if (!host->pdata->no_detect) {
- ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
- if (ret) {
- dev_err(&pdev->dev, "failed to get detect gpio\n");
- goto probe_free_irq;
- }
-
- host->irq_cd = gpio_to_irq(host->pdata->gpio_detect);
-
- if (host->irq_cd >= 0) {
- if (request_irq(host->irq_cd, s3cmci_irq_cd,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
- DRIVER_NAME, host)) {
- dev_err(&pdev->dev,
- "can't get card detect irq.\n");
- ret = -ENOENT;
- goto probe_free_gpio_cd;
- }
- } else {
- dev_warn(&pdev->dev,
- "host detect has no irq available\n");
- gpio_direction_input(host->pdata->gpio_detect);
- }
- } else
- host->irq_cd = -1;
-
- if (!host->pdata->no_wprotect) {
- ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
- if (ret) {
- dev_err(&pdev->dev, "failed to get writeprotect\n");
- goto probe_free_irq_cd;
- }
-
- gpio_direction_input(host->pdata->gpio_wprotect);
- }
-
/* Depending on the dma state, get a DMA channel to use. */
if (s3cmci_host_usedma(host)) {
@@ -1688,7 +1702,7 @@ static int s3cmci_probe(struct platform_device *pdev)
ret = PTR_ERR_OR_ZERO(host->dma);
if (ret) {
dev_err(&pdev->dev, "cannot get DMA channel.\n");
- goto probe_free_gpio_wp;
+ goto probe_free_irq;
}
}
@@ -1730,7 +1744,7 @@ static int s3cmci_probe(struct platform_device *pdev)
dbg(host, dbg_debug,
"probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%p.\n",
- (host->is2440?"2440":""),
+ (host->variant->s3c2440_compatible?"2440":""),
host->base, host->irq, host->irq_cd, host->dma);
ret = s3cmci_cpufreq_register(host);
@@ -1767,18 +1781,6 @@ static int s3cmci_probe(struct platform_device *pdev)
if (s3cmci_host_usedma(host))
dma_release_channel(host->dma);
- probe_free_gpio_wp:
- if (!host->pdata->no_wprotect)
- gpio_free(host->pdata->gpio_wprotect);
-
- probe_free_gpio_cd:
- if (!host->pdata->no_detect)
- gpio_free(host->pdata->gpio_detect);
-
- probe_free_irq_cd:
- if (host->irq_cd >= 0)
- free_irq(host->irq_cd, host);
-
probe_free_irq:
free_irq(host->irq, host);
@@ -1789,8 +1791,9 @@ static int s3cmci_probe(struct platform_device *pdev)
release_mem_region(host->mem->start, resource_size(host->mem));
probe_free_gpio:
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
probe_free_host:
mmc_free_host(mmc);
@@ -1817,7 +1820,6 @@ static int s3cmci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pd = host->pdata;
int i;
s3cmci_shutdown(pdev);
@@ -1831,15 +1833,9 @@ static int s3cmci_remove(struct platform_device *pdev)
free_irq(host->irq, host);
- if (!pd->no_wprotect)
- gpio_free(pd->gpio_wprotect);
-
- if (!pd->no_detect)
- gpio_free(pd->gpio_detect);
-
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
-
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
iounmap(host->base);
release_mem_region(host->mem->start, resource_size(host->mem));
@@ -1848,16 +1844,33 @@ static int s3cmci_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id s3cmci_dt_match[] = {
+ {
+ .compatible = "samsung,s3c2410-sdi",
+ .data = &s3c2410_s3cmci_variant_data,
+ },
+ {
+ .compatible = "samsung,s3c2412-sdi",
+ .data = &s3c2412_s3cmci_variant_data,
+ },
+ {
+ .compatible = "samsung,s3c2440-sdi",
+ .data = &s3c2440_s3cmci_variant_data,
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
+
static const struct platform_device_id s3cmci_driver_ids[] = {
{
.name = "s3c2410-sdi",
- .driver_data = 0,
+ .driver_data = (kernel_ulong_t) &s3c2410_s3cmci_variant_data,
}, {
.name = "s3c2412-sdi",
- .driver_data = 1,
+ .driver_data = (kernel_ulong_t) &s3c2412_s3cmci_variant_data,
}, {
.name = "s3c2440-sdi",
- .driver_data = 1,
+ .driver_data = (kernel_ulong_t) &s3c2440_s3cmci_variant_data,
},
{ }
};
@@ -1867,6 +1880,7 @@ static int s3cmci_remove(struct platform_device *pdev)
static struct platform_driver s3cmci_driver = {
.driver = {
.name = "s3c-sdi",
+ .of_match_table = s3cmci_dt_match,
},
.id_table = s3cmci_driver_ids,
.probe = s3cmci_probe,
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index 30c2c0dd1bc8..e9fe48915a2e 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -33,7 +33,8 @@ struct s3cmci_host {
unsigned long real_rate;
u8 prescaler;
- int is2440;
+ const struct s3cmci_variant_data *variant;
+
unsigned sdiimsk;
unsigned sdidata;
--
1.9.1
^ permalink raw reply related
* [PATCH 1/3] ARM: dts: Ux500: move USB PHY pins to PHY device
From: Linus Walleij @ 2017-01-13 15:11 UTC (permalink / raw)
To: linux-arm-kernel
The physical pins from the SoC are in a sense belonging to the
PHY device (AB8500 USB) rather than the MUSB USB IP block.
The driver definately assumes so: before this change it
complains that it cannot control the pins it is using:
abx5x0-usb ab8500-usb.0: could not get/set default pinstate
After this patch the warning goes away.
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/boot/dts/ste-href.dtsi | 12 ++++++------
arch/arm/boot/dts/ste-snowball.dts | 12 ++++++------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 48dc38482633..965fa10d1e8a 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -19,12 +19,6 @@
};
soc {
- usb_per5 at a03e0000 {
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&musb_default_mode>;
- pinctrl-1 = <&musb_sleep_mode>;
- };
-
uart at 80120000 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&uart0_default_mode>;
@@ -225,6 +219,12 @@
ab8500-gpio {
};
+ ab8500_usb {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&musb_default_mode>;
+ pinctrl-1 = <&musb_sleep_mode>;
+ };
+
ab8500-regulators {
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
regulator-name = "V-DISPLAY";
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index 386eee6de232..71daa27bb7e3 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -159,12 +159,6 @@
"", "", "", "", "", "", "", "";
};
- usb_per5 at a03e0000 {
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&musb_default_mode>;
- pinctrl-1 = <&musb_sleep_mode>;
- };
-
sound {
compatible = "stericsson,snd-soc-mop500";
@@ -448,6 +442,12 @@
"PM_GPIO42"; /* AB8500 GPIO42 */
};
+ ab8500_usb {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&musb_default_mode>;
+ pinctrl-1 = <&musb_sleep_mode>;
+ };
+
ext_regulators: ab8500-ext-regulators {
ab8500_ext1_reg: ab8500_ext1 {
regulator-name = "ab8500-ext-supply1";
--
2.9.3
^ permalink raw reply related
* [PATCH 2/3] ARM: dts: add the AB8500 sysclk to the device trees
From: Linus Walleij @ 2017-01-13 15:11 UTC (permalink / raw)
To: linux-arm-kernel
This clock has been missing since some early stages of device tree
conversion. Adding the right clocks to the device tree makes USB
work again.
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/boot/dts/ste-dbx5x0.dtsi | 2 ++
arch/arm/boot/dts/ste-href.dtsi | 2 ++
arch/arm/boot/dts/ste-snowball.dts | 2 ++
3 files changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index d309314f3a36..82d8c4771293 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -669,6 +669,8 @@
vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
v-ape-supply = <&db8500_vape_reg>;
musb_1v8-supply = <&db8500_vsmps2_reg>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>;
+ clock-names = "sysclk";
};
ab8500-ponkey {
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 965fa10d1e8a..4f70088d3c8a 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -191,6 +191,8 @@
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>;
+ clock-names = "sysclk";
};
msp0: msp at 80123000 {
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index 71daa27bb7e3..c6bcc8e2f29a 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -164,6 +164,8 @@
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>;
+ clock-names = "sysclk";
};
msp0: msp at 80123000 {
--
2.9.3
^ permalink raw reply related
* [PATCH 3/3] ARM: dts: add the AB8500 clocks to the device tree
From: Linus Walleij @ 2017-01-13 15:11 UTC (permalink / raw)
To: linux-arm-kernel
This adds the AB8500 clocks to the device tree using the new
bindings from the clk subsystem, making audio work again.
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/boot/dts/ste-dbx5x0.dtsi | 19 +++++++++++++++++++
arch/arm/boot/dts/ste-href.dtsi | 9 ---------
arch/arm/boot/dts/ste-snowball.dts | 9 ---------
3 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index 82d8c4771293..084fb4f13a7b 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -14,6 +14,7 @@
#include <dt-bindings/mfd/dbx500-prcmu.h>
#include <dt-bindings/arm/ux500_pm_domains.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/ste-ab8500.h>
#include "skeleton.dtsi"
/ {
@@ -603,6 +604,11 @@
interrupt-controller;
#interrupt-cells = <2>;
+ ab8500_clock: ab8500-clock {
+ compatible = "stericsson,ab8500-clk";
+ #clock-cells = <1>;
+ };
+
ab8500_gpio: ab8500-gpio {
compatible = "stericsson,ab8500-gpio";
gpio-controller;
@@ -686,6 +692,8 @@
ab8500-pwm {
compatible = "stericsson,ab8500-pwm";
+ clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
+ clock-names = "intclk";
};
ab8500-debugfs {
@@ -700,6 +708,9 @@
V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
V-DMIC-supply = <&ab8500_ldo_dmic_reg>;
+ clocks = <&ab8500_clock AB8500_SYSCLK_AUDIO>;
+ clock-names = "audioclk";
+
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
@@ -1095,6 +1106,14 @@
status = "disabled";
};
+ sound {
+ compatible = "stericsson,snd-soc-mop500";
+ stericsson,cpu-dai = <&msp1 &msp3>;
+ stericsson,audio-codec = <&codec>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
+ clock-names = "sysclk", "ulpclk", "intclk";
+ };
+
msp0: msp at 80123000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80123000 0x1000>;
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 4f70088d3c8a..a10369ed36e0 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -186,15 +186,6 @@
status = "okay";
};
- sound {
- compatible = "stericsson,snd-soc-mop500";
-
- stericsson,cpu-dai = <&msp1 &msp3>;
- stericsson,audio-codec = <&codec>;
- clocks = <&prcmu_clk PRCMU_SYSCLK>;
- clock-names = "sysclk";
- };
-
msp0: msp at 80123000 {
pinctrl-names = "default";
pinctrl-0 = <&msp0_default_mode>;
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index c6bcc8e2f29a..d1be40f96154 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -159,15 +159,6 @@
"", "", "", "", "", "", "", "";
};
- sound {
- compatible = "stericsson,snd-soc-mop500";
-
- stericsson,cpu-dai = <&msp1 &msp3>;
- stericsson,audio-codec = <&codec>;
- clocks = <&prcmu_clk PRCMU_SYSCLK>;
- clock-names = "sysclk";
- };
-
msp0: msp at 80123000 {
pinctrl-names = "default";
pinctrl-0 = <&msp0_default_mode>;
--
2.9.3
^ permalink raw reply related
* [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Matthias Brugger @ 2017-01-13 15:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113151747.6bc85245@bbrezillon>
On 13/01/17 15:17, Boris Brezillon wrote:
> On Fri, 13 Jan 2017 15:13:29 +0800
> Guochun Mao <guochun.mao@mediatek.com> wrote:
>
>> Add Mediatek nor flash node.
>>
>> Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
>> ---
>> arch/arm/boot/dts/mt2701-evb.dts | 25 +++++++++++++++++++++++++
>> arch/arm/boot/dts/mt2701.dtsi | 12 ++++++++++++
>> 2 files changed, 37 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
>> index 082ca88..85e5ae8 100644
>> --- a/arch/arm/boot/dts/mt2701-evb.dts
>> +++ b/arch/arm/boot/dts/mt2701-evb.dts
>> @@ -24,6 +24,31 @@
>> };
>> };
>>
>> +&nor_flash {
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&nor_pins_default>;
>> + status = "okay";
>> + flash at 0 {
>> + compatible = "jedec,spi-nor";
>> + reg = <0>;
>> + };
>> +};
>> +
>> +&pio {
>> + nor_pins_default: nor {
>> + pins1 {
>> + pinmux = <MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS>,
>> + <MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK>,
>> + <MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0>,
>> + <MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1>,
>> + <MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2>,
>> + <MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3>;
>> + drive-strength = <MTK_DRIVE_4mA>;
>> + bias-pull-up;
>> + };
>> + };
>> +};
>> +
>> &uart0 {
>> status = "okay";
>> };
>> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
>> index bdf8954..1eefce4 100644
>> --- a/arch/arm/boot/dts/mt2701.dtsi
>> +++ b/arch/arm/boot/dts/mt2701.dtsi
>> @@ -227,6 +227,18 @@
>> status = "disabled";
>> };
>>
>> + nor_flash: spi at 11014000 {
>> + compatible = "mediatek,mt2701-nor",
>> + "mediatek,mt8173-nor";
>
> Why define both here? Is "mediatek,mt8173-nor" really providing a
> subset of the features supported by "mediatek,mt2701-nor"?
>
I think even if the ip block is the same, we should provide both
bindings, just in case in the future we find out that mt2701 has some
hidden bug, feature or bug-feature. This way even if we update the
driver, we stay compatible with older device tree blobs in the wild.
We can drop the mt2701-nor in the bindings definition if you want.
Regards,
Matthias
>> + reg = <0 0x11014000 0 0xe0>;
>> + clocks = <&pericfg CLK_PERI_FLASH>,
>> + <&topckgen CLK_TOP_FLASH_SEL>;
>> + clock-names = "spi", "sf";
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + status = "disabled";
>> + };
>> +
>> mmsys: syscon at 14000000 {
>> compatible = "mediatek,mt2701-mmsys", "syscon";
>> reg = <0 0x14000000 0 0x1000>;
>
^ permalink raw reply
* [PATCH v3 3/5] arm64: Create and use __tlbi_dsb() macros
From: Christopher Covington @ 2017-01-13 15:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170112165852.GH13843@arm.com>
Hi Will,
On 01/12/2017 11:58 AM, Will Deacon wrote:
> Hi Christopher,
>
> On Wed, Jan 11, 2017 at 09:41:16AM -0500, Christopher Covington wrote:
>> This refactoring will allow an errata workaround that repeats tlbi dsb
>> sequences to only change one location. This is not intended to change the
>> generated assembly and comparison of before and after preprocessor output
>> of arch/arm64/mm/mmu.c and vmlinux objdump shows no functional changes.
>>
>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
>> ---
>> arch/arm64/include/asm/tlbflush.h | 104 +++++++++++++++++++++++++-------------
>> 1 file changed, 69 insertions(+), 35 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
>> index deab523..f28813c 100644
>> --- a/arch/arm64/include/asm/tlbflush.h
>> +++ b/arch/arm64/include/asm/tlbflush.h
>> @@ -25,22 +25,69 @@
>> #include <asm/cputype.h>
>>
>> /*
>> - * Raw TLBI operations.
>> + * Raw TLBI, DSB operations
>> *
>> - * Where necessary, use the __tlbi() macro to avoid asm()
>> - * boilerplate. Drivers and most kernel code should use the TLB
>> - * management routines in preference to the macro below.
>> + * Where necessary, use __tlbi_*dsb() macros to avoid asm() boilerplate.
>> + * Drivers and most kernel code should use the TLB management routines in
>> + * preference to the macros below.
>> *
>> - * The macro can be used as __tlbi(op) or __tlbi(op, arg), depending
>> - * on whether a particular TLBI operation takes an argument or
>> - * not. The macros handles invoking the asm with or without the
>> - * register argument as appropriate.
>> + * The __tlbi_dsb() macro handles invoking the asm without any register
>> + * argument, with a single register argument, and with start (included)
>> + * and end (excluded) range of register arguments. For example:
>> + *
>> + * __tlbi_dsb(op, attr)
>> + *
>> + * tlbi op
>> + * dsb attr
>> + *
>> + * __tlbi_dsb(op, attr, addr)
>> + *
>> + * mov %[addr], =addr
>> + * tlbi op, %[addr]
>> + * dsb attr
>> + *
>> + * __tlbi_range_dsb(op, attr, start, end)
>> + *
>> + * mov %[arg], =start
>> + * mov %[end], =end
>> + * for:
>> + * tlbi op, %[addr]
>> + * add %[addr], %[addr], #(1 << (PAGE_SHIFT - 12))
>> + * cmp %[addr], %[end]
>> + * b.ne for
>> + * dsb attr
>> */
>> -#define __TLBI_0(op, arg) asm ("tlbi " #op)
>> -#define __TLBI_1(op, arg) asm ("tlbi " #op ", %0" : : "r" (arg))
>> -#define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
>>
>> -#define __tlbi(op, ...) __TLBI_N(op, ##__VA_ARGS__, 1, 0)
>> +#define __TLBI_FOR_0(ig0, ig1, ig2)
>> +#define __TLBI_INSTR_0(op, ig1, ig2) "tlbi " #op
>> +#define __TLBI_IO_0(ig0, ig1, ig2) : :
>> +
>> +#define __TLBI_FOR_1(ig0, ig1, ig2)
>> +#define __TLBI_INSTR_1(op, ig0, ig1) "tlbi " #op ", %0"
>> +#define __TLBI_IO_1(ig0, arg, ig1) : : "r" (arg)
>> +
>> +#define __TLBI_FOR_2(ig0, start, ig1) unsigned long addr; \
>> + for (addr = start; addr < end; \
>> + addr += 1 << (PAGE_SHIFT - 12))
>> +#define __TLBI_INSTR_2(op, ig0, ig1) "tlbi " #op ", %0"
>> +#define __TLBI_IO_2(ig0, ig1, ig2) : : "r" (addr)
>> +
>> +#define __TLBI_FOR_N(op, a1, a2, n, ...) __TLBI_FOR_##n(op, a1, a2)
>> +#define __TLBI_INSTR_N(op, a1, a2, n, ...) __TLBI_INSTR_##n(op, a1, a2)
>> +#define __TLBI_IO_N(op, a1, a2, n, ...) __TLBI_IO_##n(op, a1, a2)
>> +
>> +#define __TLBI_FOR(op, ...) __TLBI_FOR_N(op, ##__VA_ARGS__, 2, 1, 0)
>> +#define __TLBI_INSTR(op, ...) __TLBI_INSTR_N(op, ##__VA_ARGS__, 2, 1, 0)
>> +#define __TLBI_IO(op, ...) __TLBI_IO_N(op, ##__VA_ARGS__, 2, 1, 0)
>> +
>> +#define __tlbi_asm_dsb(as, op, attr, ...) do { \
>> + __TLBI_FOR(op, ##__VA_ARGS__) \
>> + asm (__TLBI_INSTR(op, ##__VA_ARGS__) \
>> + __TLBI_IO(op, ##__VA_ARGS__)); \
>> + asm volatile ( as "\ndsb " #attr "\n" \
>> + : : : "memory"); } while (0)
>> +
>> +#define __tlbi_dsb(...) __tlbi_asm_dsb("", ##__VA_ARGS__)
>
> I can't deny that this is cool, but ultimately it's completely unreadable.
> What I was thinking you'd do would be make __tlbi expand to:
>
> tlbi
> dsb
> tlbi
> dsb
>
> for Falkor, and:
>
> tlbi
> nop
> nop
> nop
>
> for everybody else.
Thanks for the suggestion. So would __tlbi take a dsb sharability argument in
your proposal? Or would it be communicated in some other fashion, maybe inferred
from the tlbi argument? Or would the workaround dsbs all be the worst/broadest
case?
> Wouldn't that localise this change sufficiently that you wouldn't need
> to change all the callers and encode the looping in your cpp macros?
>
> I realise you get an extra dsb in some places with that change, but I'd
> like to see numbers for the impact of that on top of the workaround. If
> it's an issue, then an alternative sequence would be:
>
> tlbi
> dsb
> tlbi
>
> and you'd rely on the existing dsb to complete that.
>
> Having said that, I don't understand how your current loop code works
> when the workaround is applied. AFAICT, you end up emitting something
> like:
>
> dsb ishst
> for i in 0 to n
> tlbi va+i
> dsb
> tlbi va+n
> dsb
>
> which looks wrong to me. Am I misreading something here?
You're right, I am off by 1 << (PAGE_SHIFT - 12) here. I would need to
increment, compare, not take the loop branch (regular for loop stuff),
then decrement (missing) and perform TLB invalidation again (present but
using incorrect value).
Thanks,
Cov
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code
Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH v3 16/24] media: Add i.MX media core driver
From: Philipp Zabel @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483755102-24785-17-git-send-email-steve_longerbeam@mentor.com>
Am Freitag, den 06.01.2017, 18:11 -0800 schrieb Steve Longerbeam:
> Add the core media driver for i.MX SOC.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
> ---
> Documentation/media/v4l-drivers/imx.rst | 443 ++++++++++
> drivers/staging/media/Kconfig | 2 +
> drivers/staging/media/Makefile | 1 +
> drivers/staging/media/imx/Kconfig | 8 +
> drivers/staging/media/imx/Makefile | 6 +
> drivers/staging/media/imx/TODO | 22 +
> drivers/staging/media/imx/imx-media-common.c | 981 ++++++++++++++++++++++
> drivers/staging/media/imx/imx-media-dev.c | 486 +++++++++++
> drivers/staging/media/imx/imx-media-fim.c | 471 +++++++++++
> drivers/staging/media/imx/imx-media-internal-sd.c | 457 ++++++++++
> drivers/staging/media/imx/imx-media-of.c | 289 +++++++
> drivers/staging/media/imx/imx-media.h | 310 +++++++
> include/media/imx.h | 15 +
> include/uapi/linux/v4l2-controls.h | 4 +
> 14 files changed, 3495 insertions(+)
> create mode 100644 Documentation/media/v4l-drivers/imx.rst
> create mode 100644 drivers/staging/media/imx/Kconfig
> create mode 100644 drivers/staging/media/imx/Makefile
> create mode 100644 drivers/staging/media/imx/TODO
> create mode 100644 drivers/staging/media/imx/imx-media-common.c
> create mode 100644 drivers/staging/media/imx/imx-media-dev.c
> create mode 100644 drivers/staging/media/imx/imx-media-fim.c
> create mode 100644 drivers/staging/media/imx/imx-media-internal-sd.c
> create mode 100644 drivers/staging/media/imx/imx-media-of.c
> create mode 100644 drivers/staging/media/imx/imx-media.h
> create mode 100644 include/media/imx.h
>
> diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
> new file mode 100644
> index 0000000..87b37b5
> --- /dev/null
> +++ b/Documentation/media/v4l-drivers/imx.rst
> @@ -0,0 +1,443 @@
> +i.MX Video Capture Driver
> +=========================
> +
> +Introduction
> +------------
> +
> +The Freescale i.MX5/6 contains an Image Processing Unit (IPU), which
> +handles the flow of image frames to and from capture devices and
> +display devices.
> +
> +For image capture, the IPU contains the following internal subunits:
> +
> +- Image DMA Controller (IDMAC)
> +- Camera Serial Interface (CSI)
> +- Image Converter (IC)
> +- Sensor Multi-FIFO Controller (SMFC)
> +- Image Rotator (IRT)
> +- Video De-Interlace Controller (VDIC)
Nitpick: Video De-Interlacing or Combining Block (VDIC)
> +
> +The IDMAC is the DMA controller for transfer of image frames to and from
> +memory. Various dedicated DMA channels exist for both video capture and
> +display paths.
> +
> +The CSI is the frontend capture unit that interfaces directly with
> +capture sensors over Parallel, BT.656/1120, and MIPI CSI-2 busses.
> +
> +The IC handles color-space conversion, resizing, and rotation
> +operations.
And horizontal flipping.
> There are three independent "tasks" within the IC that can
> +carry out conversions concurrently: pre-processing encoding,
> +pre-processing preview, and post-processing.
s/preview/viewfinder/ seems to be the commonly used name.
This paragraph could mention that a single hardware unit is used
transparently time multiplexed by the three tasks at different
granularity for the downsizing, main processing, and rotation sections.
The downscale unit switches between tasks at 8-pixel burst granularity,
the main processing unit at line granularity. The rotation units switch
only at frame granularity.
> +The SMFC is composed of four independent channels that each can transfer
> +captured frames from sensors directly to memory concurrently.
> +
> +The IRT carries out 90 and 270 degree image rotation operations.
... on 8x8 pixel blocks, supported by the IDMAC which handles block
transfers, block reordering, and vertical flipping.
> +The VDIC handles the conversion of interlaced video to progressive, with
> +support for different motion compensation modes (low, medium, and high
> +motion). The deinterlaced output frames from the VDIC can be sent to the
> +IC pre-process preview task for further conversions.
> +
> +In addition to the IPU internal subunits, there are also two units
> +outside the IPU that are also involved in video capture on i.MX:
> +
> +- MIPI CSI-2 Receiver for camera sensors with the MIPI CSI-2 bus
> + interface. This is a Synopsys DesignWare core.
> +- A video multiplexer for selecting among multiple sensor inputs to
> + send to a CSI.
Two of them, actually.
> +For more info, refer to the latest versions of the i.MX5/6 reference
> +manuals listed under References.
> +
> +
> +Features
> +--------
> +
> +Some of the features of this driver include:
> +
> +- Many different pipelines can be configured via media controller API,
> + that correspond to the hardware video capture pipelines supported in
> + the i.MX.
> +
> +- Supports parallel, BT.565, and MIPI CSI-2 interfaces.
> +
> +- Up to four concurrent sensor acquisitions, by configuring each
> + sensor's pipeline using independent entities. This is currently
> + demonstrated with the SabreSD and SabreLite reference boards with
> + independent OV5642 and MIPI CSI-2 OV5640 sensor modules.
> +
> +- Scaling, color-space conversion, and image rotation via IC task
> + subdevs.
> +
> +- Many pixel formats supported (RGB, packed and planar YUV, partial
> + planar YUV).
> +
> +- The IC pre-process preview subdev supports motion compensated
> + de-interlacing using the VDIC, with three motion compensation modes:
> + low, medium, and high motion. The mode is specified with a custom
> + control. Pipelines are defined that allow sending frames to the
> + preview subdev directly from the CSI or from the SMFC.
> +
> +- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
> + problems with the ADV718x video decoders. See below for a description
> + of the FIM.
Could this also be used to calculate more precise capture timestamps?
> +Capture Pipelines
> +-----------------
> +
> +The following describe the various use-cases supported by the pipelines.
> +
> +The links shown do not include the frontend sensor, video mux, or mipi
> +csi-2 receiver links. This depends on the type of sensor interface
> +(parallel or mipi csi-2). So in all cases, these pipelines begin with:
> +
> +sensor -> ipu_csi_mux -> ipu_csi -> ...
> +
> +for parallel sensors, or:
> +
> +sensor -> imx-mipi-csi2 -> (ipu_csi_mux) -> ipu_csi -> ...
> +
> +for mipi csi-2 sensors. The imx-mipi-csi2 receiver may need to route
> +to the video mux (ipu_csi_mux) before sending to the CSI, depending
> +on the mipi csi-2 virtual channel, hence ipu_csi_mux is shown in
> +parenthesis.
> +
> +Unprocessed Video Capture:
> +--------------------------
> +
> +Send frames directly from sensor to camera interface, with no
> +conversions:
> +
> +-> ipu_smfc -> camif
I'd call this capture interface, this is not just for cameras. Or maybe
idmac if you want to mirror hardware names?
> +Note the ipu_smfc can do pixel reordering within the same colorspace.
That isn't a feature of the SMFC, but of the IDMAC (FCW & FCR).
> +For example, its sink pad can take UYVY2X8, but its source pad can
> +output YUYV2X8.
I don't think this is correct. Re-reading "37.4.3.7 Packing to memory"
in the CSI chapter, for 8-bit per component data, the internal format
between CSI, SMFC, and IDMAC is always some 32-bit RGBx/YUVx variant
(or "bayer/generic data"). In either case, the internal format does not
change along the way.
> +IC Direct Conversions:
> +----------------------
> +
> +This pipeline uses the preprocess encode entity to route frames directly
> +from the CSI to the IC (bypassing the SMFC), to carry out scaling up to
> +1024x1024 resolution, CSC, and image rotation:
> +
> +-> ipu_ic_prpenc -> camif
> +
> +This can be a useful capture pipeline for heavily loaded memory bus
> +traffic environments, since it has minimal IDMAC channel usage.
Note that if rotation is enabled, transfers between IC processing and
rotation still have to go through memory once.
> +Post-Processing Conversions:
> +----------------------------
> +
> +This pipeline routes frames from the SMFC to the post-processing
> +entity.
No, frames written by the CSI -> SMFC -> IDMAC path are read back into
the post-processing entity.
> In addition to CSC and rotation, this entity supports tiling
> +which allows scaled output beyond the 1024x1024 limitation of the IC
> +(up to 4096x4096 scaling output is supported):
> +
> +-> ipu_smfc -> ipu_ic_pp -> camif
> +
> +Motion Compensated De-interlace:
> +--------------------------------
> +
> +This pipeline routes frames from the SMFC to the preprocess preview
> +entity to support motion-compensated de-interlacing using the VDIC,
> +scaling up to 1024x1024, and CSC:
> +
> +-> ipu_smfc -> ipu_ic_prpvf -> camif
Same as above.
> +This pipeline also carries out the same conversions as above, but routes
> +frames directly from the CSI to the IC preprocess preview entity for
> +minimal memory bandwidth usage (note: this pipeline only works in
> +"high motion" mode):
> +
> +-> ipu_ic_prpvf -> camif
> +
> +This pipeline takes the motion-compensated de-interlaced frames and
> +sends them to the post-processor, to support motion-compensated
> +de-interlacing, scaling up to 4096x4096, CSC, and rotation:
> +
> +-> (ipu_smfc) -> ipu_ic_prpvf -> ipu_ic_pp -> camif
> +
> +
> +Usage Notes
> +-----------
[...]
> +SabreLite with OV5642 and OV5640
> +--------------------------------
> +
> +This platform requires the OmniVision OV5642 module with a parallel
> +camera interface, and the OV5640 module with a MIPI CSI-2
> +interface. Both modules are available from Boundary Devices:
> +
> +https://boundarydevices.com/products/nit6x_5mp
> +https://boundarydevices.com/product/nit6x_5mp_mipi
> +
> +Note that if only one camera module is available, the other sensor
> +node can be disabled in the device tree.
> +
> +The OV5642 module is connected to the parallel bus input on the i.MX
> +internal video mux to IPU1 CSI0. It's i2c bus connects to i2c bus 2.
> +
> +The MIPI CSI-2 OV5640 module is connected to the i.MX internal MIPI CSI-2
> +receiver, and the four virtual channel outputs from the receiver are
> +routed as follows: vc0 to the IPU1 CSI0 mux, vc1 directly to IPU1 CSI1,
> +vc2 directly to IPU2 CSI0, and vc3 to the IPU2 CSI1 mux. The OV5640 is
> +also connected to i2c bus 2 on the SabreLite, therefore the OV5642 and
> +OV5640 must not share the same i2c slave address.
> +
> +The following basic example configures unprocessed video capture
> +pipelines for both sensors. The OV5642 is routed to camif0
> +(usually /dev/video0), and the OV5640 (transmitting on mipi csi-2
> +virtual channel 1) is routed to camif1 (usually /dev/video1). Both
> +sensors are configured to output 640x480, UYVY (not shown: all pad
> +field types should be set to "NONE"):
> +
> +.. code-block:: none
> +
> + # Setup links for OV5642
> + media-ctl -l '"ov5642 1-0042":0 -> "ipu1_csi0_mux":1[1]'
> + media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
> + media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
> + media-ctl -l '"ipu1_smfc0":1 -> "camif0":0[1]'
> + media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
> + # Setup links for OV5640
> + media-ctl -l '"ov5640_mipi 1-0040":0 -> "imx-mipi-csi2":0[1]'
> + media-ctl -l '"imx-mipi-csi2":2 -> "ipu1_csi1":0[1]'
> + media-ctl -l '"ipu1_csi1":1 -> "ipu1_smfc1":0[1]'
> + media-ctl -l '"ipu1_smfc1":1 -> "camif1":0[1]'
> + media-ctl -l '"camif1":1 -> "camif1 devnode":0[1]'
> + # Configure pads for OV5642 pipeline
> + media-ctl -V "\"ov5642 1-0042\":0 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0\":0 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0\":1 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_smfc0\":0 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/640x480]"
I think the smfc entities should be dropped.
> + media-ctl -V "\"camif0\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"camif0\":1 [fmt:UYVY2X8/640x480]"
> + # Configure pads for OV5640 pipeline
> + media-ctl -V "\"ov5640_mipi 1-0040\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"imx-mipi-csi2\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"imx-mipi-csi2\":2 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"ipu1_csi1\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"ipu1_csi1\":1 [fmt:UYVY2X8/640x480]"
[...]
> + media-ctl -V "\"camif1\":0 [fmt:UYVY2X8/640x480]"
I agree this looks very intuitive, but technically correct for the
csi1:1 and camif1:0 pads would be a 32-bit YUV format.
(MEDIA_BUS_FMT_YUV8_1X32_PADLO doesn't exist yet).
I think it would be better to use the correct format as that will allow
to chose the regular vs. companded packings in the future for formats
with more than 8 bits per component.
> + media-ctl -V "\"camif1\":1 [fmt:UYVY2X8/640x480]"
>+
> +Streaming can then begin independently on device nodes /dev/video0
> +and /dev/video1.
> +
> +SabreAuto with ADV7180 decoder
> +------------------------------
> +
> +On the SabreAuto, an on-board ADV7180 SD decoder is connected to the
> +parallel bus input on the internal video mux to IPU1 CSI0.
> +
> +The following example configures a pipeline to capture from the ADV7180
> +video decoder, assuming NTSC 720x480 input signals, with Motion
> +Compensated de-interlacing (not shown: all pad field types should be set
> +as indicated). $outputfmt can be any format supported by the
> +ipu1_ic_prpvf entity at its output pad:
> +
> +.. code-block:: none
> +
> + # Setup links
> + media-ctl -l '"adv7180 3-0021":0 -> "ipu1_csi0_mux":1[1]'
> + media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
> + media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
> + media-ctl -l '"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0[1]'
> + media-ctl -l '"ipu1_ic_prpvf":1 -> "camif0":0[1]'
> + media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
> + # Configure pads
> + # pad field types for below pads must be an interlaced type
> + # such as "ALTERNATE"
I think alternate should only extend as far as the CSI, since the CSI
can only capture NTSC/PAL fields in a fixed order.
> + media-ctl -V "\"adv7180 3-0021\":0 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:UYVY2X8/720x480]"
>From here the interlaced field type should be sequential in the correct
order depending on NTSC/PAL.
> + media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_csi0\":0 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_csi0\":1 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_smfc0\":0 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_ic_prpvf\":0 [fmt:UYVY2X8/720x480]"
> + # pad field types for below pads must be "NONE"
> + media-ctl -V "\"ipu1_ic_prpvf\":1 [fmt:$outputfmt]"
> + media-ctl -V "\"camif0\":0 [fmt:$outputfmt]"
> + media-ctl -V "\"camif0\":1 [fmt:$outputfmt]"
> +
> +Streaming can then begin on /dev/video0.
> +
> +This platform accepts Composite Video analog inputs to the ADV7180 on
> +Ain1 (connector J42) and Ain3 (connector J43).
> +
> +To switch to Ain1:
> +
> +.. code-block:: none
> +
> + # v4l2-ctl -i0
> +
> +To switch to Ain3:
> +
> +.. code-block:: none
> +
> + # v4l2-ctl -i1
> +
> +
> +Frame Interval Monitor
> +----------------------
> +
> +The adv718x decoders can occasionally send corrupt fields during
> +NTSC/PAL signal re-sync (too little or too many video lines). When
> +this happens, the IPU triggers a mechanism to re-establish vertical
> +sync by adding 1 dummy line every frame, which causes a rolling effect
> +from image to image, and can last a long time before a stable image is
> +recovered. Or sometimes the mechanism doesn't work at all, causing a
> +permanent split image (one frame contains lines from two consecutive
> +captured images).
Is it only SabreAuto on which the FIM mechanism can be used due to the
pad routing?
[...]
> +/*
> + * DMA buffer ring handling
> + */
> +struct imx_media_dma_buf_ring {
> + struct imx_media_dev *imxmd;
> +
> + /* the ring */
> + struct imx_media_dma_buf buf[IMX_MEDIA_MAX_RING_BUFS];
> + /* the scratch buffer for underruns */
> + struct imx_media_dma_buf scratch;
> +
> + /* buffer generator */
> + struct media_entity *src;
> + /* buffer receiver */
> + struct media_entity *sink;
> +
> + spinlock_t lock;
> +
> + int num_bufs;
> + unsigned long last_seq;
> +};
I don't think this belongs in the capture driver at all.
Memory-to-memory transfers should be handled at the videobuf2 level.
[...]
> +static struct imx_media_dma_buf *
> +__dma_buf_queue(struct imx_media_dma_buf_ring *ring, int index)
> +{
> + struct imx_media_dma_buf *buf;
> +
> + if (index >= ring->num_bufs)
> + return ERR_PTR(-EINVAL);
> +
> + buf = &ring->buf[index];
> + if (WARN_ON(buf->state != IMX_MEDIA_BUF_STATUS_PREPARED))
> + return ERR_PTR(-EINVAL);
> +
> + buf->state = IMX_MEDIA_BUF_STATUS_QUEUED;
> + buf->seq = ring->last_seq++;
> +
> + return buf;
> +}
Is this a whole software buffer queue implementation? I thought the
whole point of putting the custom mem2mem framework into the capture
driver was to use the hardware FSU channel linking?
> +int imx_media_dma_buf_queue(struct imx_media_dma_buf_ring *ring, int index)
> +{
> + struct imx_media_dma_buf *buf;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ring->lock, flags);
> + buf = __dma_buf_queue(ring, index);
> + spin_unlock_irqrestore(&ring->lock, flags);
> +
> + if (IS_ERR(buf))
> + return PTR_ERR(buf);
> +
> + dev_dbg(ring->imxmd->dev, "buf%d [%s -> %s] queued\n",
> + index, ring->src->name, ring->sink->name);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(imx_media_dma_buf_queue);
> +
> +int imx_media_dma_buf_queue_from_vb(struct imx_media_dma_buf_ring *ring,
> + struct vb2_buffer *vb)
> +{
> + struct imx_media_dma_buf *buf;
> + unsigned long flags;
> + dma_addr_t phys;
> + void *virt;
> +
> + if (vb->index >= ring->num_bufs)
> + return -EINVAL;
> +
> + virt = vb2_plane_vaddr(vb, 0);
> + phys = vb2_dma_contig_plane_dma_addr(vb, 0);
> +
> + spin_lock_irqsave(&ring->lock, flags);
> + buf = __dma_buf_queue(ring, vb->index);
> + if (IS_ERR(buf))
> + goto err_unlock;
> +
> + buf->virt = virt;
> + buf->phys = phys;
> + buf->vb = vb;
> + spin_unlock_irqrestore(&ring->lock, flags);
> +
> + dev_dbg(ring->imxmd->dev, "buf%d [%s -> %s] queued from vb\n",
> + buf->index, ring->src->name, ring->sink->name);
> +
> + return 0;
> +err_unlock:
> + spin_unlock_irqrestore(&ring->lock, flags);
> + return PTR_ERR(buf);
> +}
> +EXPORT_SYMBOL_GPL(imx_media_dma_buf_queue_from_vb);
> +
> +void imx_media_dma_buf_done(struct imx_media_dma_buf *buf,
> + enum imx_media_dma_buf_status status)
> +{
> + struct imx_media_dma_buf_ring *ring = buf->ring;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ring->lock, flags);
> + WARN_ON(buf->state != IMX_MEDIA_BUF_STATUS_ACTIVE);
> + buf->state = buf->status = status;
> + spin_unlock_irqrestore(&ring->lock, flags);
> +
> + if (buf == &ring->scratch)
> + dev_dbg(ring->imxmd->dev, "buf-scratch [%s -> %s] done\n",
> + ring->src->name, ring->sink->name);
> + else
> + dev_dbg(ring->imxmd->dev, "buf%d [%s -> %s] done\n",
> + buf->index, ring->src->name, ring->sink->name);
> +
> + /* if the sink is a subdev, inform it that new buffers are available */
> + if (is_media_entity_v4l2_subdev(ring->sink)) {
> + struct v4l2_subdev *sd =
> + media_entity_to_v4l2_subdev(ring->sink);
> + v4l2_subdev_call(sd, core, ioctl, IMX_MEDIA_NEW_DMA_BUF, NULL);
What is the purpose of this if the sink should be triggered by the FSU?
[...]
> +/*
> + * The subdevs have to be powered on/off, and streaming
> + * enabled/disabled, in a specific sequence.
> + */
> +static const u32 stream_on_seq[] = {
> + IMX_MEDIA_GRP_ID_IC_PP,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_SENSOR,
> + IMX_MEDIA_GRP_ID_CSI2,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_CSI,
> +};
> +
> +static const u32 stream_off_seq[] = {
> + IMX_MEDIA_GRP_ID_IC_PP,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_CSI,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_CSI2,
> + IMX_MEDIA_GRP_ID_SENSOR,
> +};
> +
> +#define NUM_STREAM_ENTITIES ARRAY_SIZE(stream_on_seq)
> +
> +static const u32 power_on_seq[] = {
> + IMX_MEDIA_GRP_ID_CSI2,
> + IMX_MEDIA_GRP_ID_SENSOR,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_CSI,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PP,
> +};
> +
> +static const u32 power_off_seq[] = {
> + IMX_MEDIA_GRP_ID_IC_PP,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_CSI,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_SENSOR,
> + IMX_MEDIA_GRP_ID_CSI2,
> +};
This seems somewhat arbitrary. Why is a power sequence needed?
[...]
> +/*
> + * Turn current pipeline power on/off starting from start_entity.
> + * Must be called with mdev->graph_mutex held.
> + */
> +int imx_media_pipeline_set_power(struct imx_media_dev *imxmd,
> + struct media_entity_graph *graph,
> + struct media_entity *start_entity, bool on)
> +{
> + struct media_entity *entity;
> + struct v4l2_subdev *sd;
> + int i, ret = 0;
> + u32 id;
> +
> + for (i = 0; i < NUM_POWER_ENTITIES; i++) {
> + id = on ? power_on_seq[i] : power_off_seq[i];
> + entity = find_pipeline_entity(imxmd, graph, start_entity, id);
> + if (!entity)
> + continue;
> +
> + sd = media_entity_to_v4l2_subdev(entity);
> +
> + ret = v4l2_subdev_call(sd, core, s_power, on);
> + if (ret && ret != -ENOIOCTLCMD)
> + break;
> + }
> +
> + return (ret && ret != -ENOIOCTLCMD) ? ret : 0;
> +}
> +EXPORT_SYMBOL_GPL(imx_media_pipeline_set_power);
This should really be handled by v4l2_pipeline_pm_use.
> +/*
> + * Inherit the v4l2 controls from all entities in a pipeline
> + * to the given video device.
> + * Must be called with mdev->graph_mutex held.
> + */
> +int imx_media_inherit_controls(struct imx_media_dev *imxmd,
> + struct video_device *vfd,
> + struct media_entity *start_entity)
> +{
> + struct media_entity_graph graph;
> + struct media_entity *entity;
> + struct v4l2_subdev *sd;
> + int ret;
> +
> + ret = media_entity_graph_walk_init(&graph, &imxmd->md);
> + if (ret)
> + return ret;
> +
> + media_entity_graph_walk_start(&graph, start_entity);
> +
> + while ((entity = media_entity_graph_walk_next(&graph))) {
> + if (is_media_entity_v4l2_video_device(entity))
> + continue;
> +
> + sd = media_entity_to_v4l2_subdev(entity);
> +
> + dev_dbg(imxmd->dev, "%s: adding controls from %s\n",
> + __func__, sd->name);
> +
> + ret = v4l2_ctrl_add_handler(vfd->ctrl_handler,
> + sd->ctrl_handler,
> + NULL);
> + if (ret)
> + break;
> + }
> +
> + media_entity_graph_walk_cleanup(&graph);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(imx_media_inherit_controls);
> +
> +MODULE_DESCRIPTION("i.MX5/6 v4l2 media controller driver");
> +MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
> new file mode 100644
> index 0000000..357654d
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-media-dev.c
This file is full of code that should live in the v4l2 core.
[...]
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-media-internal-sd.c
[...]
> +int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
> + struct imx_media_subdev *csi[4])
> +{
> + int ret;
> +
> + /* there must be at least one CSI in first IPU */
Why?
> + if (!(csi[0] || csi[1]))
> + return -EINVAL;
> +
> + ret = add_ipu_internal_subdevs(imxmd, csi[0], csi[1], 0);
> + if (ret)
> + return ret;
> +
> + if (csi[2] || csi[3])
> + ret = add_ipu_internal_subdevs(imxmd, csi[2], csi[3], 1);
> +
> + return ret;
> +}
> diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
> new file mode 100644
> index 0000000..a939c34
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-media-of.c
> @@ -0,0 +1,289 @@
> +/*
> + * Media driver for Freescale i.MX5/6 SOC
> + *
> + * Open Firmware parsing.
> + *
> + * Copyright (c) 2016 Mentor Graphics Inc.
> + *
> + * This program 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.
> + */
> +#include <linux/of_platform.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-of.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <video/imx-ipu-v3.h>
> +#include "imx-media.h"
> +
> +static int of_add_pad_link(struct imx_media_dev *imxmd,
> + struct imx_media_pad *pad,
> + struct device_node *local_sd_node,
> + struct device_node *remote_sd_node,
> + int local_pad, int remote_pad)
> +{
> + dev_dbg(imxmd->dev, "%s: adding %s:%d -> %s:%d\n", __func__,
> + local_sd_node->name, local_pad,
> + remote_sd_node->name, remote_pad);
> +
> + return imx_media_add_pad_link(imxmd, pad, remote_sd_node, NULL,
> + local_pad, remote_pad);
> +}
> +
> +/* parse inputs property from a sensor node */
> +static void of_parse_sensor_inputs(struct imx_media_dev *imxmd,
> + struct imx_media_subdev *sensor,
> + struct device_node *sensor_np)
> +{
> + struct imx_media_sensor_input *sinput = &sensor->input;
> + int ret, i;
> +
> + for (i = 0; i < IMX_MEDIA_MAX_SENSOR_INPUTS; i++) {
> + const char *input_name;
> + u32 val;
> +
> + ret = of_property_read_u32_index(sensor_np, "inputs", i, &val);
> + if (ret)
> + break;
> +
> + sinput->value[i] = val;
> +
> + ret = of_property_read_string_index(sensor_np, "input-names",
> + i, &input_name);
> + /*
> + * if input-names not provided, they will be set using
> + * the subdev name once the sensor is known during
> + * async bind
> + */
> + if (!ret)
> + strncpy(sinput->name[i], input_name,
> + sizeof(sinput->name[i]));
> + }
> +
> + sinput->num = i;
> +
> + /* if no inputs provided just assume a single input */
> + if (sinput->num == 0)
> + sinput->num = 1;
> +}
This should be parsed by the sensor driver, not imx-media.
> +static void of_parse_sensor(struct imx_media_dev *imxmd,
> + struct imx_media_subdev *sensor,
> + struct device_node *sensor_np)
> +{
> + struct device_node *endpoint;
> +
> + of_parse_sensor_inputs(imxmd, sensor, sensor_np);
> +
> + endpoint = of_graph_get_next_endpoint(sensor_np, NULL);
> + if (endpoint) {
> + v4l2_of_parse_endpoint(endpoint, &sensor->sensor_ep);
> + of_node_put(endpoint);
> + }
> +}
> +
> +static int of_get_port_count(const struct device_node *np)
> +{
> + struct device_node *child;
> + int num = 0;
> +
> + /* if this node is itself a port, return 1 */
> + if (of_node_cmp(np->name, "port") == 0)
> + return 1;
> +
> + for_each_child_of_node(np, child)
> + if (of_node_cmp(child->name, "port") == 0)
> + num++;
> +
> + return num;
> +}
If this is extended to handle the ports subnode properly, it could be
moved into drivers/of/base.c.
regards
Philipp
^ permalink raw reply
* [GIT PULL 1/4] ARM: exynos: Mach/soc for v4.11
From: Krzysztof Kozlowski @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Mostly cleanups for v4.11.
Best regards,
Krzysztof
The following changes since commit 7ce7d89f48834cefece7804d38fc5d85382edf77:
Linux 4.10-rc1 (2016-12-25 16:13:08 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-soc-4.11
for you to fetch changes up to cda1a52dab50340728e46601e6c9da9fc4beaf1f:
ARM: s3c64xx: Constify wake_irqs (2016-12-29 15:41:44 +0200)
----------------------------------------------------------------
Samsung mach/soc update for v4.11. Mostly cleanups:
1. Removal of unused platform data in S3C24XX and S3C64xx as follow up of
conversion to new DMA channel request API.
2. Adding const and __ro_after_init to various data in Samsung platforms.
----------------------------------------------------------------
Krzysztof Kozlowski (7):
ARM: EXYNOS: Constify list of retention registers
ARM: EXYNOS: Annotate iomem and pm_data pointers __ro_after_init
ARM: s3c24xx: Constify few integer tables
ARM: s3c64xx: Annotate external clock frequencies __ro_after_init
ARM: SAMSUNG: Constify array of wake irqs passed to samsung_sync_wakemask
ARM: s3c24xx: Constify wake_irqs
ARM: s3c64xx: Constify wake_irqs
Sylwester Nawrocki (2):
ARM: s3c64xx: Drop initialization of unused struct s3c_audio_pdata fields
ARM: s3c24xx: Drop unused struct s3c_audio_pdata entries
arch/arm/mach-exynos/exynos.c | 4 ++--
arch/arm/mach-exynos/mcpm-exynos.c | 2 +-
arch/arm/mach-exynos/suspend.c | 10 +++++-----
arch/arm/mach-s3c24xx/bast-irq.c | 4 ++--
arch/arm/mach-s3c24xx/iotiming-s3c2410.c | 2 +-
arch/arm/mach-s3c24xx/pm-s3c2412.c | 2 +-
arch/arm/mach-s3c64xx/common.c | 3 ++-
arch/arm/mach-s3c64xx/dev-audio.c | 19 -------------------
arch/arm/mach-s3c64xx/pm.c | 2 +-
arch/arm/plat-samsung/devs.c | 19 -------------------
arch/arm/plat-samsung/include/plat/wakeup-mask.h | 2 +-
arch/arm/plat-samsung/wakeup-mask.c | 2 +-
12 files changed, 17 insertions(+), 54 deletions(-)
^ permalink raw reply
* [GIT PULL 2/4] ARM: dts: exynos: DT for v4.11
From: Krzysztof Kozlowski @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113152030.13586-1-krzk@kernel.org>
Hi,
Few improvements and Exynos4412 DTSI removal.
This pulls external dependecy from clock tree (one clock commit).
Best regards,
Krzysztof
The following changes since commit 7ce7d89f48834cefece7804d38fc5d85382edf77:
Linux 4.10-rc1 (2016-12-25 16:13:08 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt-4.11
for you to fetch changes up to bca9085e0ae93253bc93ce218c85ac7d7e7f1831:
ARM: dts: exynos: remove Exynos4212 support (dead code) (2017-01-11 18:28:43 +0200)
----------------------------------------------------------------
Samsung DeviceTree update for v4.11:
1. Fixes for initial audio clocks configuration.
2. Enable sound on Odroid-X board.
3. Enable DMA for UART modules on Exynos5 SoCs.
4. Add CPU OPPs for Exynos4412 Prime (newer version of Exynos4412). This pulls
necessary change in the clocks.
5. Remove Exynos4212. We do not have any mainline boards with it. This will
simplify few bits later.
----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (2):
clk: samsung: Add CPU clk configuration data for Exynos4412 Prime
ARM: dts: exynos: Add CPU OPPs for Exynos4412 Prime
Krzysztof Kozlowski (1):
Merge tag 'clk-v4.11-exynos4-pll' of git://linuxtv.org/snawrocki/samsung into next/dt
Marek Szyprowski (4):
ARM: dts: exynos: Correct clocks for Exynos4 I2S module
ARM: dts: exynos: Fix initial audio clocks configuration on Exynos4 boards
ARM: dts: exynos: Enable DMA support for UART modules on Exynos5 SoCs
ARM: dts: exynos: remove Exynos4212 support (dead code)
Markus Reichl (1):
ARM: dts: exynos: Cleanup Odroid-X2 and enable sound on Odroid-X
arch/arm/boot/dts/exynos4.dtsi | 6 +-
arch/arm/boot/dts/exynos4212.dtsi | 133 -----
arch/arm/boot/dts/exynos4412-itop-elite.dts | 25 +-
arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 28 +-
arch/arm/boot/dts/exynos4412-odroidu3.dts | 5 +-
arch/arm/boot/dts/exynos4412-odroidx.dts | 13 +
arch/arm/boot/dts/exynos4412-odroidx2.dts | 25 +-
...os4x12-pinctrl.dtsi => exynos4412-pinctrl.dtsi} | 4 +-
arch/arm/boot/dts/exynos4412-prime.dtsi | 41 ++
arch/arm/boot/dts/exynos4412.dtsi | 577 +++++++++++++++++++-
arch/arm/boot/dts/exynos4x12.dtsi | 594 ---------------------
arch/arm/boot/dts/exynos5250.dtsi | 8 +
arch/arm/boot/dts/exynos5410.dtsi | 8 +
arch/arm/boot/dts/exynos5420.dtsi | 8 +
drivers/clk/samsung/clk-exynos4.c | 4 +
15 files changed, 685 insertions(+), 794 deletions(-)
delete mode 100644 arch/arm/boot/dts/exynos4212.dtsi
rename arch/arm/boot/dts/{exynos4x12-pinctrl.dtsi => exynos4412-pinctrl.dtsi} (99%)
create mode 100644 arch/arm/boot/dts/exynos4412-prime.dtsi
delete mode 100644 arch/arm/boot/dts/exynos4x12.dtsi
^ permalink raw reply
* [GIT PULL 3/4] arm64: dts: exynos: DT for v4.11
From: Krzysztof Kozlowski @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113152030.13586-1-krzk@kernel.org>
Hi,
Important:
1. Unlike others, this is rebased on v4.10-rc2 because v4.10-rc1 was not
building on arm64.
2. This contains pinctrl change (in header), acked by Linus Walleij.
Although I kept it on separate branch and merged here, but I did not
prepare a separate pull request for this one pinctrl change - it is
just one patch. Anyway it sits on separate branch so this is still
possible if you need it.
Best regards,
Krzysztof
Cc: Linus Walleij <linus.walleij@linaro.org>
The following changes since commit 0c744ea4f77d72b3dcebb7a8f2684633ec79be88:
Linux 4.10-rc2 (2017-01-01 14:31:53 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-4.11
for you to fetch changes up to e4e381133241a27d732e78be09973b89a193eaf7:
arm64: dts: exynos: Enable HDMI/TV path on Exynos5433-TM2 (2017-01-11 18:20:28 +0200)
----------------------------------------------------------------
Samsung DeviceTree ARM64 update for v4.11:
1. Add bus frequency and voltage scalling on Exynos5433 TM2 device (along with
necessary bus nodes and Platform Performance Monitoring Unit on Exynos5433).
2. Use macros for pinctrl settings on Exynos5433.
This contains necessary header with bindings.
3. Minor cleanups in Exynos5433 DTSI and boards using it.
4. Create common DTSI betweem Exynos5433 TM2E and TM2E.
5. Add HDMI/TV to Exynos5433 TM2.
----------------------------------------------------------------
Andi Shyti (4):
pinctrl: dt-bindings: samsung: add drive strength macros for Exynos5433
arm64: dts: exynos: Use macros for pinctrl configuration on Exynos5433
arm64: dts: exynos: Comply to the samsung pinctrl naming convention in TM2
arm64: dts: exynos: Make TM2 and TM2E independent from each other
Andrzej Hajda (4):
arm64: dts: exynos: Fix addresses in node names on Exynos5433
arm64: dts: exynos: Add DECON_TV node to Exynos5433
arm64: dts: exynos: Add HDMI node to Exynos5433
arm64: dts: exynos: Enable HDMI/TV path on Exynos5433-TM2
Chanwoo Choi (4):
arm64: dts: exynos: Add PPMU node to Exynos5433
arm64: dts: exynos: Add bus nodes using VDD_INT for Exynos5433
arm64: dts: exynos: Add support of bus frequency using VDD_INT on Exynos5433 TM2
arm64: dts: exynos: Fix wrong values for ldo23 and ldo25 on TM2/TM2E
Krzysztof Kozlowski (2):
Merge branch 'for-v4.11/pinctrl-macros' into next/dt64
arm64: dts: exynos: Remove unsupported regulator-always-off property from TM2E
arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi | 197 ++++
arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi | 373 +++---
.../boot/dts/exynos/exynos5433-tm2-common.dtsi | 1187 ++++++++++++++++++++
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 1036 +----------------
arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts | 12 +-
arch/arm64/boot/dts/exynos/exynos5433.dtsi | 115 +-
include/dt-bindings/pinctrl/samsung.h | 14 +
7 files changed, 1695 insertions(+), 1239 deletions(-)
create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
^ permalink raw reply
* [GIT PULL 4/4] ARM: defconfig: exynos: Defconfig for v4.11
From: Krzysztof Kozlowski @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113152030.13586-1-krzk@kernel.org>
The following changes since commit 7ce7d89f48834cefece7804d38fc5d85382edf77:
Linux 4.10-rc1 (2016-12-25 16:13:08 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-defconfig-4.11
for you to fetch changes up to 74b0ee7579f279dae053053008d29f10f3890c07:
ARM: exynos_defconfig: Enable IP multicast (2016-12-29 16:04:57 +0200)
----------------------------------------------------------------
Samsung defconfig update for v4.11:
1. Cleanup from old MACHs in s5pv210.
2. Enable IP_MULTICAST for libnss-mdns.
----------------------------------------------------------------
Krzysztof Kozlowski (1):
ARM: s5pv210_defconfig: Remove old MACHs
Robie Basak (1):
ARM: exynos_defconfig: Enable IP multicast
arch/arm/configs/exynos_defconfig | 1 +
arch/arm/configs/s5pv210_defconfig | 4 ----
2 files changed, 1 insertion(+), 4 deletions(-)
^ permalink raw reply
* [PATCH RFC 0/7] Clean up PHY MMD accessors
From: Russell King - ARM Linux @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
This series cleans up phylib's MMD accessors, so that we have a common
way of accessing the Clause 45 register set.
The current situation is far from ideal - we have phy_(read|write)_mmd()
which accesses Clause 45 registers over Clause 45 accesses, and we have
phy_(read|write)_mmd_indirect(), which accesses Clause 45 registers via
Clause 22 register 13/14.
Generic code uses the indirect methods to access standard Clause 45
features, and when we come to add Clause 45 PHY support to phylib, we
would need to make these conditional upon the PHY type, or duplicate
these functions.
An alternative solution is to merge these accessors together, and select
the appropriate access method depending upon the 802.3 clause that the
PHY conforms with. The result is that we have a single set of
phy_(read|write)_mmd() accessors.
For cases which require special handling, we still allow PHY drivers to
override all MMD accesses - except rather than just overriding the
indirect accesses. This keeps existing overrides working.
Combining the two also has another beneficial side effect - we get rid
of similar functions that take arguments in different orders. The
old direct accessors took the phy structure, devad and register number,
whereas the indirect accessors took the phy structure, register number
and devad in that order. Care must be taken when updating future
drivers that the argument order is correct, and the function name is
not merely replaced.
This patch set is against 4.10-rc3 at present.
drivers/net/phy/Makefile | 3 +-
drivers/net/phy/bcm-phy-lib.c | 12 ++---
drivers/net/phy/dp83867.c | 18 +++----
drivers/net/phy/intel-xway.c | 26 +++++-----
drivers/net/phy/micrel.c | 13 +++--
drivers/net/phy/microchip.c | 5 +-
drivers/net/phy/phy-core.c | 101 ++++++++++++++++++++++++++++++++++++++
drivers/net/phy/phy.c | 110 ++++--------------------------------------
drivers/net/phy/phy_device.c | 4 +-
drivers/net/usb/lan78xx.c | 10 ++--
include/linux/phy.h | 56 +++++++++------------
11 files changed, 176 insertions(+), 182 deletions(-)
create mode 100644 drivers/net/phy/phy-core.c
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Boris Brezillon @ 2017-01-13 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d7b866ad-5b2f-62d3-3aa3-6fa42803d625@gmail.com>
On Fri, 13 Jan 2017 16:12:20 +0100
Matthias Brugger <matthias.bgg@gmail.com> wrote:
> On 13/01/17 15:17, Boris Brezillon wrote:
> > On Fri, 13 Jan 2017 15:13:29 +0800
> > Guochun Mao <guochun.mao@mediatek.com> wrote:
> >
> >> Add Mediatek nor flash node.
> >>
> >> Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
> >> ---
> >> arch/arm/boot/dts/mt2701-evb.dts | 25 +++++++++++++++++++++++++
> >> arch/arm/boot/dts/mt2701.dtsi | 12 ++++++++++++
> >> 2 files changed, 37 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
> >> index 082ca88..85e5ae8 100644
> >> --- a/arch/arm/boot/dts/mt2701-evb.dts
> >> +++ b/arch/arm/boot/dts/mt2701-evb.dts
> >> @@ -24,6 +24,31 @@
> >> };
> >> };
> >>
> >> +&nor_flash {
> >> + pinctrl-names = "default";
> >> + pinctrl-0 = <&nor_pins_default>;
> >> + status = "okay";
> >> + flash at 0 {
> >> + compatible = "jedec,spi-nor";
> >> + reg = <0>;
> >> + };
> >> +};
> >> +
> >> +&pio {
> >> + nor_pins_default: nor {
> >> + pins1 {
> >> + pinmux = <MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS>,
> >> + <MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK>,
> >> + <MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0>,
> >> + <MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1>,
> >> + <MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2>,
> >> + <MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3>;
> >> + drive-strength = <MTK_DRIVE_4mA>;
> >> + bias-pull-up;
> >> + };
> >> + };
> >> +};
> >> +
> >> &uart0 {
> >> status = "okay";
> >> };
> >> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> >> index bdf8954..1eefce4 100644
> >> --- a/arch/arm/boot/dts/mt2701.dtsi
> >> +++ b/arch/arm/boot/dts/mt2701.dtsi
> >> @@ -227,6 +227,18 @@
> >> status = "disabled";
> >> };
> >>
> >> + nor_flash: spi at 11014000 {
> >> + compatible = "mediatek,mt2701-nor",
> >> + "mediatek,mt8173-nor";
> >
> > Why define both here? Is "mediatek,mt8173-nor" really providing a
> > subset of the features supported by "mediatek,mt2701-nor"?
> >
>
> I think even if the ip block is the same, we should provide both
> bindings, just in case in the future we find out that mt2701 has some
> hidden bug, feature or bug-feature. This way even if we update the
> driver, we stay compatible with older device tree blobs in the wild.
I'm fine with this approach, but in this case, defining both is wrong.
>
> We can drop the mt2701-nor in the bindings definition if you want.
Yes, please.
>
> Regards,
> Matthias
>
> >> + reg = <0 0x11014000 0 0xe0>;
> >> + clocks = <&pericfg CLK_PERI_FLASH>,
> >> + <&topckgen CLK_TOP_FLASH_SEL>;
> >> + clock-names = "spi", "sf";
> >> + #address-cells = <1>;
> >> + #size-cells = <0>;
> >> + status = "disabled";
> >> + };
> >> +
> >> mmsys: syscon at 14000000 {
> >> compatible = "mediatek,mt2701-mmsys", "syscon";
> >> reg = <0 0x14000000 0 0x1000>;
> >
^ permalink raw reply
* [PATCH RFC 1/7] net: phy: move phy MMD accessors to phy-core.c
From: Russell King @ 2017-01-13 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113152059.GR14217@n2100.armlinux.org.uk>
Move the phy_(read|write)__mmd() helpers out of line, they will become
our main MMD accessor functions, and so will be a little more complex.
This complexity doesn't belong in an inline function. Also move the
_indirect variants as well to keep like functionality together.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/Makefile | 3 +-
drivers/net/phy/phy-core.c | 135 +++++++++++++++++++++++++++++++++++++++++++++
drivers/net/phy/phy.c | 85 ----------------------------
include/linux/phy.h | 20 +------
4 files changed, 139 insertions(+), 104 deletions(-)
create mode 100644 drivers/net/phy/phy-core.c
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 356859ac7c18..06fa2e04ac7e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,6 +1,7 @@
# Makefile for Linux PHY drivers and MDIO bus drivers
-libphy-y := phy.o phy_device.o mdio_bus.o mdio_device.o
+libphy-y := phy.o phy_device.o mdio_bus.o mdio_device.o \
+ phy-core.o
libphy-$(CONFIG_SWPHY) += swphy.o
libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_led_triggers.o
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
new file mode 100644
index 000000000000..b8d8276a3099
--- /dev/null
+++ b/drivers/net/phy/phy-core.c
@@ -0,0 +1,135 @@
+/*
+ * Core PHY library, taken from phy.c
+ *
+ * This program 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.
+ */
+#include <linux/export.h>
+#include <linux/phy.h>
+
+static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
+ int addr)
+{
+ /* Write the desired MMD Devad */
+ bus->write(bus, addr, MII_MMD_CTRL, devad);
+
+ /* Write the desired MMD register address */
+ bus->write(bus, addr, MII_MMD_DATA, prtad);
+
+ /* Select the Function : DATA with no post increment */
+ bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
+}
+
+/**
+ * phy_read_mmd_indirect - reads data from the MMD registers
+ * @phydev: The PHY device bus
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ *
+ * Description: it reads data from the MMD registers (clause 22 to access to
+ * clause 45) of the specified phy address.
+ * To read these register we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Read reg 14 // Read MMD data
+ */
+int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad)
+{
+ struct phy_driver *phydrv = phydev->drv;
+ int addr = phydev->mdio.addr;
+ int value = -1;
+
+ if (!phydrv->read_mmd_indirect) {
+ struct mii_bus *bus = phydev->mdio.bus;
+
+ mutex_lock(&bus->mdio_lock);
+ mmd_phy_indirect(bus, prtad, devad, addr);
+
+ /* Read the content of the MMD's selected register */
+ value = bus->read(bus, addr, MII_MMD_DATA);
+ mutex_unlock(&bus->mdio_lock);
+ } else {
+ value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr);
+ }
+ return value;
+}
+EXPORT_SYMBOL(phy_read_mmd_indirect);
+
+/**
+ * phy_read_mmd - Convenience function for reading a register
+ * from an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ *
+ * Same rules as for phy_read();
+ */
+int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
+{
+ if (!phydev->is_c45)
+ return -EOPNOTSUPP;
+
+ return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
+ MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
+}
+EXPORT_SYMBOL(phy_read_mmd);
+
+/**
+ * phy_write_mmd_indirect - writes data to the MMD registers
+ * @phydev: The PHY device
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ * @data: data to write in the MMD register
+ *
+ * Description: Write data from the MMD registers of the specified
+ * phy address.
+ * To write these register we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Write reg 14 // Write MMD data
+ */
+void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
+ int devad, u32 data)
+{
+ struct phy_driver *phydrv = phydev->drv;
+ int addr = phydev->mdio.addr;
+
+ if (!phydrv->write_mmd_indirect) {
+ struct mii_bus *bus = phydev->mdio.bus;
+
+ mutex_lock(&bus->mdio_lock);
+ mmd_phy_indirect(bus, prtad, devad, addr);
+
+ /* Write the data into MMD's selected register */
+ bus->write(bus, addr, MII_MMD_DATA, data);
+ mutex_unlock(&bus->mdio_lock);
+ } else {
+ phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
+ }
+}
+EXPORT_SYMBOL(phy_write_mmd_indirect);
+
+/**
+ * phy_write_mmd - Convenience function for writing a register
+ * on an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ * @val: value to write to @regnum
+ *
+ * Same rules as for phy_write();
+ */
+int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
+{
+ if (!phydev->is_c45)
+ return -EOPNOTSUPP;
+
+ regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
+
+ return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
+}
+EXPORT_SYMBOL(phy_write_mmd);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 25f93a98863b..c6022b66f81d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1175,91 +1175,6 @@ void phy_mac_interrupt(struct phy_device *phydev, int new_link)
}
EXPORT_SYMBOL(phy_mac_interrupt);
-static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
- int addr)
-{
- /* Write the desired MMD Devad */
- bus->write(bus, addr, MII_MMD_CTRL, devad);
-
- /* Write the desired MMD register address */
- bus->write(bus, addr, MII_MMD_DATA, prtad);
-
- /* Select the Function : DATA with no post increment */
- bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
-}
-
-/**
- * phy_read_mmd_indirect - reads data from the MMD registers
- * @phydev: The PHY device bus
- * @prtad: MMD Address
- * @devad: MMD DEVAD
- *
- * Description: it reads data from the MMD registers (clause 22 to access to
- * clause 45) of the specified phy address.
- * To read these register we have:
- * 1) Write reg 13 // DEVAD
- * 2) Write reg 14 // MMD Address
- * 3) Write reg 13 // MMD Data Command for MMD DEVAD
- * 3) Read reg 14 // Read MMD data
- */
-int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad)
-{
- struct phy_driver *phydrv = phydev->drv;
- int addr = phydev->mdio.addr;
- int value = -1;
-
- if (!phydrv->read_mmd_indirect) {
- struct mii_bus *bus = phydev->mdio.bus;
-
- mutex_lock(&bus->mdio_lock);
- mmd_phy_indirect(bus, prtad, devad, addr);
-
- /* Read the content of the MMD's selected register */
- value = bus->read(bus, addr, MII_MMD_DATA);
- mutex_unlock(&bus->mdio_lock);
- } else {
- value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr);
- }
- return value;
-}
-EXPORT_SYMBOL(phy_read_mmd_indirect);
-
-/**
- * phy_write_mmd_indirect - writes data to the MMD registers
- * @phydev: The PHY device
- * @prtad: MMD Address
- * @devad: MMD DEVAD
- * @data: data to write in the MMD register
- *
- * Description: Write data from the MMD registers of the specified
- * phy address.
- * To write these register we have:
- * 1) Write reg 13 // DEVAD
- * 2) Write reg 14 // MMD Address
- * 3) Write reg 13 // MMD Data Command for MMD DEVAD
- * 3) Write reg 14 // Write MMD data
- */
-void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
- int devad, u32 data)
-{
- struct phy_driver *phydrv = phydev->drv;
- int addr = phydev->mdio.addr;
-
- if (!phydrv->write_mmd_indirect) {
- struct mii_bus *bus = phydev->mdio.bus;
-
- mutex_lock(&bus->mdio_lock);
- mmd_phy_indirect(bus, prtad, devad, addr);
-
- /* Write the data into MMD's selected register */
- bus->write(bus, addr, MII_MMD_DATA, data);
- mutex_unlock(&bus->mdio_lock);
- } else {
- phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
- }
-}
-EXPORT_SYMBOL(phy_write_mmd_indirect);
-
/**
* phy_init_eee - init and check the EEE feature
* @phydev: target phy_device struct
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f7d95f644eed..72acb0233b5f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -647,14 +647,7 @@ struct phy_fixup {
*
* Same rules as for phy_read();
*/
-static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
-{
- if (!phydev->is_c45)
- return -EOPNOTSUPP;
-
- return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
- MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
-}
+int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
/**
* phy_read_mmd_indirect - reads data from the MMD registers
@@ -748,16 +741,7 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev)
*
* Same rules as for phy_write();
*/
-static inline int phy_write_mmd(struct phy_device *phydev, int devad,
- u32 regnum, u16 val)
-{
- if (!phydev->is_c45)
- return -EOPNOTSUPP;
-
- regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
-
- return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
-}
+int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
/**
* phy_write_mmd_indirect - writes data to the MMD registers
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox