aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/83xx/km83xx.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-07-25 00:31:09 -0400
committerGrant Likely <grant.likely@secretlab.ca>2012-07-25 00:34:40 -0400
commit6aeea3ecc33b1f36dbc3b80461d15a7052ae424f (patch)
treebbd273e3e0ca76094aed8e9c77e5adfe2b07f779 /arch/powerpc/platforms/83xx/km83xx.c
parent9844a5524ec532aee826c35e3031637c7fc8287b (diff)
parentbdc0077af574800d24318b6945cf2344e8dbb050 (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.c100
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
123machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); 157machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices);