1 #include <assert.h> 2 #include <sys/types.h> 3 #include <machine/cpu.h> 4 #include <minix/type.h> 5 #include <minix/board.h> 6 #include <io.h> 7 8 #include "kernel/kernel.h" 9 #include "kernel/proc.h" 10 #include "kernel/vm.h" 11 #include "kernel/proto.h" 12 #include "arch_proto.h" 13 14 #include "omap_serial.h" 15 16 struct omap_serial 17 { 18 vir_bytes base; 19 vir_bytes size; 20 }; 21 22 static struct omap_serial omap_serial = { 23 .base = 0, 24 }; 25 26 static kern_phys_map serial_phys_map; 27 28 /* 29 * In kernel serial for the omap. The serial driver, like most other 30 * drivers, needs to be started early and even before the MMU is turned on. 31 * We start by directly accessing the hardware memory address. Later on 32 * when the MMU is turned on we still use a 1:1 mapping for these addresses. 33 * 34 * Pretty soon we are going to remap these addresses at a later stage. And this 35 * requires us to use a dynamic base address. The idea is to receive a callback 36 * from VM with the new address to use. 37 * 38 * We also try on the BeagleBone port to keep the differences between the 39 * drivers to a minimum by initializing a struct here and not using (too many) 40 * constants in the code. 41 * 42 * The serial driver also gets used in the "pre_init" stage before the kernel is loaded 43 * in high memory, so keep in mind there are two copies of this code in the kernel. 44 */ 45 void 46 bsp_ser_init(void) 47 { 48 if (BOARD_IS_BBXM(machine.board_id)) { 49 omap_serial.base = OMAP3_DM37XX_DEBUG_UART_BASE; 50 } else if (BOARD_IS_BB(machine.board_id)) { 51 omap_serial.base = OMAP3_AM335X_DEBUG_UART_BASE; 52 } 53 omap_serial.size = 0x1000; /* 4k */ 54 55 kern_phys_map_ptr(omap_serial.base, omap_serial.size, 56 VMMF_UNCACHED | VMMF_WRITE, &serial_phys_map, 57 (vir_bytes) & omap_serial.base); 58 assert(omap_serial.base); 59 } 60 61 void 62 bsp_ser_putc(char c) 63 { 64 int i; 65 assert(omap_serial.base); 66 67 /* Wait until FIFO's empty */ 68 for (i = 0; i < 100000; i++) { 69 if (mmio_read(omap_serial.base + OMAP3_LSR) & OMAP3_LSR_THRE) { 70 break; 71 } 72 } 73 74 /* Write character */ 75 mmio_write(omap_serial.base + OMAP3_THR, c); 76 77 /* And wait again until FIFO's empty to prevent TTY from overwriting */ 78 for (i = 0; i < 100000; i++) { 79 if (mmio_read(omap_serial.base + 80 OMAP3_LSR) & (OMAP3_LSR_THRE | OMAP3_LSR_TEMT)) { 81 break; 82 } 83 } 84 } 85