powerpc/8xx: Use IO accessors in microcode programming.
[linux-2.6-block.git] / arch / powerpc / platforms / 8xx / micropatch.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
f2a0bd37 2
4128a89a
CL
3/*
4 * Microcode patches for the CPM as supplied by Motorola.
f2a0bd37
VB
5 * This is the one for IIC/SPI. There is a newer one that
6 * also relocates SMC2, but this would require additional changes
7 * to uart.c, so I am holding off on that for a moment.
8 */
af71bcfe 9#include <linux/init.h>
f2a0bd37
VB
10#include <linux/errno.h>
11#include <linux/sched.h>
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/string.h>
15#include <linux/mm.h>
16#include <linux/interrupt.h>
17#include <asm/irq.h>
f2a0bd37
VB
18#include <asm/page.h>
19#include <asm/pgtable.h>
20#include <asm/8xx_immap.h>
56825c88 21#include <asm/cpm.h>
b5677d84 22#include <asm/cpm1.h>
f2a0bd37 23
f5348c08
CL
24struct patch_params {
25 ushort rccr;
26 ushort cpmcr1;
27 ushort cpmcr2;
28 ushort cpmcr3;
29 ushort cpmcr4;
30};
31
f2a0bd37
VB
32/*
33 * I2C/SPI relocation patch arrays.
34 */
35
36#ifdef CONFIG_I2C_SPI_UCODE_PATCH
37
5cfd5d89
CL
38static char patch_name[] __initdata = "I2C/SPI";
39
f5348c08
CL
40static struct patch_params patch_params __initdata = {
41 1, 0x802a, 0x8028, 0x802e, 0x802c,
42};
43
af71bcfe 44static uint patch_2000[] __initdata = {
9fb7e639
CL
45 0x7FFFEFD9, 0x3FFD0000, 0x7FFB49F7, 0x7FF90000,
46 0x5FEFADF7, 0x5F89ADF7, 0x5FEFAFF7, 0x5F89AFF7,
47 0x3A9CFBC8, 0xE7C0EDF0, 0x77C1E1BB, 0xF4DC7F1D,
48 0xABAD932F, 0x4E08FDCF, 0x6E0FAFF8, 0x7CCF76CF,
49 0xFD1FF9CF, 0xABF88DC6, 0xAB5679F7, 0xB0937383,
50 0xDFCE79F7, 0xB091E6BB, 0xE5BBE74F, 0xB3FA6F0F,
51 0x6FFB76CE, 0xEE0DF9CF, 0x2BFBEFEF, 0xCFEEF9CF,
52 0x76CEAD24, 0x90B2DF9A, 0x7FDDD0BF, 0x4BF847FD,
53 0x7CCF76CE, 0xCFEF7E1F, 0x7F1D7DFD, 0xF0B6EF71,
54 0x7FC177C1, 0xFBC86079, 0xE722FBC8, 0x5FFFDFFF,
55 0x5FB2FFFB, 0xFBC8F3C8, 0x94A67F01, 0x7F1D5F39,
56 0xAFE85F5E, 0xFFDFDF96, 0xCB9FAF7D, 0x5FC1AFED,
57 0x8C1C5FC1, 0xAFDD5FC3, 0xDF9A7EFD, 0xB0B25FB2,
58 0xFFFEABAD, 0x5FB2FFFE, 0x5FCE600B, 0xE6BB600B,
59 0x5FCEDFC6, 0x27FBEFDF, 0x5FC8CFDE, 0x3A9CE7C0,
60 0xEDF0F3C8, 0x7F0154CD, 0x7F1D2D3D, 0x363A7570,
61 0x7E0AF1CE, 0x37EF2E68, 0x7FEE10EC, 0xADF8EFDE,
62 0xCFEAE52F, 0x7D0FE12B, 0xF1CE5F65, 0x7E0A4DF8,
63 0xCFEA5F72, 0x7D0BEFEE, 0xCFEA5F74, 0xE522EFDE,
64 0x5F74CFDA, 0x0B627385, 0xDF627E0A, 0x30D8145B,
65 0xBFFFF3C8, 0x5FFFDFFF, 0xA7F85F5E, 0xBFFE7F7D,
66 0x10D31450, 0x5F36BFFF, 0xAF785F5E, 0xBFFDA7F8,
67 0x5F36BFFE, 0x77FD30C0, 0x4E08FDCF, 0xE5FF6E0F,
68 0xAFF87E1F, 0x7E0FFD1F, 0xF1CF5F1B, 0xABF80D5E,
69 0x5F5EFFEF, 0x79F730A2, 0xAFDD5F34, 0x47F85F34,
70 0xAFED7FDD, 0x50B24978, 0x47FD7F1D, 0x7DFD70AD,
71 0xEF717EC1, 0x6BA47F01, 0x2D267EFD, 0x30DE5F5E,
72 0xFFFD5F5E, 0xFFEF5F5E, 0xFFDF0CA0, 0xAFED0A9E,
73 0xAFDD0C3A, 0x5F3AAFBD, 0x7FBDB082, 0x5F8247F8
f2a0bd37
VB
74};
75
af71bcfe 76static uint patch_2f00[] __initdata = {
9fb7e639
CL
77 0x3E303430, 0x34343737, 0xABF7BF9B, 0x994B4FBD,
78 0xBD599493, 0x349FFF37, 0xFB9B177D, 0xD9936956,
79 0xBBFDD697, 0xBDD2FD11, 0x31DB9BB3, 0x63139637,
80 0x93733693, 0x193137F7, 0x331737AF, 0x7BB9B999,
81 0xBB197957, 0x7FDFD3D5, 0x73B773F7, 0x37933B99,
82 0x1D115316, 0x99315315, 0x31694BF4, 0xFBDBD359,
83 0x31497353, 0x76956D69, 0x7B9D9693, 0x13131979,
f2a0bd37
VB
84 0x79376935
85};
11597ff2
CL
86
87static uint patch_2e00[] __initdata = {};
f2a0bd37
VB
88#endif
89
90/*
91 * I2C/SPI/SMC1 relocation patch arrays.
92 */
93
94#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
95
5cfd5d89
CL
96static char patch_name[] __initdata = "I2C/SPI/SMC1";
97
f5348c08
CL
98static struct patch_params patch_params __initdata = {
99 3, 0x8080, 0x808a, 0x8028, 0x802a,
100};
101
af71bcfe 102static uint patch_2000[] __initdata = {
9fb7e639
CL
103 0x3fff0000, 0x3ffd0000, 0x3ffb0000, 0x3ff90000,
104 0x5f13eff8, 0x5eb5eff8, 0x5f88adf7, 0x5fefadf7,
105 0x3a9cfbc8, 0x77cae1bb, 0xf4de7fad, 0xabae9330,
106 0x4e08fdcf, 0x6e0faff8, 0x7ccf76cf, 0xfdaff9cf,
107 0xabf88dc8, 0xab5879f7, 0xb0925d8d, 0xdfd079f7,
108 0xb090e6bb, 0xe5bbe74f, 0x9e046f0f, 0x6ffb76ce,
109 0xee0cf9cf, 0x2bfbefef, 0xcfeef9cf, 0x76cead23,
110 0x90b3df99, 0x7fddd0c1, 0x4bf847fd, 0x7ccf76ce,
111 0xcfef77ca, 0x7eaf7fad, 0x7dfdf0b7, 0xef7a7fca,
112 0x77cafbc8, 0x6079e722, 0xfbc85fff, 0xdfff5fb3,
113 0xfffbfbc8, 0xf3c894a5, 0xe7c9edf9, 0x7f9a7fad,
114 0x5f36afe8, 0x5f5bffdf, 0xdf95cb9e, 0xaf7d5fc3,
115 0xafed8c1b, 0x5fc3afdd, 0x5fc5df99, 0x7efdb0b3,
116 0x5fb3fffe, 0xabae5fb3, 0xfffe5fd0, 0x600be6bb,
117 0x600b5fd0, 0xdfc827fb, 0xefdf5fca, 0xcfde3a9c,
118 0xe7c9edf9, 0xf3c87f9e, 0x54ca7fed, 0x2d3a3637,
119 0x756f7e9a, 0xf1ce37ef, 0x2e677fee, 0x10ebadf8,
120 0xefdecfea, 0xe52f7d9f, 0xe12bf1ce, 0x5f647e9a,
121 0x4df8cfea, 0x5f717d9b, 0xefeecfea, 0x5f73e522,
122 0xefde5f73, 0xcfda0b61, 0x5d8fdf61, 0xe7c9edf9,
123 0x7e9a30d5, 0x1458bfff, 0xf3c85fff, 0xdfffa7f8,
124 0x5f5bbffe, 0x7f7d10d0, 0x144d5f33, 0xbfffaf78,
125 0x5f5bbffd, 0xa7f85f33, 0xbffe77fd, 0x30bd4e08,
126 0xfdcfe5ff, 0x6e0faff8, 0x7eef7e9f, 0xfdeff1cf,
127 0x5f17abf8, 0x0d5b5f5b, 0xffef79f7, 0x309eafdd,
128 0x5f3147f8, 0x5f31afed, 0x7fdd50af, 0x497847fd,
129 0x7f9e7fed, 0x7dfd70a9, 0xef7e7ece, 0x6ba07f9e,
130 0x2d227efd, 0x30db5f5b, 0xfffd5f5b, 0xffef5f5b,
131 0xffdf0c9c, 0xafed0a9a, 0xafdd0c37, 0x5f37afbd,
132 0x7fbdb081, 0x5f8147f8, 0x3a11e710, 0xedf0ccdd,
133 0xf3186d0a, 0x7f0e5f06, 0x7fedbb38, 0x3afe7468,
134 0x7fedf4fc, 0x8ffbb951, 0xb85f77fd, 0xb0df5ddd,
135 0xdefe7fed, 0x90e1e74d, 0x6f0dcbf7, 0xe7decfed,
136 0xcb74cfed, 0xcfeddf6d, 0x91714f74, 0x5dd2deef,
137 0x9e04e7df, 0xefbb6ffb, 0xe7ef7f0e, 0x9e097fed,
138 0xebdbeffa, 0xeb54affb, 0x7fea90d7, 0x7e0cf0c3,
139 0xbffff318, 0x5fffdfff, 0xac59efea, 0x7fce1ee5,
140 0xe2ff5ee1, 0xaffbe2ff, 0x5ee3affb, 0xf9cc7d0f,
141 0xaef8770f, 0x7d0fb0c6, 0xeffbbfff, 0xcfef5ede,
142 0x7d0fbfff, 0x5ede4cf8, 0x7fddd0bf, 0x49f847fd,
143 0x7efdf0bb, 0x7fedfffd, 0x7dfdf0b7, 0xef7e7e1e,
144 0x5ede7f0e, 0x3a11e710, 0xedf0ccab, 0xfb18ad2e,
145 0x1ea9bbb8, 0x74283b7e, 0x73c2e4bb, 0x2ada4fb8,
146 0xdc21e4bb, 0xb2a1ffbf, 0x5e2c43f8, 0xfc87e1bb,
147 0xe74ffd91, 0x6f0f4fe8, 0xc7ba32e2, 0xf396efeb,
148 0x600b4f78, 0xe5bb760b, 0x53acaef8, 0x4ef88b0e,
149 0xcfef9e09, 0xabf8751f, 0xefef5bac, 0x741f4fe8,
150 0x751e760d, 0x7fdbf081, 0x741cafce, 0xefcc7fce,
151 0x751e70ac, 0x741ce7bb, 0x3372cfed, 0xafdbefeb,
152 0xe5bb760b, 0x53f2aef8, 0xafe8e7eb, 0x4bf8771e,
153 0x7e247fed, 0x4fcbe2cc, 0x7fbc30a9, 0x7b0f7a0f,
154 0x34d577fd, 0x308b5db7, 0xde553e5f, 0xaf78741f,
155 0x741f30f0, 0xcfef5e2c, 0x741f3eac, 0xafb8771e,
156 0x5e677fed, 0x0bd3e2cc, 0x741ccfec, 0xe5ca53cd,
157 0x6fcb4f74, 0x5dadde4b, 0x2ab63d38, 0x4bb3de30,
158 0x751f741c, 0x6c42effa, 0xefea7fce, 0x6ffc30be,
159 0xefec3fca, 0x30b3de2e, 0xadf85d9e, 0xaf7daefd,
160 0x5d9ede2e, 0x5d9eafdd, 0x761f10ac, 0x1da07efd,
161 0x30adfffe, 0x4908fb18, 0x5fffdfff, 0xafbb709b,
162 0x4ef85e67, 0xadf814ad, 0x7a0f70ad, 0xcfef50ad,
163 0x7a0fde30, 0x5da0afed, 0x3c12780f, 0xefef780f,
164 0xefef790f, 0xa7f85e0f, 0xffef790f, 0xefef790f,
165 0x14adde2e, 0x5d9eadfd, 0x5e2dfffb, 0xe79addfd,
166 0xeff96079, 0x607ae79a, 0xddfceff9, 0x60795dff,
167 0x607acfef, 0xefefefdf, 0xefbfef7f, 0xeeffedff,
168 0xebffe7ff, 0xafefafdf, 0xafbfaf7f, 0xaeffadff,
169 0xabffa7ff, 0x6fef6fdf, 0x6fbf6f7f, 0x6eff6dff,
170 0x6bff67ff, 0x2fef2fdf, 0x2fbf2f7f, 0x2eff2dff,
171 0x2bff27ff, 0x4e08fd1f, 0xe5ff6e0f, 0xaff87eef,
172 0x7e0ffdef, 0xf11f6079, 0xabf8f542, 0x7e0af11c,
173 0x37cfae3a, 0x7fec90be, 0xadf8efdc, 0xcfeae52f,
174 0x7d0fe12b, 0xf11c6079, 0x7e0a4df8, 0xcfea5dc4,
175 0x7d0befec, 0xcfea5dc6, 0xe522efdc, 0x5dc6cfda,
176 0x4e08fd1f, 0x6e0faff8, 0x7c1f761f, 0xfdeff91f,
177 0x6079abf8, 0x761cee24, 0xf91f2bfb, 0xefefcfec,
178 0xf91f6079, 0x761c27fb, 0xefdf5da7, 0xcfdc7fdd,
179 0xd09c4bf8, 0x47fd7c1f, 0x761ccfcf, 0x7eef7fed,
180 0x7dfdf093, 0xef7e7f1e, 0x771efb18, 0x6079e722,
181 0xe6bbe5bb, 0xae0ae5bb, 0x600bae85, 0xe2bbe2bb,
182 0xe2bbe2bb, 0xaf02e2bb, 0xe2bb2ff9, 0x6079e2bb
f2a0bd37
VB
183};
184
af71bcfe 185static uint patch_2f00[] __initdata = {
9fb7e639
CL
186 0x30303030, 0x3e3e3434, 0xabbf9b99, 0x4b4fbdbd,
187 0x59949334, 0x9fff37fb, 0x9b177dd9, 0x936956bb,
188 0xfbdd697b, 0xdd2fd113, 0x1db9f7bb, 0x36313963,
189 0x79373369, 0x3193137f, 0x7331737a, 0xf7bb9b99,
190 0x9bb19795, 0x77fdfd3d, 0x573b773f, 0x737933f7,
191 0xb991d115, 0x31699315, 0x31531694, 0xbf4fbdbd,
192 0x35931497, 0x35376956, 0xbd697b9d, 0x96931313,
193 0x19797937, 0x6935af78, 0xb9b3baa3, 0xb8788683,
194 0x368f78f7, 0x87778733, 0x3ffffb3b, 0x8e8f78b8,
195 0x1d118e13, 0xf3ff3f8b, 0x6bd8e173, 0xd1366856,
196 0x68d1687b, 0x3daf78b8, 0x3a3a3f87, 0x8f81378f,
197 0xf876f887, 0x77fd8778, 0x737de8d6, 0xbbf8bfff,
198 0xd8df87f7, 0xfd876f7b, 0x8bfff8bd, 0x8683387d,
199 0xb873d87b, 0x3b8fd7f8, 0xf7338883, 0xbb8ee1f8,
200 0xef837377, 0x3337b836, 0x817d11f8, 0x7378b878,
201 0xd3368b7d, 0xed731b7d, 0x833731f3, 0xf22f3f23
f2a0bd37
VB
202};
203
af71bcfe 204static uint patch_2e00[] __initdata = {
9fb7e639
CL
205 0x27eeeeee, 0xeeeeeeee, 0xeeeeeeee, 0xeeeeeeee,
206 0xee4bf4fb, 0xdbd259bb, 0x1979577f, 0xdfd2d573,
207 0xb773f737, 0x4b4fbdbd, 0x25b9b177, 0xd2d17376,
208 0x956bbfdd, 0x697bdd2f, 0xff9f79ff, 0xff9ff22f
f2a0bd37
VB
209};
210#endif
211
212/*
213 * USB SOF patch arrays.
214 */
215
216#ifdef CONFIG_USB_SOF_UCODE_PATCH
217
5cfd5d89
CL
218static char patch_name[] __initdata = "USB SOF";
219
f5348c08
CL
220static struct patch_params patch_params __initdata = {
221 9,
222};
223
af71bcfe 224static uint patch_2000[] __initdata = {
9fb7e639
CL
225 0x7fff0000, 0x7ffd0000, 0x7ffb0000, 0x49f7ba5b,
226 0xba383ffb, 0xf9b8b46d, 0xe5ab4e07, 0xaf77bffe,
227 0x3f7bbf79, 0xba5bba38, 0xe7676076, 0x60750000
f2a0bd37
VB
228};
229
af71bcfe 230static uint patch_2f00[] __initdata = {
9fb7e639 231 0x3030304c, 0xcab9e441, 0xa1aaf220
f2a0bd37 232};
11597ff2
CL
233
234static uint patch_2e00[] __initdata = {};
f2a0bd37
VB
235#endif
236
372fba9c
CL
237static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int len)
238{
239 if (!len)
240 return;
241 memcpy_toio(cp->cp_dpmem + offset, patch, len);
242}
243
af71bcfe 244void __init cpm_load_patch(cpm8xx_t *cp)
f2a0bd37 245{
c3eec5d7 246 out_be16(&cp->cp_rccr, 0);
f2a0bd37 247
372fba9c
CL
248 cpm_write_patch(cp, 0, patch_2000, sizeof(patch_2000));
249 cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00));
11597ff2 250 cpm_write_patch(cp, 0xe00, patch_2e00, sizeof(patch_2e00));
f2a0bd37 251
647d5ed0
CL
252 if (IS_ENABLED(CONFIG_I2C_SPI_UCODE_PATCH) ||
253 IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) {
254 u16 rpbase = 0x500;
c3eec5d7
CL
255 iic_t *iip;
256 struct spi_pram *spp;
f2a0bd37 257
c3eec5d7
CL
258 iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
259 out_be16(&iip->iic_rpbase, rpbase);
f2a0bd37 260
647d5ed0 261 /* Put SPI above the IIC, also 32-byte aligned. */
c3eec5d7
CL
262 spp = (struct spi_pram *)&cp->cp_dparam[PROFF_SPI];
263 out_be16(&spp->rpbase, (rpbase + sizeof(iic_t) + 31) & ~31);
f2a0bd37 264
647d5ed0 265 if (IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) {
c3eec5d7
CL
266 smc_uart_t *smp;
267
268 smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
269 out_be16(&smp->smc_rpbase, 0x1FC0);
647d5ed0
CL
270 }
271 }
5cfd5d89 272
c3eec5d7
CL
273 out_be16(&cp->cp_cpmcr1, patch_params.cpmcr1);
274 out_be16(&cp->cp_cpmcr2, patch_params.cpmcr2);
275 out_be16(&cp->cp_cpmcr3, patch_params.cpmcr3);
276 out_be16(&cp->cp_cpmcr4, patch_params.cpmcr4);
f5348c08 277
c3eec5d7 278 out_be16(&cp->cp_rccr, patch_params.rccr);
f5348c08 279
5cfd5d89 280 pr_info("%s microcode patch installed\n", patch_name);
f2a0bd37 281}