diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2012-07-25 00:31:09 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2012-07-25 00:34:40 -0400 |
commit | 6aeea3ecc33b1f36dbc3b80461d15a7052ae424f (patch) | |
tree | bbd273e3e0ca76094aed8e9c77e5adfe2b07f779 /arch/powerpc/platforms/83xx/km83xx.c | |
parent | 9844a5524ec532aee826c35e3031637c7fc8287b (diff) | |
parent | bdc0077af574800d24318b6945cf2344e8dbb050 (diff) |
Merge remote-tracking branch 'origin' into irqdomain/next
Diffstat (limited to 'arch/powerpc/platforms/83xx/km83xx.c')
-rw-r--r-- | arch/powerpc/platforms/83xx/km83xx.c | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index a266ba876863..89923d723349 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Author: Heiko Schocher <hs@denx.de> | 3 | * Author: Heiko Schocher <hs@denx.de> |
4 | * | 4 | * |
5 | * Description: | 5 | * Description: |
6 | * Keymile KMETER1 board specific routines. | 6 | * Keymile 83xx platform specific routines. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -70,54 +70,88 @@ static void __init mpc83xx_km_setup_arch(void) | |||
70 | for_each_node_by_name(np, "spi") | 70 | for_each_node_by_name(np, "spi") |
71 | par_io_of_config(np); | 71 | par_io_of_config(np); |
72 | 72 | ||
73 | for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) | 73 | for_each_node_by_name(np, "ucc") |
74 | par_io_of_config(np); | 74 | par_io_of_config(np); |
75 | } | 75 | } |
76 | 76 | ||
77 | np = of_find_compatible_node(NULL, "network", "ucc_geth"); | 77 | np = of_find_compatible_node(NULL, "network", "ucc_geth"); |
78 | if (np != NULL) { | 78 | if (np != NULL) { |
79 | uint svid; | 79 | /* |
80 | * handle mpc8360E Erratum QE_ENET10: | ||
81 | * RGMII AC values do not meet the specification | ||
82 | */ | ||
83 | uint svid = mfspr(SPRN_SVR); | ||
84 | struct device_node *np_par; | ||
85 | struct resource res; | ||
86 | void __iomem *base; | ||
87 | int ret; | ||
88 | |||
89 | np_par = of_find_node_by_name(NULL, "par_io"); | ||
90 | if (np_par == NULL) { | ||
91 | printk(KERN_WARNING "%s couldn;t find par_io node\n", | ||
92 | __func__); | ||
93 | return; | ||
94 | } | ||
95 | /* Map Parallel I/O ports registers */ | ||
96 | ret = of_address_to_resource(np_par, 0, &res); | ||
97 | if (ret) { | ||
98 | printk(KERN_WARNING "%s couldn;t map par_io registers\n", | ||
99 | __func__); | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | base = ioremap(res.start, res.end - res.start + 1); | ||
104 | |||
105 | /* | ||
106 | * set output delay adjustments to default values according | ||
107 | * table 5 in Errata Rev. 5, 9/2011: | ||
108 | * | ||
109 | * write 0b01 to UCC1 bits 18:19 | ||
110 | * write 0b01 to UCC2 option 1 bits 4:5 | ||
111 | * write 0b01 to UCC2 option 2 bits 16:17 | ||
112 | */ | ||
113 | clrsetbits_be32((base + 0xa8), 0x0c00f000, 0x04005000); | ||
114 | |||
115 | /* | ||
116 | * set output delay adjustments to default values according | ||
117 | * table 3-13 in Reference Manual Rev.3 05/2010: | ||
118 | * | ||
119 | * write 0b01 to UCC2 option 2 bits 16:17 | ||
120 | * write 0b0101 to UCC1 bits 20:23 | ||
121 | * write 0b0101 to UCC2 option 1 bits 24:27 | ||
122 | */ | ||
123 | clrsetbits_be32((base + 0xac), 0x0000cff0, 0x00004550); | ||
80 | 124 | ||
81 | /* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */ | ||
82 | svid = mfspr(SPRN_SVR); | ||
83 | if (SVR_REV(svid) == 0x0021) { | 125 | if (SVR_REV(svid) == 0x0021) { |
84 | struct device_node *np_par; | 126 | /* |
85 | struct resource res; | 127 | * UCC2 option 1: write 0b1010 to bits 24:27 |
86 | void __iomem *base; | 128 | * at address IMMRBAR+0x14AC |
87 | int ret; | 129 | */ |
88 | 130 | clrsetbits_be32((base + 0xac), 0x000000f0, 0x000000a0); | |
89 | np_par = of_find_node_by_name(NULL, "par_io"); | 131 | } else if (SVR_REV(svid) == 0x0020) { |
90 | if (np_par == NULL) { | 132 | /* |
91 | printk(KERN_WARNING "%s couldn;t find par_io node\n", | 133 | * UCC1: write 0b11 to bits 18:19 |
92 | __func__); | 134 | * at address IMMRBAR+0x14A8 |
93 | return; | 135 | */ |
94 | } | 136 | setbits32((base + 0xa8), 0x00003000); |
95 | /* Map Parallel I/O ports registers */ | ||
96 | ret = of_address_to_resource(np_par, 0, &res); | ||
97 | if (ret) { | ||
98 | printk(KERN_WARNING "%s couldn;t map par_io registers\n", | ||
99 | __func__); | ||
100 | return; | ||
101 | } | ||
102 | base = ioremap(res.start, resource_size(&res)); | ||
103 | 137 | ||
104 | /* | 138 | /* |
105 | * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2) | 139 | * UCC2 option 1: write 0b11 to bits 4:5 |
106 | * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1) | 140 | * at address IMMRBAR+0x14A8 |
107 | */ | 141 | */ |
108 | setbits32((base + 0xa8), 0x0c003000); | 142 | setbits32((base + 0xa8), 0x0c000000); |
109 | 143 | ||
110 | /* | 144 | /* |
111 | * IMMR + 0x14AC[20:27] = 10101010 | 145 | * UCC2 option 2: write 0b11 to bits 16:17 |
112 | * (data delay for both UCC's) | 146 | * at address IMMRBAR+0x14AC |
113 | */ | 147 | */ |
114 | clrsetbits_be32((base + 0xac), 0xff0, 0xaa0); | 148 | setbits32((base + 0xac), 0x0000c000); |
115 | iounmap(base); | ||
116 | of_node_put(np_par); | ||
117 | } | 149 | } |
150 | iounmap(base); | ||
151 | of_node_put(np_par); | ||
118 | of_node_put(np); | 152 | of_node_put(np); |
119 | } | 153 | } |
120 | #endif /* CONFIG_QUICC_ENGINE */ | 154 | #endif /* CONFIG_QUICC_ENGINE */ |
121 | } | 155 | } |
122 | 156 | ||
123 | machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); | 157 | machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); |