static void cyg_hal_plf_smcx_init_channel(struct port_info *info, int cpm_page) { unsigned int rxbase, txbase; int i; struct cp_bufdesc *rxbd, *txbd; volatile struct smc_regs_8260 *regs = (volatile struct smc_regs_8260*)((char *)IMM + info->regs); t_Smc_Pram *uart_pram = (t_Smc_Pram *)((char *)IMM + info->pram); if (info->init) return; info->init = 1; // Make sure device is stopped while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); IMM->cpm_cpcr = cpm_page | CPCR_STOP_TX | CPCR_FLG; /* ISSUE COMMAND */ while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); // Allocate buffer descriptors + buffers (adjacent to descriptors) rxbase = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*info->Rxnum + info->Rxnum); txbase = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*info->Txnum + info->Txnum); // setup RX buffer descriptors rxbd = (struct cp_bufdesc *)((char *)IMM + rxbase); info->next_rxbd = rxbd; for (i = 0; i < info->Rxnum; i++) { rxbd->length = 0; rxbd->buffer = ((char *)IMM + (rxbase+(info->Rxnum*sizeof(struct cp_bufdesc))))+i; rxbd->ctrl = _BD_CTL_Ready | _BD_CTL_Int; rxbd++; } rxbd--; rxbd->ctrl |= _BD_CTL_Wrap; // setup TX buffer descriptor txbd = (struct cp_bufdesc *)((char *)IMM + txbase); txbd->length = 1; txbd->buffer = ((char *)IMM + (txbase+(info->Txnum*sizeof(struct cp_bufdesc)))); txbd->ctrl = _BD_CTL_Wrap; // Set the baud rate generator. Note: on the MPC8xxx, // there are a number of BRGs, but the usage/layout is // somewhat restricted, so we rely on a fixed mapping. // See the setup in the platform init code for details. *(unsigned long *)((char *)IMM + info->brg) = 0x00010000 | (UART_BIT_RATE(UART_BAUD_RATE) << 1); // Rx, Tx function codes (used for access) uart_pram->rfcr = 0x18; uart_pram->tfcr = 0x18; // Pointers to Rx & Tx buffer descriptor rings uart_pram->rbase = rxbase; uart_pram->tbase = txbase; // Max receive buffer length uart_pram->mrblr = 1; // Mode register for 8N1 regs->smc_smcmr = 0x4823; // Clear events regs->smc_smce = 0xFF; regs->smc_smcm = SMCE_Rx; // Init channel while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); IMM->cpm_cpcr = cpm_page | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG; /* ISSUE COMMAND */ while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); }
// Function to initialize the device. Called at bootstrap time. static bool mpc8xxx_sxx_serial_init(struct cyg_devtab_entry *tab) { serial_channel *chan = (serial_channel *)tab->priv; mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv; int TxBD, RxBD; int cache_state; HAL_DCACHE_IS_ENABLED(cache_state); HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); #ifdef CYGDBG_IO_INIT diag_printf("MPC8XXX_SMC SERIAL init - dev: %x.%d = %s\n", smc_chan->channel, smc_chan->int_num, tab->name); #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1 if (chan == &mpc8xxx_sxx_serial_channel_smc1) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM); mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc1, (t_Smc_Pram *)((char *)IMM + DPRAM_SMC1_OFFSET), &IMM->smc_regs[SMC1], (unsigned long *)&IMM->brgs_brgc7, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE, &mpc8xxx_smc1_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE, &mpc8xxx_smc1_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2 #warning "Serial driver on SMC2 is unverified" if (chan == &mpc8xxx_sxx_serial_channel_smc2) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM); mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc2, &IMM->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM &IMM->smc_regs[1], // Control registers &IMM->brgs_brgc7, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE, &mpc8xxx_smc2_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE, &mpc8xxx_smc2_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1 if (chan == &mpc8xxx_sxx_serial_channel_scc1) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM); mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc1, &IMM->pram.serials.scc_pram[SCC1], &IMM->scc_regs[SCC1], (unsigned long *)&IMM->brgs_brgc1, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE, &mpc8xxx_scc1_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE, &mpc8xxx_scc1_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2 #warning "Serial driver on SCC2 is unverified" if (chan == &mpc8xxx_sxx_serial_channel_scc2) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM); mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc2, &IMM->pram[1].scc.pscc.u, // PRAM &IMM->scc_regs[1], // Control registers &IMM->brgs_brgc2, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE, &mpc8xxx_scc2_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE, &mpc8xxx_scc2_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3 #warning "Serial driver on SCC3 is unverified" if (chan == &mpc8xxx_sxx_serial_channel_scc3) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM); mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc3, &IMM->pram[2].scc.pscc.u, // PRAM &IMM->scc_regs[2], // Control registersn &IMM->brgs_brgc3, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE, &mpc8xxx_scc3_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE, &mpc8xxx_scc3_rxbuf[0] ); } #endif (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices if (chan->out_cbuf.len != 0) { cyg_drv_interrupt_create(smc_chan->int_num, 0, // Priority - unused (but asserted) (cyg_addrword_t)chan, // Data item passed to interrupt handler mpc8xxx_sxx_serial_ISR, mpc8xxx_sxx_serial_DSR, &smc_chan->serial_interrupt_handle, &smc_chan->serial_interrupt); cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle); cyg_drv_interrupt_unmask(smc_chan->int_num); } if (smc_chan->type == _SMC_CHAN) { mpc8xxx_smc_serial_config_port(chan, &chan->config, true); } else { mpc8xxx_scc_serial_config_port(chan, &chan->config, true); } if (cache_state) HAL_DCACHE_ENABLE(); return true; }
static void cyg_hal_plf_sccx_init_channel(struct port_info *info, int cpm_page) { unsigned int rxbase, txbase; int i; struct cp_bufdesc *rxbd, *txbd; volatile struct scc_regs_8260 *regs = (volatile struct scc_regs_8260*)((char *)IMM + info->regs); volatile t_Scc_Pram *pram = (volatile t_Scc_Pram *)((char *)IMM + info->pram); if (info->init) return; info->init = 1; // Make sure device is stopped regs->gsmr_l &= DISABLE_TX_RX; while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); IMM->cpm_cpcr = cpm_page | CPCR_STOP_TX | CPCR_FLG; /* ISSUE COMMAND */ while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); // Allocate buffer descriptors + buffers (adjacent to descriptors) rxbase = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*info->Rxnum + info->Rxnum); txbase = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*info->Txnum + info->Txnum); // setup RX buffer descriptors rxbd = (struct cp_bufdesc *)((char *)IMM + rxbase); info->next_rxbd = rxbd; for (i = 0; i < info->Rxnum; i++) { rxbd->length = 0; rxbd->buffer = ((char *)IMM + (rxbase+(info->Rxnum*sizeof(struct cp_bufdesc))))+i; rxbd->ctrl = _BD_CTL_Ready | _BD_CTL_Int; rxbd++; } rxbd--; rxbd->ctrl |= _BD_CTL_Wrap; // setup TX buffer descriptor txbd = (struct cp_bufdesc *)((char *)IMM + txbase); txbd->length = 1; txbd->buffer = ((char *)IMM + (txbase+(info->Txnum*sizeof(struct cp_bufdesc)))); txbd->ctrl = _BD_CTL_Wrap; // Set the baud rate generator. Note: on the MPC8xxx, // there are a number of BRGs, but the usage/layout is // somewhat restricted, so we rely on a fixed mapping. // See the setup in the platform init code for details. *(unsigned long *)((char *)IMM + info->brg) = 0x00010000 | (UART_BIT_RATE(UART_BAUD_RATE) << 1); // Rx, Tx function codes (used for access) pram->rfcr = 0x18; pram->tfcr = 0x18; regs->psmr = 0xB000; // Pointers to Rx & Tx buffer descriptor rings pram->rbase = rxbase; pram->tbase = txbase; // Max receive buffer length pram->mrblr = 1; // Mode register for 8N1 regs->gsmr_h = 0x00000060; regs->gsmr_l = 0x00028004; // Clear events regs->scce = ALL_ONES; regs->sccm = SCCE_Rx; // Init channel while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); IMM->cpm_cpcr = cpm_page | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG; /* ISSUE COMMAND */ while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); /*-------------------------------------------------------------*/ /* Set the ENT/ENR bits in the GSMR -- Enable Transmit/Receive */ /*-------------------------------------------------------------*/ regs->gsmr_l |= GSMR_L1_ENT | GSMR_L1_ENR; #if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) // Fill out the control Character Table. Make the first entry // an end of table line. // cc[0] = 0x4003 ==> reject if char = 0x3, write to RCCR pram->SpecificProtocol.u.cc[0] = 0x4003; { int i; for (i = 0; i < 8; i++){ pram->SpecificProtocol.u.cc[i] = 0x8000; } } pram->SpecificProtocol.u.rccm = 0xc000; #endif }