From 4ed46c23c7257e15a419eb3176375601b312c157 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 22 Oct 2012 09:47:09 +0200 Subject: [PATCH 105/113] MIPS: lantiq: xway: adds reset code for 11G PHYs Signed-off-by: John Crispin --- arch/mips/a | 42 +++++++++++++ arch/mips/b | 36 +++++++++++ .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 + arch/mips/lantiq/xway/reset.c | 63 +++++++++++++++++++- 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 arch/mips/a create mode 100644 arch/mips/b diff --git a/arch/mips/a b/arch/mips/a new file mode 100644 index 0000000..31e61f8 --- /dev/null +++ b/arch/mips/a @@ -0,0 +1,42 @@ +diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +index 6a2df70..056df1a 100644 +--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h ++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +@@ -87,5 +87,8 @@ extern __iomem void *ltq_cgu_membase; + extern void ltq_pmu_enable(unsigned int module); + extern void ltq_pmu_disable(unsigned int module); + ++/* allow drivers to reset clock domains and ip cores */ ++void ltq_reset_once(unsigned int module, ulong u); ++ + #endif /* CONFIG_SOC_TYPE_XWAY */ + #endif /* _LTQ_XWAY_H__ */ +diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c +index 22c55f7..c2a7e65 100644 +--- a/arch/mips/lantiq/xway/reset.c ++++ b/arch/mips/lantiq/xway/reset.c +@@ -55,13 +62,23 @@ unsigned char ltq_boot_select(void) + return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; + } + ++static void ltq_reset_enter(unsigned int module) ++{ ++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); ++} ++ ++static void ltq_reset_leave(unsigned int module) ++{ ++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); ++} ++ + /* reset a io domain for u micro seconds */ + void ltq_reset_once(unsigned int module, ulong u) + { +- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); ++ ltq_reset_enter(RCU_RST_REQ); + udelay(u); +- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); ++ ltq_reset_leave(RCU_RST_REQ); + } + + static void ltq_machine_restart(char *command) diff --git a/arch/mips/b b/arch/mips/b new file mode 100644 index 0000000..c6a0323 --- /dev/null +++ b/arch/mips/b @@ -0,0 +1,36 @@ +diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +index 6a2df70..056df1a 100644 +--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h ++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +@@ -87,8 +87,11 @@ extern __iomem void *ltq_cgu_membase; + extern void ltq_pmu_enable(unsigned int module); + extern void ltq_pmu_disable(unsigned int module); + ++/* allow booting xrx200 phys */ ++int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr); ++ + #endif /* CONFIG_SOC_TYPE_XWAY */ + #endif /* _LTQ_XWAY_H__ */ +diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c +index 22c55f7..c2a7e65 100644 +--- a/arch/mips/lantiq/xway/reset.c ++++ b/arch/mips/lantiq/xway/reset.c +@@ -26,11 +26,18 @@ + + /* reset request register */ + #define RCU_RST_REQ 0x0010 ++ ++#define VR9_RCU_GFS_ADD0 0x0020 ++#define VR9_RCU_GFS_ADD1 0x0068 ++ + /* reset status register */ + #define RCU_RST_STAT 0x0014 + + /* reboot bit */ ++#define VR9_RCU_RD_GPHY0 BIT(31) + #define RCU_RD_SRST BIT(30) ++#define VR9_RCU_RD_GPHY1 BIT(29) ++ + /* reset cause */ + #define RCU_STAT_SHIFT 26 + /* boot selection */ diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h index 6b9f5be..056df1a 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h @@ -90,5 +90,8 @@ extern void ltq_pmu_disable(unsigned int module); /* allow drivers to reset clock domains and ip cores */ void ltq_reset_once(unsigned int module, ulong u); +/* allow booting xrx200 phys */ +int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr); + #endif /* CONFIG_SOC_TYPE_XWAY */ #endif /* _LTQ_XWAY_H__ */ diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 1b77f82..56293cf 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c @@ -28,9 +28,15 @@ #define RCU_RST_REQ 0x0010 /* reset status register */ #define RCU_RST_STAT 0x0014 +/* vr9 gphy registers */ +#define VR9_RCU_GFS_ADD0 0x0020 +#define VR9_RCU_GFS_ADD1 0x0068 /* reboot bit */ +#define VR9_RCU_RD_GPHY0 BIT(31) #define RCU_RD_SRST BIT(30) +#define VR9_RCU_RD_GPHY1 BIT(29) + /* reset cause */ #define RCU_STAT_SHIFT 26 /* boot selection */ @@ -65,13 +71,66 @@ static void ltq_reset_leave(unsigned int module) ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); } +/* reset / boot a gphy */ +static struct ltq_xrx200_gphy_reset { + u32 rd; + u32 addr; +} xrx200_gphy[] = { + {VR9_RCU_RD_GPHY0, VR9_RCU_GFS_ADD0}, + {VR9_RCU_RD_GPHY1, VR9_RCU_GFS_ADD1}, +}; + +/* reset and boot a gphy. these phys only exist on xrx200 SoC */ +int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) +{ + if (id > 1) { + dev_err(dev, "%u is an invalid gphy id\n", id); + return -EINVAL; + } + dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr); + + ltq_reset_enter(xrx200_gphy[id].rd); + ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr); + ltq_reset_leave(xrx200_gphy[id].rd); + return 0; +} +EXPORT_SYMBOL_GPL(xrx200_gphy_boot); + /* reset a io domain for u micro seconds */ void ltq_reset_once(unsigned int module, ulong u) { - ltq_reset_enter(RCU_RST_REQ); + ltq_reset_enter(module); udelay(u); - ltq_reset_leave(RCU_RST_REQ); + ltq_reset_leave(module); +} + +int ifx_rcu_rst(unsigned int reset_domain_id, unsigned int module_id) +{ + ltq_reset_once(BIT(module_id), 20); + return 0; +} +EXPORT_SYMBOL(ifx_rcu_rst); + +unsigned int ifx_rcu_rst_req_read(void) +{ + unsigned int ret; + + ret = ltq_rcu_r32(RCU_RST_REQ); + + return ret; +} +EXPORT_SYMBOL(ifx_rcu_rst_req_read); + +void ifx_rcu_rst_req_write(unsigned int value, unsigned int mask) +{ + unsigned int ret; + + ret = ltq_rcu_r32(RCU_RST_REQ); + ret &= ~mask; + ret |= value & mask; + ltq_rcu_w32(ret, RCU_RST_REQ); } +EXPORT_SYMBOL(ifx_rcu_rst_req_write); static void ltq_machine_restart(char *command) { -- 1.7.10.4