/* Node's "compatible" property determines which serial driver to use */ int serial_console_init(void) { void *devp; int rc = -1; devp = serial_get_stdout_devp(); if (devp == NULL) goto err_out; if (dt_is_compatible(devp, "ns16550") || dt_is_compatible(devp, "pnpPNP,501")) rc = ns16550_console_init(devp, &serial_cd); else if (dt_is_compatible(devp, "marvell,mv64360-mpsc")) rc = mpsc_console_init(devp, &serial_cd); else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") || dt_is_compatible(devp, "fsl,cpm1-smc-uart") || dt_is_compatible(devp, "fsl,cpm2-scc-uart") || dt_is_compatible(devp, "fsl,cpm2-smc-uart")) rc = cpm_console_init(devp, &serial_cd); else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart")) rc = mpc5200_psc_console_init(devp, &serial_cd); else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") || dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a")) rc = uartlite_console_init(devp, &serial_cd); /* Add other serial console driver calls here */ if (!rc) { console_ops.open = serial_open; console_ops.write = serial_write; console_ops.close = serial_close; console_ops.data = &serial_cd; if (serial_cd.getc) console_ops.edit_cmdline = serial_edit_cmdline; return 0; } err_out: return -1; }
/* For virtex, the kernel may be loaded without using a bootloader and if so some UARTs need more setup than is provided in the normal console init */ int platform_specific_init(void) { void *devp; char devtype[MAX_PROP_LEN]; char path[MAX_PATH_LEN]; devp = finddevice("/chosen"); if (devp == NULL) return -1; if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) { devp = finddevice(path); if (devp == NULL) return -1; if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0) && !strcmp(devtype, "serial") && (dt_is_compatible(devp, "ns16550"))) virtex_ns16550_console_init(devp); } return 0; }
/* Node's "compatible" property determines which serial driver to use */ int serial_console_init(void) { void *devp; int rc = -1; devp = serial_get_stdout_devp(); if (devp == NULL) goto err_out; if (dt_is_compatible(devp, "ns16550") || dt_is_compatible(devp, "pnpPNP,501")) rc = ns16550_console_init(devp, &serial_cd); #ifdef CONFIG_EMBEDDED6xx else if (dt_is_compatible(devp, "marvell,mv64360-mpsc")) rc = mpsc_console_init(devp, &serial_cd); #endif #ifdef CONFIG_CPM else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") || dt_is_compatible(devp, "fsl,cpm1-smc-uart") || dt_is_compatible(devp, "fsl,cpm2-scc-uart") || dt_is_compatible(devp, "fsl,cpm2-smc-uart")) rc = cpm_console_init(devp, &serial_cd); #endif #ifdef CONFIG_PPC_MPC52XX else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart")) rc = mpc5200_psc_console_init(devp, &serial_cd); #endif #ifdef CONFIG_XILINX_VIRTEX else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") || dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a")) rc = uartlite_console_init(devp, &serial_cd); #endif #ifdef CONFIG_PPC64_BOOT_WRAPPER else if (dt_is_compatible(devp, "ibm,opal-console-raw")) rc = opal_console_init(devp, &serial_cd); #endif /* Add other serial console driver calls here */ if (!rc) { console_ops.open = serial_open; console_ops.write = serial_write; console_ops.close = serial_close; console_ops.data = &serial_cd; if (serial_cd.getc) console_ops.edit_cmdline = serial_edit_cmdline; return 0; } err_out: return -1; }
static void update_cs_ranges(void) { void *bus_node, *parent_node; u32 *ctrl_addr; unsigned long ctrl_size; u32 naddr, nsize; int len; int i; bus_node = finddevice("/localbus"); if (!bus_node || !dt_is_compatible(bus_node, "fsl,pq2-localbus")) return; dt_get_reg_format(bus_node, &naddr, &nsize); if (naddr != 2 || nsize != 1) goto err; parent_node = get_parent(bus_node); if (!parent_node) goto err; dt_get_reg_format(parent_node, &naddr, &nsize); if (naddr != 1 || nsize != 1) goto err; if (!dt_xlate_reg(bus_node, 0, (unsigned long *)&ctrl_addr, &ctrl_size)) goto err; len = getprop(bus_node, "ranges", cs_ranges_buf, sizeof(cs_ranges_buf)); for (i = 0; i < len / sizeof(struct cs_range); i++) { u32 base, option; int cs = cs_ranges_buf[i].csnum; if (cs >= ctrl_size / 8) goto err; if (cs_ranges_buf[i].base != 0) goto err; base = in_be32(&ctrl_addr[cs * 2]); /* */ if (base & 1) { base &= 0x7fff; option = in_be32(&ctrl_addr[cs * 2 + 1]) & 0x7fff; } else { base = 0x1801; option = 0x10; } out_be32(&ctrl_addr[cs * 2], 0); out_be32(&ctrl_addr[cs * 2 + 1], option | ~(cs_ranges_buf[i].size - 1)); out_be32(&ctrl_addr[cs * 2], base | cs_ranges_buf[i].addr); } return; err: printf("Bad /localbus node\r\n"); }
static void fixup_pci(void) { struct pci_range *mem = NULL, *mmio = NULL, *io = NULL, *mem_base = NULL; u32 *pci_regs[3]; u8 *soc_regs; int i, len; void *node, *parent_node; u32 naddr, nsize, mem_pow2, mem_mask; node = finddevice("/pci"); if (!node || !dt_is_compatible(node, "fsl,pq2-pci")) return; for (i = 0; i < 3; i++) if (!dt_xlate_reg(node, i, (unsigned long *)&pci_regs[i], NULL)) goto err; soc_regs = (u8 *)fsl_get_immr(); if (!soc_regs) goto unhandled; dt_get_reg_format(node, &naddr, &nsize); if (naddr != 3 || nsize != 2) goto err; parent_node = get_parent(node); if (!parent_node) goto err; dt_get_reg_format(parent_node, &naddr, &nsize); if (naddr != 1 || nsize != 1) goto unhandled; len = getprop(node, "ranges", pci_ranges_buf, sizeof(pci_ranges_buf)); for (i = 0; i < len / sizeof(struct pci_range); i++) { u32 flags = pci_ranges_buf[i].flags & 0x43000000; if (flags == 0x42000000) mem = &pci_ranges_buf[i]; else if (flags == 0x02000000) mmio = &pci_ranges_buf[i]; else if (flags == 0x01000000) io = &pci_ranges_buf[i]; } if (!mem || !mmio || !io) goto unhandled; if (mem->size[1] != mmio->size[1]) goto unhandled; if (mem->size[1] & (mem->size[1] - 1)) goto unhandled; if (io->size[1] & (io->size[1] - 1)) goto unhandled; if (mem->phys_addr + mem->size[1] == mmio->phys_addr) mem_base = mem; else if (mmio->phys_addr + mmio->size[1] == mem->phys_addr) mem_base = mmio; else goto unhandled; out_be32(&pci_regs[1][0], mem_base->phys_addr | 1); out_be32(&pci_regs[2][0], ~(mem->size[1] + mmio->size[1] - 1)); out_be32(&pci_regs[1][1], io->phys_addr | 1); out_be32(&pci_regs[2][1], ~(io->size[1] - 1)); out_le32(&pci_regs[0][0], mem->pci_addr[1] >> 12); out_le32(&pci_regs[0][2], mem->phys_addr >> 12); out_le32(&pci_regs[0][4], (~(mem->size[1] - 1) >> 12) | 0xa0000000); out_le32(&pci_regs[0][6], mmio->pci_addr[1] >> 12); out_le32(&pci_regs[0][8], mmio->phys_addr >> 12); out_le32(&pci_regs[0][10], (~(mmio->size[1] - 1) >> 12) | 0x80000000); out_le32(&pci_regs[0][12], io->pci_addr[1] >> 12); out_le32(&pci_regs[0][14], io->phys_addr >> 12); out_le32(&pci_regs[0][16], (~(io->size[1] - 1) >> 12) | 0xc0000000); /* */ out_le32(&pci_regs[0][58], 0); out_le32(&pci_regs[0][60], 0); mem_pow2 = 1 << (__ilog2_u32(bd.bi_memsize - 1) + 1); mem_mask = ~(mem_pow2 - 1) >> 12; out_le32(&pci_regs[0][62], 0xa0000000 | mem_mask); /* */ if (!(in_le32(&pci_regs[0][32]) & 1)) { /* */ udelay(100000); out_le32(&pci_regs[0][32], 1); /* */ udelay(1020000); } /* */ out_le32(&pci_regs[0][64], 0x80000004); out_le32(&pci_regs[0][65], in_le32(&pci_regs[0][65]) | 6); /* */ out_8(&soc_regs[0x10028], 3); out_be32((u32 *)&soc_regs[0x1002c], 0x01236745); return; err: printf("Bad PCI node -- using existing firmware setup.\r\n"); return; unhandled: printf("Unsupported PCI node -- using existing firmware setup.\r\n"); }
int cpm_console_init(void *devp, struct serial_console_data *scdp) { void *vreg[2]; u32 reg[2]; int is_smc = 0, is_cpm2 = 0; void *parent, *muram; void *muram_addr; unsigned long muram_offset, muram_size; if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) { is_smc = 1; } else if (dt_is_compatible(devp, "fsl,cpm2-scc-uart")) { is_cpm2 = 1; } else if (dt_is_compatible(devp, "fsl,cpm2-smc-uart")) { is_cpm2 = 1; is_smc = 1; } if (is_smc) { enable_port = smc_enable_port; disable_port = smc_disable_port; } else { enable_port = scc_enable_port; disable_port = scc_disable_port; } if (is_cpm2) do_cmd = cpm2_cmd; else do_cmd = cpm1_cmd; if (getprop(devp, "fsl,cpm-command", &cpm_cmd, 4) < 4) return -1; if (dt_get_virtual_reg(devp, vreg, 2) < 2) return -1; if (is_smc) smc = vreg[0]; else scc = vreg[0]; param = vreg[1]; parent = get_parent(devp); if (!parent) return -1; if (dt_get_virtual_reg(parent, &cpcr, 1) < 1) return -1; muram = finddevice("/soc/cpm/muram/data"); if (!muram) return -1; /* For bootwrapper-compatible device trees, we assume that the first * entry has at least 128 bytes, and that #address-cells/#data-cells * is one for both parent and child. */ if (dt_get_virtual_reg(muram, &muram_addr, 1) < 1) return -1; if (getprop(muram, "reg", reg, 8) < 8) return -1; muram_offset = reg[0]; muram_size = reg[1]; /* Store the buffer descriptors at the end of the first muram chunk. * For SMC ports on CPM2-based platforms, relocate the parameter RAM * just before the buffer descriptors. */ cbd_offset = muram_offset + muram_size - 2 * sizeof(struct cpm_bd); if (is_cpm2 && is_smc) { u16 *smc_base = (u16 *)param; u16 pram_offset; pram_offset = cbd_offset - 64; pram_offset = _ALIGN_DOWN(pram_offset, 64); disable_port(); out_be16(smc_base, pram_offset); param = muram_addr - muram_offset + pram_offset; } cbd_addr = muram_addr - muram_offset + cbd_offset; scdp->open = cpm_serial_open; scdp->putc = cpm_serial_putc; scdp->getc = cpm_serial_getc; scdp->tstc = cpm_serial_tstc; return 0; }