Пример #1
0
/*
 * Generate a break.
 */
static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;

	pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
		break_state);

	if (break_state)
		cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
	else
		cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX);
}
Пример #2
0
static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
{
	int line = pinfo - cpm_uart_ports;
	volatile scc_t *scp;
	volatile scc_uart_t *sup;

	pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line);

	scp = pinfo->sccp;
	sup = pinfo->sccup;

	/* Store address */
	pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE;
	pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE;

	/* Set up the uart parameters in the
	 * parameter ram.
	 */

	cpm_set_scc_fcr(sup);

	sup->scc_genscc.scc_mrblr = pinfo->rx_fifosize;
	sup->scc_maxidl = pinfo->rx_fifosize;
	sup->scc_brkcr = 1;
	sup->scc_parec = 0;
	sup->scc_frmec = 0;
	sup->scc_nosec = 0;
	sup->scc_brkec = 0;
	sup->scc_uaddr1 = 0;
	sup->scc_uaddr2 = 0;
	sup->scc_toseq = 0;
	sup->scc_char1 = 0x8000;
	sup->scc_char2 = 0x8000;
	sup->scc_char3 = 0x8000;
	sup->scc_char4 = 0x8000;
	sup->scc_char5 = 0x8000;
	sup->scc_char6 = 0x8000;
	sup->scc_char7 = 0x8000;
	sup->scc_char8 = 0x8000;
	sup->scc_rccm = 0xc0ff;

	/* Send the CPM an initialize command.
	 */
	cpm_line_cr_cmd(line, CPM_CR_INIT_TRX);

	/* Set UART mode, 8 bit, no parity, one stop.
	 * Enable receive and transmit.
	 */
	scp->scc_gsmrh = 0;
	scp->scc_gsmrl =
	    (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);

	/* Enable rx interrupts  and clear all pending events.  */
	scp->scc_sccm = 0;
	scp->scc_scce = 0xffff;
	scp->scc_dsr = 0x7e7e;
	scp->scc_psmr = 0x3000;

	scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
Пример #3
0
static int cpm_uart_startup(struct uart_port *port)
{
	int retval;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	int line = pinfo - cpm_uart_ports;

	pr_debug("CPM uart[%d]:startup\n", port->line);

	/* Install interrupt handler. */
	retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
	if (retval)
		return retval;

	/* Startup rx-int */
	if (IS_SMC(pinfo)) {
		pinfo->smcp->smc_smcm |= SMCM_RX;
		pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
	} else {
		pinfo->sccp->scc_sccm |= UART_SCCM_RX;
		pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}

	if (!(pinfo->flags & FLAG_CONSOLE))
		cpm_line_cr_cmd(line,CPM_CR_INIT_TRX);
	return 0;
}
Пример #4
0
static int cpm_uart_startup(struct uart_port *port)
{
	int retval;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;

	pr_debug("CPM uart[%d]:startup\n", port->line);

	/* If the port is not the console, make sure rx is disabled. */
	if (!(pinfo->flags & FLAG_CONSOLE)) {
		/* Disable UART rx */
		if (IS_SMC(pinfo)) {
			clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN);
			clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX);
		} else {
			clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR);
			clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
		}
		cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
	}
	/* Install interrupt handler. */
	retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
	if (retval)
		return retval;

	/* Startup rx-int */
	if (IS_SMC(pinfo)) {
		setbits8(&pinfo->smcp->smc_smcm, SMCM_RX);
		setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN));
	} else {
		setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
		setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT));
	}

	return 0;
}
Пример #5
0
/*
 * Shutdown the uart
 */
static void cpm_uart_shutdown(struct uart_port *port)
{
    struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
    int line = pinfo - cpm_uart_ports;

    pr_debug("CPM uart[%d]:shutdown\n", port->line);

    /* free interrupt handler */
    free_irq(port->irq, port);

    /* If the port is not the console, disable Rx and Tx. */
    if (!(pinfo->flags & FLAG_CONSOLE)) {
        /* Stop uarts */
        if (IS_SMC(pinfo)) {
            volatile smc_t *smcp = pinfo->smcp;
            smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
            smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
        } else {
            volatile scc_t *sccp = pinfo->sccp;
            sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
            sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
        }

        /* Shut them really down and reinit buffer descriptors */
        cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
        cpm_uart_initbd(pinfo);
    }
}
Пример #6
0
/*
 * Shutdown the uart
 */
