File indexing completed on 2025-05-11 08:23:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #include <bsp.h>
0049 #include <rtems/libio.h>
0050 #include <mpc8260.h>
0051 #include <mpc8260/console.h>
0052 #include <mpc8260/cpm.h>
0053 #include <stdlib.h>
0054 #include <unistd.h>
0055 #include <termios.h>
0056 #include <bsp/irq.h>
0057 #include <rtems/bspIo.h> /* for printk */
0058
0059
0060
0061
0062 #define RXBUFSIZE 16
0063
0064
0065
0066
0067
0068
0069
0070
0071 static volatile char rxBuf[NUM_PORTS][RXBUFSIZE];
0072 static volatile char txBuf[NUM_PORTS];
0073
0074
0075 static volatile m8260BufferDescriptor_t *RxBd[NUM_PORTS], *TxBd[NUM_PORTS];
0076
0077
0078 struct rtems_termios_tty *ttyp[NUM_PORTS];
0079
0080 #if 0
0081
0082 static rtems_isr_entry old_handler[NUM_PORTS];
0083 #endif
0084
0085
0086
0087
0088 static int m8xx_smc_set_attributes(int, const struct termios*);
0089 static int m8xx_scc_set_attributes(int, const struct termios*);
0090 static rtems_isr m8xx_smc1_interrupt_handler(rtems_irq_hdl_param unused);
0091 static rtems_isr m8xx_smc2_interrupt_handler(rtems_irq_hdl_param unused);
0092 static rtems_isr m8xx_scc1_interrupt_handler(rtems_irq_hdl_param unused);
0093 static rtems_isr m8xx_scc2_interrupt_handler(rtems_irq_hdl_param unused);
0094 static rtems_isr m8xx_scc3_interrupt_handler(rtems_irq_hdl_param unused);
0095 static rtems_isr m8xx_scc4_interrupt_handler(rtems_irq_hdl_param unused);
0096
0097
0098
0099
0100 static int
0101 m8xx_smc_set_attributes (int minor, const struct termios *t)
0102 {
0103 int baud, brg=0, csize=0, ssize, psize;
0104 uint16_t clen=0, cstopb, parenb, parodd, cread;
0105
0106
0107 switch (t->c_ospeed) {
0108 default: baud = -1; break;
0109 case B50: baud = 50; break;
0110 case B75: baud = 75; break;
0111 case B110: baud = 110; break;
0112 case B134: baud = 134; break;
0113 case B150: baud = 150; break;
0114 case B200: baud = 200; break;
0115 case B300: baud = 300; break;
0116 case B600: baud = 600; break;
0117 case B1200: baud = 1200; break;
0118 case B1800: baud = 1800; break;
0119 case B2400: baud = 2400; break;
0120 case B4800: baud = 4800; break;
0121 case B9600: baud = 9600; break;
0122 case B19200: baud = 19200; break;
0123 case B38400: baud = 38400; break;
0124 case B57600: baud = 57600; break;
0125 case B115200: baud = 115200; break;
0126 case B230400: baud = 230400; break;
0127 case B460800: baud = 460800; break;
0128 }
0129 if (baud > 0) {
0130 switch( minor ) {
0131 case SMC1_MINOR:
0132
0133 brg = m8xx_get_brg( M8260_SMC1_BRGS, baud*16 ) + 1;
0134 m8260.cmxsmr &= ~0x30;
0135 m8260.cmxsmr |= (brg==1? 0x00: 0x10 );
0136 break;
0137 case SMC2_MINOR:
0138
0139 brg = m8xx_get_brg( M8260_SMC2_BRGS, baud*16 ) + 1;
0140 m8260.cmxsmr &= ~0x30;
0141 m8260.cmxsmr |= (brg==2? 0x00: 0x01 );
0142 break;
0143 }
0144 }
0145
0146
0147 switch ( t->c_cflag & CSIZE ) {
0148 case CS5: csize = 5; break;
0149 case CS6: csize = 6; break;
0150 case CS7: csize = 7; break;
0151 case CS8: csize = 8; break;
0152 }
0153
0154
0155 if ( t->c_cflag & CSTOPB ) {
0156 cstopb = 0x0400;
0157 ssize = 2;
0158 } else {
0159 cstopb = 0x0000;
0160 ssize = 1;
0161 }
0162
0163
0164 if ( t->c_cflag & PARENB ) {
0165 parenb = 0x0200;
0166 psize = 1;
0167 } else {
0168 parenb = 0x0000;
0169 psize = 0;
0170 }
0171
0172 if ( t->c_cflag & PARODD )
0173 parodd = 0x0000;
0174 else
0175 parodd = 0x0100;
0176
0177
0178
0179
0180 switch ( 1 + csize + psize + ssize - 1 ) {
0181 case 6: clen = 0x3000; break;
0182 case 7: clen = 0x3800; break;
0183 case 8: clen = 0x4000; break;
0184 case 9: clen = 0x4800; break;
0185 case 10: clen = 0x5000; break;
0186 case 11: clen = 0x5800; break;
0187 }
0188
0189 if ( t->c_cflag & CREAD )
0190 cread = 0x0023;
0191 else
0192 cread = 0x0021;
0193
0194
0195 switch (minor) {
0196 case SMC1_MINOR:
0197
0198
0199
0200 m8260.smc1.smcmr = clen | cstopb | parenb | parodd | cread;
0201 break;
0202 case SMC2_MINOR:
0203
0204
0205
0206
0207 m8260.smc2.smcmr = clen | cstopb | parenb | parodd | cread;
0208 break;
0209 }
0210 return 0;
0211 }
0212
0213 static int
0214 m8xx_scc_set_attributes (int minor, const struct termios *t)
0215 {
0216 int baud, brg=0;
0217 uint16_t csize=0, cstopb, parenb, parodd;
0218
0219
0220 switch (t->c_ospeed) {
0221 default: baud = -1; break;
0222 case B50: baud = 50; break;
0223 case B75: baud = 75; break;
0224 case B110: baud = 110; break;
0225 case B134: baud = 134; break;
0226 case B150: baud = 150; break;
0227 case B200: baud = 200; break;
0228 case B300: baud = 300; break;
0229 case B600: baud = 600; break;
0230 case B1200: baud = 1200; break;
0231 case B1800: baud = 1800; break;
0232 case B2400: baud = 2400; break;
0233 case B4800: baud = 4800; break;
0234 case B9600: baud = 9600; break;
0235 case B19200: baud = 19200; break;
0236 case B38400: baud = 38400; break;
0237 case B57600: baud = 57600; break;
0238 case B115200: baud = 115200; break;
0239 case B230400: baud = 230400; break;
0240 case B460800: baud = 460800; break;
0241 }
0242 if (baud > 0) {
0243 brg = m8xx_get_brg( M8260_SCC_BRGS, baud*16 );
0244 m8260.cmxscr &= ~(0xFF000000 >> (8*(minor-SCC1_MINOR)) );
0245 m8260.cmxscr |= ((brg<<(3+8*(3-(minor-SCC1_MINOR)))) &
0246 (brg<<(8*(3-(minor-SCC1_MINOR)))));
0247 }
0248
0249 switch ( t->c_cflag & CSIZE ) {
0250 case CS5: csize = 0x0000; break;
0251 case CS6: csize = 0x1000; break;
0252 case CS7: csize = 0x2000; break;
0253 case CS8: csize = 0x3000; break;
0254 }
0255
0256
0257 if ( t->c_cflag & CSTOPB )
0258 cstopb = 0x4000;
0259 else
0260 cstopb = 0x0000;
0261
0262
0263 if ( t->c_cflag & PARENB )
0264 parenb = 0x0010;
0265 else
0266 parenb = 0x0000;
0267
0268 if ( t->c_cflag & PARODD )
0269 parodd = 0x0000;
0270 else
0271 parodd = 0x000a;
0272
0273
0274 switch (minor) {
0275 case SCC1_MINOR:
0276
0277
0278
0279 m8260.scc1.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc1.psmr & 0x8fe0) );
0280 break;
0281 case SCC2_MINOR:
0282
0283
0284
0285 m8260.scc2.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc2.psmr & 0x8fe0) );
0286 break;
0287 case SCC3_MINOR:
0288
0289
0290
0291 m8260.scc3.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc3.psmr & 0x8fe0) );
0292 break;
0293 case SCC4_MINOR:
0294
0295
0296
0297 m8260.scc4.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc4.psmr & 0x8fe0) );
0298 break;
0299 }
0300
0301 return 0;
0302 }
0303
0304 int
0305 m8xx_uart_setAttributes(
0306 int minor,
0307 const struct termios *t
0308 )
0309 {
0310
0311
0312
0313 if ( (minor < SMC1_MINOR) || (minor > NUM_PORTS-1) )
0314 return 0;
0315
0316 switch (minor) {
0317 case SMC1_MINOR:
0318 case SMC2_MINOR:
0319 return m8xx_smc_set_attributes( minor, t );
0320
0321 case SCC1_MINOR:
0322 case SCC2_MINOR:
0323 case SCC3_MINOR:
0324 case SCC4_MINOR:
0325 return m8xx_scc_set_attributes( minor, t );
0326 }
0327 return 0;
0328 }
0329
0330
0331
0332
0333 static void
0334 m8xx_scc1_interrupt_handler (rtems_irq_hdl_param unused)
0335 {
0336
0337
0338
0339 if ((m8260.scc1.sccm & M8260_SCCE_RX) && (m8260.scc1.scce & M8260_SCCE_RX)) {
0340 m8260.scc1.scce = M8260_SCCE_RX;
0341
0342
0343
0344 if ((RxBd[SCC1_MINOR]->status & M8260_BD_EMPTY) == 0) {
0345 rtems_cache_invalidate_multiple_data_lines(
0346 (const void *) RxBd[SCC1_MINOR]->buffer,
0347 RxBd[SCC1_MINOR]->length );
0348 rtems_termios_enqueue_raw_characters(
0349 (void *)ttyp[SCC1_MINOR],
0350 (char *)RxBd[SCC1_MINOR]->buffer,
0351 (int)RxBd[SCC1_MINOR]->length );
0352 RxBd[SCC1_MINOR]->status = M8260_BD_EMPTY | M8260_BD_WRAP |
0353 M8260_BD_INTERRUPT;
0354 }
0355 }
0356
0357
0358
0359
0360 if (m8260.scc1.scce & M8260_SCCE_TX) {
0361 m8260.scc1.scce = M8260_SCCE_TX;
0362
0363
0364 if ((TxBd[SCC1_MINOR]->status & M8260_BD_READY) == 0)
0365 rtems_termios_dequeue_characters (
0366 (void *)ttyp[SCC1_MINOR],
0367 (int)TxBd[SCC1_MINOR]->length);
0368 }
0369
0370 #if 0
0371 m8260.sipnr_l |= M8260_SIMASK_SCC1;
0372 #endif
0373 }
0374
0375 static void
0376 m8xx_scc2_interrupt_handler (rtems_irq_hdl_param unused)
0377 {
0378
0379
0380
0381 if ((m8260.scc2.sccm & M8260_SCCE_RX) && (m8260.scc2.scce & M8260_SCCE_RX)) {
0382 m8260.scc2.scce = M8260_SCCE_RX;
0383
0384
0385
0386 if ((RxBd[SCC2_MINOR]->status & M8260_BD_EMPTY) == 0) {
0387 rtems_cache_invalidate_multiple_data_lines(
0388 (const void *) RxBd[SCC2_MINOR]->buffer,
0389 RxBd[SCC2_MINOR]->length );
0390 rtems_termios_enqueue_raw_characters(
0391 (void *)ttyp[SCC2_MINOR],
0392 (char *)RxBd[SCC2_MINOR]->buffer,
0393 (int)RxBd[SCC2_MINOR]->length );
0394 RxBd[SCC2_MINOR]->status = M8260_BD_EMPTY | M8260_BD_WRAP |
0395 M8260_BD_INTERRUPT;
0396 }
0397 }
0398
0399
0400
0401
0402 if (m8260.scc2.scce & M8260_SCCE_TX) {
0403 m8260.scc2.scce = M8260_SCCE_TX;
0404
0405
0406 if ((TxBd[SCC2_MINOR]->status & M8260_BD_READY) == 0)
0407 rtems_termios_dequeue_characters (
0408 (void *)ttyp[SCC2_MINOR],
0409 (int)TxBd[SCC2_MINOR]->length);
0410 }
0411
0412 #if 0
0413 m8260.sipnr_l |= M8260_SIMASK_SCC2;
0414 #endif
0415 }
0416
0417 static void
0418 m8xx_scc3_interrupt_handler (rtems_irq_hdl_param unused)
0419 {
0420
0421
0422
0423 if ((m8260.scc3.sccm & M8260_SCCE_RX) && (m8260.scc3.scce & M8260_SCCE_RX)) {
0424 m8260.scc3.scce = M8260_SCCE_RX;
0425
0426
0427
0428 if ((RxBd[SCC3_MINOR]->status & M8260_BD_EMPTY) == 0) {
0429 rtems_cache_invalidate_multiple_data_lines(
0430 (const void *) RxBd[SCC3_MINOR]->buffer,
0431 RxBd[SCC3_MINOR]->length );
0432 rtems_termios_enqueue_raw_characters(
0433 (void *)ttyp[SCC3_MINOR],
0434 (char *)RxBd[SCC3_MINOR]->buffer,
0435 (int)RxBd[SCC3_MINOR]->length );
0436 RxBd[SCC3_MINOR]->status = M8260_BD_EMPTY | M8260_BD_WRAP |
0437 M8260_BD_INTERRUPT;
0438 }
0439 }
0440
0441
0442
0443
0444 if (m8260.scc3.scce & M8260_SCCE_TX) {
0445 m8260.scc3.scce = M8260_SCCE_TX;
0446
0447
0448 if ((TxBd[SCC3_MINOR]->status & M8260_BD_READY) == 0)
0449 rtems_termios_dequeue_characters (
0450 (void *)ttyp[SCC3_MINOR],
0451 (int)TxBd[SCC3_MINOR]->length);
0452 }
0453
0454
0455 #if 0
0456 m8260.sipnr_l |= M8260_SIMASK_SCC3;
0457 #endif
0458 }
0459
0460 static void
0461 m8xx_scc4_interrupt_handler (rtems_irq_hdl_param unused)
0462 {
0463
0464
0465
0466 if ((m8260.scc4.sccm & M8260_SCCE_RX) && (m8260.scc4.scce & M8260_SCCE_RX)) {
0467 m8260.scc4.scce = M8260_SCCE_RX;
0468
0469
0470
0471 if ((RxBd[SCC4_MINOR]->status & M8260_BD_EMPTY) == 0) {
0472 rtems_cache_invalidate_multiple_data_lines(
0473 (const void *) RxBd[SCC4_MINOR]->buffer,
0474 RxBd[SCC4_MINOR]->length );
0475 rtems_termios_enqueue_raw_characters(
0476 (void *)ttyp[SCC4_MINOR],
0477 (char *)RxBd[SCC4_MINOR]->buffer,
0478 (int)RxBd[SCC4_MINOR]->length );
0479 RxBd[SCC4_MINOR]->status = M8260_BD_EMPTY | M8260_BD_WRAP |
0480 M8260_BD_INTERRUPT;
0481 }
0482 }
0483
0484
0485
0486
0487 if (m8260.scc4.scce & M8260_SCCE_TX) {
0488 m8260.scc4.scce = M8260_SCCE_TX;
0489
0490
0491 if ((TxBd[SCC4_MINOR]->status & M8260_BD_READY) == 0)
0492 rtems_termios_dequeue_characters (
0493 (void *)ttyp[SCC4_MINOR],
0494 (int)TxBd[SCC4_MINOR]->length);
0495 }
0496
0497 #if 0
0498 m8260.sipnr_l |= M8260_SIMASK_SCC4;
0499 #endif
0500 }
0501
0502 static void
0503 m8xx_smc1_interrupt_handler (rtems_irq_hdl_param unused)
0504 {
0505
0506
0507
0508 if (m8260.smc1.smce & M8260_SMCE_RX) {
0509 m8260.smc1.smce = M8260_SMCE_RX;
0510
0511
0512
0513 if ((RxBd[SMC1_MINOR]->status & M8260_BD_EMPTY) == 0) {
0514 rtems_cache_invalidate_multiple_data_lines(
0515 (const void *) RxBd[SMC1_MINOR]->buffer,
0516 RxBd[SMC1_MINOR]->length );
0517 rtems_termios_enqueue_raw_characters(
0518 (void *)ttyp[SMC1_MINOR],
0519 (char *)RxBd[SMC1_MINOR]->buffer,
0520 (int)RxBd[SMC1_MINOR]->length );
0521 RxBd[SMC1_MINOR]->status = M8260_BD_EMPTY | M8260_BD_WRAP |
0522 M8260_BD_INTERRUPT;
0523 }
0524 }
0525
0526
0527
0528
0529 if (m8260.smc1.smce & M8260_SMCE_TX) {
0530 m8260.smc1.smce = M8260_SMCE_TX;
0531
0532
0533 if ((TxBd[SMC1_MINOR]->status & M8260_BD_READY) == 0)
0534 rtems_termios_dequeue_characters (
0535 (void *)ttyp[SMC1_MINOR],
0536 (int)TxBd[SMC1_MINOR]->length);
0537 }
0538
0539 #if 0
0540 m8260.sipnr_l = 0x00001000;
0541 #endif
0542 }
0543
0544 static void
0545 m8xx_smc2_interrupt_handler (rtems_irq_hdl_param unused)
0546 {
0547
0548
0549
0550 if (m8260.smc2.smce & M8260_SMCE_RX) {
0551 m8260.smc2.smce = M8260_SMCE_RX;
0552
0553
0554
0555 if ((RxBd[SMC2_MINOR]->status & M8260_BD_EMPTY) == 0) {
0556 rtems_cache_invalidate_multiple_data_lines(
0557 (const void *) RxBd[SMC2_MINOR]->buffer,
0558 RxBd[SMC2_MINOR]->length );
0559 rtems_termios_enqueue_raw_characters(
0560 (void *)ttyp[SMC2_MINOR],
0561 (char *)RxBd[SMC2_MINOR]->buffer,
0562 (int)RxBd[SMC2_MINOR]->length );
0563 RxBd[SMC2_MINOR]->status = M8260_BD_EMPTY | M8260_BD_WRAP |
0564 M8260_BD_INTERRUPT;
0565 }
0566 }
0567
0568
0569
0570
0571 if (m8260.smc2.smce & M8260_SMCE_TX) {
0572 m8260.smc2.smce = M8260_SMCE_TX;
0573
0574
0575 if ((TxBd[SMC2_MINOR]->status & M8260_BD_READY) == 0)
0576 rtems_termios_dequeue_characters (
0577 (void *)ttyp[SMC2_MINOR],
0578 (int)TxBd[SMC2_MINOR]->length);
0579 }
0580
0581 #if 0
0582 m8260.sipnr_l = 0x00000800;
0583 #endif
0584 }
0585
0586 static void m8xx_scc_enable(const rtems_irq_connect_data* ptr)
0587 {
0588 volatile m8260SCCRegisters_t *sccregs = 0;
0589 switch (ptr->name) {
0590 case BSP_CPM_IRQ_SCC4 :
0591 m8260.sipnr_l |= M8260_SIMASK_SCC4;
0592 sccregs = &m8260.scc4;
0593 break;
0594 case BSP_CPM_IRQ_SCC3 :
0595 m8260.sipnr_l |= M8260_SIMASK_SCC3;
0596 sccregs = &m8260.scc3;
0597 break;
0598 case BSP_CPM_IRQ_SCC2 :
0599 m8260.sipnr_l |= M8260_SIMASK_SCC2;
0600 sccregs = &m8260.scc2;
0601 break;
0602 case BSP_CPM_IRQ_SCC1 :
0603 m8260.sipnr_l |= M8260_SIMASK_SCC1;
0604 sccregs = &m8260.scc1;
0605 break;
0606 default:
0607 break;
0608 }
0609 sccregs->sccm = 3;
0610 }
0611
0612 static void m8xx_scc_disable(const rtems_irq_connect_data* ptr)
0613 {
0614 volatile m8260SCCRegisters_t *sccregs = 0;
0615 switch (ptr->name) {
0616 case BSP_CPM_IRQ_SCC4 :
0617 sccregs = &m8260.scc4;
0618 break;
0619 case BSP_CPM_IRQ_SCC3 :
0620 sccregs = &m8260.scc3;
0621 break;
0622 case BSP_CPM_IRQ_SCC2 :
0623 sccregs = &m8260.scc2;
0624 break;
0625 case BSP_CPM_IRQ_SCC1 :
0626 sccregs = &m8260.scc1;
0627 break;
0628 default:
0629 break;
0630 }
0631 sccregs->sccm &= (~3);
0632 }
0633
0634 static int m8xx_scc_isOn(const rtems_irq_connect_data* ptr)
0635 {
0636 return BSP_irq_enabled_at_cpm (ptr->name);
0637 }
0638
0639 static rtems_irq_connect_data consoleIrqData =
0640 {
0641 BSP_CPM_IRQ_SCC1,
0642 (rtems_irq_hdl)m8xx_scc1_interrupt_handler,
0643 NULL,
0644 (rtems_irq_enable) m8xx_scc_enable,
0645 (rtems_irq_disable) m8xx_scc_disable,
0646 (rtems_irq_is_enabled) m8xx_scc_isOn
0647 };
0648
0649 void
0650 m8xx_uart_scc_initialize (int minor)
0651 {
0652 unsigned char brg;
0653 volatile m8260SCCparms_t *sccparms = 0;
0654 volatile m8260SCCRegisters_t *sccregs = 0;
0655
0656
0657
0658
0659 if ( (minor < SCC1_MINOR) || (minor > NUM_PORTS-1) )
0660 return;
0661
0662
0663 brg = m8xx_get_brg(M8260_SCC_BRGS, 9600*16);
0664
0665 m8260.cmxscr &= ~(0xFF000000 >> (8*(minor-SCC1_MINOR)) );
0666 m8260.cmxscr |= (brg<<(3+8*(3-(minor-SCC1_MINOR))));
0667 m8260.cmxscr |= (brg<<(8*(3-(minor-SCC1_MINOR))));
0668
0669
0670
0671
0672 RxBd[minor] = m8xx_bd_allocate(1);
0673 TxBd[minor] = m8xx_bd_allocate(1);
0674
0675
0676
0677
0678
0679 m8260.ppard |= (0x07 << ((minor-SCC1_MINOR)*3));
0680 m8260.psord &= ~(0x07 << ((minor-SCC1_MINOR)*3));
0681 if( minor == SCC1_MINOR )
0682 m8260.psord |= 0x02;
0683 m8260.pdird |= (0x06 << ((minor-SCC1_MINOR)*3));
0684 m8260.pdird &= ~(0x01 << ((minor-SCC1_MINOR)*3));
0685
0686
0687
0688
0689
0690 if( minor == SCC1_MINOR ) {
0691 sccparms = (m8260SCCparms_t*)&m8260.scc1p;
0692 sccregs = (m8260SCCRegisters_t*)&m8260.scc1;
0693 }
0694 else if( minor == SCC2_MINOR ) {
0695 sccparms = (m8260SCCparms_t*)&m8260.scc2p;
0696 sccregs = (m8260SCCRegisters_t*)&m8260.scc2;
0697 }
0698 else if( minor == SCC3_MINOR ) {
0699 sccparms = (m8260SCCparms_t*)&m8260.scc3p;
0700 sccregs = (m8260SCCRegisters_t*)&m8260.scc3;
0701 }
0702 else {
0703 sccparms = (m8260SCCparms_t*)&m8260.scc4p;
0704 sccregs = (m8260SCCRegisters_t*)&m8260.scc4;
0705 }
0706
0707 sccparms->rbase = (char *)RxBd[minor] - (char *)&m8260;
0708 sccparms->tbase = (char *)TxBd[minor] - (char *)&m8260;
0709
0710 sccparms->rfcr = M8260_RFCR_MOT | M8260_RFCR_60X_BUS;
0711 sccparms->tfcr = M8260_TFCR_MOT | M8260_TFCR_60X_BUS;
0712 if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 )
0713 sccparms->mrblr = RXBUFSIZE;
0714 else
0715 sccparms->mrblr = 1;
0716 sccparms->un.uart.max_idl = 10;
0717 sccparms->un.uart.brkcr = 0;
0718
0719 sccparms->un.uart.parec = 0;
0720 sccparms->un.uart.frmec = 0;
0721 sccparms->un.uart.nosec = 0;
0722 sccparms->un.uart.brkec = 0;
0723
0724 sccparms->un.uart.uaddr[0] = 0;
0725 sccparms->un.uart.uaddr[1] = 0;
0726 sccparms->un.uart.toseq = 0;
0727
0728 sccparms->un.uart.character[0] = 0x8000;
0729 sccparms->un.uart.character[1] = 0x8000;
0730 sccparms->un.uart.character[2] = 0x8000;
0731 sccparms->un.uart.character[3] = 0x8000;
0732 sccparms->un.uart.character[4] = 0x8000;
0733 sccparms->un.uart.character[5] = 0x8000;
0734 sccparms->un.uart.character[6] = 0x8000;
0735 sccparms->un.uart.character[7] = 0x8000;
0736
0737 sccparms->un.uart.rccm = 0xc0ff;
0738
0739
0740
0741
0742 RxBd[minor]->status = M8260_BD_EMPTY | M8260_BD_WRAP | M8260_BD_INTERRUPT;
0743 RxBd[minor]->length = 0;
0744 RxBd[minor]->buffer = rxBuf[minor];
0745
0746
0747
0748
0749 TxBd[minor]->status = M8260_BD_WRAP;
0750
0751
0752
0753
0754 sccregs->gsmr_h = 0x00000020;
0755 sccregs->gsmr_l = 0x00028004;
0756 sccregs->scce = ~0;
0757 sccregs->sccm = 0;
0758 sccregs->psmr = 0x3000;
0759
0760 sccregs->dsr = 0x7E7E;
0761 sccregs->gsmr_l = 0x00028034;
0762
0763
0764
0765
0766 switch (minor) {
0767 case SCC1_MINOR:
0768 m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC1);
0769 break;
0770 case SCC2_MINOR:
0771 m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC2);
0772 break;
0773 case SCC3_MINOR:
0774 m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC3);
0775 break;
0776 case SCC4_MINOR:
0777 m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC4);
0778 break;
0779 }
0780
0781 if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
0782 switch (minor) {
0783 case SCC1_MINOR:
0784 consoleIrqData.name = BSP_CPM_IRQ_SCC1;
0785 consoleIrqData.hdl = m8xx_scc1_interrupt_handler;
0786 break;
0787 case SCC2_MINOR:
0788 consoleIrqData.name = BSP_CPM_IRQ_SCC2;
0789 consoleIrqData.hdl = m8xx_scc2_interrupt_handler;
0790 break;
0791 case SCC3_MINOR:
0792 consoleIrqData.name = BSP_CPM_IRQ_SCC3;
0793 consoleIrqData.hdl = m8xx_scc3_interrupt_handler;
0794 break;
0795 case SCC4_MINOR:
0796 consoleIrqData.name = BSP_CPM_IRQ_SCC4;
0797 consoleIrqData.hdl = m8xx_scc4_interrupt_handler;
0798 break;
0799
0800 }
0801 if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
0802 printk("Unable to connect SCC Irq handler\n");
0803 rtems_fatal_error_occurred(1);
0804 }
0805 }
0806 }
0807
0808 static void m8xx_smc_enable(const rtems_irq_connect_data* ptr)
0809 {
0810 volatile m8260SMCRegisters_t *smcregs = 0;
0811 switch (ptr->name) {
0812 case BSP_CPM_IRQ_SMC1 :
0813 smcregs = &m8260.smc1;
0814 break;
0815 case BSP_CPM_IRQ_SMC2 :
0816 smcregs = &m8260.smc2;
0817 break;
0818 default:
0819 break;
0820 }
0821 smcregs->smcm = 3;
0822 }
0823
0824 static void m8xx_smc_disable(const rtems_irq_connect_data* ptr)
0825 {
0826 volatile m8260SMCRegisters_t *smcregs = 0;
0827 switch (ptr->name) {
0828 case BSP_CPM_IRQ_SMC1 :
0829 smcregs = &m8260.smc1;
0830 break;
0831 case BSP_CPM_IRQ_SMC2 :
0832 smcregs = &m8260.smc2;
0833 break;
0834 default:
0835 break;
0836 }
0837 smcregs->smcm &= (~3);
0838 }
0839
0840 static int m8xx_smc_isOn(const rtems_irq_connect_data* ptr)
0841 {
0842 return BSP_irq_enabled_at_cpm (ptr->name);
0843 }
0844
0845 void
0846 m8xx_uart_smc_initialize (int minor)
0847 {
0848 unsigned char brg;
0849 volatile m8260SMCparms_t *smcparms = 0;
0850 volatile m8260SMCRegisters_t *smcregs = 0;
0851
0852
0853
0854
0855 if ( (minor < SMC1_MINOR) || (minor > SMC2_MINOR) )
0856 return;
0857
0858
0859 if( minor == SMC1_MINOR )
0860 brg = m8xx_get_brg(M8260_SMC1_BRGS, 9600*16);
0861 else
0862 brg = m8xx_get_brg(M8260_SMC2_BRGS, 9600*16);
0863 (void) brg;
0864
0865
0866
0867
0868 RxBd[minor] = m8xx_bd_allocate (1);
0869 TxBd[minor] = m8xx_bd_allocate (1);
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881 switch (minor) {
0882 case SMC1_MINOR:
0883 smcparms = &m8260.smc1p;
0884 smcregs = &m8260.smc1;
0885
0886 #if 0
0887 m8260.pbpar |= 0x000000C0;
0888 m8260.pbdir &= ~0x000000C0;
0889 m8260.pbodr &= ~0x000000C0;
0890
0891 m8260.simode &= 0xFFFF0FFF;
0892 m8260.simode |= brg << 12;
0893 #endif
0894 break;
0895
0896 case SMC2_MINOR:
0897 smcparms = &m8260.smc2p;
0898 smcregs = &m8260.smc2;
0899 #if 0
0900 m8260.pbpar |= 0x00000C00;
0901 m8260.pbdir &= ~0x00000C00;
0902 m8260.pbodr &= ~0x00000C00;
0903
0904 m8260.simode &= 0x0FFFFFFF;
0905 m8260.simode |= brg << 28;
0906 #endif
0907 break;
0908 }
0909
0910
0911
0912
0913 smcparms->rbase = (char *)RxBd[minor] - (char *)&m8260;
0914 smcparms->tbase = (char *)TxBd[minor] - (char *)&m8260;
0915 smcparms->rfcr = M8260_RFCR_MOT | M8260_RFCR_60X_BUS;
0916 smcparms->tfcr = M8260_TFCR_MOT | M8260_TFCR_60X_BUS;
0917 if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 )
0918 smcparms->mrblr = RXBUFSIZE;
0919 else
0920 smcparms->mrblr = 1;
0921
0922
0923
0924
0925 smcparms->un.uart.max_idl = 10;
0926 smcparms->un.uart.brkcr = 0;
0927 smcparms->un.uart.brkec = 0;
0928
0929
0930
0931
0932 RxBd[minor]->status = M8260_BD_EMPTY | M8260_BD_WRAP | M8260_BD_INTERRUPT;
0933 RxBd[minor]->length = 0;
0934 RxBd[minor]->buffer = rxBuf[minor];
0935
0936
0937
0938
0939 TxBd[minor]->status = M8260_BD_WRAP;
0940
0941
0942
0943
0944 smcregs->smce = ~0;
0945 smcregs->smcm = 0;
0946 smcregs->smcmr = M8260_SMCMR_CLEN(9) | M8260_SMCMR_SM_UART;
0947
0948
0949
0950
0951 switch (minor) {
0952 case SMC1_MINOR:
0953 m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SMC1);
0954 break;
0955
0956 case SMC2_MINOR:
0957 m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SMC2);
0958 break;
0959 }
0960
0961
0962
0963
0964 smcregs->smcmr |= M8260_SMCMR_TEN | M8260_SMCMR_REN;
0965 if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
0966 consoleIrqData.on = m8xx_smc_enable;
0967 consoleIrqData.off = m8xx_smc_disable;
0968 consoleIrqData.isOn = m8xx_smc_isOn;
0969 switch (minor) {
0970 case SMC1_MINOR:
0971 consoleIrqData.name = BSP_CPM_IRQ_SMC1;
0972 consoleIrqData.hdl = m8xx_smc1_interrupt_handler;
0973 break;
0974
0975 case SMC2_MINOR:
0976 consoleIrqData.name = BSP_CPM_IRQ_SMC2;
0977 consoleIrqData.hdl = m8xx_smc2_interrupt_handler;
0978 break;
0979 #if 0
0980 case SMC1_MINOR:
0981 rtems_interrupt_catch (m8xx_smc1_interrupt_handler,
0982 PPC_IRQ_CPM_SMC1,
0983 &old_handler[minor]);
0984
0985 smcregs->smcm = 3;
0986 m8260.sipnr_l |= M8260_SIMASK_SMC1;
0987 m8260.simr_l |= M8260_SIMASK_SMC1;
0988 break;
0989
0990 case SMC2_MINOR:
0991 rtems_interrupt_catch (m8xx_smc2_interrupt_handler,
0992 PPC_IRQ_CPM_SMC2,
0993 &old_handler[minor]);
0994
0995 smcregs->smcm = 3;
0996 m8260.sipnr_l |= M8260_SIMASK_SMC2;
0997 m8260.simr_l |= M8260_SIMASK_SMC2;
0998 break;
0999 #endif
1000 }
1001 if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
1002 printk("Unable to connect SMC Irq handler\n");
1003 rtems_fatal_error_occurred(1);
1004 }
1005 }
1006 }
1007
1008 void
1009 m8xx_uart_initialize(void)
1010 {
1011 }
1012
1013 void
1014 m8xx_uart_interrupts_initialize(void)
1015 {
1016 #ifdef mpc8260
1017
1018
1019 #else
1020
1021 #if defined(mpc860)
1022 m8xx.cicr = 0x00E43F80;
1023
1024 #else
1025 m8xx.cicr = 0x00043F80;
1026 #endif
1027 m8xx.simask |= M8xx_SIMASK_LVM1;
1028 #endif
1029 }
1030
1031 int
1032 m8xx_uart_pollRead(
1033 int minor
1034 )
1035 {
1036 unsigned char c;
1037
1038 if (RxBd[minor]->status & M8260_BD_EMPTY) {
1039 return -1;
1040 }
1041 rtems_cache_invalidate_multiple_data_lines(
1042 (const void *) RxBd[minor]->buffer,
1043 RxBd[minor]->length
1044 );
1045 c = ((char *)RxBd[minor]->buffer)[0];
1046 RxBd[minor]->status = M8260_BD_EMPTY | M8260_BD_WRAP;
1047 return c;
1048 }
1049
1050
1051
1052
1053 ssize_t
1054 m8xx_uart_write(
1055 int minor,
1056 const char *buf,
1057 size_t len
1058 )
1059 {
1060 if (len > 0) {
1061 while( (TxBd[minor]->status) & M8260_BD_READY );
1062
1063 rtems_cache_flush_multiple_data_lines( buf, len );
1064 TxBd[minor]->buffer = (char *) buf;
1065 TxBd[minor]->length = len;
1066 TxBd[minor]->status = M8260_BD_READY | M8260_BD_WRAP | M8260_BD_INTERRUPT;
1067 }
1068
1069 return 0;
1070 }
1071
1072 ssize_t
1073 m8xx_uart_pollWrite(
1074 int minor,
1075 const char *buf,
1076 size_t len
1077 )
1078 {
1079 size_t retval = len;
1080
1081 while (len--) {
1082 while (TxBd[minor]->status & M8260_BD_READY)
1083 continue;
1084 txBuf[minor] = *buf++;
1085 rtems_cache_flush_multiple_data_lines( (void *)&txBuf[minor], 1 );
1086 TxBd[minor]->buffer = &txBuf[minor];
1087 TxBd[minor]->length = 1;
1088 TxBd[minor]->status = M8260_BD_READY | M8260_BD_WRAP;
1089 }
1090
1091 return retval;
1092 }