Lines Matching +full:ucc +full:- +full:hdlc

1 // SPDX-License-Identifier: GPL-2.0
12 #include <linux/dma-mapping.h>
14 #include <linux/hdlc.h>
55 /* UCC Extended Mode Register (8 bits, QE only) */
64 /* Tx time-slot assignment table pointer (16 bits) */
76 /* Rx time-slot assignment table pointer (16 bits) */
92 /* A reserved area (0xB0 -> 0xC3) that must be initialized to 0 (QE only) */
129 /* Zero-insertion state (32 bits) */
135 /* HDLC: Maximum frame length register (16 bits) */
247 u32 zdstate_hdlc; /* Initial ZDSTATE value (HDLC mode) */
322 return qmc->data->version == QMC_QE; in qmc_is_qe()
334 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &tsa_info); in qmc_chan_get_info()
338 spin_lock_irqsave(&chan->ts_lock, flags); in qmc_chan_get_info()
340 info->mode = chan->mode; in qmc_chan_get_info()
341 info->rx_fs_rate = tsa_info.rx_fs_rate; in qmc_chan_get_info()
342 info->rx_bit_rate = tsa_info.rx_bit_rate; in qmc_chan_get_info()
343 info->nb_tx_ts = hweight64(chan->tx_ts_mask); in qmc_chan_get_info()
344 info->tx_fs_rate = tsa_info.tx_fs_rate; in qmc_chan_get_info()
345 info->tx_bit_rate = tsa_info.tx_bit_rate; in qmc_chan_get_info()
346 info->nb_rx_ts = hweight64(chan->rx_ts_mask); in qmc_chan_get_info()
348 spin_unlock_irqrestore(&chan->ts_lock, flags); in qmc_chan_get_info()
358 spin_lock_irqsave(&chan->ts_lock, flags); in qmc_chan_get_ts_info()
360 ts_info->rx_ts_mask_avail = chan->rx_ts_mask_avail; in qmc_chan_get_ts_info()
361 ts_info->tx_ts_mask_avail = chan->tx_ts_mask_avail; in qmc_chan_get_ts_info()
362 ts_info->rx_ts_mask = chan->rx_ts_mask; in qmc_chan_get_ts_info()
363 ts_info->tx_ts_mask = chan->tx_ts_mask; in qmc_chan_get_ts_info()
365 spin_unlock_irqrestore(&chan->ts_lock, flags); in qmc_chan_get_ts_info()
377 if ((ts_info->rx_ts_mask & chan->rx_ts_mask_avail) != ts_info->rx_ts_mask) in qmc_chan_set_ts_info()
378 return -EINVAL; in qmc_chan_set_ts_info()
379 if ((ts_info->tx_ts_mask & chan->tx_ts_mask_avail) != ts_info->tx_ts_mask) in qmc_chan_set_ts_info()
380 return -EINVAL; in qmc_chan_set_ts_info()
383 if (chan->qmc->is_tsa_64rxtx) { in qmc_chan_set_ts_info()
384 if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) in qmc_chan_set_ts_info()
385 return -EINVAL; in qmc_chan_set_ts_info()
388 spin_lock_irqsave(&chan->ts_lock, flags); in qmc_chan_set_ts_info()
390 if ((chan->tx_ts_mask != ts_info->tx_ts_mask && !chan->is_tx_stopped) || in qmc_chan_set_ts_info()
391 (chan->rx_ts_mask != ts_info->rx_ts_mask && !chan->is_rx_stopped)) { in qmc_chan_set_ts_info()
392 dev_err(chan->qmc->dev, "Channel rx and/or tx not stopped\n"); in qmc_chan_set_ts_info()
393 ret = -EBUSY; in qmc_chan_set_ts_info()
395 chan->tx_ts_mask = ts_info->tx_ts_mask; in qmc_chan_set_ts_info()
396 chan->rx_ts_mask = ts_info->rx_ts_mask; in qmc_chan_set_ts_info()
399 spin_unlock_irqrestore(&chan->ts_lock, flags); in qmc_chan_set_ts_info()
407 if (param->mode != chan->mode) in qmc_chan_set_param()
408 return -EINVAL; in qmc_chan_set_param()
410 switch (param->mode) { in qmc_chan_set_param()
412 if (param->hdlc.max_rx_buf_size % 4 || in qmc_chan_set_param()
413 param->hdlc.max_rx_buf_size < 8) in qmc_chan_set_param()
414 return -EINVAL; in qmc_chan_set_param()
416 qmc_write16(chan->qmc->scc_pram + QMC_GBL_MRBLR, in qmc_chan_set_param()
417 param->hdlc.max_rx_buf_size - 8); in qmc_chan_set_param()
418 qmc_write16(chan->s_param + QMC_SPE_MFLR, in qmc_chan_set_param()
419 param->hdlc.max_rx_frame_size); in qmc_chan_set_param()
420 if (param->hdlc.is_crc32) { in qmc_chan_set_param()
421 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, in qmc_chan_set_param()
424 qmc_clrbits16(chan->s_param + QMC_SPE_CHAMR, in qmc_chan_set_param()
430 qmc_write16(chan->s_param + QMC_SPE_TMRBLR, in qmc_chan_set_param()
431 param->transp.max_rx_buf_size); in qmc_chan_set_param()
435 return -EINVAL; in qmc_chan_set_param()
459 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_write_submit()
460 bd = chan->txbd_free; in qmc_chan_write_submit()
462 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_write_submit()
465 ret = -EBUSY; in qmc_chan_write_submit()
469 qmc_write16(&bd->cbd_datlen, length); in qmc_chan_write_submit()
470 qmc_write32(&bd->cbd_bufaddr, addr); in qmc_chan_write_submit()
472 xfer_desc = &chan->tx_desc[bd - chan->txbds]; in qmc_chan_write_submit()
473 xfer_desc->tx_complete = complete; in qmc_chan_write_submit()
474 xfer_desc->context = context; in qmc_chan_write_submit()
479 qmc_write16(&bd->cbd_sc, ctrl); in qmc_chan_write_submit()
481 if (!chan->is_tx_stopped) in qmc_chan_write_submit()
482 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_POL); in qmc_chan_write_submit()
485 chan->txbd_free = chan->txbds; in qmc_chan_write_submit()
487 chan->txbd_free++; in qmc_chan_write_submit()
492 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_write_submit()
514 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_write_done()
515 bd = chan->txbd_done; in qmc_chan_write_done()
517 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_write_done()
522 xfer_desc = &chan->tx_desc[bd - chan->txbds]; in qmc_chan_write_done()
523 complete = xfer_desc->tx_complete; in qmc_chan_write_done()
524 context = xfer_desc->context; in qmc_chan_write_done()
525 xfer_desc->tx_complete = NULL; in qmc_chan_write_done()
526 xfer_desc->context = NULL; in qmc_chan_write_done()
528 qmc_write16(&bd->cbd_sc, ctrl & ~QMC_BD_TX_UB); in qmc_chan_write_done()
531 chan->txbd_done = chan->txbds; in qmc_chan_write_done()
533 chan->txbd_done++; in qmc_chan_write_done()
536 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_write_done()
538 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_write_done()
541 bd = chan->txbd_done; in qmc_chan_write_done()
542 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_write_done()
546 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_write_done()
567 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_read_submit()
568 bd = chan->rxbd_free; in qmc_chan_read_submit()
570 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_read_submit()
573 ret = -EBUSY; in qmc_chan_read_submit()
577 qmc_write16(&bd->cbd_datlen, 0); /* data length is updated by the QMC */ in qmc_chan_read_submit()
578 qmc_write32(&bd->cbd_bufaddr, addr); in qmc_chan_read_submit()
580 xfer_desc = &chan->rx_desc[bd - chan->rxbds]; in qmc_chan_read_submit()
581 xfer_desc->rx_complete = complete; in qmc_chan_read_submit()
582 xfer_desc->context = context; in qmc_chan_read_submit()
591 qmc_write16(&bd->cbd_sc, ctrl); in qmc_chan_read_submit()
594 if (chan->is_rx_halted && !chan->is_rx_stopped) { in qmc_chan_read_submit()
596 qmc_write32(chan->s_param + QMC_SPE_RPACK, chan->qmc->data->rpack); in qmc_chan_read_submit()
597 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, in qmc_chan_read_submit()
598 chan->mode == QMC_TRANSPARENT ? in qmc_chan_read_submit()
599 chan->qmc->data->zdstate_transp : in qmc_chan_read_submit()
600 chan->qmc->data->zdstate_hdlc); in qmc_chan_read_submit()
601 qmc_write32(chan->s_param + QMC_SPE_RSTATE, chan->qmc->data->rstate); in qmc_chan_read_submit()
602 chan->is_rx_halted = false; in qmc_chan_read_submit()
604 chan->rx_pending++; in qmc_chan_read_submit()
607 chan->rxbd_free = chan->rxbds; in qmc_chan_read_submit()
609 chan->rxbd_free++; in qmc_chan_read_submit()
613 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_read_submit()
636 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_read_done()
637 bd = chan->rxbd_done; in qmc_chan_read_done()
639 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_read_done()
644 xfer_desc = &chan->rx_desc[bd - chan->rxbds]; in qmc_chan_read_done()
645 complete = xfer_desc->rx_complete; in qmc_chan_read_done()
646 context = xfer_desc->context; in qmc_chan_read_done()
647 xfer_desc->rx_complete = NULL; in qmc_chan_read_done()
648 xfer_desc->context = NULL; in qmc_chan_read_done()
650 datalen = qmc_read16(&bd->cbd_datlen); in qmc_chan_read_done()
651 qmc_write16(&bd->cbd_sc, ctrl & ~QMC_BD_RX_UB); in qmc_chan_read_done()
654 chan->rxbd_done = chan->rxbds; in qmc_chan_read_done()
656 chan->rxbd_done++; in qmc_chan_read_done()
658 chan->rx_pending--; in qmc_chan_read_done()
661 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_read_done()
666 * -> Be sure that the software API flags are consistent in qmc_chan_read_done()
679 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_read_done()
682 bd = chan->rxbd_done; in qmc_chan_read_done()
683 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_read_done()
687 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_read_done()
701 if (chan->tx_ts_mask != chan->rx_ts_mask) { in qmc_chan_setup_tsa_64rxtx()
702 dev_err(chan->qmc->dev, "chan %u uses different Rx and Tx TS\n", chan->id); in qmc_chan_setup_tsa_64rxtx()
703 return -EINVAL; in qmc_chan_setup_tsa_64rxtx()
706 val = QMC_TSA_VALID | QMC_TSA_MASK_8BIT | QMC_TSA_CHANNEL(chan->id); in qmc_chan_setup_tsa_64rxtx()
709 for (i = 0; i < info->nb_rx_ts; i++) { in qmc_chan_setup_tsa_64rxtx()
710 if (!(chan->rx_ts_mask & (((u64)1) << i))) in qmc_chan_setup_tsa_64rxtx()
713 curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2)); in qmc_chan_setup_tsa_64rxtx()
715 dev_err(chan->qmc->dev, "chan %u TxRx entry %d already used\n", in qmc_chan_setup_tsa_64rxtx()
716 chan->id, i); in qmc_chan_setup_tsa_64rxtx()
717 return -EBUSY; in qmc_chan_setup_tsa_64rxtx()
722 for (i = 0; i < info->nb_rx_ts; i++) { in qmc_chan_setup_tsa_64rxtx()
723 if (!(chan->rx_ts_mask & (((u64)1) << i))) in qmc_chan_setup_tsa_64rxtx()
726 qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), in qmc_chan_setup_tsa_64rxtx()
742 val = QMC_TSA_VALID | QMC_TSA_MASK_8BIT | QMC_TSA_CHANNEL(chan->id); in qmc_chan_setup_tsa_32rx()
745 for (i = 0; i < info->nb_rx_ts; i++) { in qmc_chan_setup_tsa_32rx()
746 if (!(chan->rx_ts_mask & (((u64)1) << i))) in qmc_chan_setup_tsa_32rx()
749 curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2)); in qmc_chan_setup_tsa_32rx()
751 dev_err(chan->qmc->dev, "chan %u Rx entry %d already used\n", in qmc_chan_setup_tsa_32rx()
752 chan->id, i); in qmc_chan_setup_tsa_32rx()
753 return -EBUSY; in qmc_chan_setup_tsa_32rx()
758 for (i = 0; i < info->nb_rx_ts; i++) { in qmc_chan_setup_tsa_32rx()
759 if (!(chan->rx_ts_mask & (((u64)1) << i))) in qmc_chan_setup_tsa_32rx()
762 qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), in qmc_chan_setup_tsa_32rx()
778 val = QMC_TSA_VALID | QMC_TSA_MASK_8BIT | QMC_TSA_CHANNEL(chan->id); in qmc_chan_setup_tsa_32tx()
781 for (i = 0; i < info->nb_tx_ts; i++) { in qmc_chan_setup_tsa_32tx()
782 if (!(chan->tx_ts_mask & (((u64)1) << i))) in qmc_chan_setup_tsa_32tx()
785 curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2)); in qmc_chan_setup_tsa_32tx()
787 dev_err(chan->qmc->dev, "chan %u Tx entry %d already used\n", in qmc_chan_setup_tsa_32tx()
788 chan->id, i); in qmc_chan_setup_tsa_32tx()
789 return -EBUSY; in qmc_chan_setup_tsa_32tx()
794 for (i = 0; i < info->nb_tx_ts; i++) { in qmc_chan_setup_tsa_32tx()
795 if (!(chan->tx_ts_mask & (((u64)1) << i))) in qmc_chan_setup_tsa_32tx()
798 qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), in qmc_chan_setup_tsa_32tx()
811 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &info); in qmc_chan_setup_tsa_tx()
816 if (chan->qmc->is_tsa_64rxtx) in qmc_chan_setup_tsa_tx()
828 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &info); in qmc_chan_setup_tsa_rx()
833 if (chan->qmc->is_tsa_64rxtx) in qmc_chan_setup_tsa_rx()
841 return cpm_command(chan->id << 2, (qmc_opcode << 4) | 0x0E); in qmc_chan_cpm1_command()
846 if (!qe_issue_cmd(cmd, chan->qmc->qe_subblock, chan->id, 0)) in qmc_chan_qe_command()
847 return -EIO; in qmc_chan_qe_command()
856 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_stop_rx()
858 if (chan->is_rx_stopped) { in qmc_chan_stop_rx()
859 /* The channel is already stopped -> simply return ok */ in qmc_chan_stop_rx()
865 ret = qmc_is_qe(chan->qmc) ? in qmc_chan_stop_rx()
869 dev_err(chan->qmc->dev, "chan %u: Send STOP RECEIVE failed (%d)\n", in qmc_chan_stop_rx()
870 chan->id, ret); in qmc_chan_stop_rx()
874 chan->is_rx_stopped = true; in qmc_chan_stop_rx()
876 if (!chan->qmc->is_tsa_64rxtx || chan->is_tx_stopped) { in qmc_chan_stop_rx()
879 dev_err(chan->qmc->dev, "chan %u: Disable tsa entries failed (%d)\n", in qmc_chan_stop_rx()
880 chan->id, ret); in qmc_chan_stop_rx()
886 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_stop_rx()
895 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_stop_tx()
897 if (chan->is_tx_stopped) { in qmc_chan_stop_tx()
898 /* The channel is already stopped -> simply return ok */ in qmc_chan_stop_tx()
904 ret = qmc_is_qe(chan->qmc) ? in qmc_chan_stop_tx()
908 dev_err(chan->qmc->dev, "chan %u: Send STOP TRANSMIT failed (%d)\n", in qmc_chan_stop_tx()
909 chan->id, ret); in qmc_chan_stop_tx()
913 chan->is_tx_stopped = true; in qmc_chan_stop_tx()
915 if (!chan->qmc->is_tsa_64rxtx || chan->is_rx_stopped) { in qmc_chan_stop_tx()
918 dev_err(chan->qmc->dev, "chan %u: Disable tsa entries failed (%d)\n", in qmc_chan_stop_tx()
919 chan->id, ret); in qmc_chan_stop_tx()
925 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_stop_tx()
937 spin_lock_irqsave(&chan->ts_lock, flags); in qmc_chan_stop()
940 is_rx_rollback_needed = !chan->is_rx_stopped; in qmc_chan_stop()
957 spin_unlock_irqrestore(&chan->ts_lock, flags); in qmc_chan_stop()
971 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &info); in qmc_setup_chan_trnsync()
975 w_rx = hweight64(chan->rx_ts_mask); in qmc_setup_chan_trnsync()
976 w_tx = hweight64(chan->tx_ts_mask); in qmc_setup_chan_trnsync()
978 dev_dbg(qmc->dev, "only one or zero ts -> disable trnsync\n"); in qmc_setup_chan_trnsync()
979 qmc_clrbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_TRANSP_SYNC); in qmc_setup_chan_trnsync()
984 first_rx = chan->rx_ts_mask ? __ffs64(chan->rx_ts_mask) + 1 : 0; in qmc_setup_chan_trnsync()
987 last_tx = fls64(chan->tx_ts_mask); in qmc_setup_chan_trnsync()
995 qmc_write16(chan->s_param + QMC_SPE_TRNSYNC, trnsync); in qmc_setup_chan_trnsync()
996 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_TRANSP_SYNC); in qmc_setup_chan_trnsync()
998 dev_dbg(qmc->dev, "chan %u: trnsync=0x%04x, rx %u/%u 0x%llx, tx %u/%u 0x%llx\n", in qmc_setup_chan_trnsync()
999 chan->id, trnsync, in qmc_setup_chan_trnsync()
1000 first_rx, info.nb_rx_ts, chan->rx_ts_mask, in qmc_setup_chan_trnsync()
1001 last_tx, info.nb_tx_ts, chan->tx_ts_mask); in qmc_setup_chan_trnsync()
1011 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_start_rx()
1013 if (!chan->is_rx_stopped) { in qmc_chan_start_rx()
1014 /* The channel is already started -> simply return ok */ in qmc_chan_start_rx()
1021 dev_err(chan->qmc->dev, "chan %u: Enable tsa entries failed (%d)\n", in qmc_chan_start_rx()
1022 chan->id, ret); in qmc_chan_start_rx()
1026 if (chan->mode == QMC_TRANSPARENT) { in qmc_chan_start_rx()
1027 ret = qmc_setup_chan_trnsync(chan->qmc, chan); in qmc_chan_start_rx()
1029 dev_err(chan->qmc->dev, "chan %u: setup TRNSYNC failed (%d)\n", in qmc_chan_start_rx()
1030 chan->id, ret); in qmc_chan_start_rx()
1036 qmc_write32(chan->s_param + QMC_SPE_RPACK, chan->qmc->data->rpack); in qmc_chan_start_rx()
1037 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, in qmc_chan_start_rx()
1038 chan->mode == QMC_TRANSPARENT ? in qmc_chan_start_rx()
1039 chan->qmc->data->zdstate_transp : in qmc_chan_start_rx()
1040 chan->qmc->data->zdstate_hdlc); in qmc_chan_start_rx()
1041 qmc_write32(chan->s_param + QMC_SPE_RSTATE, chan->qmc->data->rstate); in qmc_chan_start_rx()
1042 chan->is_rx_halted = false; in qmc_chan_start_rx()
1044 chan->is_rx_stopped = false; in qmc_chan_start_rx()
1047 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_start_rx()
1056 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_start_tx()
1058 if (!chan->is_tx_stopped) { in qmc_chan_start_tx()
1059 /* The channel is already started -> simply return ok */ in qmc_chan_start_tx()
1066 dev_err(chan->qmc->dev, "chan %u: Enable tsa entries failed (%d)\n", in qmc_chan_start_tx()
1067 chan->id, ret); in qmc_chan_start_tx()
1071 if (chan->mode == QMC_TRANSPARENT) { in qmc_chan_start_tx()
1072 ret = qmc_setup_chan_trnsync(chan->qmc, chan); in qmc_chan_start_tx()
1074 dev_err(chan->qmc->dev, "chan %u: setup TRNSYNC failed (%d)\n", in qmc_chan_start_tx()
1075 chan->id, ret); in qmc_chan_start_tx()
1084 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_ENT); in qmc_chan_start_tx()
1087 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_POL); in qmc_chan_start_tx()
1089 chan->is_tx_stopped = false; in qmc_chan_start_tx()
1092 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_start_tx()
1102 spin_lock_irqsave(&chan->ts_lock, flags); in qmc_chan_start()
1105 is_rx_rollback_needed = chan->is_rx_stopped; in qmc_chan_start()
1122 spin_unlock_irqrestore(&chan->ts_lock, flags); in qmc_chan_start()
1134 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_reset_rx()
1135 bd = chan->rxbds; in qmc_chan_reset_rx()
1137 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_reset_rx()
1138 qmc_write16(&bd->cbd_sc, ctrl & ~(QMC_BD_RX_UB | QMC_BD_RX_E)); in qmc_chan_reset_rx()
1140 xfer_desc = &chan->rx_desc[bd - chan->rxbds]; in qmc_chan_reset_rx()
1141 xfer_desc->rx_complete = NULL; in qmc_chan_reset_rx()
1142 xfer_desc->context = NULL; in qmc_chan_reset_rx()
1147 chan->rxbd_free = chan->rxbds; in qmc_chan_reset_rx()
1148 chan->rxbd_done = chan->rxbds; in qmc_chan_reset_rx()
1149 qmc_write16(chan->s_param + QMC_SPE_RBPTR, in qmc_chan_reset_rx()
1150 qmc_read16(chan->s_param + QMC_SPE_RBASE)); in qmc_chan_reset_rx()
1152 chan->rx_pending = 0; in qmc_chan_reset_rx()
1154 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_reset_rx()
1164 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_reset_tx()
1166 /* Disable transmitter. It will be re-enable on qmc_chan_start() */ in qmc_chan_reset_tx()
1167 qmc_clrbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_ENT); in qmc_chan_reset_tx()
1169 bd = chan->txbds; in qmc_chan_reset_tx()
1171 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_reset_tx()
1172 qmc_write16(&bd->cbd_sc, ctrl & ~(QMC_BD_TX_UB | QMC_BD_TX_R)); in qmc_chan_reset_tx()
1174 xfer_desc = &chan->tx_desc[bd - chan->txbds]; in qmc_chan_reset_tx()
1175 xfer_desc->tx_complete = NULL; in qmc_chan_reset_tx()
1176 xfer_desc->context = NULL; in qmc_chan_reset_tx()
1181 chan->txbd_free = chan->txbds; in qmc_chan_reset_tx()
1182 chan->txbd_done = chan->txbds; in qmc_chan_reset_tx()
1183 qmc_write16(chan->s_param + QMC_SPE_TBPTR, in qmc_chan_reset_tx()
1184 qmc_read16(chan->s_param + QMC_SPE_TBASE)); in qmc_chan_reset_tx()
1187 qmc_write32(chan->s_param + QMC_SPE_TSTATE, chan->qmc->data->tstate); in qmc_chan_reset_tx()
1188 qmc_write32(chan->s_param + QMC_SPE_ZISTATE, chan->qmc->data->zistate); in qmc_chan_reset_tx()
1190 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_reset_tx()
1214 ret = tsa_serial_get_info(qmc->tsa_serial, &info); in qmc_check_chans()
1219 dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned not supported\n"); in qmc_check_chans()
1220 return -EINVAL; in qmc_check_chans()
1229 dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned are not equal\n"); in qmc_check_chans()
1230 return -EINVAL; in qmc_check_chans()
1234 tx_ts_assigned_mask = info.nb_tx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_tx_ts) - 1; in qmc_check_chans()
1235 rx_ts_assigned_mask = info.nb_rx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_rx_ts) - 1; in qmc_check_chans()
1237 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_check_chans()
1238 if (chan->tx_ts_mask_avail > tx_ts_assigned_mask) { in qmc_check_chans()
1239 dev_err(qmc->dev, "chan %u can use TSA unassigned Tx TS\n", chan->id); in qmc_check_chans()
1240 return -EINVAL; in qmc_check_chans()
1243 if (chan->rx_ts_mask_avail > rx_ts_assigned_mask) { in qmc_check_chans()
1244 dev_err(qmc->dev, "chan %u can use TSA unassigned Rx TS\n", chan->id); in qmc_check_chans()
1245 return -EINVAL; in qmc_check_chans()
1257 list_for_each_entry(chan, &qmc->chan_head, list) in qmc_nb_chans()
1275 dev_err(qmc->dev, "%pOF: failed to read reg\n", chan_np); in qmc_of_parse_chans()
1280 dev_err(qmc->dev, "%pOF: Invalid chan_id\n", chan_np); in qmc_of_parse_chans()
1282 return -EINVAL; in qmc_of_parse_chans()
1285 chan = devm_kzalloc(qmc->dev, sizeof(*chan), GFP_KERNEL); in qmc_of_parse_chans()
1288 return -ENOMEM; in qmc_of_parse_chans()
1291 chan->id = chan_id; in qmc_of_parse_chans()
1292 spin_lock_init(&chan->ts_lock); in qmc_of_parse_chans()
1293 spin_lock_init(&chan->rx_lock); in qmc_of_parse_chans()
1294 spin_lock_init(&chan->tx_lock); in qmc_of_parse_chans()
1296 ret = of_property_read_u64(chan_np, "fsl,tx-ts-mask", &ts_mask); in qmc_of_parse_chans()
1298 dev_err(qmc->dev, "%pOF: failed to read fsl,tx-ts-mask\n", in qmc_of_parse_chans()
1303 chan->tx_ts_mask_avail = ts_mask; in qmc_of_parse_chans()
1304 chan->tx_ts_mask = chan->tx_ts_mask_avail; in qmc_of_parse_chans()
1306 ret = of_property_read_u64(chan_np, "fsl,rx-ts-mask", &ts_mask); in qmc_of_parse_chans()
1308 dev_err(qmc->dev, "%pOF: failed to read fsl,rx-ts-mask\n", in qmc_of_parse_chans()
1313 chan->rx_ts_mask_avail = ts_mask; in qmc_of_parse_chans()
1314 chan->rx_ts_mask = chan->rx_ts_mask_avail; in qmc_of_parse_chans()
1317 ret = of_property_read_string(chan_np, "fsl,operational-mode", &mode); in qmc_of_parse_chans()
1318 if (ret && ret != -EINVAL) { in qmc_of_parse_chans()
1319 dev_err(qmc->dev, "%pOF: failed to read fsl,operational-mode\n", in qmc_of_parse_chans()
1325 chan->mode = QMC_TRANSPARENT; in qmc_of_parse_chans()
1326 } else if (!strcmp(mode, "hdlc")) { in qmc_of_parse_chans()
1327 chan->mode = QMC_HDLC; in qmc_of_parse_chans()
1329 dev_err(qmc->dev, "%pOF: Invalid fsl,operational-mode (%s)\n", in qmc_of_parse_chans()
1332 return -EINVAL; in qmc_of_parse_chans()
1335 chan->is_reverse_data = of_property_read_bool(chan_np, in qmc_of_parse_chans()
1336 "fsl,reverse-data"); in qmc_of_parse_chans()
1338 list_add_tail(&chan->list, &qmc->chan_head); in qmc_of_parse_chans()
1339 qmc->chans[chan->id] = chan; in qmc_of_parse_chans()
1353 * identical -> Used Rx related stuff to build the table in qmc_init_tsa_64rxtx()
1355 qmc->is_tsa_64rxtx = true; in qmc_init_tsa_64rxtx()
1359 qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), 0x0000); in qmc_init_tsa_64rxtx()
1362 qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATRX + ((info->nb_rx_ts - 1) * 2), in qmc_init_tsa_64rxtx()
1366 val = qmc->scc_pram_offset + QMC_GBL_TSATRX; in qmc_init_tsa_64rxtx()
1367 qmc_write16(qmc->scc_pram + QMC_GBL_RX_S_PTR, val); in qmc_init_tsa_64rxtx()
1368 qmc_write16(qmc->scc_pram + QMC_GBL_RXPTR, val); in qmc_init_tsa_64rxtx()
1369 qmc_write16(qmc->scc_pram + QMC_GBL_TX_S_PTR, val); in qmc_init_tsa_64rxtx()
1370 qmc_write16(qmc->scc_pram + QMC_GBL_TXPTR, val); in qmc_init_tsa_64rxtx()
1384 qmc->is_tsa_64rxtx = false; in qmc_init_tsa_32rx_32tx()
1388 qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), 0x0000); in qmc_init_tsa_32rx_32tx()
1389 qmc_write16(qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), 0x0000); in qmc_init_tsa_32rx_32tx()
1393 qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATRX + ((info->nb_rx_ts - 1) * 2), in qmc_init_tsa_32rx_32tx()
1395 qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATTX + ((info->nb_tx_ts - 1) * 2), in qmc_init_tsa_32rx_32tx()
1399 val = qmc->scc_pram_offset + QMC_GBL_TSATRX; in qmc_init_tsa_32rx_32tx()
1400 qmc_write16(qmc->scc_pram + QMC_GBL_RX_S_PTR, val); in qmc_init_tsa_32rx_32tx()
1401 qmc_write16(qmc->scc_pram + QMC_GBL_RXPTR, val); in qmc_init_tsa_32rx_32tx()
1404 val = qmc->scc_pram_offset + QMC_GBL_TSATTX; in qmc_init_tsa_32rx_32tx()
1405 qmc_write16(qmc->scc_pram + QMC_GBL_TX_S_PTR, val); in qmc_init_tsa_32rx_32tx()
1406 qmc_write16(qmc->scc_pram + QMC_GBL_TXPTR, val); in qmc_init_tsa_32rx_32tx()
1417 ret = tsa_serial_get_info(qmc->tsa_serial, &info); in qmc_init_tsa()
1437 chan->qmc = qmc; in qmc_setup_chan()
1440 chan->s_param = qmc->dpram + (chan->id * 64); in qmc_setup_chan()
1442 chan->txbds = qmc->bd_table + (chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)); in qmc_setup_chan()
1443 chan->rxbds = qmc->bd_table + (chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)) + QMC_NB_TXBDS; in qmc_setup_chan()
1445 chan->txbd_free = chan->txbds; in qmc_setup_chan()
1446 chan->txbd_done = chan->txbds; in qmc_setup_chan()
1447 chan->rxbd_free = chan->rxbds; in qmc_setup_chan()
1448 chan->rxbd_done = chan->rxbds; in qmc_setup_chan()
1451 val = chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS) * sizeof(cbd_t); in qmc_setup_chan()
1452 qmc_write16(chan->s_param + QMC_SPE_TBASE, val); in qmc_setup_chan()
1453 qmc_write16(chan->s_param + QMC_SPE_TBPTR, val); in qmc_setup_chan()
1456 val = ((chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)) + QMC_NB_TXBDS) * sizeof(cbd_t); in qmc_setup_chan()
1457 qmc_write16(chan->s_param + QMC_SPE_RBASE, val); in qmc_setup_chan()
1458 qmc_write16(chan->s_param + QMC_SPE_RBPTR, val); in qmc_setup_chan()
1459 qmc_write32(chan->s_param + QMC_SPE_TSTATE, chan->qmc->data->tstate); in qmc_setup_chan()
1460 qmc_write32(chan->s_param + QMC_SPE_RSTATE, chan->qmc->data->rstate); in qmc_setup_chan()
1461 qmc_write32(chan->s_param + QMC_SPE_ZISTATE, chan->qmc->data->zistate); in qmc_setup_chan()
1462 qmc_write32(chan->s_param + QMC_SPE_RPACK, chan->qmc->data->rpack); in qmc_setup_chan()
1463 if (chan->mode == QMC_TRANSPARENT) { in qmc_setup_chan()
1464 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, chan->qmc->data->zdstate_transp); in qmc_setup_chan()
1465 qmc_write16(chan->s_param + QMC_SPE_TMRBLR, 60); in qmc_setup_chan()
1467 if (chan->is_reverse_data) in qmc_setup_chan()
1469 qmc_write16(chan->s_param + QMC_SPE_CHAMR, val); in qmc_setup_chan()
1474 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, chan->qmc->data->zdstate_hdlc); in qmc_setup_chan()
1475 qmc_write16(chan->s_param + QMC_SPE_MFLR, 60); in qmc_setup_chan()
1476 qmc_write16(chan->s_param + QMC_SPE_CHAMR, in qmc_setup_chan()
1481 qmc_write16(chan->s_param + QMC_SPE_INTMSK, 0x0000); in qmc_setup_chan()
1487 bd = chan->rxbds + i; in qmc_setup_chan()
1488 qmc_write16(&bd->cbd_sc, val); in qmc_setup_chan()
1490 bd = chan->rxbds + QMC_NB_RXBDS - 1; in qmc_setup_chan()
1491 qmc_write16(&bd->cbd_sc, val | QMC_BD_RX_W); in qmc_setup_chan()
1496 if (chan->mode == QMC_HDLC) in qmc_setup_chan()
1499 bd = chan->txbds + i; in qmc_setup_chan()
1500 qmc_write16(&bd->cbd_sc, val); in qmc_setup_chan()
1502 bd = chan->txbds + QMC_NB_TXBDS - 1; in qmc_setup_chan()
1503 qmc_write16(&bd->cbd_sc, val | QMC_BD_TX_W); in qmc_setup_chan()
1513 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_setup_chans()
1527 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_finalize_chans()
1529 if (chan->mode == QMC_HDLC) { in qmc_finalize_chans()
1530 qmc_write16(chan->s_param + QMC_SPE_INTMSK, in qmc_finalize_chans()
1535 qmc_write16(chan->s_param + QMC_SPE_INTMSK, in qmc_finalize_chans()
1555 for (i = 0; i < (qmc->int_size / sizeof(u16)); i++) in qmc_setup_ints()
1556 qmc_write16(qmc->int_table + i, 0x0000); in qmc_setup_ints()
1559 if (qmc->int_size >= sizeof(u16)) { in qmc_setup_ints()
1560 last = qmc->int_table + (qmc->int_size / sizeof(u16)) - 1; in qmc_setup_ints()
1574 int_entry = qmc_read16(qmc->int_curr); in qmc_irq_gint()
1577 qmc_write16(qmc->int_curr, int_entry & QMC_INT_W); in qmc_irq_gint()
1580 chan = qmc->chans[chan_id]; in qmc_irq_gint()
1582 dev_err(qmc->dev, "interrupt on invalid chan %u\n", chan_id); in qmc_irq_gint()
1590 dev_info(qmc->dev, "intr chan %u, 0x%04x (UN)\n", chan_id, in qmc_irq_gint()
1592 chan->nb_tx_underrun++; in qmc_irq_gint()
1596 dev_info(qmc->dev, "intr chan %u, 0x%04x (BSY)\n", chan_id, in qmc_irq_gint()
1598 chan->nb_rx_busy++; in qmc_irq_gint()
1600 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_irq_gint()
1601 if (chan->rx_pending && !chan->is_rx_stopped) { in qmc_irq_gint()
1602 qmc_write32(chan->s_param + QMC_SPE_RPACK, in qmc_irq_gint()
1603 chan->qmc->data->rpack); in qmc_irq_gint()
1604 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, in qmc_irq_gint()
1605 chan->mode == QMC_TRANSPARENT ? in qmc_irq_gint()
1606 chan->qmc->data->zdstate_transp : in qmc_irq_gint()
1607 chan->qmc->data->zdstate_hdlc); in qmc_irq_gint()
1608 qmc_write32(chan->s_param + QMC_SPE_RSTATE, in qmc_irq_gint()
1609 chan->qmc->data->rstate); in qmc_irq_gint()
1610 chan->is_rx_halted = false; in qmc_irq_gint()
1612 chan->is_rx_halted = true; in qmc_irq_gint()
1614 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_irq_gint()
1622 qmc->int_curr = qmc->int_table; in qmc_irq_gint()
1624 qmc->int_curr++; in qmc_irq_gint()
1625 int_entry = qmc_read16(qmc->int_curr); in qmc_irq_gint()
1634 scce = qmc_read16(qmc->scc_regs + SCC_SCCE); in qmc_irq_handler()
1635 qmc_write16(qmc->scc_regs + SCC_SCCE, scce); in qmc_irq_handler()
1638 dev_info(qmc->dev, "IRQ queue overflow\n"); in qmc_irq_handler()
1641 dev_err(qmc->dev, "Global transmitter underrun\n"); in qmc_irq_handler()
1644 dev_err(qmc->dev, "Global receiver overrun\n"); in qmc_irq_handler()
1661 ret = of_property_read_string(np, "fsl,soft-qmc", &filename); in qmc_qe_soft_qmc_init()
1665 case -EINVAL: in qmc_qe_soft_qmc_init()
1666 /* fsl,soft-qmc property not set -> Simply do nothing */ in qmc_qe_soft_qmc_init()
1669 dev_err(qmc->dev, "%pOF: failed to read fsl,soft-qmc\n", in qmc_qe_soft_qmc_init()
1676 if (!strstr(qe_fw_info->id, "Soft-QMC")) { in qmc_qe_soft_qmc_init()
1677 dev_err(qmc->dev, "Another Firmware is already loaded\n"); in qmc_qe_soft_qmc_init()
1678 return -EALREADY; in qmc_qe_soft_qmc_init()
1680 dev_info(qmc->dev, "Firmware already loaded\n"); in qmc_qe_soft_qmc_init()
1684 dev_info(qmc->dev, "Using firmware %s\n", filename); in qmc_qe_soft_qmc_init()
1686 ret = request_firmware(&fw, filename, qmc->dev); in qmc_qe_soft_qmc_init()
1688 dev_err(qmc->dev, "Failed to request firmware %s\n", filename); in qmc_qe_soft_qmc_init()
1692 qe_fw = (const struct qe_firmware *)fw->data; in qmc_qe_soft_qmc_init()
1694 if (fw->size < sizeof(qe_fw->header) || in qmc_qe_soft_qmc_init()
1695 be32_to_cpu(qe_fw->header.length) != fw->size) { in qmc_qe_soft_qmc_init()
1696 dev_err(qmc->dev, "Invalid firmware %s\n", filename); in qmc_qe_soft_qmc_init()
1697 ret = -EINVAL; in qmc_qe_soft_qmc_init()
1703 dev_err(qmc->dev, "Failed to load firmware %s\n", filename); in qmc_qe_soft_qmc_init()
1717 qmc->scc_regs = devm_platform_ioremap_resource_byname(pdev, "scc_regs"); in qmc_cpm1_init_resources()
1718 if (IS_ERR(qmc->scc_regs)) in qmc_cpm1_init_resources()
1719 return PTR_ERR(qmc->scc_regs); in qmc_cpm1_init_resources()
1723 return -EINVAL; in qmc_cpm1_init_resources()
1724 qmc->scc_pram_offset = res->start - get_immrbase(); in qmc_cpm1_init_resources()
1725 qmc->scc_pram = devm_ioremap_resource(qmc->dev, res); in qmc_cpm1_init_resources()
1726 if (IS_ERR(qmc->scc_pram)) in qmc_cpm1_init_resources()
1727 return PTR_ERR(qmc->scc_pram); in qmc_cpm1_init_resources()
1729 qmc->dpram = devm_platform_ioremap_resource_byname(pdev, "dpram"); in qmc_cpm1_init_resources()
1730 if (IS_ERR(qmc->dpram)) in qmc_cpm1_init_resources()
1731 return PTR_ERR(qmc->dpram); in qmc_cpm1_init_resources()
1742 qmc->scc_regs = devm_platform_ioremap_resource_byname(pdev, "ucc_regs"); in qmc_qe_init_resources()
1743 if (IS_ERR(qmc->scc_regs)) in qmc_qe_init_resources()
1744 return PTR_ERR(qmc->scc_regs); in qmc_qe_init_resources()
1746 ucc_num = tsa_serial_get_num(qmc->tsa_serial); in qmc_qe_init_resources()
1748 return dev_err_probe(qmc->dev, ucc_num, "Failed to get UCC num\n"); in qmc_qe_init_resources()
1750 qmc->qe_subblock = ucc_slow_get_qe_cr_subblock(ucc_num); in qmc_qe_init_resources()
1751 if (qmc->qe_subblock == QE_CR_SUBBLOCK_INVALID) { in qmc_qe_init_resources()
1752 dev_err(qmc->dev, "Unsupported ucc num %u\n", ucc_num); in qmc_qe_init_resources()
1753 return -EINVAL; in qmc_qe_init_resources()
1762 info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64, in qmc_qe_init_resources()
1767 if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock, in qmc_qe_init_resources()
1769 dev_err(qmc->dev, "QE_ASSIGN_PAGE_TO_DEVICE cmd failed"); in qmc_qe_init_resources()
1770 return -EIO; in qmc_qe_init_resources()
1772 qmc->scc_pram = qe_muram_addr(info); in qmc_qe_init_resources()
1773 qmc->scc_pram_offset = info; in qmc_qe_init_resources()
1777 return -EINVAL; in qmc_qe_init_resources()
1778 qmc->dpram_offset = res->start - qe_muram_dma(qe_muram_addr(0)); in qmc_qe_init_resources()
1779 qmc->dpram = devm_ioremap_resource(qmc->dev, res); in qmc_qe_init_resources()
1780 if (IS_ERR(qmc->scc_pram)) in qmc_qe_init_resources()
1781 return PTR_ERR(qmc->scc_pram); in qmc_qe_init_resources()
1799 ret = tsa_serial_connect(qmc->tsa_serial); in qmc_cpm1_init_scc()
1801 return dev_err_probe(qmc->dev, ret, "Failed to connect TSA serial\n"); in qmc_cpm1_init_scc()
1805 qmc_write32(qmc->scc_regs + SCC_GSMRH, val); in qmc_cpm1_init_scc()
1808 qmc_write32(qmc->scc_regs + SCC_GSMRL, SCC_CPM1_GSMRL_MODE_QMC); in qmc_cpm1_init_scc()
1811 qmc_write16(qmc->scc_regs + SCC_SCCM, 0x0000); in qmc_cpm1_init_scc()
1812 qmc_write16(qmc->scc_regs + SCC_SCCE, 0x000F); in qmc_cpm1_init_scc()
1822 /* Set the UCC in slow mode */ in qmc_qe_init_ucc()
1823 qmc_write8(qmc->scc_regs + SCC_QE_UCC_GUEMR, in qmc_qe_init_ucc()
1826 /* Connect the serial (UCC) to TSA */ in qmc_qe_init_ucc()
1827 ret = tsa_serial_connect(qmc->tsa_serial); in qmc_qe_init_ucc()
1829 return dev_err_probe(qmc->dev, ret, "Failed to connect TSA serial\n"); in qmc_qe_init_ucc()
1832 if (!qe_issue_cmd(QE_PUSHSCHED, qmc->qe_subblock, in qmc_qe_init_ucc()
1834 dev_err(qmc->dev, "QE_CMD_PUSH_SCHED tx cmd failed"); in qmc_qe_init_ucc()
1835 ret = -EIO; in qmc_qe_init_ucc()
1840 if (!qe_issue_cmd(QE_PUSHSCHED, qmc->qe_subblock | 0x00020000, in qmc_qe_init_ucc()
1842 dev_err(qmc->dev, "QE_CMD_PUSH_SCHED rx cmd failed"); in qmc_qe_init_ucc()
1843 ret = -EIO; in qmc_qe_init_ucc()
1847 /* Re-init RXPTR and TXPTR with the content of RX_S_PTR and in qmc_qe_init_ucc()
1851 val = qmc_read16(qmc->scc_pram + QMC_GBL_RX_S_PTR); in qmc_qe_init_ucc()
1852 qmc_write16(qmc->scc_pram + QMC_GBL_RXPTR, val); in qmc_qe_init_ucc()
1853 val = qmc_read16(qmc->scc_pram + QMC_GBL_TX_S_PTR); in qmc_qe_init_ucc()
1854 qmc_write16(qmc->scc_pram + QMC_GBL_TXPTR, val); in qmc_qe_init_ucc()
1859 qmc_write32(qmc->scc_regs + SCC_GSMRH, val); in qmc_qe_init_ucc()
1862 qmc_write32(qmc->scc_regs + SCC_GSMRL, SCC_QE_GSMRL_MODE_QMC); in qmc_qe_init_ucc()
1865 qmc_write16(qmc->scc_regs + SCC_SCCM, 0x0000); in qmc_qe_init_ucc()
1866 qmc_write16(qmc->scc_regs + SCC_SCCE, 0x000F); in qmc_qe_init_ucc()
1871 tsa_serial_disconnect(qmc->tsa_serial); in qmc_qe_init_ucc()
1885 tsa_serial_disconnect(qmc->tsa_serial); in qmc_exit_xcc()
1890 struct device_node *np = pdev->dev.of_node; in qmc_probe()
1896 qmc = devm_kzalloc(&pdev->dev, sizeof(*qmc), GFP_KERNEL); in qmc_probe()
1898 return -ENOMEM; in qmc_probe()
1900 qmc->dev = &pdev->dev; in qmc_probe()
1901 qmc->data = of_device_get_match_data(&pdev->dev); in qmc_probe()
1902 if (!qmc->data) { in qmc_probe()
1903 dev_err(qmc->dev, "Missing match data\n"); in qmc_probe()
1904 return -EINVAL; in qmc_probe()
1906 INIT_LIST_HEAD(&qmc->chan_head); in qmc_probe()
1908 qmc->tsa_serial = devm_tsa_serial_get_byphandle(qmc->dev, np, "fsl,tsa-serial"); in qmc_probe()
1909 if (IS_ERR(qmc->tsa_serial)) { in qmc_probe()
1910 return dev_err_probe(qmc->dev, PTR_ERR(qmc->tsa_serial), in qmc_probe()
1935 qmc->bd_size = (nb_chans * (QMC_NB_TXBDS + QMC_NB_RXBDS)) * sizeof(cbd_t); in qmc_probe()
1936 qmc->bd_table = dmam_alloc_coherent(qmc->dev, qmc->bd_size, in qmc_probe()
1937 &qmc->bd_dma_addr, GFP_KERNEL); in qmc_probe()
1938 if (!qmc->bd_table) { in qmc_probe()
1939 dev_err(qmc->dev, "Failed to allocate bd table\n"); in qmc_probe()
1940 return -ENOMEM; in qmc_probe()
1942 memset(qmc->bd_table, 0, qmc->bd_size); in qmc_probe()
1944 qmc_write32(qmc->scc_pram + QMC_GBL_MCBASE, qmc->bd_dma_addr); in qmc_probe()
1947 qmc->int_size = QMC_NB_INTS * sizeof(u16); in qmc_probe()
1948 qmc->int_table = dmam_alloc_coherent(qmc->dev, qmc->int_size, in qmc_probe()
1949 &qmc->int_dma_addr, GFP_KERNEL); in qmc_probe()
1950 if (!qmc->int_table) { in qmc_probe()
1951 dev_err(qmc->dev, "Failed to allocate interrupt table\n"); in qmc_probe()
1952 return -ENOMEM; in qmc_probe()
1954 memset(qmc->int_table, 0, qmc->int_size); in qmc_probe()
1956 qmc->int_curr = qmc->int_table; in qmc_probe()
1957 qmc_write32(qmc->scc_pram + QMC_GBL_INTBASE, qmc->int_dma_addr); in qmc_probe()
1958 qmc_write32(qmc->scc_pram + QMC_GBL_INTPTR, qmc->int_dma_addr); in qmc_probe()
1960 /* Set MRBLR (valid for HDLC only) max MRU + max CRC */ in qmc_probe()
1961 qmc_write16(qmc->scc_pram + QMC_GBL_MRBLR, HDLC_MAX_MRU + 4); in qmc_probe()
1963 qmc_write16(qmc->scc_pram + QMC_GBL_GRFTHR, 1); in qmc_probe()
1964 qmc_write16(qmc->scc_pram + QMC_GBL_GRFCNT, 1); in qmc_probe()
1966 qmc_write32(qmc->scc_pram + QMC_GBL_C_MASK32, 0xDEBB20E3); in qmc_probe()
1967 qmc_write16(qmc->scc_pram + QMC_GBL_C_MASK16, 0xF0B8); in qmc_probe()
1971 memset_io(qmc->scc_pram + QMC_QE_GBL_RSV_B0_START, 0, in qmc_probe()
1974 qmc_write32(qmc->scc_pram + QMC_QE_GBL_GCSBASE, qmc->dpram_offset); in qmc_probe()
1977 memset_io(qmc->scc_pram + UCC_SLOW_PRAM_SIZE, 0x01, 64); in qmc_probe()
1978 memset_io(qmc->scc_pram + UCC_SLOW_PRAM_SIZE + 64, 0x01, 64); in qmc_probe()
1979 qmc_write16(qmc->scc_pram + QMC_QE_GBL_RX_FRM_BASE, in qmc_probe()
1980 qmc->scc_pram_offset + UCC_SLOW_PRAM_SIZE); in qmc_probe()
1981 qmc_write16(qmc->scc_pram + QMC_QE_GBL_TX_FRM_BASE, in qmc_probe()
1982 qmc->scc_pram_offset + UCC_SLOW_PRAM_SIZE + 64); in qmc_probe()
1989 qmc_write16(qmc->scc_pram + QMC_GBL_QMCSTATE, 0x8000); in qmc_probe()
2000 /* Init SCC (CPM1) or UCC (QE) */ in qmc_probe()
2011 ret = devm_request_irq(qmc->dev, irq, qmc_irq_handler, 0, "qmc", qmc); in qmc_probe()
2016 qmc_write16(qmc->scc_regs + SCC_SCCM, in qmc_probe()
2024 qmc_setbits32(qmc->scc_regs + SCC_GSMRL, SCC_GSMRL_ENR | SCC_GSMRL_ENT); in qmc_probe()
2029 ret = devm_of_platform_populate(qmc->dev); in qmc_probe()
2036 qmc_setbits32(qmc->scc_regs + SCC_GSMRL, 0); in qmc_probe()
2039 qmc_write16(qmc->scc_regs + SCC_SCCM, 0); in qmc_probe()
2051 qmc_setbits32(qmc->scc_regs + SCC_GSMRL, 0); in qmc_remove()
2054 qmc_write16(qmc->scc_regs + SCC_SCCM, 0); in qmc_remove()
2056 /* Exit SCC (CPM1) or UCC (QE) */ in qmc_remove()
2082 { .compatible = "fsl,cpm1-scc-qmc", .data = &qmc_data_cpm1 },
2085 { .compatible = "fsl,qe-ucc-qmc", .data = &qmc_data_qe },
2093 .name = "fsl-qmc",
2108 return ERR_PTR(-EINVAL); in qmc_chan_get_from_qmc()
2112 return ERR_PTR(-ENODEV); in qmc_chan_get_from_qmc()
2117 return ERR_PTR(-EPROBE_DEFER); in qmc_chan_get_from_qmc()
2120 if (chan_index >= ARRAY_SIZE(qmc->chans)) { in qmc_chan_get_from_qmc()
2122 return ERR_PTR(-EINVAL); in qmc_chan_get_from_qmc()
2125 qmc_chan = qmc->chans[chan_index]; in qmc_chan_get_from_qmc()
2128 return ERR_PTR(-ENOENT); in qmc_chan_get_from_qmc()
2162 return ERR_PTR(-EINVAL); in qmc_chan_get_byphandles_index()
2177 qmc_np = np->parent; in qmc_chan_get_bychild()
2180 return ERR_PTR(-EINVAL); in qmc_chan_get_bychild()
2188 put_device(chan->qmc->dev); in qmc_chan_put()
2209 return ERR_PTR(-ENOMEM); in devm_qmc_chan_get_byphandles_index()
2231 return ERR_PTR(-ENOMEM); in devm_qmc_chan_get_bychild()