Example #1
0
void samsung_lowlevel_init(virtual_addr_t base, u32 baudrate, u32 input_clock)
{
    unsigned int divider;
    unsigned int temp;
    unsigned int remainder;

    /* First, disable everything */
    vmm_out_le16((void *)(base + S3C2410_UCON), 0);

    /*
     * Set baud rate
     *
     * UBRDIV  = (UART_CLK / (16 * BAUD_RATE)) - 1
     * DIVSLOT = MOD(UART_CLK / BAUD_RATE, 16)
     */
    temp = udiv32(input_clock, baudrate);
    divider =  udiv32(temp, 16) - 1;
    remainder = umod32(temp, 16);

    vmm_out_le16((void *)(base + S3C2410_UBRDIV), (u16)
                 divider);
    vmm_out_8((void *)(base + S3C2443_DIVSLOT), (u8)
              remainder);

    /* Set the UART to be 8 bits, 1 stop bit, no parity */
    vmm_out_le32((void *)(base + S3C2410_ULCON),
                 S3C2410_LCON_CS8 | S3C2410_LCON_PNONE);

    /* enable FIFO, set RX and TX trigger */
    vmm_out_le32((void *)(base + S3C2410_UFCON), S3C2410_UFCON_DEFAULT);

    /* enable the UART */
    vmm_out_le32((void *)(base + S3C2410_UCON), S3C2410_UCON_DEFAULT);
}
Example #2
0
void imx_lowlevel_init(virtual_addr_t base, u32 baudrate, u32 input_clock)
{
	unsigned int temp = vmm_readl((void *)(base + UCR1));
#if 0
	unsigned int divider;
	unsigned int remainder;
#endif

	/* First, disable everything */
	temp &= ~UCR1_UARTEN;
	vmm_writel(temp, (void *)base + UCR1);

#if 0
	/*
	 * Set baud rate
	 *
	 * UBRDIV  = (UART_CLK / (16 * BAUD_RATE)) - 1
	 * DIVSLOT = MOD(UART_CLK / BAUD_RATE, 16)
	 */
	temp = udiv32(input_clock, baudrate);
	divider = udiv32(temp, 16) - 1;
	remainder = umod32(temp, 16);

	vmm_out_le16((void *)(base + S3C2410_UBRDIV), (u16)
		     divider);
	vmm_out_8((void *)(base + S3C2443_DIVSLOT), (u8)
		  remainder);

	/* Set the UART to be 8 bits, 1 stop bit, no parity */
	vmm_out_le32((void *)(base + S3C2410_ULCON),
		     S3C2410_LCON_CS8 | S3C2410_LCON_PNONE);

	/* enable FIFO, set RX and TX trigger */
	vmm_out_le32((void *)(base + S3C2410_UFCON), S3C2410_UFCON_DEFAULT);
#else
	/* enable the UART */
	temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;

	vmm_writel(temp, (void *)(base + UCR1));
#endif
}
Example #3
0
static int samsung_driver_probe(struct vmm_device *dev,
                                const struct vmm_devtree_nodeid *devid)
{
    u32 ucon;
    int rc = VMM_EFAIL;
    struct samsung_port *port = NULL;

    port = vmm_zalloc(sizeof(struct samsung_port));
    if (!port) {
        rc = VMM_ENOMEM;
        goto free_nothing;
    }

    rc = vmm_devtree_request_regmap(dev->of_node, &port->base, 0,
                                    "Samsung UART");
    if (rc) {
        goto free_port;
    }

    /* Make sure all interrupts except Rx are masked. */
    port->mask = S3C64XX_UINTM_RXD_MSK;
    port->mask = ~port->mask;
    vmm_out_le16((void *)(port->base + S3C64XX_UINTM), port->mask);

    if (vmm_devtree_read_u32(dev->of_node, "baudrate",
                             &port->baudrate)) {
        port->baudrate = 115200;
    }

    rc = vmm_devtree_clock_frequency(dev->of_node, &port->input_clock);
    if (rc) {
        goto free_reg;
    }

    /* Setup interrupt handler */
    port->irq = vmm_devtree_irq_parse_map(dev->of_node, 0);
    if (!port->irq) {
        rc = VMM_ENODEV;
        goto free_reg;
    }
    if ((rc = vmm_host_irq_register(port->irq, dev->name,
                                    samsung_irq_handler, port))) {
        goto free_reg;
    }

    /* Call low-level init function */
    samsung_lowlevel_init(port->base, port->baudrate, port->input_clock);

    /* Create Serial Port */
    port->p = serial_create(dev, 256, samsung_tx, port);
    if (VMM_IS_ERR_OR_NULL(port->p)) {
        rc = VMM_PTR_ERR(port->p);
        goto free_irq;
    }

    /* Save port pointer */
    dev->priv = port;

    /* Unmask RX interrupt */
    ucon = vmm_in_le32((void *)(port->base + S3C2410_UCON));
    ucon |= S3C2410_UCON_RXIRQMODE;
    vmm_out_le32((void *)(port->base + S3C2410_UCON), ucon);

    return VMM_OK;

free_irq:
    vmm_host_irq_unregister(port->irq, port);
free_reg:
    vmm_devtree_regunmap_release(dev->of_node, port->base, 0);
free_port:
    vmm_free(port);
free_nothing:
    return rc;
}
Example #4
0
void imx_lowlevel_init(virtual_addr_t base, u32 baudrate, u32 input_clock)
{
	unsigned int temp = vmm_readl((void *)(base + UCR1));
#if 0
	unsigned int divider;
	unsigned int remainder;
#endif

	/* First, disable everything */
	temp &= ~UCR1_UARTEN;
	vmm_writel(temp, (void *)base + UCR1);

#if 0
	/*
	 * Set baud rate
	 *
	 * UBRDIV  = (UART_CLK / (16 * BAUD_RATE)) - 1
	 * DIVSLOT = MOD(UART_CLK / BAUD_RATE, 16)
	 */
	temp = udiv32(input_clock, baudrate);
	divider = udiv32(temp, 16) - 1;
	remainder = umod32(temp, 16);

	vmm_out_le16((void *)(base + S3C2410_UBRDIV), (u16)
		     divider);
	vmm_out_8((void *)(base + S3C2443_DIVSLOT), (u8)
		  remainder);

	/* Set the UART to be 8 bits, 1 stop bit, no parity */
	vmm_out_le32((void *)(base + S3C2410_ULCON),
		     S3C2410_LCON_CS8 | S3C2410_LCON_PNONE);

	/* enable FIFO, set RX and TX trigger */
	vmm_out_le32((void *)(base + S3C2410_UFCON), S3C2410_UFCON_DEFAULT);
#else
	/* disable all UCR2 related interrupts */
	temp = vmm_readl((void *)(base + UCR2));
	vmm_writel(temp & ~(UCR2_ATEN | UCR2_ESCI | UCR2_RTSEN),
		   (void *)(base + UCR2));

	/* disable all UCR3 related interrupts */
	temp = vmm_readl((void *)(base + UCR3));
	vmm_writel(temp &
		   ~(UCR3_RXDSEN | UCR3_DTREN | UCR3_FRAERREN | UCR3_TIMEOUTEN |
		     UCR3_AIRINTEN | UCR3_AWAKEN | UCR3_DTRDEN),
		   (void *)(base + UCR3));

	/* disable all UCR4 related interrupts */
	temp = vmm_readl((void *)(base + UCR4));
	vmm_writel(temp &
		   ~(UCR4_DREN | UCR4_TCEN | UCR4_ENIRI | UCR4_WKEN | UCR4_BKEN
		     | UCR4_OREN), (void *)(base + UCR4));

	/* trigger interrupt when there is 1 by in the RXFIFO */
	temp = vmm_readl((void *)(base + UFCR));
	vmm_writel((temp & 0xFFC0) | 1, (void *)(base + UFCR));

	/* enable the UART and the receive interrupt */
	temp = UCR1_RRDYEN | UCR1_UARTEN;
	vmm_writel(temp, (void *)(base + UCR1));
#endif
}