2013-05-23 10:03:09 +02:00
|
|
|
#include <assert.h>
|
2012-10-08 03:38:03 +02:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <machine/cpu.h>
|
2013-05-23 10:03:09 +02:00
|
|
|
#include <minix/type.h>
|
2012-10-08 03:38:03 +02:00
|
|
|
#include <io.h>
|
2013-06-11 16:07:43 +02:00
|
|
|
|
|
|
|
#include "kernel/kernel.h"
|
|
|
|
#include "kernel/proc.h"
|
|
|
|
#include "kernel/vm.h"
|
|
|
|
#include "kernel/proto.h"
|
|
|
|
#include "arch_proto.h"
|
|
|
|
|
2012-10-08 03:38:03 +02:00
|
|
|
#include "omap_serial.h"
|
|
|
|
|
2013-06-11 16:07:43 +02:00
|
|
|
|
2013-05-23 10:03:09 +02:00
|
|
|
struct omap_serial {
|
|
|
|
vir_bytes base;
|
2013-06-11 16:07:43 +02:00
|
|
|
vir_bytes size;
|
2013-05-23 10:03:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct omap_serial omap_serial = {
|
|
|
|
.base = 0,
|
|
|
|
};
|
|
|
|
|
2013-06-11 16:07:43 +02:00
|
|
|
static kern_phys_map serial_phys_map;
|
|
|
|
|
2013-05-23 10:03:09 +02:00
|
|
|
/*
|
|
|
|
* In kernel serial for the omap. The serial driver like most other
|
|
|
|
* drivers needs to be started early and even before the MMU is turned on.
|
|
|
|
* We start by directly accessing the hardware memory address. Later on
|
|
|
|
* a when the MMU is turned on we still use a 1:1 mapping for these addresses.
|
|
|
|
*
|
|
|
|
* Pretty soon we are going to remap these addresses at later stage. And this
|
|
|
|
* requires us to use a dynamic base address. The idea is to receive a callback
|
|
|
|
* from VM with the new address to use.
|
|
|
|
*
|
|
|
|
* We also anticipate on the beaglebone port an try to keep the differences between
|
|
|
|
* the drivers to a minimum by initializing a struct here and not using (to much)
|
|
|
|
* constants in the code.
|
|
|
|
*
|
|
|
|
* The serial driver also gets used in the "pre_init" stage before the kernel is loaded
|
|
|
|
* in high memory so keep in mind there are two copies of this code in the kernel.
|
|
|
|
*/
|
|
|
|
void omap3_ser_init(){
|
|
|
|
#ifdef DM37XX
|
2013-05-23 13:16:24 +02:00
|
|
|
omap_serial.base = OMAP3_DM37XX_DEBUG_UART_BASE;
|
|
|
|
#endif
|
|
|
|
#ifdef AM335X
|
|
|
|
omap_serial.base = OMAP3_AM335X_DEBUG_UART_BASE;
|
2013-05-23 10:03:09 +02:00
|
|
|
#endif
|
2013-06-11 16:07:43 +02:00
|
|
|
omap_serial.size = 0x1000 ; /* 4k */
|
|
|
|
|
|
|
|
|
2013-08-26 18:43:05 +02:00
|
|
|
kern_phys_map_ptr(omap_serial.base,omap_serial.size,
|
|
|
|
&serial_phys_map, (vir_bytes) &omap_serial.base);
|
2013-05-23 10:03:09 +02:00
|
|
|
assert(omap_serial.base);
|
|
|
|
}
|
|
|
|
|
2012-10-08 03:38:03 +02:00
|
|
|
void omap3_ser_putc(char c)
|
|
|
|
{
|
2013-05-23 10:03:09 +02:00
|
|
|
assert(omap_serial.base);
|
|
|
|
|
2012-10-08 03:38:03 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Wait until FIFO's empty */
|
|
|
|
for (i = 0; i < 100000; i++)
|
2013-05-23 10:03:09 +02:00
|
|
|
if (mmio_read(omap_serial.base + OMAP3_LSR) & OMAP3_LSR_THRE)
|
2012-10-08 03:38:03 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* Write character */
|
2013-05-23 10:03:09 +02:00
|
|
|
mmio_write(omap_serial.base + OMAP3_THR, c);
|
2012-10-17 16:57:08 +02:00
|
|
|
|
|
|
|
/* And wait again until FIFO's empty to prevent TTY from overwriting */
|
|
|
|
for (i = 0; i < 100000; i++)
|
2013-05-23 10:03:09 +02:00
|
|
|
if (mmio_read(omap_serial.base + OMAP3_LSR) & (OMAP3_LSR_THRE | OMAP3_LSR_TEMT))
|
2012-10-17 16:57:08 +02:00
|
|
|
break;
|
2012-10-08 03:38:03 +02:00
|
|
|
}
|