arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / powerpc / platforms / 8xx / micropatch.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Microcode patches for the CPM as supplied by Motorola.
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  */
9 #include <linux/init.h>
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>
18 #include <asm/page.h>
19 #include <asm/8xx_immap.h>
20 #include <asm/cpm.h>
21 #include <asm/cpm1.h>
22
23 struct patch_params {
24         ushort rccr;
25         ushort cpmcr1;
26         ushort cpmcr2;
27         ushort cpmcr3;
28         ushort cpmcr4;
29 };
30
31 /*
32  * I2C/SPI relocation patch arrays.
33  */
34
35 #ifdef CONFIG_I2C_SPI_UCODE_PATCH
36
37 static char patch_name[] __initdata = "I2C/SPI";
38
39 static struct patch_params patch_params __initdata = {
40         1, 0x802a, 0x8028, 0x802e, 0x802c,
41 };
42
43 /*(DEBLOBBED)*/
44
45 /*(DEBLOBBED)*/
46
47 /*(DEBLOBBED)*/
48 #endif
49
50 /*
51  * I2C/SPI/SMC1 relocation patch arrays.
52  */
53
54 #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
55
56 static char patch_name[] __initdata = "I2C/SPI/SMC1";
57
58 static struct patch_params patch_params __initdata = {
59         3, 0x8080, 0x808a, 0x8028, 0x802a,
60 };
61
62 /*(DEBLOBBED)*/
63
64 /*(DEBLOBBED)*/
65
66 /*(DEBLOBBED)*/
67 #endif
68
69 /*
70  *  USB SOF patch arrays.
71  */
72
73 #ifdef CONFIG_USB_SOF_UCODE_PATCH
74
75 static char patch_name[] __initdata = "USB SOF";
76
77 static struct patch_params patch_params __initdata = {
78         9,
79 };
80
81 /*(DEBLOBBED)*/
82
83 /*(DEBLOBBED)*/
84
85 /*(DEBLOBBED)*/
86 #endif
87
88 /*
89  * SMC relocation patch arrays.
90  */
91
92 #ifdef CONFIG_SMC_UCODE_PATCH
93
94 static char patch_name[] __initdata = "SMC";
95
96 static struct patch_params patch_params __initdata = {
97         2, 0x8080, 0x8088,
98 };
99
100 /*(DEBLOBBED)*/
101
102 /*(DEBLOBBED)*/
103
104 /*(DEBLOBBED)*/
105 #endif
106
107 static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int len)
108 {
109         if (!len)
110                 return;
111         memcpy_toio(cp->cp_dpmem + offset, patch, len);
112 }
113
114 void __init cpm_load_patch(cpm8xx_t *cp)
115 {
116         out_be16(&cp->cp_rccr, 0);
117
118         /*(DEBLOBBED)*/
119         /*(DEBLOBBED)*/
120         /*(DEBLOBBED)*/
121
122         if (IS_ENABLED(CONFIG_I2C_SPI_UCODE_PATCH) ||
123             IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) {
124                 u16 rpbase = 0x500;
125                 iic_t *iip;
126                 struct spi_pram *spp;
127
128                 iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
129                 out_be16(&iip->iic_rpbase, rpbase);
130
131                 /* Put SPI above the IIC, also 32-byte aligned. */
132                 spp = (struct spi_pram *)&cp->cp_dparam[PROFF_SPI];
133                 out_be16(&spp->rpbase, (rpbase + sizeof(iic_t) + 31) & ~31);
134
135                 if (IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) {
136                         smc_uart_t *smp;
137
138                         smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
139                         out_be16(&smp->smc_rpbase, 0x1FC0);
140                 }
141         }
142
143         if (IS_ENABLED(CONFIG_SMC_UCODE_PATCH)) {
144                 smc_uart_t *smp;
145
146                 if (IS_ENABLED(CONFIG_PPC_EARLY_DEBUG_CPM)) {
147                         int i;
148
149                         for (i = 0; i < sizeof(*smp); i += 4) {
150                                 u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i];
151                                 u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i];
152
153                                 out_be32(dst, in_be32(src));
154                         }
155                 }
156
157                 smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
158                 out_be16(&smp->smc_rpbase, 0x1ec0);
159                 smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
160                 out_be16(&smp->smc_rpbase, 0x1fc0);
161         }
162
163         out_be16(&cp->cp_cpmcr1, patch_params.cpmcr1);
164         out_be16(&cp->cp_cpmcr2, patch_params.cpmcr2);
165         out_be16(&cp->cp_cpmcr3, patch_params.cpmcr3);
166         out_be16(&cp->cp_cpmcr4, patch_params.cpmcr4);
167
168         out_be16(&cp->cp_rccr, patch_params.rccr);
169
170         pr_info("%s microcode patch installed\n", patch_name);
171 }