Lines Matching +full:tx +full:- +full:ts +full:- +full:mask
1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/dma-mapping.h>
44 /* SCC mask register (16 bits) */
52 /* Tx time-slot assignment table pointer (16 bits) */
64 /* Rx time-slot assignment table pointer (16 bits) */
66 /* Tx pointer (16 bits) */
72 /* Time slot assignment table Tx (32 x 16 bits) */
83 /* Tx buffer descriptor base address (16 bits, offset from MCBASE) */
98 /* Tx internal state (32 bits) */
100 /* Tx buffer descriptor pointer (16 bits) */
102 /* Zero-insertion state (32 bits) */
104 /* Channel’s interrupt mask flags (16 bits) */
262 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &tsa_info); in qmc_chan_get_info()
266 info->mode = chan->mode; in qmc_chan_get_info()
267 info->rx_fs_rate = tsa_info.rx_fs_rate; in qmc_chan_get_info()
268 info->rx_bit_rate = tsa_info.rx_bit_rate; in qmc_chan_get_info()
269 info->nb_tx_ts = hweight64(chan->tx_ts_mask); in qmc_chan_get_info()
270 info->tx_fs_rate = tsa_info.tx_fs_rate; in qmc_chan_get_info()
271 info->tx_bit_rate = tsa_info.tx_bit_rate; in qmc_chan_get_info()
272 info->nb_rx_ts = hweight64(chan->rx_ts_mask); in qmc_chan_get_info()
280 if (param->mode != chan->mode) in qmc_chan_set_param()
281 return -EINVAL; in qmc_chan_set_param()
283 switch (param->mode) { in qmc_chan_set_param()
285 if ((param->hdlc.max_rx_buf_size % 4) || in qmc_chan_set_param()
286 (param->hdlc.max_rx_buf_size < 8)) in qmc_chan_set_param()
287 return -EINVAL; in qmc_chan_set_param()
289 qmc_write16(chan->qmc->scc_pram + QMC_GBL_MRBLR, in qmc_chan_set_param()
290 param->hdlc.max_rx_buf_size - 8); in qmc_chan_set_param()
291 qmc_write16(chan->s_param + QMC_SPE_MFLR, in qmc_chan_set_param()
292 param->hdlc.max_rx_frame_size); in qmc_chan_set_param()
293 if (param->hdlc.is_crc32) { in qmc_chan_set_param()
294 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, in qmc_chan_set_param()
297 qmc_clrbits16(chan->s_param + QMC_SPE_CHAMR, in qmc_chan_set_param()
303 qmc_write16(chan->s_param + QMC_SPE_TMRBLR, in qmc_chan_set_param()
304 param->transp.max_rx_buf_size); in qmc_chan_set_param()
308 return -EINVAL; in qmc_chan_set_param()
332 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_write_submit()
333 bd = chan->txbd_free; in qmc_chan_write_submit()
335 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_write_submit()
338 ret = -EBUSY; in qmc_chan_write_submit()
342 qmc_write16(&bd->cbd_datlen, length); in qmc_chan_write_submit()
343 qmc_write32(&bd->cbd_bufaddr, addr); in qmc_chan_write_submit()
345 xfer_desc = &chan->tx_desc[bd - chan->txbds]; in qmc_chan_write_submit()
346 xfer_desc->tx_complete = complete; in qmc_chan_write_submit()
347 xfer_desc->context = context; in qmc_chan_write_submit()
352 qmc_write16(&bd->cbd_sc, ctrl); in qmc_chan_write_submit()
354 if (!chan->is_tx_stopped) in qmc_chan_write_submit()
355 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_POL); in qmc_chan_write_submit()
358 chan->txbd_free = chan->txbds; in qmc_chan_write_submit()
360 chan->txbd_free++; in qmc_chan_write_submit()
365 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_write_submit()
387 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_write_done()
388 bd = chan->txbd_done; in qmc_chan_write_done()
390 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_write_done()
395 xfer_desc = &chan->tx_desc[bd - chan->txbds]; in qmc_chan_write_done()
396 complete = xfer_desc->tx_complete; in qmc_chan_write_done()
397 context = xfer_desc->context; in qmc_chan_write_done()
398 xfer_desc->tx_complete = NULL; in qmc_chan_write_done()
399 xfer_desc->context = NULL; in qmc_chan_write_done()
401 qmc_write16(&bd->cbd_sc, ctrl & ~QMC_BD_TX_UB); in qmc_chan_write_done()
404 chan->txbd_done = chan->txbds; in qmc_chan_write_done()
406 chan->txbd_done++; in qmc_chan_write_done()
409 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_write_done()
411 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_write_done()
414 bd = chan->txbd_done; in qmc_chan_write_done()
415 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_write_done()
419 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_write_done()
439 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_read_submit()
440 bd = chan->rxbd_free; in qmc_chan_read_submit()
442 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_read_submit()
445 ret = -EBUSY; in qmc_chan_read_submit()
449 qmc_write16(&bd->cbd_datlen, 0); /* data length is updated by the QMC */ in qmc_chan_read_submit()
450 qmc_write32(&bd->cbd_bufaddr, addr); in qmc_chan_read_submit()
452 xfer_desc = &chan->rx_desc[bd - chan->rxbds]; in qmc_chan_read_submit()
453 xfer_desc->rx_complete = complete; in qmc_chan_read_submit()
454 xfer_desc->context = context; in qmc_chan_read_submit()
459 qmc_write16(&bd->cbd_sc, ctrl); in qmc_chan_read_submit()
462 if (chan->is_rx_halted && !chan->is_rx_stopped) { in qmc_chan_read_submit()
464 if (chan->mode == QMC_TRANSPARENT) in qmc_chan_read_submit()
465 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080); in qmc_chan_read_submit()
467 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080); in qmc_chan_read_submit()
468 qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000); in qmc_chan_read_submit()
469 chan->is_rx_halted = false; in qmc_chan_read_submit()
471 chan->rx_pending++; in qmc_chan_read_submit()
474 chan->rxbd_free = chan->rxbds; in qmc_chan_read_submit()
476 chan->rxbd_free++; in qmc_chan_read_submit()
480 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_read_submit()
503 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_read_done()
504 bd = chan->rxbd_done; in qmc_chan_read_done()
506 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_read_done()
511 xfer_desc = &chan->rx_desc[bd - chan->rxbds]; in qmc_chan_read_done()
512 complete = xfer_desc->rx_complete; in qmc_chan_read_done()
513 context = xfer_desc->context; in qmc_chan_read_done()
514 xfer_desc->rx_complete = NULL; in qmc_chan_read_done()
515 xfer_desc->context = NULL; in qmc_chan_read_done()
517 datalen = qmc_read16(&bd->cbd_datlen); in qmc_chan_read_done()
518 qmc_write16(&bd->cbd_sc, ctrl & ~QMC_BD_RX_UB); in qmc_chan_read_done()
521 chan->rxbd_done = chan->rxbds; in qmc_chan_read_done()
523 chan->rxbd_done++; in qmc_chan_read_done()
525 chan->rx_pending--; in qmc_chan_read_done()
528 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_read_done()
530 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_read_done()
533 bd = chan->rxbd_done; in qmc_chan_read_done()
534 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_read_done()
538 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_read_done()
543 return cpm_command(chan->id << 2, (qmc_opcode << 4) | 0x0E); in qmc_chan_command()
551 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_stop_rx()
556 dev_err(chan->qmc->dev, "chan %u: Send STOP RECEIVE failed (%d)\n", in qmc_chan_stop_rx()
557 chan->id, ret); in qmc_chan_stop_rx()
561 chan->is_rx_stopped = true; in qmc_chan_stop_rx()
564 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_stop_rx()
573 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_stop_tx()
578 dev_err(chan->qmc->dev, "chan %u: Send STOP TRANSMIT failed (%d)\n", in qmc_chan_stop_tx()
579 chan->id, ret); in qmc_chan_stop_tx()
583 chan->is_tx_stopped = true; in qmc_chan_stop_tx()
586 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_stop_tx()
614 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_start_rx()
617 if (chan->mode == QMC_TRANSPARENT) in qmc_chan_start_rx()
618 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080); in qmc_chan_start_rx()
620 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080); in qmc_chan_start_rx()
621 qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000); in qmc_chan_start_rx()
622 chan->is_rx_halted = false; in qmc_chan_start_rx()
624 chan->is_rx_stopped = false; in qmc_chan_start_rx()
626 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_start_rx()
633 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_start_tx()
639 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_ENT); in qmc_chan_start_tx()
642 qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_POL); in qmc_chan_start_tx()
644 chan->is_tx_stopped = false; in qmc_chan_start_tx()
646 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_start_tx()
668 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_chan_reset_rx()
669 bd = chan->rxbds; in qmc_chan_reset_rx()
671 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_reset_rx()
672 qmc_write16(&bd->cbd_sc, ctrl & ~(QMC_BD_RX_UB | QMC_BD_RX_E)); in qmc_chan_reset_rx()
674 xfer_desc = &chan->rx_desc[bd - chan->rxbds]; in qmc_chan_reset_rx()
675 xfer_desc->rx_complete = NULL; in qmc_chan_reset_rx()
676 xfer_desc->context = NULL; in qmc_chan_reset_rx()
681 chan->rxbd_free = chan->rxbds; in qmc_chan_reset_rx()
682 chan->rxbd_done = chan->rxbds; in qmc_chan_reset_rx()
683 qmc_write16(chan->s_param + QMC_SPE_RBPTR, in qmc_chan_reset_rx()
684 qmc_read16(chan->s_param + QMC_SPE_RBASE)); in qmc_chan_reset_rx()
686 chan->rx_pending = 0; in qmc_chan_reset_rx()
688 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_chan_reset_rx()
698 spin_lock_irqsave(&chan->tx_lock, flags); in qmc_chan_reset_tx()
700 /* Disable transmitter. It will be re-enable on qmc_chan_start() */ in qmc_chan_reset_tx()
701 qmc_clrbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_ENT); in qmc_chan_reset_tx()
703 bd = chan->txbds; in qmc_chan_reset_tx()
705 ctrl = qmc_read16(&bd->cbd_sc); in qmc_chan_reset_tx()
706 qmc_write16(&bd->cbd_sc, ctrl & ~(QMC_BD_TX_UB | QMC_BD_TX_R)); in qmc_chan_reset_tx()
708 xfer_desc = &chan->tx_desc[bd - chan->txbds]; in qmc_chan_reset_tx()
709 xfer_desc->tx_complete = NULL; in qmc_chan_reset_tx()
710 xfer_desc->context = NULL; in qmc_chan_reset_tx()
715 chan->txbd_free = chan->txbds; in qmc_chan_reset_tx()
716 chan->txbd_done = chan->txbds; in qmc_chan_reset_tx()
717 qmc_write16(chan->s_param + QMC_SPE_TBPTR, in qmc_chan_reset_tx()
718 qmc_read16(chan->s_param + QMC_SPE_TBASE)); in qmc_chan_reset_tx()
721 qmc_write32(chan->s_param + QMC_SPE_TSTATE, 0x30000000); in qmc_chan_reset_tx()
722 qmc_write32(chan->s_param + QMC_SPE_ZISTATE, 0x00000100); in qmc_chan_reset_tx()
724 spin_unlock_irqrestore(&chan->tx_lock, flags); in qmc_chan_reset_tx()
751 ret = tsa_serial_get_info(qmc->tsa_serial, &info); in qmc_check_chans()
756 dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned not supported\n"); in qmc_check_chans()
757 return -EINVAL; in qmc_check_chans()
761 * If more than 32 TS are assigned to this serial, one common table is in qmc_check_chans()
762 * used for Tx and Rx and so masks must be equal for all channels. in qmc_check_chans()
766 dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned are not equal\n"); in qmc_check_chans()
767 return -EINVAL; in qmc_check_chans()
772 tx_ts_assigned_mask = info.nb_tx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_tx_ts) - 1; in qmc_check_chans()
773 rx_ts_assigned_mask = info.nb_rx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_rx_ts) - 1; in qmc_check_chans()
775 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_check_chans()
776 if (chan->tx_ts_mask > tx_ts_assigned_mask) { in qmc_check_chans()
777 dev_err(qmc->dev, "chan %u uses TSA unassigned Tx TS\n", chan->id); in qmc_check_chans()
778 return -EINVAL; in qmc_check_chans()
780 if (tx_ts_mask & chan->tx_ts_mask) { in qmc_check_chans()
781 dev_err(qmc->dev, "chan %u uses an already used Tx TS\n", chan->id); in qmc_check_chans()
782 return -EINVAL; in qmc_check_chans()
785 if (chan->rx_ts_mask > rx_ts_assigned_mask) { in qmc_check_chans()
786 dev_err(qmc->dev, "chan %u uses TSA unassigned Rx TS\n", chan->id); in qmc_check_chans()
787 return -EINVAL; in qmc_check_chans()
789 if (rx_ts_mask & chan->rx_ts_mask) { in qmc_check_chans()
790 dev_err(qmc->dev, "chan %u uses an already used Rx TS\n", chan->id); in qmc_check_chans()
791 return -EINVAL; in qmc_check_chans()
794 if (is_one_table && (chan->tx_ts_mask != chan->rx_ts_mask)) { in qmc_check_chans()
795 dev_err(qmc->dev, "chan %u uses different Rx and Tx TS\n", chan->id); in qmc_check_chans()
796 return -EINVAL; in qmc_check_chans()
799 tx_ts_mask |= chan->tx_ts_mask; in qmc_check_chans()
800 rx_ts_mask |= chan->rx_ts_mask; in qmc_check_chans()
811 list_for_each_entry(chan, &qmc->chan_head, list) in qmc_nb_chans()
829 dev_err(qmc->dev, "%pOF: failed to read reg\n", chan_np); in qmc_of_parse_chans()
834 dev_err(qmc->dev, "%pOF: Invalid chan_id\n", chan_np); in qmc_of_parse_chans()
836 return -EINVAL; in qmc_of_parse_chans()
839 chan = devm_kzalloc(qmc->dev, sizeof(*chan), GFP_KERNEL); in qmc_of_parse_chans()
842 return -ENOMEM; in qmc_of_parse_chans()
845 chan->id = chan_id; in qmc_of_parse_chans()
846 spin_lock_init(&chan->rx_lock); in qmc_of_parse_chans()
847 spin_lock_init(&chan->tx_lock); in qmc_of_parse_chans()
849 ret = of_property_read_u64(chan_np, "fsl,tx-ts-mask", &ts_mask); in qmc_of_parse_chans()
851 dev_err(qmc->dev, "%pOF: failed to read fsl,tx-ts-mask\n", in qmc_of_parse_chans()
856 chan->tx_ts_mask = ts_mask; in qmc_of_parse_chans()
858 ret = of_property_read_u64(chan_np, "fsl,rx-ts-mask", &ts_mask); in qmc_of_parse_chans()
860 dev_err(qmc->dev, "%pOF: failed to read fsl,rx-ts-mask\n", in qmc_of_parse_chans()
865 chan->rx_ts_mask = ts_mask; in qmc_of_parse_chans()
868 ret = of_property_read_string(chan_np, "fsl,operational-mode", &mode); in qmc_of_parse_chans()
869 if (ret && ret != -EINVAL) { in qmc_of_parse_chans()
870 dev_err(qmc->dev, "%pOF: failed to read fsl,operational-mode\n", in qmc_of_parse_chans()
876 chan->mode = QMC_TRANSPARENT; in qmc_of_parse_chans()
878 chan->mode = QMC_HDLC; in qmc_of_parse_chans()
880 dev_err(qmc->dev, "%pOF: Invalid fsl,operational-mode (%s)\n", in qmc_of_parse_chans()
883 return -EINVAL; in qmc_of_parse_chans()
886 chan->is_reverse_data = of_property_read_bool(chan_np, in qmc_of_parse_chans()
887 "fsl,reverse-data"); in qmc_of_parse_chans()
889 list_add_tail(&chan->list, &qmc->chan_head); in qmc_of_parse_chans()
890 qmc->chans[chan->id] = chan; in qmc_of_parse_chans()
903 * Use a common Tx/Rx 64 entries table. in qmc_setup_tsa_64rxtx()
904 * Everything was previously checked, Tx and Rx related stuffs are in qmc_setup_tsa_64rxtx()
905 * identical -> Used Rx related stuff to build the table in qmc_setup_tsa_64rxtx()
910 qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), 0x0000); in qmc_setup_tsa_64rxtx()
913 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_setup_tsa_64rxtx()
914 for (i = 0; i < info->nb_rx_ts; i++) { in qmc_setup_tsa_64rxtx()
915 if (!(chan->rx_ts_mask & (((u64)1) << i))) in qmc_setup_tsa_64rxtx()
919 QMC_TSA_CHANNEL(chan->id); in qmc_setup_tsa_64rxtx()
920 qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), val); in qmc_setup_tsa_64rxtx()
925 qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATRX + ((info->nb_rx_ts - 1) * 2), in qmc_setup_tsa_64rxtx()
929 val = qmc->scc_pram_offset + QMC_GBL_TSATRX; in qmc_setup_tsa_64rxtx()
930 qmc_write16(qmc->scc_pram + QMC_GBL_RX_S_PTR, val); in qmc_setup_tsa_64rxtx()
931 qmc_write16(qmc->scc_pram + QMC_GBL_RXPTR, val); in qmc_setup_tsa_64rxtx()
932 qmc_write16(qmc->scc_pram + QMC_GBL_TX_S_PTR, val); in qmc_setup_tsa_64rxtx()
933 qmc_write16(qmc->scc_pram + QMC_GBL_TXPTR, val); in qmc_setup_tsa_64rxtx()
945 * Use a Tx 32 entries table and a Rx 32 entries table. in qmc_setup_tsa_32rx_32tx()
951 qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), 0x0000); in qmc_setup_tsa_32rx_32tx()
952 qmc_write16(qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), 0x0000); in qmc_setup_tsa_32rx_32tx()
955 /* Set entries based on Rx and Tx stuff*/ in qmc_setup_tsa_32rx_32tx()
956 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_setup_tsa_32rx_32tx()
958 for (i = 0; i < info->nb_rx_ts; i++) { in qmc_setup_tsa_32rx_32tx()
959 if (!(chan->rx_ts_mask & (((u64)1) << i))) in qmc_setup_tsa_32rx_32tx()
963 QMC_TSA_CHANNEL(chan->id); in qmc_setup_tsa_32rx_32tx()
964 qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), val); in qmc_setup_tsa_32rx_32tx()
966 /* Tx part */ in qmc_setup_tsa_32rx_32tx()
967 for (i = 0; i < info->nb_tx_ts; i++) { in qmc_setup_tsa_32rx_32tx()
968 if (!(chan->tx_ts_mask & (((u64)1) << i))) in qmc_setup_tsa_32rx_32tx()
972 QMC_TSA_CHANNEL(chan->id); in qmc_setup_tsa_32rx_32tx()
973 qmc_write16(qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), val); in qmc_setup_tsa_32rx_32tx()
978 qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATRX + ((info->nb_rx_ts - 1) * 2), in qmc_setup_tsa_32rx_32tx()
980 qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATTX + ((info->nb_tx_ts - 1) * 2), in qmc_setup_tsa_32rx_32tx()
984 val = qmc->scc_pram_offset + QMC_GBL_TSATRX; in qmc_setup_tsa_32rx_32tx()
985 qmc_write16(qmc->scc_pram + QMC_GBL_RX_S_PTR, val); in qmc_setup_tsa_32rx_32tx()
986 qmc_write16(qmc->scc_pram + QMC_GBL_RXPTR, val); in qmc_setup_tsa_32rx_32tx()
988 /* ... and Tx pointers */ in qmc_setup_tsa_32rx_32tx()
989 val = qmc->scc_pram_offset + QMC_GBL_TSATTX; in qmc_setup_tsa_32rx_32tx()
990 qmc_write16(qmc->scc_pram + QMC_GBL_TX_S_PTR, val); in qmc_setup_tsa_32rx_32tx()
991 qmc_write16(qmc->scc_pram + QMC_GBL_TXPTR, val); in qmc_setup_tsa_32rx_32tx()
1002 ret = tsa_serial_get_info(qmc->tsa_serial, &info); in qmc_setup_tsa()
1007 * Setup one common 64 entries table or two 32 entries (one for Tx and in qmc_setup_tsa()
1008 * one for Tx) according to assigned TS numbers. in qmc_setup_tsa()
1023 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &info); in qmc_setup_chan_trnsync()
1027 /* Find the first Rx TS allocated to the channel */ in qmc_setup_chan_trnsync()
1028 first_rx = chan->rx_ts_mask ? __ffs64(chan->rx_ts_mask) + 1 : 0; in qmc_setup_chan_trnsync()
1030 /* Find the last Tx TS allocated to the channel */ in qmc_setup_chan_trnsync()
1031 last_tx = fls64(chan->tx_ts_mask); in qmc_setup_chan_trnsync()
1039 qmc_write16(chan->s_param + QMC_SPE_TRNSYNC, trnsync); in qmc_setup_chan_trnsync()
1041 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()
1042 chan->id, trnsync, in qmc_setup_chan_trnsync()
1043 first_rx, info.nb_rx_ts, chan->rx_ts_mask, in qmc_setup_chan_trnsync()
1044 last_tx, info.nb_tx_ts, chan->tx_ts_mask); in qmc_setup_chan_trnsync()
1056 chan->qmc = qmc; in qmc_setup_chan()
1059 chan->s_param = qmc->dpram + (chan->id * 64); in qmc_setup_chan()
1060 /* 16 bd per channel (8 rx and 8 tx) */ in qmc_setup_chan()
1061 chan->txbds = qmc->bd_table + (chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)); in qmc_setup_chan()
1062 chan->rxbds = qmc->bd_table + (chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)) + QMC_NB_TXBDS; in qmc_setup_chan()
1064 chan->txbd_free = chan->txbds; in qmc_setup_chan()
1065 chan->txbd_done = chan->txbds; in qmc_setup_chan()
1066 chan->rxbd_free = chan->rxbds; in qmc_setup_chan()
1067 chan->rxbd_done = chan->rxbds; in qmc_setup_chan()
1070 val = chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS) * sizeof(cbd_t); in qmc_setup_chan()
1071 qmc_write16(chan->s_param + QMC_SPE_TBASE, val); in qmc_setup_chan()
1072 qmc_write16(chan->s_param + QMC_SPE_TBPTR, val); in qmc_setup_chan()
1075 val = ((chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)) + QMC_NB_TXBDS) * sizeof(cbd_t); in qmc_setup_chan()
1076 qmc_write16(chan->s_param + QMC_SPE_RBASE, val); in qmc_setup_chan()
1077 qmc_write16(chan->s_param + QMC_SPE_RBPTR, val); in qmc_setup_chan()
1078 qmc_write32(chan->s_param + QMC_SPE_TSTATE, 0x30000000); in qmc_setup_chan()
1079 qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000); in qmc_setup_chan()
1080 qmc_write32(chan->s_param + QMC_SPE_ZISTATE, 0x00000100); in qmc_setup_chan()
1081 if (chan->mode == QMC_TRANSPARENT) { in qmc_setup_chan()
1082 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080); in qmc_setup_chan()
1083 qmc_write16(chan->s_param + QMC_SPE_TMRBLR, 60); in qmc_setup_chan()
1085 if (chan->is_reverse_data) in qmc_setup_chan()
1087 qmc_write16(chan->s_param + QMC_SPE_CHAMR, val); in qmc_setup_chan()
1092 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080); in qmc_setup_chan()
1093 qmc_write16(chan->s_param + QMC_SPE_MFLR, 60); in qmc_setup_chan()
1094 qmc_write16(chan->s_param + QMC_SPE_CHAMR, in qmc_setup_chan()
1099 qmc_write16(chan->s_param + QMC_SPE_INTMSK, 0x0000); in qmc_setup_chan()
1105 bd = chan->rxbds + i; in qmc_setup_chan()
1106 qmc_write16(&bd->cbd_sc, val); in qmc_setup_chan()
1108 bd = chan->rxbds + QMC_NB_RXBDS - 1; in qmc_setup_chan()
1109 qmc_write16(&bd->cbd_sc, val | QMC_BD_RX_W); in qmc_setup_chan()
1111 /* Init Tx BDs and set Wrap bit on last descriptor */ in qmc_setup_chan()
1114 if (chan->mode == QMC_HDLC) in qmc_setup_chan()
1117 bd = chan->txbds + i; in qmc_setup_chan()
1118 qmc_write16(&bd->cbd_sc, val); in qmc_setup_chan()
1120 bd = chan->txbds + QMC_NB_TXBDS - 1; in qmc_setup_chan()
1121 qmc_write16(&bd->cbd_sc, val | QMC_BD_TX_W); in qmc_setup_chan()
1131 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_setup_chans()
1145 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_finalize_chans()
1147 if (chan->mode == QMC_HDLC) { in qmc_finalize_chans()
1148 qmc_write16(chan->s_param + QMC_SPE_INTMSK, in qmc_finalize_chans()
1153 qmc_write16(chan->s_param + QMC_SPE_INTMSK, in qmc_finalize_chans()
1173 for (i = 0; i < (qmc->int_size / sizeof(u16)); i++) in qmc_setup_ints()
1174 qmc_write16(qmc->int_table + i, 0x0000); in qmc_setup_ints()
1177 if (qmc->int_size >= sizeof(u16)) { in qmc_setup_ints()
1178 last = qmc->int_table + (qmc->int_size / sizeof(u16)) - 1; in qmc_setup_ints()
1192 int_entry = qmc_read16(qmc->int_curr); in qmc_irq_gint()
1195 qmc_write16(qmc->int_curr, int_entry & QMC_INT_W); in qmc_irq_gint()
1198 chan = qmc->chans[chan_id]; in qmc_irq_gint()
1200 dev_err(qmc->dev, "interrupt on invalid chan %u\n", chan_id); in qmc_irq_gint()
1208 dev_info(qmc->dev, "intr chan %u, 0x%04x (UN)\n", chan_id, in qmc_irq_gint()
1210 chan->nb_tx_underrun++; in qmc_irq_gint()
1214 dev_info(qmc->dev, "intr chan %u, 0x%04x (BSY)\n", chan_id, in qmc_irq_gint()
1216 chan->nb_rx_busy++; in qmc_irq_gint()
1218 spin_lock_irqsave(&chan->rx_lock, flags); in qmc_irq_gint()
1219 if (chan->rx_pending && !chan->is_rx_stopped) { in qmc_irq_gint()
1220 if (chan->mode == QMC_TRANSPARENT) in qmc_irq_gint()
1221 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080); in qmc_irq_gint()
1223 qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080); in qmc_irq_gint()
1224 qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000); in qmc_irq_gint()
1225 chan->is_rx_halted = false; in qmc_irq_gint()
1227 chan->is_rx_halted = true; in qmc_irq_gint()
1229 spin_unlock_irqrestore(&chan->rx_lock, flags); in qmc_irq_gint()
1237 qmc->int_curr = qmc->int_table; in qmc_irq_gint()
1239 qmc->int_curr++; in qmc_irq_gint()
1240 int_entry = qmc_read16(qmc->int_curr); in qmc_irq_gint()
1249 scce = qmc_read16(qmc->scc_regs + SCC_SCCE); in qmc_irq_handler()
1250 qmc_write16(qmc->scc_regs + SCC_SCCE, scce); in qmc_irq_handler()
1253 dev_info(qmc->dev, "IRQ queue overflow\n"); in qmc_irq_handler()
1256 dev_err(qmc->dev, "Global transmitter underrun\n"); in qmc_irq_handler()
1259 dev_err(qmc->dev, "Global receiver overrun\n"); in qmc_irq_handler()
1272 qmc->scc_regs = devm_platform_ioremap_resource_byname(pdev, "scc_regs"); in qmc_cpm1_init_resources()
1273 if (IS_ERR(qmc->scc_regs)) in qmc_cpm1_init_resources()
1274 return PTR_ERR(qmc->scc_regs); in qmc_cpm1_init_resources()
1278 return -EINVAL; in qmc_cpm1_init_resources()
1279 qmc->scc_pram_offset = res->start - get_immrbase(); in qmc_cpm1_init_resources()
1280 qmc->scc_pram = devm_ioremap_resource(qmc->dev, res); in qmc_cpm1_init_resources()
1281 if (IS_ERR(qmc->scc_pram)) in qmc_cpm1_init_resources()
1282 return PTR_ERR(qmc->scc_pram); in qmc_cpm1_init_resources()
1284 qmc->dpram = devm_platform_ioremap_resource_byname(pdev, "dpram"); in qmc_cpm1_init_resources()
1285 if (IS_ERR(qmc->dpram)) in qmc_cpm1_init_resources()
1286 return PTR_ERR(qmc->dpram); in qmc_cpm1_init_resources()
1302 ret = tsa_serial_connect(qmc->tsa_serial); in qmc_cpm1_init_scc()
1304 return dev_err_probe(qmc->dev, ret, "Failed to connect TSA serial\n"); in qmc_cpm1_init_scc()
1308 qmc_write32(qmc->scc_regs + SCC_GSMRH, val); in qmc_cpm1_init_scc()
1311 qmc_write32(qmc->scc_regs + SCC_GSMRL, SCC_GSMRL_MODE_QMC); in qmc_cpm1_init_scc()
1314 qmc_write16(qmc->scc_regs + SCC_SCCM, 0x0000); in qmc_cpm1_init_scc()
1315 qmc_write16(qmc->scc_regs + SCC_SCCE, 0x000F); in qmc_cpm1_init_scc()
1328 tsa_serial_disconnect(qmc->tsa_serial); in qmc_exit_xcc()
1333 struct device_node *np = pdev->dev.of_node; in qmc_probe()
1339 qmc = devm_kzalloc(&pdev->dev, sizeof(*qmc), GFP_KERNEL); in qmc_probe()
1341 return -ENOMEM; in qmc_probe()
1343 qmc->dev = &pdev->dev; in qmc_probe()
1344 INIT_LIST_HEAD(&qmc->chan_head); in qmc_probe()
1346 qmc->tsa_serial = devm_tsa_serial_get_byphandle(qmc->dev, np, "fsl,tsa-serial"); in qmc_probe()
1347 if (IS_ERR(qmc->tsa_serial)) { in qmc_probe()
1348 return dev_err_probe(qmc->dev, PTR_ERR(qmc->tsa_serial), in qmc_probe()
1365 * 8 rx and 8 tx descriptors per channel in qmc_probe()
1367 qmc->bd_size = (nb_chans * (QMC_NB_TXBDS + QMC_NB_RXBDS)) * sizeof(cbd_t); in qmc_probe()
1368 qmc->bd_table = dmam_alloc_coherent(qmc->dev, qmc->bd_size, in qmc_probe()
1369 &qmc->bd_dma_addr, GFP_KERNEL); in qmc_probe()
1370 if (!qmc->bd_table) { in qmc_probe()
1371 dev_err(qmc->dev, "Failed to allocate bd table\n"); in qmc_probe()
1372 return -ENOMEM; in qmc_probe()
1374 memset(qmc->bd_table, 0, qmc->bd_size); in qmc_probe()
1376 qmc_write32(qmc->scc_pram + QMC_GBL_MCBASE, qmc->bd_dma_addr); in qmc_probe()
1379 qmc->int_size = QMC_NB_INTS * sizeof(u16); in qmc_probe()
1380 qmc->int_table = dmam_alloc_coherent(qmc->dev, qmc->int_size, in qmc_probe()
1381 &qmc->int_dma_addr, GFP_KERNEL); in qmc_probe()
1382 if (!qmc->int_table) { in qmc_probe()
1383 dev_err(qmc->dev, "Failed to allocate interrupt table\n"); in qmc_probe()
1384 return -ENOMEM; in qmc_probe()
1386 memset(qmc->int_table, 0, qmc->int_size); in qmc_probe()
1388 qmc->int_curr = qmc->int_table; in qmc_probe()
1389 qmc_write32(qmc->scc_pram + QMC_GBL_INTBASE, qmc->int_dma_addr); in qmc_probe()
1390 qmc_write32(qmc->scc_pram + QMC_GBL_INTPTR, qmc->int_dma_addr); in qmc_probe()
1393 qmc_write16(qmc->scc_pram + QMC_GBL_MRBLR, HDLC_MAX_MRU + 4); in qmc_probe()
1395 qmc_write16(qmc->scc_pram + QMC_GBL_GRFTHR, 1); in qmc_probe()
1396 qmc_write16(qmc->scc_pram + QMC_GBL_GRFCNT, 1); in qmc_probe()
1398 qmc_write32(qmc->scc_pram + QMC_GBL_C_MASK32, 0xDEBB20E3); in qmc_probe()
1399 qmc_write16(qmc->scc_pram + QMC_GBL_C_MASK16, 0xF0B8); in qmc_probe()
1405 qmc_write16(qmc->scc_pram + QMC_GBL_QMCSTATE, 0x8000); in qmc_probe()
1427 ret = devm_request_irq(qmc->dev, irq, qmc_irq_handler, 0, "qmc", qmc); in qmc_probe()
1432 qmc_write16(qmc->scc_regs + SCC_SCCM, in qmc_probe()
1440 qmc_setbits32(qmc->scc_regs + SCC_GSMRL, SCC_GSMRL_ENR | SCC_GSMRL_ENT); in qmc_probe()
1447 qmc_write16(qmc->scc_regs + SCC_SCCM, 0); in qmc_probe()
1459 qmc_setbits32(qmc->scc_regs + SCC_GSMRL, 0); in qmc_remove()
1462 qmc_write16(qmc->scc_regs + SCC_SCCM, 0); in qmc_remove()
1469 { .compatible = "fsl,cpm1-scc-qmc" },
1476 .name = "fsl-qmc",
1499 return ERR_PTR(-EINVAL); in qmc_chan_get_byphandle()
1505 return ERR_PTR(-ENODEV); in qmc_chan_get_byphandle()
1510 return ERR_PTR(-EPROBE_DEFER); in qmc_chan_get_byphandle()
1515 return ERR_PTR(-EINVAL); in qmc_chan_get_byphandle()
1518 if (out_args.args[0] >= ARRAY_SIZE(qmc->chans)) { in qmc_chan_get_byphandle()
1520 return ERR_PTR(-EINVAL); in qmc_chan_get_byphandle()
1523 qmc_chan = qmc->chans[out_args.args[0]]; in qmc_chan_get_byphandle()
1526 return ERR_PTR(-ENOENT); in qmc_chan_get_byphandle()
1535 put_device(chan->qmc->dev); in qmc_chan_put()
1555 return ERR_PTR(-ENOMEM); in devm_qmc_chan_get_byphandle()