static void cpm_uart_shutdown(struct uart_port *port)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;

	pr_debug("CPM uart[%d]:shutdown\n", port->line);

	/* free interrupt handler */
	free_irq(port->irq, port);

	/* If the port is not the console, disable Rx and Tx. */
	if (!(pinfo->flags & FLAG_CONSOLE)) {
		/* Wait for all the BDs marked sent */
		while(!cpm_uart_tx_empty(port)) {
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(2);
		}

		if (pinfo->wait_closing)
			cpm_uart_wait_until_send(pinfo);

		/* Stop uarts */
		if (IS_SMC(pinfo)) {
			smc_t __iomem *smcp = pinfo->smcp;
			clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
			clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX);
		} else {
			scc_t __iomem *sccp = pinfo->sccp;
			clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
			clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
		}

		/* Shut them really down and reinit buffer descriptors */
		if (IS_SMC(pinfo)) {
			out_be16(&pinfo->smcup->smc_brkcr, 0);
			cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
		} else {
			out_be16(&pinfo->sccup->scc_brkcr, 0);
			cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
		}

		cpm_uart_initbd(pinfo);
	}
}
Пример #7
0
static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
{
	smc_t __iomem *sp;
	smc_uart_t __iomem *up;

	pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line);

	sp = pinfo->smcp;
	up = pinfo->smcup;

	/* Store address */
	out_be16(&pinfo->smcup->smc_rbase,
	         (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE);
	out_be16(&pinfo->smcup->smc_tbase,
	         (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);

/*
 *  In case SMC1 is being relocated...
 */
#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
	out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase));
	out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase));
	out_be32(&up->smc_rstate, 0);
	out_be32(&up->smc_tstate, 0);
	out_be16(&up->smc_brkcr, 1);              /* number of break chars */
	out_be16(&up->smc_brkec, 0);
#endif

	/* Set up the uart parameters in the
	 * parameter ram.
	 */
	cpm_set_smc_fcr(up);

	/* Using idle charater time requires some additional tuning.  */
	out_be16(&up->smc_mrblr, pinfo->rx_fifosize);
	out_be16(&up->smc_maxidl, pinfo->rx_fifosize);
	out_be16(&up->smc_brklen, 0);
	out_be16(&up->smc_brkec, 0);
	out_be16(&up->smc_brkcr, 1);

	cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);

	/* Set UART mode, 8 bit, no parity, one stop.
	 * Enable receive and transmit.
	 */
	out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART);

	/* Enable only rx interrupts clear all pending events. */
	out_8(&sp->smc_smcm, 0);
	out_8(&sp->smc_smce, 0xff);

	setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
}
Пример #8
0
static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
{
	int line = pinfo - cpm_uart_ports;
	volatile smc_t *sp;
	volatile smc_uart_t *up;

	pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line);

	sp = pinfo->smcp;
	up = pinfo->smcup;

	/* Store address */
	pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE;
	pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE;

/*
 *  In case SMC1 is being relocated...
 */
#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
	up->smc_rbptr = pinfo->smcup->smc_rbase;
	up->smc_tbptr = pinfo->smcup->smc_tbase;
	up->smc_rstate = 0;
	up->smc_tstate = 0;
	up->smc_brkcr = 1;              /* number of break chars */
	up->smc_brkec = 0;
#endif

	/* Set up the uart parameters in the
	 * parameter ram.
	 */
	cpm_set_smc_fcr(up);

	/* Using idle charater time requires some additional tuning.  */
	up->smc_mrblr = pinfo->rx_fifosize;
	up->smc_maxidl = pinfo->rx_fifosize;
	up->smc_brklen = 0;
	up->smc_brkec = 0;
	up->smc_brkcr = 1;

	cpm_line_cr_cmd(line, CPM_CR_INIT_TRX);

	/* Set UART mode, 8 bit, no parity, one stop.
	 * Enable receive and transmit.
	 */
	sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;

	/* Enable only rx interrupts clear all pending events. */
	sp->smc_smcm = 0;
	sp->smc_smce = 0xff;

	sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
}
Пример #9
0
int cpm_uart_early_setup(int index, int early)
{
	int ret;
	struct uart_port *port;
	struct uart_cpm_port *pinfo = &cpm_uart_ports[index];
	struct fs_uart_platform_info *pdata;
	struct platform_device* pdev = early_uart_get_pdev(index);
	int line = pinfo - cpm_uart_ports;

	BUG_ON(index>UART_NR);
	port =
		(struct uart_port *)&cpm_uart_ports[index];
	pinfo = (struct uart_cpm_port *)port;
	if (!pdev) {
		if (pinfo->set_lineif)
			pinfo->set_lineif(pinfo);
	} else {
		pdata = pdev->dev.platform_data;
		if (pdata)
			if (pdata->init_ioports)
    	                	pdata->init_ioports(pdata);

		cpm_uart_drv_get_platform_data(pdev, 1);
	}

	cpm_line_cr_cmd(line, CPM_CR_STOP_TX);

	if (IS_SMC(pinfo)) {
		pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
		pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
	} else {
		pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
		pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}
	ret = cpm_uart_allocbuf(pinfo, early);

	if (ret)
		return ret;

	cpm_uart_initbd(pinfo);

	if (IS_SMC(pinfo))
		cpm_uart_init_smc(pinfo);
	else
		cpm_uart_init_scc(pinfo);

	return 0;
}
Пример #10
0
/*
 * Setup console. Be careful is called early !
 */
