aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/lantiq/xway/reset.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/lantiq/xway/reset.c')
-rw-r--r--arch/mips/lantiq/xway/reset.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 22c55f73aa9d..544dbb7fb421 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -28,17 +28,24 @@
28#define RCU_RST_REQ 0x0010 28#define RCU_RST_REQ 0x0010
29/* reset status register */ 29/* reset status register */
30#define RCU_RST_STAT 0x0014 30#define RCU_RST_STAT 0x0014
31/* vr9 gphy registers */
32#define RCU_GFS_ADD0_XRX200 0x0020
33#define RCU_GFS_ADD1_XRX200 0x0068
31 34
32/* reboot bit */ 35/* reboot bit */
36#define RCU_RD_GPHY0_XRX200 BIT(31)
33#define RCU_RD_SRST BIT(30) 37#define RCU_RD_SRST BIT(30)
38#define RCU_RD_GPHY1_XRX200 BIT(29)
39
34/* reset cause */ 40/* reset cause */
35#define RCU_STAT_SHIFT 26 41#define RCU_STAT_SHIFT 26
36/* boot selection */ 42/* boot selection */
37#define RCU_BOOT_SEL_SHIFT 26 43#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7)
38#define RCU_BOOT_SEL_MASK 0x7 44#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10))
39 45
40/* remapped base addr of the reset control unit */ 46/* remapped base addr of the reset control unit */
41static void __iomem *ltq_rcu_membase; 47static void __iomem *ltq_rcu_membase;
48static struct device_node *ltq_rcu_np;
42 49
43/* This function is used by the watchdog driver */ 50/* This function is used by the watchdog driver */
44int ltq_reset_cause(void) 51int ltq_reset_cause(void)
@@ -52,7 +59,41 @@ EXPORT_SYMBOL_GPL(ltq_reset_cause);
52unsigned char ltq_boot_select(void) 59unsigned char ltq_boot_select(void)
53{ 60{
54 u32 val = ltq_rcu_r32(RCU_RST_STAT); 61 u32 val = ltq_rcu_r32(RCU_RST_STAT);
55 return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; 62
63 if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
64 return RCU_BOOT_SEL_XRX200(val);
65
66 return RCU_BOOT_SEL(val);
67}
68
69/* reset / boot a gphy */
70static struct ltq_xrx200_gphy_reset {
71 u32 rd;
72 u32 addr;
73} xrx200_gphy[] = {
74 {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200},
75 {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200},
76};
77
78/* reset and boot a gphy. these phys only exist on xrx200 SoC */
79int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
80{
81 if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) {
82 dev_err(dev, "this SoC has no GPHY\n");
83 return -EINVAL;
84 }
85 if (id > 1) {
86 dev_err(dev, "%u is an invalid gphy id\n", id);
87 return -EINVAL;
88 }
89 dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr);
90
91 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd,
92 RCU_RST_REQ);
93 ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr);
94 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd,
95 RCU_RST_REQ);
96 return 0;
56} 97}
57 98
58/* reset a io domain for u micro seconds */ 99/* reset a io domain for u micro seconds */
@@ -85,14 +126,17 @@ static void ltq_machine_power_off(void)
85static int __init mips_reboot_setup(void) 126static int __init mips_reboot_setup(void)
86{ 127{
87 struct resource res; 128 struct resource res;
88 struct device_node *np = 129
89 of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); 130 ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
131 if (!ltq_rcu_np)
132 ltq_rcu_np = of_find_compatible_node(NULL, NULL,
133 "lantiq,rcu-xrx200");
90 134
91 /* check if all the reset register range is available */ 135 /* check if all the reset register range is available */
92 if (!np) 136 if (!ltq_rcu_np)
93 panic("Failed to load reset resources from devicetree"); 137 panic("Failed to load reset resources from devicetree");
94 138
95 if (of_address_to_resource(np, 0, &res)) 139 if (of_address_to_resource(ltq_rcu_np, 0, &res))
96 panic("Failed to get rcu memory range"); 140 panic("Failed to get rcu memory range");
97 141
98 if (request_mem_region(res.start, resource_size(&res), res.name) < 0) 142 if (request_mem_region(res.start, resource_size(&res), res.name) < 0)