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); }
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 }
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; }
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 }