예제 #1
0
파일: serial.c 프로젝트: CSCLOG/beaglebone
/* 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;
}
예제 #2
0
파일: virtex.c 프로젝트: 0-T-0/ps4-linux
/* 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;
}
예제 #3
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;
}
예제 #4
0
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");
}
예제 #5
0
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");
}
예제 #6
0
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;
}