Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | /* * Simple serial driver for Cogent motherboard serial ports * for use during boot */ #include <common.h> #include <board/cogent/serial.h> DECLARE_GLOBAL_DATA_PTR; #if (CMA_MB_CAPS & CMA_MB_CAP_SERPAR) #if (defined(CONFIG_8xx) && defined(CONFIG_8xx_CONS_NONE)) || \ (defined(CONFIG_8260) && defined(CONFIG_CONS_NONE)) #if CONFIG_CONS_INDEX == 1 #define CMA_MB_SERIAL_BASE CMA_MB_SERIALA_BASE #elif CONFIG_CONS_INDEX == 2 #define CMA_MB_SERIAL_BASE CMA_MB_SERIALB_BASE #elif CONFIG_CONS_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2) #define CMA_MB_SERIAL_BASE CMA_MB_SER2A_BASE #elif CONFIG_CONS_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2) #define CMA_MB_SERIAL_BASE CMA_MB_SER2B_BASE #else #error CONFIG_CONS_INDEX must be configured for Cogent motherboard serial #endif int serial_init (void) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE; cma_mb_reg_write (&mbsp->ser_ier, 0x00); /* turn off interrupts */ serial_setbrg (); cma_mb_reg_write (&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */ cma_mb_reg_write (&mbsp->ser_mcr, 0x03); /* RTS/DTR */ cma_mb_reg_write (&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */ return (0); } void serial_setbrg (void) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE; unsigned int divisor; unsigned char lcr; if ((divisor = br_to_div (gd->baudrate)) == 0) divisor = DEFDIV; lcr = cma_mb_reg_read (&mbsp->ser_lcr); cma_mb_reg_write (&mbsp->ser_lcr, lcr | 0x80); /* Access baud rate(set DLAB) */ cma_mb_reg_write (&mbsp->ser_brl, divisor & 0xff); cma_mb_reg_write (&mbsp->ser_brh, (divisor >> 8) & 0xff); cma_mb_reg_write (&mbsp->ser_lcr, lcr); /* unset DLAB */ } void serial_putc (const char c) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE; if (c == '\n') serial_putc ('\r'); while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_THRE) == 0); cma_mb_reg_write (&mbsp->ser_thr, c); } void serial_puts (const char *s) { while (*s != '\0') serial_putc (*s++); } int serial_getc (void) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE; while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0); return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f); } int serial_tstc (void) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE; return ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) != 0); } #endif /* CONS_NONE */ #if defined(CONFIG_CMD_KGDB) && \ defined(CONFIG_KGDB_NONE) #if CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX #error Console and kgdb are on the same serial port - this is not supported #endif #if CONFIG_KGDB_INDEX == 1 #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALA_BASE #elif CONFIG_KGDB_INDEX == 2 #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALB_BASE #elif CONFIG_KGDB_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2) #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2A_BASE #elif CONFIG_KGDB_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2) #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2B_BASE #else #error CONFIG_KGDB_INDEX must be configured for Cogent motherboard serial #endif void kgdb_serial_init (void) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE; unsigned int divisor; if ((divisor = br_to_div (CONFIG_KGDB_BAUDRATE)) == 0) divisor = DEFDIV; cma_mb_reg_write (&mbsp->ser_ier, 0x00); /* turn off interrupts */ cma_mb_reg_write (&mbsp->ser_lcr, 0x80); /* Access baud rate(set DLAB) */ cma_mb_reg_write (&mbsp->ser_brl, divisor & 0xff); cma_mb_reg_write (&mbsp->ser_brh, (divisor >> 8) & 0xff); cma_mb_reg_write (&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */ cma_mb_reg_write (&mbsp->ser_mcr, 0x03); /* RTS/DTR */ cma_mb_reg_write (&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */ printf ("[on cma10x serial port B] "); } void putDebugChar (int c) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE; while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_THRE) == 0); cma_mb_reg_write (&mbsp->ser_thr, c & 0xff); } void putDebugStr (const char *str) { while (*str != '\0') { if (*str == '\n') putDebugChar ('\r'); putDebugChar (*str++); } } int getDebugChar (void) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE; while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0); return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f); } void kgdb_interruptible (int yes) { cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE; if (yes == 1) { printf ("kgdb: turning serial ints on\n"); cma_mb_reg_write (&mbsp->ser_ier, 0xf); } else { printf ("kgdb: turning serial ints off\n"); cma_mb_reg_write (&mbsp->ser_ier, 0x0); } } #endif /* KGDB && KGDB_NONE */ #endif /* CAPS & SERPAR */ |