+#ifdef CONFIG_DM_SERIAL
+static void ns16550_writeb(NS16550_t port, int offset, int value)
+{
+ struct ns16550_platdata *plat = port->plat;
+ unsigned char *addr;
+
+ offset *= 1 << plat->reg_shift;
+ addr = map_sysmem(plat->base, 0) + offset;
+ /*
+ * As far as we know it doesn't make sense to support selection of
+ * these options at run-time, so use the existing CONFIG options.
+ */
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+ outb(value, (ulong)addr);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
+ out_le32(addr, value);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
+ out_be32(addr, value);
+#elif defined(CONFIG_SYS_BIG_ENDIAN)
+ writeb(value, addr + (1 << plat->reg_shift) - 1);
+#else
+ writeb(value, addr);
+#endif
+}
+
+static int ns16550_readb(NS16550_t port, int offset)
+{
+ struct ns16550_platdata *plat = port->plat;
+ unsigned char *addr;
+
+ offset *= 1 << plat->reg_shift;
+ addr = map_sysmem(plat->base, 0) + offset;
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+ return inb((ulong)addr);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
+ return in_le32(addr);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
+ return in_be32(addr);
+#elif defined(CONFIG_SYS_BIG_ENDIAN)
+ return readb(addr + (1 << plat->reg_shift) - 1);
+#else
+ return readb(addr);
+#endif
+}
+
+/* We can clean these up once everything is moved to driver model */
+#define serial_out(value, addr) \
+ ns16550_writeb(com_port, addr - (unsigned char *)com_port, value)
+#define serial_in(addr) \
+ ns16550_readb(com_port, addr - (unsigned char *)com_port)
+#endif
+
+int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
+{
+ const unsigned int mode_x_div = 16;
+
+#ifdef CONFIG_OMAP1510
+ /* If can't cleanly clock 115200 set div to 1 */
+ if ((clock == 12000000) && (baudrate == 115200)) {
+ port->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */
+ return 1; /* return 1 for base divisor */
+ }
+ port->osc_12m_sel = 0; /* clear if previsouly set */
+#endif
+
+ return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate);
+}
+
+static void NS16550_setbrg(NS16550_t com_port, int baud_divisor)
+{
+ serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
+ serial_out(baud_divisor & 0xff, &com_port->dll);
+ serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
+ serial_out(UART_LCRVAL, &com_port->lcr);
+}
+