static int __init cpm_uart_console_setup(struct console *co, char *options)
{
	struct uart_port *port;
	struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
	int baud = 115200;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;
	struct platform_device* pdev = early_uart_get_pdev(co->index);
	int line = pinfo - cpm_uart_ports;

#ifdef CONFIG_KGDB_CPM_UART
	/* We are not interested in ports yet utilized by kgdb */
	if(co->index == KGDB_PINFO_INDEX)
		return 0;
#endif

	if (!pdev) {
		pr_info("cpm_uart: console: compat mode\n");
		/* compatibility - will be cleaned up */
		cpm_uart_init_portdesc();
	}

	port =
	    (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
	pinfo = (struct uart_cpm_port *)port;

	pinfo->flags |= FLAG_CONSOLE;

	if (options) {
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	} else {
		if ((baud = uart_baudrate()) == -1)
			baud = 9600;
	}

	ret = cpm_uart_early_setup(cpm_uart_port_map[co->index], 1);
	if(ret)
		return ret;
	uart_set_options(port, co, baud, parity, bits, flow);
	cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);

	return 0;
}
Пример #11
0
static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
{
	scc_t __iomem *scp;
	scc_uart_t __iomem *sup;

	pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line);

	scp = pinfo->sccp;
	sup = pinfo->sccup;

	/* Store address */
	out_be16(&pinfo->sccup->scc_genscc.scc_rbase,
	         (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE);
	out_be16(&pinfo->sccup->scc_genscc.scc_tbase,
	         (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);

	/* Set up the uart parameters in the
	 * parameter ram.
	 */

	cpm_set_scc_fcr(sup);

	out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize);
	out_be16(&sup->scc_maxidl, pinfo->rx_fifosize);
	out_be16(&sup->scc_brkcr, 1);
	out_be16(&sup->scc_parec, 0);
	out_be16(&sup->scc_frmec, 0);
	out_be16(&sup->scc_nosec, 0);
	out_be16(&sup->scc_brkec, 0);
	out_be16(&sup->scc_uaddr1, 0);
	out_be16(&sup->scc_uaddr2, 0);
	out_be16(&sup->scc_toseq, 0);
	out_be16(&sup->scc_char1, 0x8000);
	out_be16(&sup->scc_char2, 0x8000);
	out_be16(&sup->scc_char3, 0x8000);
	out_be16(&sup->scc_char4, 0x8000);
	out_be16(&sup->scc_char5, 0x8000);
	out_be16(&sup->scc_char6, 0x8000);
	out_be16(&sup->scc_char7, 0x8000);
	out_be16(&sup->scc_char8, 0x8000);
	out_be16(&sup->scc_rccm, 0xc0ff);

	/* Send the CPM an initialize command.
	 */
	cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);

	/* Set UART mode, 8 bit, no parity, one stop.
	 * Enable receive and transmit.
	 */
	out_be32(&scp->scc_gsmrh, 0);
	out_be32(&scp->scc_gsmrl,
	         SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);

	/* Enable rx interrupts  and clear all pending events.  */
	out_be16(&scp->scc_sccm, 0);
	out_be16(&scp->scc_scce, 0xffff);
	out_be16(&scp->scc_dsr, 0x7e7e);
	out_be16(&scp->scc_psmr, 0x3000);

	setbits32(&scp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
Пример #12
0
static int __init cpm_uart_console_setup(struct console *co, char *options)
{
	int baud = 38400;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;
	struct uart_cpm_port *pinfo;
	struct uart_port *port;

	struct device_node *np = NULL;
	int i = 0;

	if (co->index >= UART_NR) {
		printk(KERN_ERR "cpm_uart: console index %d too high\n",
		       co->index);
		return -ENODEV;
	}

	do {
		np = of_find_node_by_type(np, "serial");
		if (!np)
			return -ENODEV;

		if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") &&
		    !of_device_is_compatible(np, "fsl,cpm1-scc-uart") &&
		    !of_device_is_compatible(np, "fsl,cpm2-smc-uart") &&
		    !of_device_is_compatible(np, "fsl,cpm2-scc-uart"))
			i--;
	} while (i++ != co->index);

	pinfo = &cpm_uart_ports[co->index];

	pinfo->flags |= FLAG_CONSOLE;
	port = &pinfo->port;

	ret = cpm_uart_init_port(np, pinfo);
	of_node_put(np);
	if (ret)
		return ret;

	if (options) {
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	} else {
		if ((baud = uart_baudrate()) == -1)
			baud = 9600;
	}

#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
	udbg_putc = NULL;
#endif

	if (IS_SMC(pinfo)) {
		out_be16(&pinfo->smcup->smc_brkcr, 0);
		cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
		clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
		clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
	} else {
		out_be16(&pinfo->sccup->scc_brkcr, 0);
		cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
		clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
		clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}

	ret = cpm_uart_allocbuf(pinfo, 1);

	if (ret)
		return ret;

	cpm_uart_initbd(pinfo);

	if (IS_SMC(pinfo))
		cpm_uart_init_smc(pinfo);
	else
		cpm_uart_init_scc(pinfo);

	uart_set_options(port, co, baud, parity, bits, flow);
	cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX);

	return 0;
}