2018-11-12 03:24:16

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 00/18] MMP platform fixes

Hi,

this series contains contains a bunch of MMP2 platform fixes.

I've sent these in before, some as part of other patch sets, but got just
radio silence from MMP2 maintainers. Eric Miao and Haojian Zhuang -- if
you're listening, please speak up.

I'm now re-sending as a single patch set for covenience. The "v3" number
was chosen to be higher than of any of the superseded sets.
The change logs from previous submissions are in respective patches.

The MMP2 support seems to in need for some love. Notably, in absence of
the 12/18 patch, the DT/multiplatform kernels can't even boot. If the
maintainers don't show up, would it be possible to pull this via the arm-soc
tree? Would it be appropriate if I followed up with a MAINTAINERS update in
that case?

Thanks
Lubo





2018-11-12 03:21:38

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 01/18] dt-bindings: mrvl,mmp-timer: add clock

The timer needs the timer clock to be enabled, otherwise it stops
ticking.

Signed-off-by: Lubomir Rintel <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
Acked-by: Pavel Machek <[email protected]>

---
Changes since v1:
- Made the clock optional, to keep compatibility with DTs without it

Documentation/devicetree/bindings/timer/mrvl,mmp-timer.txt | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/timer/mrvl,mmp-timer.txt b/Documentation/devicetree/bindings/timer/mrvl,mmp-timer.txt
index 9a6e251462e7..b8f02c663521 100644
--- a/Documentation/devicetree/bindings/timer/mrvl,mmp-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mrvl,mmp-timer.txt
@@ -5,9 +5,13 @@ Required properties:
- reg : Address and length of the register set of timer controller.
- interrupts : Should be the interrupt number.

+Optional properties:
+- clocks : Should contain a single entry describing the clock input.
+
Example:
timer0: timer@d4014000 {
compatible = "mrvl,mmp-timer";
reg = <0xd4014000 0x100>;
interrupts = <13>;
+ clocks = <&coreclk 2>;
};
--
2.19.1


2018-11-12 03:21:42

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 03/18] DT: marvell,mmp2: give gpio node a name

This will be useful for boards that actually use GPIO pins.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/boot/dts/mmp2.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index db15d1186cd0..f2a18779de7c 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -168,7 +168,7 @@
status = "disabled";
};

- gpio@d4019000 {
+ gpio: gpio@d4019000 {
compatible = "marvell,mmp2-gpio";
#address-cells = <1>;
#size-cells = <1>;
--
2.19.1


2018-11-12 03:22:01

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 05/18] DT: marvell,mmp2: add MMC controllers

There's apparently four of them on a MMP2.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>

---
Changes since v1:
- The controllers seem to be on AXI bus, not APB. Move them.
- Remove aliases.

arch/arm/boot/dts/mmp2.dtsi | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 4743a1288280..063382b3eaca 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -117,6 +117,42 @@
reg-names = "mux status", "mux mask";
mrvl,intc-nr-irqs = <2>;
};
+
+ mmc1: mmc@d4280000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xd4280000 0x120>;
+ clocks = <&soc_clocks MMP2_CLK_SDH0>;
+ clock-names = "io";
+ interrupts = <39>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@d4280800 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xd4280800 0x120>;
+ clocks = <&soc_clocks MMP2_CLK_SDH1>;
+ clock-names = "io";
+ interrupts = <52>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@d4281000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xd4281000 0x120>;
+ clocks = <&soc_clocks MMP2_CLK_SDH2>;
+ clock-names = "io";
+ interrupts = <53>;
+ status = "disabled";
+ };
+
+ mmc4: mmc@d4288000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xd4281800 0x120>;
+ clocks = <&soc_clocks MMP2_CLK_SDH3>;
+ clock-names = "io";
+ interrupts = <54>;
+ status = "disabled";
+ };
};

apb@d4000000 { /* APB */
--
2.19.1


2018-11-12 03:22:04

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 06/18] DT: marvell,mmp2: fix TWSI2

Marvell keeps their MMP2 datasheet secret, but there are good clues
that TWSI2 is not on 0xd4025000 on that platform, not does it use
IRQ 58. In fact, the IRQ 58 on MMP2 seems to be a signal processor:

arch/arm/mach-mmp/irqs.h:#define IRQ_MMP2_MSP 58

I'm taking a somewhat educated guess that is probably a copy & paste
error from PXA168 or PXA910 and that the real controller in fact hides
at address 0xd4031000 and uses an interrupt line multiplexed via IRQ 17.

I'm also copying some properties from TWSI1 that were missing or
incorrect.

Tested on a OLPC XO 1.75 machine, where the RTC is on TWSI2.

Signed-off-by: Lubomir Rintel <[email protected]>
Tested-by: Pavel Machek <[email protected]>
---
arch/arm/boot/dts/mmp2.dtsi | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 063382b3eaca..63d49abf4e92 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -257,12 +257,15 @@
status = "disabled";
};

- twsi2: i2c@d4025000 {
+ twsi2: i2c@d4031000 {
compatible = "mrvl,mmp-twsi";
- reg = <0xd4025000 0x1000>;
- interrupts = <58>;
+ reg = <0xd4031000 0x1000>;
+ interrupt-parent = <&intcmux17>;
+ interrupts = <0>;
clocks = <&soc_clocks MMP2_CLK_TWSI1>;
resets = <&soc_clocks MMP2_CLK_TWSI1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
status = "disabled";
};

--
2.19.1


2018-11-12 03:22:07

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 08/18] DT: marvell,mmp2: add OTG PHY

The USB OTG PHY chip. To be used by the OTG controller.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/boot/dts/mmp2.dtsi | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 7549680ab2e3..6ca1e17b6ac2 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -118,6 +118,13 @@
mrvl,intc-nr-irqs = <2>;
};

