aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/cpm-serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/boot/cpm-serial.c')
-rw-r--r--arch/powerpc/boot/cpm-serial.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/arch/powerpc/boot/cpm-serial.c b/arch/powerpc/boot/cpm-serial.c
index fcb8b5e956bd..28296facb2ae 100644
--- a/arch/powerpc/boot/cpm-serial.c
+++ b/arch/powerpc/boot/cpm-serial.c
@@ -56,7 +56,8 @@ static struct cpm_smc *smc;
56static struct cpm_scc *scc; 56static struct cpm_scc *scc;
57struct cpm_bd *tbdf, *rbdf; 57struct cpm_bd *tbdf, *rbdf;
58static u32 cpm_cmd; 58static u32 cpm_cmd;
59static u8 *dpram_start; 59static u8 *muram_start;
60static u32 muram_offset;
60 61
61static void (*do_cmd)(int op); 62static void (*do_cmd)(int op);
62static void (*enable_port)(void); 63static void (*enable_port)(void);
@@ -114,13 +115,12 @@ static void scc_enable_port(void)
114 115
115static int cpm_serial_open(void) 116static int cpm_serial_open(void)
116{ 117{
117 int dpaddr = 0x800;
118 disable_port(); 118 disable_port();
119 119
120 out_8(&param->rfcr, 0x10); 120 out_8(&param->rfcr, 0x10);
121 out_8(&param->tfcr, 0x10); 121 out_8(&param->tfcr, 0x10);
122 122
123 rbdf = (struct cpm_bd *)(dpram_start + dpaddr); 123 rbdf = (struct cpm_bd *)muram_start;
124 rbdf->addr = (u8 *)(rbdf + 2); 124 rbdf->addr = (u8 *)(rbdf + 2);
125 rbdf->sc = 0xa000; 125 rbdf->sc = 0xa000;
126 rbdf->len = 1; 126 rbdf->len = 1;
@@ -131,8 +131,8 @@ static int cpm_serial_open(void)
131 tbdf->len = 1; 131 tbdf->len = 1;
132 132
133 sync(); 133 sync();
134 out_be16(&param->rbase, dpaddr); 134 out_be16(&param->rbase, muram_offset);
135 out_be16(&param->tbase, dpaddr + sizeof(struct cpm_bd)); 135 out_be16(&param->tbase, muram_offset + sizeof(struct cpm_bd));
136 136
137 do_cmd(CPM_CMD_INIT_RX_TX); 137 do_cmd(CPM_CMD_INIT_RX_TX);
138 138
@@ -178,7 +178,7 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp)
178 void *reg_virt[2]; 178 void *reg_virt[2];
179 int is_smc = 0, is_cpm2 = 0, n; 179 int is_smc = 0, is_cpm2 = 0, n;
180 unsigned long reg_phys; 180 unsigned long reg_phys;
181 void *parent; 181 void *parent, *muram;
182 182
183 if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) { 183 if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) {
184 is_smc = 1; 184 is_smc = 1;
@@ -229,16 +229,36 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp)
229 229
230 n = getprop(parent, "virtual-reg", reg_virt, sizeof(reg_virt)); 230 n = getprop(parent, "virtual-reg", reg_virt, sizeof(reg_virt));
231 if (n < (int)sizeof(reg_virt)) { 231 if (n < (int)sizeof(reg_virt)) {
232 for (n = 0; n < 2; n++) { 232 if (!dt_xlate_reg(parent, 0, &reg_phys, NULL))
233 if (!dt_xlate_reg(parent, n, &reg_phys, NULL)) 233 return -1;
234 return -1;
235 234
236 reg_virt[n] = (void *)reg_phys; 235 reg_virt[0] = (void *)reg_phys;
237 }
238 } 236 }
239 237
240 cpcr = reg_virt[0]; 238 cpcr = reg_virt[0];
241 dpram_start = reg_virt[1]; 239
240 muram = finddevice("/soc/cpm/muram/data");
241 if (!muram)
242 return -1;
243
244 /* For bootwrapper-compatible device trees, we assume that the first
245 * entry has at least 18 bytes, and that #address-cells/#data-cells
246 * is one for both parent and child.
247 */
248
249 n = getprop(muram, "virtual-reg", reg_virt, sizeof(reg_virt));
250 if (n < (int)sizeof(reg_virt)) {
251 if (!dt_xlate_reg(muram, 0, &reg_phys, NULL))
252 return -1;
253
254 reg_virt[0] = (void *)reg_phys;
255 }
256
257 muram_start = reg_virt[0];
258
259 n = getprop(muram, "reg", &muram_offset, 4);
260 if (n < 4)
261 return -1;
242 262
243 scdp->open = cpm_serial_open; 263 scdp->open = cpm_serial_open;
244 scdp->putc = cpm_serial_putc; 264 scdp->putc = cpm_serial_putc;