Lines Matching full:qmc

3  * QMC driver
10 #include <soc/fsl/qe/qmc.h>
177 struct qmc *qmc; member
203 struct qmc { struct
262 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &tsa_info); in qmc_chan_get_info()
289 qmc_write16(chan->qmc->scc_pram + QMC_GBL_MRBLR, in qmc_chan_set_param()
449 qmc_write16(&bd->cbd_datlen, 0); /* data length is updated by the QMC */ in qmc_chan_read_submit()
556 dev_err(chan->qmc->dev, "chan %u: Send STOP RECEIVE failed (%d)\n", in qmc_chan_stop_rx()
578 dev_err(chan->qmc->dev, "chan %u: Send STOP TRANSMIT failed (%d)\n", in qmc_chan_stop_tx()
739 static int qmc_check_chans(struct qmc *qmc) in qmc_check_chans() argument
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()
766 dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned are not equal\n"); in qmc_check_chans()
775 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_check_chans()
777 dev_err(qmc->dev, "chan %u uses TSA unassigned Tx TS\n", chan->id); in qmc_check_chans()
781 dev_err(qmc->dev, "chan %u uses an already used Tx TS\n", chan->id); in qmc_check_chans()
786 dev_err(qmc->dev, "chan %u uses TSA unassigned Rx TS\n", chan->id); in qmc_check_chans()
790 dev_err(qmc->dev, "chan %u uses an already used Rx TS\n", chan->id); in qmc_check_chans()
795 dev_err(qmc->dev, "chan %u uses different Rx and Tx TS\n", chan->id); in qmc_check_chans()
806 static unsigned int qmc_nb_chans(struct qmc *qmc) in qmc_nb_chans() argument
811 list_for_each_entry(chan, &qmc->chan_head, list) in qmc_nb_chans()
817 static int qmc_of_parse_chans(struct qmc *qmc, struct device_node *np) in qmc_of_parse_chans() argument
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()
839 chan = devm_kzalloc(qmc->dev, sizeof(*chan), GFP_KERNEL); in qmc_of_parse_chans()
851 dev_err(qmc->dev, "%pOF: failed to read fsl,tx-ts-mask\n", in qmc_of_parse_chans()
860 dev_err(qmc->dev, "%pOF: failed to read fsl,rx-ts-mask\n", in qmc_of_parse_chans()
870 dev_err(qmc->dev, "%pOF: failed to read fsl,operational-mode\n", in qmc_of_parse_chans()
880 dev_err(qmc->dev, "%pOF: Invalid fsl,operational-mode (%s)\n", 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()
893 return qmc_check_chans(qmc); in qmc_of_parse_chans()
896 static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info *info) in qmc_setup_tsa_64rxtx() argument
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()
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()
938 static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, const struct tsa_serial_info *info) in qmc_setup_tsa_32rx_32tx() argument
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()
956 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_setup_tsa_32rx_32tx()
964 qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), val); 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()
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()
996 static int qmc_setup_tsa(struct qmc *qmc) in qmc_setup_tsa() argument
1002 ret = tsa_serial_get_info(qmc->tsa_serial, &info); in qmc_setup_tsa()
1011 qmc_setup_tsa_64rxtx(qmc, &info) : in qmc_setup_tsa()
1012 qmc_setup_tsa_32rx_32tx(qmc, &info); in qmc_setup_tsa()
1015 static int qmc_setup_chan_trnsync(struct qmc *qmc, struct qmc_chan *chan) in qmc_setup_chan_trnsync() argument
1023 ret = tsa_serial_get_info(chan->qmc->tsa_serial, &info); 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()
1049 static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan) in qmc_setup_chan() argument
1056 chan->qmc = qmc; in qmc_setup_chan()
1059 chan->s_param = qmc->dpram + (chan->id * 64); 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()
1088 ret = qmc_setup_chan_trnsync(qmc, chan); in qmc_setup_chan()
1126 static int qmc_setup_chans(struct qmc *qmc) in qmc_setup_chans() argument
1131 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_setup_chans()
1132 ret = qmc_setup_chan(qmc, chan); in qmc_setup_chans()
1140 static int qmc_finalize_chans(struct qmc *qmc) in qmc_finalize_chans() argument
1145 list_for_each_entry(chan, &qmc->chan_head, list) { in qmc_finalize_chans()
1167 static int qmc_setup_ints(struct qmc *qmc) in qmc_setup_ints() argument
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()
1185 static void qmc_irq_gint(struct qmc *qmc) in qmc_irq_gint() argument
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()
1214 dev_info(qmc->dev, "intr chan %u, 0x%04x (BSY)\n", chan_id, 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()
1246 struct qmc *qmc = (struct qmc *)priv; in qmc_irq_handler() local
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()
1263 qmc_irq_gint(qmc); in qmc_irq_handler()
1268 static int qmc_cpm1_init_resources(struct qmc *qmc, struct platform_device *pdev) in qmc_cpm1_init_resources() argument
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()
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()
1291 static int qmc_init_resources(struct qmc *qmc, struct platform_device *pdev) in qmc_init_resources() argument
1293 return qmc_cpm1_init_resources(qmc, pdev); in qmc_init_resources()
1296 static int qmc_cpm1_init_scc(struct qmc *qmc) in qmc_cpm1_init_scc() argument
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()
1310 /* enable QMC mode */ 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()
1320 static int qmc_init_xcc(struct qmc *qmc) in qmc_init_xcc() argument
1322 return qmc_cpm1_init_scc(qmc); in qmc_init_xcc()
1325 static void qmc_exit_xcc(struct qmc *qmc) in qmc_exit_xcc() argument
1328 tsa_serial_disconnect(qmc->tsa_serial); in qmc_exit_xcc()
1335 struct qmc *qmc; in qmc_probe() local
1339 qmc = devm_kzalloc(&pdev->dev, sizeof(*qmc), GFP_KERNEL); in qmc_probe()
1340 if (!qmc) 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()
1352 ret = qmc_init_resources(qmc, pdev); in qmc_probe()
1357 ret = qmc_of_parse_chans(qmc, np); in qmc_probe()
1361 nb_chans = qmc_nb_chans(qmc); 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()
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()
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()
1401 ret = qmc_setup_tsa(qmc); in qmc_probe()
1405 qmc_write16(qmc->scc_pram + QMC_GBL_QMCSTATE, 0x8000); in qmc_probe()
1407 ret = qmc_setup_chans(qmc); in qmc_probe()
1412 ret = qmc_setup_ints(qmc); in qmc_probe()
1417 ret = qmc_init_xcc(qmc); 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()
1435 ret = qmc_finalize_chans(qmc); in qmc_probe()
1440 qmc_setbits32(qmc->scc_regs + SCC_GSMRL, SCC_GSMRL_ENR | SCC_GSMRL_ENT); in qmc_probe()
1442 platform_set_drvdata(pdev, qmc); in qmc_probe()
1447 qmc_write16(qmc->scc_regs + SCC_SCCM, 0); in qmc_probe()
1450 qmc_exit_xcc(qmc); in qmc_probe()
1456 struct qmc *qmc = platform_get_drvdata(pdev); in qmc_remove() local
1459 qmc_setbits32(qmc->scc_regs + SCC_GSMRL, 0); in qmc_remove()
1462 qmc_write16(qmc->scc_regs + SCC_SCCM, 0); in qmc_remove()
1465 qmc_exit_xcc(qmc); in qmc_remove()
1469 { .compatible = "fsl,cpm1-scc-qmc" },
1476 .name = "fsl-qmc",
1489 struct qmc *qmc; in qmc_chan_get_byphandle() local
1507 qmc = platform_get_drvdata(pdev); in qmc_chan_get_byphandle()
1508 if (!qmc) { in qmc_chan_get_byphandle()
1518 if (out_args.args[0] >= ARRAY_SIZE(qmc->chans)) { in qmc_chan_get_byphandle()
1523 qmc_chan = qmc->chans[out_args.args[0]]; in qmc_chan_get_byphandle()
1535 put_device(chan->qmc->dev); in qmc_chan_put()
1570 MODULE_DESCRIPTION("CPM QMC driver");