+ usb_otg_phy0: usb-otg-phy@d4207000 {
+ compatible = "marvell,mmp2-usb-phy";
+ reg = <0xd4207000 0x40>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
mmc1: mmc@d4280000 {
compatible = "mrvl,pxav3-mmc";
reg = <0xd4280000 0x120>;
--
2.19.1


2018-11-12 03:22:17

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 07/18] DT: marvell,mmp2: add more TWSI controllers

I've gotten the base addresses, clocks and interrupts from an rusty and old
out-of-tree driver. I haven't actually checked against the datasheet, since
that one is reserved for the Marvell inner circle.

Tested with an accelerometer on TWSI6 on an OLPC XO 1.75 machine.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/boot/dts/mmp2.dtsi | 49 +++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 63d49abf4e92..7549680ab2e3 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -269,6 +269,55 @@
status = "disabled";
};

+ twsi3: i2c@d4032000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4032000 0x1000>;
+ interrupt-parent = <&intcmux17>;
+ interrupts = <1>;
+ clocks = <&soc_clocks MMP2_CLK_TWSI2>;
+ resets = <&soc_clocks MMP2_CLK_TWSI2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ twsi4: i2c@d4033000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4033000 0x1000>;
+ interrupt-parent = <&intcmux17>;
+ interrupts = <2>;
+ clocks = <&soc_clocks MMP2_CLK_TWSI3>;
+ resets = <&soc_clocks MMP2_CLK_TWSI3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+
+ twsi5: i2c@d4033800 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4033800 0x1000>;
+ interrupt-parent = <&intcmux17>;
+ interrupts = <3>;
+ clocks = <&soc_clocks MMP2_CLK_TWSI4>;
+ resets = <&soc_clocks MMP2_CLK_TWSI4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ twsi6: i2c@d4034000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4034000 0x1000>;
+ interrupt-parent = <&intcmux17>;
+ interrupts = <4>;
+ clocks = <&soc_clocks MMP2_CLK_TWSI5>;
+ resets = <&soc_clocks MMP2_CLK_TWSI5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
rtc: rtc@d4010000 {
compatible = "mrvl,mmp-rtc";
reg = <0xd4010000 0x1000>;
--
2.19.1


2018-11-12 03:22:25

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 15/18] ARM: mmp: add a pxa-usb-phy device

This is to replace the USB PHY initialization code (pxa_usb_phy_init(),
pxa_usb_phy_deinit()) with a proper PHY driver.

Signed-off-by: Lubomir Rintel <[email protected]>
---
arch/arm/mach-mmp/devices.c | 21 +++++++++++++++++++++
arch/arm/mach-mmp/pxa910.h | 1 +
2 files changed, 22 insertions(+)

diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
index 0fca63c80e1a..822b8be042b9 100644
--- a/arch/arm/mach-mmp/devices.c
+++ b/arch/arm/mach-mmp/devices.c
@@ -240,6 +240,27 @@ void pxa_usb_phy_deinit(void __iomem *phy_reg)
#if IS_ENABLED(CONFIG_USB_SUPPORT)
static u64 __maybe_unused usb_dma_mask = ~(u32)0;

+#if IS_ENABLED(CONFIG_PHY_PXA_USB)
+struct resource pxa168_usb_phy_resources[] = {
+ [0] = {
+ .start = PXA168_U2O_PHYBASE,
+ .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device pxa168_device_usb_phy = {
+ .name = "pxa-usb-phy",
+ .id = -1,
+ .resource = pxa168_usb_phy_resources,
+ .num_resources = ARRAY_SIZE(pxa168_usb_phy_resources),
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ }
+};
+#endif /* CONFIG_PHY_PXA_USB */
+
#if IS_ENABLED(CONFIG_USB_MV_UDC)
struct resource pxa168_u2o_resources[] = {
/* regbase */
diff --git a/arch/arm/mach-mmp/pxa910.h b/arch/arm/mach-mmp/pxa910.h
index 42009c349eae..2dfe38e4acc1 100644
--- a/arch/arm/mach-mmp/pxa910.h
+++ b/arch/arm/mach-mmp/pxa910.h
@@ -22,6 +22,7 @@ extern struct pxa_device_desc pxa910_device_pwm2;
extern struct pxa_device_desc pxa910_device_pwm3;
extern struct pxa_device_desc pxa910_device_pwm4;
extern struct pxa_device_desc pxa910_device_nand;
+extern struct platform_device pxa168_device_usb_phy;
extern struct platform_device pxa168_device_u2o;
extern struct platform_device pxa168_device_u2ootg;
extern struct platform_device pxa168_device_u2oehci;
--
2.19.1


2018-11-12 03:22:29

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 12/18] ARM: mmp/mmp2: use cpu_is_pj4() instead of cpu_is_mmp2()

The MMP2 platform uses the PJ4 CPU. The cpu_is_mmp2() macro is thus
actually not useful at all and moreover gives the wrong result on
MACH_MMP2_DT.

The actual problem I aim to fix is that on a device-tree enabled system,
the timer ends up being initialized incorrectly. In fact, it ticks like
at rate that's 1/100 slower or so.

Perhaps the other cpu_is_mmp2() uses are more benign, but still useless.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/mach-mmp/cputype.h | 9 ---------
arch/arm/mach-mmp/mmp2.c | 2 +-
arch/arm/mach-mmp/pm-mmp2.c | 2 +-
arch/arm/mach-mmp/time.c | 2 +-
4 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-mmp/cputype.h b/arch/arm/mach-mmp/cputype.h
index 446edaeb78a7..405dbbbbbcdd 100644
--- a/arch/arm/mach-mmp/cputype.h
+++ b/arch/arm/mach-mmp/cputype.h
@@ -44,13 +44,4 @@ static inline int cpu_is_pxa910(void)
#define cpu_is_pxa910() (0)
#endif

-#ifdef CONFIG_CPU_MMP2
-static inline int cpu_is_mmp2(void)
-{
- return (((read_cpuid_id() >> 8) & 0xff) == 0x58);
-}
-#else
-#define cpu_is_mmp2() (0)
-#endif
-
#endif /* __ASM_MACH_CPUTYPE_H */
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index afba5460cdaf..b670fafedeac 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -104,7 +104,7 @@ void __init mmp2_init_irq(void)

static int __init mmp2_init(void)
{
- if (cpu_is_mmp2()) {
+ if (cpu_is_pj4()) {
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init(0);
#endif
diff --git a/arch/arm/mach-mmp/pm-mmp2.c b/arch/arm/mach-mmp/pm-mmp2.c
index 17699be3bc3d..bcd5111ffb37 100644
--- a/arch/arm/mach-mmp/pm-mmp2.c
+++ b/arch/arm/mach-mmp/pm-mmp2.c
@@ -220,7 +220,7 @@ static int __init mmp2_pm_init(void)
{
uint32_t apcr;

- if (!cpu_is_mmp2())
+ if (!cpu_is_pj4())
return -EIO;

suspend_set_ops(&mmp2_pm_ops);
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 96ad1db0b04b..0f49ac579a17 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -163,7 +163,7 @@ static void __init timer_config(void)

__raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */

- ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
+ ccr &= (cpu_is_pj4()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
(TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
__raw_writel(ccr, mmp_timer_base + TMR_CCR);

--
2.19.1


2018-11-12 03:22:34

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 14/18] ARM: mmp/mmp2: dt: enable the clock

The device-tree booted MMP2 needs to enable the timer clock, otherwise
it would stop ticking when the boot finishes.

It can also use the clock rate from the clk, the non-DT boards need to
keep using the hardcoded rates.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>

---
Changes since v2:
- Wording improvement, whitespace fix and an ack from Pavel

Changes since v1:
- Made the clock optional, to keep compatibility with DTs without it

arch/arm/mach-mmp/common.h | 2 +-
arch/arm/mach-mmp/mmp2.c | 2 +-
arch/arm/mach-mmp/pxa168.c | 2 +-
arch/arm/mach-mmp/time.c | 32 ++++++++++++++++++++------------
4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index 7e284d9c429f..5ac2851ef5d3 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -2,7 +2,7 @@
#include <linux/reboot.h>
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)

-extern void timer_init(int irq);
+extern void timer_init(int irq, unsigned long rate);

extern void __init mmp_map_io(void);
extern void mmp_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index b670fafedeac..8717de7d0757 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -134,7 +134,7 @@ void __init mmp2_timer_init(void)
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
__raw_writel(clk_rst, APBC_TIMERS);

- timer_init(IRQ_MMP2_TIMER1);
+ timer_init(IRQ_MMP2_TIMER1, 6500000);
}

/* on-chip devices */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 0f5f16fb8c66..77a358165a56 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -79,7 +79,7 @@ void __init pxa168_timer_init(void)
/* 3.25MHz, bus/functional clock enabled, release reset */
__raw_writel(TIMER_CLK_RST, APBC_TIMERS);

- timer_init(IRQ_PXA168_TIMER1);
+ timer_init(IRQ_PXA168_TIMER1, 6500000);
}

void pxa168_clear_keypad_wakeup(void)
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 0f49ac579a17..007b94a92923 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/clockchips.h>
+#include <linux/clk.h>

#include <linux/io.h>
#include <linux/irq.h>
@@ -38,12 +39,6 @@
#include "cputype.h"
#include "clock.h"

-#ifdef CONFIG_CPU_MMP2
-#define MMP_CLOCK_FREQ 6500000
-#else
-#define MMP_CLOCK_FREQ 3250000
-#endif
-
#define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE

#define MAX_DELTA (0xfffffffe)
@@ -189,19 +184,18 @@ static struct irqaction timer_irq = {
.dev_id = &ckevt,
};

-void __init timer_init(int irq)
+void __init timer_init(int irq, unsigned long rate)
{
timer_config();

- sched_clock_register(mmp_read_sched_clock, 32, MMP_CLOCK_FREQ);
+ sched_clock_register(mmp_read_sched_clock, 32, rate);

ckevt.cpumask = cpumask_of(0);

setup_irq(irq, &timer_irq);

- clocksource_register_hz(&cksrc, MMP_CLOCK_FREQ);
- clockevents_config_and_register(&ckevt, MMP_CLOCK_FREQ,
- MIN_DELTA, MAX_DELTA);
+ clocksource_register_hz(&cksrc, rate);
+ clockevents_config_and_register(&ckevt, rate, MIN_DELTA, MAX_DELTA);
}

#ifdef CONFIG_OF
@@ -213,7 +207,9 @@ static const struct of_device_id mmp_timer_dt_ids[] = {
void __init mmp_dt_init_timer(void)
{
struct device_node *np;
+ struct clk *clk;
int irq, ret;
+ unsigned long rate;

np = of_find_matching_node(NULL, mmp_timer_dt_ids);
if (!np) {
@@ -221,6 +217,18 @@ void __init mmp_dt_init_timer(void)
goto out;
}

+ clk = of_clk_get(np, 0);
+ if (!IS_ERR(clk)) {
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ goto out;
+ rate = clk_get_rate(clk) / 2;
+ } else if (cpu_is_pj4()) {
+ rate = 6500000;
+ } else {
+ rate = 3250000;
+ }
+
irq = irq_of_parse_and_map(np, 0);
if (!irq) {
ret = -EINVAL;
@@ -231,7 +239,7 @@ void __init mmp_dt_init_timer(void)
ret = -ENOMEM;
goto out;
}
- timer_init(irq);
+ timer_init(irq, rate);
return;
out:
pr_err("Failed to get timer from device tree with error:%d\n", ret);
--
2.19.1


2018-11-12 03:22:37

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 17/18] USB: phy-mv-usb: use phy-pxa-usb

Use a proper PHY driver, instead of hooks to a board support package.

Signed-off-by: Lubomir Rintel <[email protected]>
Tested-by: Pavel Machek <[email protected]>
---
arch/arm/mach-mmp/devices.c | 11 +---
drivers/usb/phy/phy-mv-usb.c | 123 ++++++++++++++++-------------------
drivers/usb/phy/phy-mv-usb.h | 8 ++-
3 files changed, 62 insertions(+), 80 deletions(-)

diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
index 822b8be042b9..eb9b3c34e90a 100644
--- a/arch/arm/mach-mmp/devices.c
+++ b/arch/arm/mach-mmp/devices.c
@@ -325,21 +325,12 @@ struct platform_device pxa168_device_u2oehci = {

#if IS_ENABLED(CONFIG_USB_MV_OTG)
struct resource pxa168_u2ootg_resources[] = {
- /* regbase */
[0] = {
- .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+ .start = PXA168_U2O_REGBASE,
.end = PXA168_U2O_REGBASE + USB_REG_RANGE,
.flags = IORESOURCE_MEM,
- .name = "capregs",
},
- /* phybase */
[1] = {
- .start = PXA168_U2O_PHYBASE,
- .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
- .flags = IORESOURCE_MEM,
- .name = "phyregs",
- },
- [2] = {
.start = IRQ_PXA168_USB1,
.end = IRQ_PXA168_USB1,
.flags = IORESOURCE_IRQ,
diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c
index cfd9add10bf4..0f67c5b65fe9 100644
--- a/drivers/usb/phy/phy-mv-usb.c
+++ b/drivers/usb/phy/phy-mv-usb.c
@@ -50,7 +50,7 @@ static char *state_string[] = {

static int mv_otg_set_vbus(struct usb_otg *otg, bool on)
{
- struct mv_otg *mvotg = container_of(otg->usb_phy, struct mv_otg, phy);
+ struct mv_otg *mvotg = container_of(otg->usb_phy, struct mv_otg, usb_phy);
if (mvotg->pdata->set_vbus == NULL)
return -ENODEV;

@@ -193,7 +193,7 @@ static void mv_otg_init_irq(struct mv_otg *mvotg)
static void mv_otg_start_host(struct mv_otg *mvotg, int on)
{
#ifdef CONFIG_USB
- struct usb_otg *otg = mvotg->phy.otg;
+ struct usb_otg *otg = mvotg->usb_phy.otg;
struct usb_hcd *hcd;

if (!otg->host)
@@ -214,12 +214,12 @@ static void mv_otg_start_host(struct mv_otg *mvotg, int on)

static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on)
{
- struct usb_otg *otg = mvotg->phy.otg;
+ struct usb_otg *otg = mvotg->usb_phy.otg;

if (!otg->gadget)
return;

- dev_info(mvotg->phy.dev, "gadget %s\n", on ? "on" : "off");
+ dev_info(mvotg->usb_phy.dev, "gadget %s\n", on ? "on" : "off");

if (on)
usb_gadget_vbus_connect(otg->gadget);
@@ -247,14 +247,11 @@ static int mv_otg_enable_internal(struct mv_otg *mvotg)
dev_dbg(&mvotg->pdev->dev, "otg enabled\n");

otg_clock_enable(mvotg);
- if (mvotg->pdata->phy_init) {
- retval = mvotg->pdata->phy_init(mvotg->phy_regs);
- if (retval) {
- dev_err(&mvotg->pdev->dev,
- "init phy error %d\n", retval);
- otg_clock_disable(mvotg);
- return retval;
- }
+ retval = phy_init(mvotg->phy);
+ if (retval) {
+ dev_err(&mvotg->pdev->dev, "init phy error %d\n", retval);
+ otg_clock_disable(mvotg);
+ return retval;
}
mvotg->active = 1;

@@ -274,8 +271,7 @@ static void mv_otg_disable_internal(struct mv_otg *mvotg)
{
if (mvotg->active) {
dev_dbg(&mvotg->pdev->dev, "otg disabled\n");
- if (mvotg->pdata->phy_deinit)
- mvotg->pdata->phy_deinit(mvotg->phy_regs);
+ phy_exit(mvotg->phy);
otg_clock_disable(mvotg);
mvotg->active = 0;
}
@@ -329,68 +325,68 @@ static void mv_otg_update_inputs(struct mv_otg *mvotg)
static void mv_otg_update_state(struct mv_otg *mvotg)
{
struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl;
- int old_state = mvotg->phy.otg->state;
+ int old_state = mvotg->usb_phy.otg->state;

switch (old_state) {
case OTG_STATE_UNDEFINED:
- mvotg->phy.otg->state = OTG_STATE_B_IDLE;
+ mvotg->usb_phy.otg->state = OTG_STATE_B_IDLE;
/* FALL THROUGH */
case OTG_STATE_B_IDLE:
if (otg_ctrl->id == 0)
- mvotg->phy.otg->state = OTG_STATE_A_IDLE;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_IDLE;
else if (otg_ctrl->b_sess_vld)
- mvotg->phy.otg->state = OTG_STATE_B_PERIPHERAL;
+ mvotg->usb_phy.otg->state = OTG_STATE_B_PERIPHERAL;
break;
case OTG_STATE_B_PERIPHERAL:
if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0)
- mvotg->phy.otg->state = OTG_STATE_B_IDLE;
+ mvotg->usb_phy.otg->state = OTG_STATE_B_IDLE;
break;
case OTG_STATE_A_IDLE:
if (otg_ctrl->id)
- mvotg->phy.otg->state = OTG_STATE_B_IDLE;
+ mvotg->usb_phy.otg->state = OTG_STATE_B_IDLE;
else if (!(otg_ctrl->a_bus_drop) &&
(otg_ctrl->a_bus_req || otg_ctrl->a_srp_det))
- mvotg->phy.otg->state = OTG_STATE_A_WAIT_VRISE;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_WAIT_VRISE;
break;
case OTG_STATE_A_WAIT_VRISE:
if (otg_ctrl->a_vbus_vld)
- mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_WAIT_BCON;
break;
case OTG_STATE_A_WAIT_BCON:
if (otg_ctrl->id || otg_ctrl->a_bus_drop
|| otg_ctrl->a_wait_bcon_timeout) {
mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER);
mvotg->otg_ctrl.a_wait_bcon_timeout = 0;
- mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_WAIT_VFALL;
otg_ctrl->a_bus_req = 0;
} else if (!otg_ctrl->a_vbus_vld) {
mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER);
mvotg->otg_ctrl.a_wait_bcon_timeout = 0;
- mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_VBUS_ERR;
} else if (otg_ctrl->b_conn) {
mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER);
mvotg->otg_ctrl.a_wait_bcon_timeout = 0;
- mvotg->phy.otg->state = OTG_STATE_A_HOST;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_HOST;
}
break;
case OTG_STATE_A_HOST:
if (otg_ctrl->id || !otg_ctrl->b_conn
|| otg_ctrl->a_bus_drop)
- mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_WAIT_BCON;
else if (!otg_ctrl->a_vbus_vld)
- mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_VBUS_ERR;
break;
case OTG_STATE_A_WAIT_VFALL:
if (otg_ctrl->id
|| (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld)
|| otg_ctrl->a_bus_req)
- mvotg->phy.otg->state = OTG_STATE_A_IDLE;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_IDLE;
break;
case OTG_STATE_A_VBUS_ERR:
if (otg_ctrl->id || otg_ctrl->a_clr_err
|| otg_ctrl->a_bus_drop) {
otg_ctrl->a_clr_err = 0;
- mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL;
+ mvotg->usb_phy.otg->state = OTG_STATE_A_WAIT_VFALL;
}
break;
default:
@@ -409,8 +405,8 @@ static void mv_otg_work(struct work_struct *work)

run:
/* work queue is single thread, or we need spin_lock to protect */
- phy = &mvotg->phy;
- otg = mvotg->phy.otg;
+ phy = &mvotg->usb_phy;
+ otg = mvotg->usb_phy.otg;
old_state = otg->state;

if (!mvotg->active)
@@ -419,24 +415,24 @@ static void mv_otg_work(struct work_struct *work)
mv_otg_update_inputs(mvotg);
mv_otg_update_state(mvotg);

- if (old_state != mvotg->phy.otg->state) {
+ if (old_state != mvotg->usb_phy.otg->state) {
dev_info(&mvotg->pdev->dev, "change from state %s to %s\n",
state_string[old_state],
- state_string[mvotg->phy.otg->state]);
+ state_string[mvotg->usb_phy.otg->state]);

- switch (mvotg->phy.otg->state) {
+ switch (mvotg->usb_phy.otg->state) {
case OTG_STATE_B_IDLE:
otg->default_a = 0;
if (old_state == OTG_STATE_B_PERIPHERAL)
mv_otg_start_periphrals(mvotg, 0);
mv_otg_reset(mvotg);
mv_otg_disable(mvotg);
- usb_phy_set_event(&mvotg->phy, USB_EVENT_NONE);
+ usb_phy_set_event(&mvotg->usb_phy, USB_EVENT_NONE);
break;
case OTG_STATE_B_PERIPHERAL:
mv_otg_enable(mvotg);
mv_otg_start_periphrals(mvotg, 1);
- usb_phy_set_event(&mvotg->phy, USB_EVENT_ENUMERATED);
+ usb_phy_set_event(&mvotg->usb_phy, USB_EVENT_ENUMERATED);
break;
case OTG_STATE_A_IDLE:
otg->default_a = 1;
@@ -536,8 +532,8 @@ a_bus_req_store(struct device *dev, struct device_attribute *attr,
return -1;

/* We will use this interface to change to A device */
- if (mvotg->phy.otg->state != OTG_STATE_B_IDLE
- && mvotg->phy.otg->state != OTG_STATE_A_IDLE)
+ if (mvotg->usb_phy.otg->state != OTG_STATE_B_IDLE
+ && mvotg->usb_phy.otg->state != OTG_STATE_A_IDLE)
return -1;

/* The clock may disabled and we need to set irq for ID detected */
@@ -566,7 +562,7 @@ a_clr_err_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct mv_otg *mvotg = dev_get_drvdata(dev);
- if (!mvotg->phy.otg->default_a)
+ if (!mvotg->usb_phy.otg->default_a)
return -1;

if (count > 2)
@@ -602,7 +598,7 @@ a_bus_drop_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct mv_otg *mvotg = dev_get_drvdata(dev);
- if (!mvotg->phy.otg->default_a)
+ if (!mvotg->usb_phy.otg->default_a)
return -1;

if (count > 2)
@@ -656,7 +652,7 @@ static int mv_otg_remove(struct platform_device *pdev)

mv_otg_disable(mvotg);

- usb_remove_phy(&mvotg->phy);
+ usb_remove_phy(&mvotg->usb_phy);

return 0;
}
@@ -687,6 +683,10 @@ static int mv_otg_probe(struct platform_device *pdev)
mvotg->pdev = pdev;
mvotg->pdata = pdata;

+ mvotg->phy = devm_phy_get(&pdev->dev, "usb");
+ if (IS_ERR(mvotg->phy))
+ return PTR_ERR(mvotg->phy);
+
mvotg->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(mvotg->clk))
return PTR_ERR(mvotg->clk);
@@ -701,12 +701,12 @@ static int mv_otg_probe(struct platform_device *pdev)

/* OTG common part */
mvotg->pdev = pdev;
- mvotg->phy.dev = &pdev->dev;
- mvotg->phy.otg = otg;
- mvotg->phy.label = driver_name;
+ mvotg->usb_phy.dev = &pdev->dev;
+ mvotg->usb_phy.otg = otg;
+ mvotg->usb_phy.label = driver_name;

otg->state = OTG_STATE_UNDEFINED;
- otg->usb_phy = &mvotg->phy;
+ otg->usb_phy = &mvotg->usb_phy;
otg->set_host = mv_otg_set_host;
otg->set_peripheral = mv_otg_set_peripheral;
otg->set_vbus = mv_otg_set_vbus;
@@ -715,36 +715,23 @@ static int mv_otg_probe(struct platform_device *pdev)
timer_setup(&mvotg->otg_ctrl.timer[i],
mv_otg_timer_await_bcon, 0);

- r = platform_get_resource_byname(mvotg->pdev,
- IORESOURCE_MEM, "phyregs");
- if (r == NULL) {
- dev_err(&pdev->dev, "no phy I/O memory resource defined\n");
- retval = -ENODEV;
- goto err_destroy_workqueue;
- }
-
- mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
- if (mvotg->phy_regs == NULL) {
- dev_err(&pdev->dev, "failed to map phy I/O memory\n");
- retval = -EFAULT;
- goto err_destroy_workqueue;
- }
-
- r = platform_get_resource_byname(mvotg->pdev,
- IORESOURCE_MEM, "capregs");
+ r = platform_get_resource(mvotg->pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "no I/O memory resource defined\n");
retval = -ENODEV;
goto err_destroy_workqueue;
}

- mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
- if (mvotg->cap_regs == NULL) {
+ mvotg->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+ if (mvotg->base == NULL) {
dev_err(&pdev->dev, "failed to map I/O memory\n");
retval = -EFAULT;
goto err_destroy_workqueue;
}

+ mvotg->cap_regs =
+ (void __iomem *) ((unsigned long)mvotg->base + U2x_CAPREGS_OFFSET);
+
/* we will acces controller register, so enable the udc controller */
retval = mv_otg_enable_internal(mvotg);
if (retval) {
@@ -804,7 +791,7 @@ static int mv_otg_probe(struct platform_device *pdev)
goto err_disable_clk;
}

- retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2);
+ retval = usb_add_phy(&mvotg->usb_phy, USB_PHY_TYPE_USB2);
if (retval < 0) {
dev_err(&pdev->dev, "can't register transceiver, %d\n",
retval);
@@ -831,7 +818,7 @@ static int mv_otg_probe(struct platform_device *pdev)
return 0;

err_remove_phy:
- usb_remove_phy(&mvotg->phy);
+ usb_remove_phy(&mvotg->usb_phy);
err_disable_clk:
mv_otg_disable_internal(mvotg);
err_destroy_workqueue:
@@ -846,10 +833,10 @@ static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state)
{
struct mv_otg *mvotg = platform_get_drvdata(pdev);

- if (mvotg->phy.otg->state != OTG_STATE_B_IDLE) {
+ if (mvotg->usb_phy.otg->state != OTG_STATE_B_IDLE) {
dev_info(&pdev->dev,
"OTG state is not B_IDLE, it is %d!\n",
- mvotg->phy.otg->state);
+ mvotg->usb_phy.otg->state);
return -EAGAIN;
}

diff --git a/drivers/usb/phy/phy-mv-usb.h b/drivers/usb/phy/phy-mv-usb.h
index 96701a1229ad..9b7bc6d958a8 100644
--- a/drivers/usb/phy/phy-mv-usb.h
+++ b/drivers/usb/phy/phy-mv-usb.h
@@ -8,6 +8,9 @@

#include <linux/types.h>

+/* registers */
+#define U2x_CAPREGS_OFFSET 0x100
+
/* Command Register Bit Masks */
#define USBCMD_RUN_STOP (0x00000001)
#define USBCMD_CTRL_RESET (0x00000002)
@@ -132,11 +135,11 @@ struct mv_otg_regs {
};

struct mv_otg {
- struct usb_phy phy;
+ struct usb_phy usb_phy;
struct mv_otg_ctrl otg_ctrl;

/* base address */
- void __iomem *phy_regs;
+ void __iomem *base;
void __iomem *cap_regs;
struct mv_otg_regs __iomem *op_regs;

@@ -155,6 +158,7 @@ struct mv_otg {
unsigned int active;
unsigned int clock_gating;
struct clk *clk;
+ struct phy *phy;
};

#endif
--
2.19.1


2018-11-12 03:22:58

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 04/18] DT: marvell,mmp2: add clock to the timer

The timer needs the timer clock to be enabled, otherwise it stops
ticking.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/boot/dts/mmp2.dtsi | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index f2a18779de7c..4743a1288280 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -130,6 +130,7 @@
compatible = "mrvl,mmp-timer";
reg = <0xd4014000 0x100>;
interrupts = <13>;
+ clocks = <&soc_clocks MMP2_CLK_TIMER>;
};

uart1: uart@d4030000 {
--
2.19.1


2018-11-12 03:22:59

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 11/18] gpio: pxa: avoid attempting to set pin direction via pinctrl on MMP2

Similarly to PXA3xx pinctrl-single can't set pin direction on MMP2 either.
See also: commit 9dabfdd84bdfa ("gpio: pxa: disable pinctrl calls for
PXA3xx")

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
drivers/gpio/gpio-pxa.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index bfe4c5c9f41c..1b437bbe5cf5 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -245,6 +245,7 @@ static bool pxa_gpio_has_pinctrl(void)
{
switch (gpio_type) {
case PXA3XX_GPIO:
+ case MMP2_GPIO:
return false;

default:
--
2.19.1


2018-11-12 03:23:21

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 10/18] irqchip/mmp: only touch the PJ4 & FIQ bits on enable/disable

On an OLPC XO 1.75 machine, the "security processor" handles the GPIO 71
and 72 interrupts. Don't reset the "route to SP" bit (4).

I'm just assuming the bit 4 is the "route to SP" bit -- it fixes the
SP-based keyboard for me and <mach-mmp/regs-icu.h> defines
ICU_INT_ROUTE_SP_IRQ to be 1 << 4. When asked for a data sheet, Marvell
was not helpful.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>

---
Changes since v1:
- Adjusted wording & ack from Pavel

drivers/irqchip/irq-mmp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index 25f32e1d7764..1ed38f9f1d0a 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -190,7 +190,7 @@ static const struct mmp_intc_conf mmp_conf = {
static const struct mmp_intc_conf mmp2_conf = {
.conf_enable = 0x20,
.conf_disable = 0x0,
- .conf_mask = 0x7f,
+ .conf_mask = 0x60,
};

static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs)
--
2.19.1


2018-11-12 03:23:30

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 13/18] ARM: mmp2: initialize clocks before the timer

The timer shall enable its clock.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/mach-mmp/mmp2-dt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c
index 0341359b24a4..50c5e8b5be3d 100644
--- a/arch/arm/mach-mmp/mmp2-dt.c
+++ b/arch/arm/mach-mmp/mmp2-dt.c
@@ -26,8 +26,8 @@ static void __init mmp_init_time(void)
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init(0);
#endif
- mmp_dt_init_timer();
of_clk_init(NULL);
+ mmp_dt_init_timer();
}

static const char *const mmp2_dt_board_compat[] __initconst = {
--
2.19.1


2018-11-12 03:23:36

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 02/18] DT: marvell,mmp2: fix the gpio interrupt cell number

gpio-pxa uses two cell to encode the interrupt source: the pin number
and the trigger type. Adjust the device node accordingly.

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/boot/dts/mmp2.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 766bbb8495b6..db15d1186cd0 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -180,7 +180,7 @@
clocks = <&soc_clocks MMP2_CLK_GPIO>;
resets = <&soc_clocks MMP2_CLK_GPIO>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
ranges;

gcb0: gpio@d4019000 {
--
2.19.1


2018-11-12 03:23:42

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 16/18] ARM: mmp: add an instance of pxa-usb-phy to ttc_dkb and aspenite

This will replace the *_pdata.phy_{de,}init()

Signed-off-by: Lubomir Rintel <[email protected]>

---
Changes since v1:
- Squashed patches with ttc_dkb and aspenite changes together.

arch/arm/mach-mmp/aspenite.c | 4 ++++
arch/arm/mach-mmp/ttc_dkb.c | 4 ++++
2 files changed, 8 insertions(+)

diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 6c2ebf01893a..23f99976b5f5 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -256,6 +256,10 @@ static void __init common_init(void)
/* off-chip devices */
platform_device_register(&smc91x_device);

+#if IS_ENABLED(CONFIG_PHY_PXA_USB)
+ platform_device_register(&pxa168_device_usb_phy);
+#endif
+
#if IS_ENABLED(CONFIG_USB_EHCI_MV)
pxa168_add_usb_host(&pxa168_sph_pdata);
#endif
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index c7897fb2b6da..767dcb23ee1c 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -282,6 +282,10 @@ static void __init ttc_dkb_init(void)
sizeof(struct pxa_gpio_platform_data));
platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));

+#if IS_ENABLED(CONFIG_PHY_PXA_USB)
+ platform_device_register(&pxa168_device_usb_phy);
+#endif
+
#if IS_ENABLED(CONFIG_USB_MV_UDC)
pxa168_device_u2o.dev.platform_data = &ttc_usb_pdata;
platform_device_register(&pxa168_device_u2o);
--
2.19.1


2018-11-12 03:23:45

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 18/18] USB: gadget: mv-udc: use phy-pxa-usb

Use a proper PHY driver, instead of hooks to a board support package.

Signed-off-by: Lubomir Rintel <[email protected]>
---
arch/arm/mach-mmp/devices.c | 11 +-------
drivers/usb/gadget/udc/mv_udc.h | 7 ++++-
drivers/usb/gadget/udc/mv_udc_core.c | 38 ++++++++--------------------
3 files changed, 17 insertions(+), 39 deletions(-)

diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
index eb9b3c34e90a..d925be9f14a9 100644
--- a/arch/arm/mach-mmp/devices.c
+++ b/arch/arm/mach-mmp/devices.c
@@ -263,21 +263,12 @@ struct platform_device pxa168_device_usb_phy = {

#if IS_ENABLED(CONFIG_USB_MV_UDC)
struct resource pxa168_u2o_resources[] = {
- /* regbase */
[0] = {
- .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+ .start = PXA168_U2O_REGBASE,
.end = PXA168_U2O_REGBASE + USB_REG_RANGE,
.flags = IORESOURCE_MEM,
- .name = "capregs",
},
- /* phybase */
[1] = {
- .start = PXA168_U2O_PHYBASE,
- .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
- .flags = IORESOURCE_MEM,
- .name = "phyregs",
- },
- [2] = {
.start = IRQ_PXA168_USB1,
.end = IRQ_PXA168_USB1,
.flags = IORESOURCE_IRQ,
diff --git a/drivers/usb/gadget/udc/mv_udc.h b/drivers/usb/gadget/udc/mv_udc.h
index b3f759c0962c..6f04f432964d 100644
--- a/drivers/usb/gadget/udc/mv_udc.h
+++ b/drivers/usb/gadget/udc/mv_udc.h
@@ -6,6 +6,9 @@
#ifndef __MV_UDC_H
#define __MV_UDC_H

+/* registers */
+#define U2x_CAPREGS_OFFSET 0x100
+
#define VUSBHS_MAX_PORTS 8

#define DQH_ALIGNMENT 2048
@@ -174,9 +177,9 @@ struct mv_udc {
struct platform_device *dev;
int irq;

+ void __iomem *base;
struct mv_cap_regs __iomem *cap_regs;
struct mv_op_regs __iomem *op_regs;
- void __iomem *phy_regs;
unsigned int max_eps;
struct mv_dqh *ep_dqh;
size_t ep_dqh_size;
@@ -219,6 +222,8 @@ struct mv_udc {

/* some SOC has mutiple clock sources for USB*/
struct clk *clk;
+
+ struct phy *phy;
};

/* endpoint data structure */
diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c
index cafde053788b..35b0bde2d46f 100644
--- a/drivers/usb/gadget/udc/mv_udc_core.c
+++ b/drivers/usb/gadget/udc/mv_udc_core.c
@@ -1069,14 +1069,11 @@ static int mv_udc_enable_internal(struct mv_udc *udc)
if (retval)
return retval;

- if (udc->pdata->phy_init) {
- retval = udc->pdata->phy_init(udc->phy_regs);
- if (retval) {
- dev_err(&udc->dev->dev,
- "init phy error %d\n", retval);
- udc_clock_disable(udc);
- return retval;
- }
+ retval = phy_init(udc->phy);
+ if (retval) {
+ dev_err(&udc->dev->dev, "init phy error %d\n", retval);
+ udc_clock_disable(udc);
+ return retval;
}
udc->active = 1;

@@ -1095,8 +1092,7 @@ static void mv_udc_disable_internal(struct mv_udc *udc)
{
if (udc->active) {
dev_dbg(&udc->dev->dev, "disable udc\n");
- if (udc->pdata->phy_deinit)
- udc->pdata->phy_deinit(udc->phy_regs);
+ phy_exit(udc->phy);
udc_clock_disable(udc);
udc->active = 0;
}
@@ -2147,30 +2143,16 @@ static int mv_udc_probe(struct platform_device *pdev)
if (IS_ERR(udc->clk))
return PTR_ERR(udc->clk);

- r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs");
+ r = platform_get_resource(udc->dev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "no I/O memory resource defined\n");
return -ENODEV;
}

- udc->cap_regs = (struct mv_cap_regs __iomem *)
- devm_ioremap(&pdev->dev, r->start, resource_size(r));
- if (udc->cap_regs == NULL) {
- dev_err(&pdev->dev, "failed to map I/O memory\n");
- return -EBUSY;
- }
-
- r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs");
- if (r == NULL) {
- dev_err(&pdev->dev, "no phy I/O memory resource defined\n");
- return -ENODEV;
- }
+ udc->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));

- udc->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
- if (udc->phy_regs == NULL) {
- dev_err(&pdev->dev, "failed to map phy I/O memory\n");
- return -EBUSY;
- }
+ udc->cap_regs =
+ (void __iomem *) ((unsigned long)udc->base + U2x_CAPREGS_OFFSET);

/* we will acces controller register, so enable the clk */
retval = mv_udc_enable_internal(udc);
--
2.19.1


2018-11-12 03:24:25

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3 09/18] DT: marvell,mmp2: add USB OTG host controller

Signed-off-by: Lubomir Rintel <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
arch/arm/boot/dts/mmp2.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 6ca1e17b6ac2..fed28c754804 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -125,6 +125,17 @@
status = "disabled";
};

+ usb_otg0: usb-otg@d4208000 {
+ compatible = "marvell,pxau2o-ehci";
+ reg = <0xd4208000 0x200>;
+ interrupts = <44>;
+ clocks = <&soc_clocks MMP2_CLK_USB>;
+ clock-names = "USBCLK";
+ phys = <&usb_otg_phy0>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
mmc1: mmc@d4280000 {
compatible = "mrvl,pxav3-mmc";
reg = <0xd4280000 0x120>;
--
2.19.1


2018-11-13 17:05:24

by Robert Jarzmik

[permalink] [raw]
Subject: Re: [PATCH v3 17/18] USB: phy-mv-usb: use phy-pxa-usb

Lubomir Rintel <[email protected]> writes:

> Use a proper PHY driver, instead of hooks to a board support package.
Hi Lubomir,

This specific patch caught my attention, because of its title : I don't see what
phy-pxa-usb stands for, is it a typo ? I don't think anybody implemented so far
a proper phy support for pxa based boards (pxa27x actually), hence my question.

Cheers.

--
Robert