Lines Matching +full:tdm +full:- +full:sync +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0
11 #include <dt-bindings/soc/cpm1-fsl,tsa.h>
33 /* SI mode register (32 bits) */
54 /* SI global mode register (8 bits) */
125 struct tsa_tdm tdm[2]; /* TDMa and TDMb */ member
135 return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]); in tsa_serial_get_tsa()
170 switch (tsa_serial->id) { in tsa_serial_connect()
184 dev_err(tsa->dev, "Unsupported serial id %u\n", tsa_serial->id); in tsa_serial_connect()
185 return -EINVAL; in tsa_serial_connect()
188 spin_lock_irqsave(&tsa->lock, flags); in tsa_serial_connect()
189 tsa_clrsetbits32(tsa->si_regs + TSA_SICR, clear, set); in tsa_serial_connect()
190 spin_unlock_irqrestore(&tsa->lock, flags); in tsa_serial_connect()
202 switch (tsa_serial->id) { in tsa_serial_disconnect()
213 dev_err(tsa->dev, "Unsupported serial id %u\n", tsa_serial->id); in tsa_serial_disconnect()
214 return -EINVAL; in tsa_serial_disconnect()
217 spin_lock_irqsave(&tsa->lock, flags); in tsa_serial_disconnect()
218 tsa_clrsetbits32(tsa->si_regs + TSA_SICR, clear, 0); in tsa_serial_disconnect()
219 spin_unlock_irqrestore(&tsa->lock, flags); in tsa_serial_disconnect()
227 memcpy(info, &tsa_serial->info, sizeof(*info)); in tsa_serial_get_info()
238 quarter = tsa->si_ram_sz/4; in tsa_init_entries_area()
239 half = tsa->si_ram_sz/2; in tsa_init_entries_area()
245 area->entries_start = tsa->si_ram; in tsa_init_entries_area()
246 area->entries_next = area->entries_start + half; in tsa_init_entries_area()
247 area->last_entry = NULL; in tsa_init_entries_area()
250 area->entries_start = tsa->si_ram + half; in tsa_init_entries_area()
251 area->entries_next = area->entries_start + half; in tsa_init_entries_area()
252 area->last_entry = NULL; in tsa_init_entries_area()
259 area->entries_start = tsa->si_ram; in tsa_init_entries_area()
260 area->entries_next = area->entries_start + quarter; in tsa_init_entries_area()
261 area->last_entry = NULL; in tsa_init_entries_area()
264 area->entries_start = tsa->si_ram + (2 * quarter); in tsa_init_entries_area()
265 area->entries_next = area->entries_start + quarter; in tsa_init_entries_area()
266 area->last_entry = NULL; in tsa_init_entries_area()
271 area->entries_start = tsa->si_ram + quarter; in tsa_init_entries_area()
272 area->entries_next = area->entries_start + quarter; in tsa_init_entries_area()
273 area->last_entry = NULL; in tsa_init_entries_area()
276 area->entries_start = tsa->si_ram + (3 * quarter); in tsa_init_entries_area()
277 area->entries_next = area->entries_start + quarter; in tsa_init_entries_area()
278 area->last_entry = NULL; in tsa_init_entries_area()
322 addr = area->last_entry ? area->last_entry + 4 : area->entries_start; in tsa_add_entry()
325 if ((addr + (nb * 4)) > area->entries_next) { in tsa_add_entry()
326 dev_err(tsa->dev, "si ram area full\n"); in tsa_add_entry()
327 return -ENOSPC; in tsa_add_entry()
330 if (area->last_entry) { in tsa_add_entry()
332 tsa_clrbits32(area->last_entry, TSA_SIRAM_ENTRY_LAST); in tsa_add_entry()
344 area->last_entry = addr; in tsa_add_entry()
346 val |= TSA_SIRAM_ENTRY_CNT(cnt - 1); in tsa_add_entry()
350 left -= cnt; in tsa_add_entry()
366 struct tsa_tdm *tdm; in tsa_of_parse_tdm_route() local
370 route_name = is_rx ? "fsl,rx-ts-routes" : "fsl,tx-ts-routes"; in tsa_of_parse_tdm_route()
374 dev_err(tsa->dev, "%pOF: failed to read %s\n", tdm_np, route_name); in tsa_of_parse_tdm_route()
378 dev_err(tsa->dev, "%pOF: wrong %s format\n", tdm_np, route_name); in tsa_of_parse_tdm_route()
379 return -EINVAL; in tsa_of_parse_tdm_route()
388 if (serial_id >= ARRAY_SIZE(tsa->serials)) { in tsa_of_parse_tdm_route()
389 dev_err(tsa->dev, "%pOF: invalid serial id (%u)\n", in tsa_of_parse_tdm_route()
391 return -EINVAL; in tsa_of_parse_tdm_route()
396 dev_err(tsa->dev, "%pOF: unsupported serial id (%u)\n", in tsa_of_parse_tdm_route()
398 return -EINVAL; in tsa_of_parse_tdm_route()
401 dev_dbg(tsa->dev, "tdm_id=%u, %s ts %u..%u -> %s\n", in tsa_of_parse_tdm_route()
402 tdm_id, route_name, ts, ts+count-1, serial_name); in tsa_of_parse_tdm_route()
409 serial_info = &tsa->serials[serial_id].info; in tsa_of_parse_tdm_route()
410 tdm = &tsa->tdm[tdm_id]; in tsa_of_parse_tdm_route()
412 serial_info->rx_fs_rate = clk_get_rate(tdm->l1rsync_clk); in tsa_of_parse_tdm_route()
413 serial_info->rx_bit_rate = clk_get_rate(tdm->l1rclk_clk); in tsa_of_parse_tdm_route()
414 serial_info->nb_rx_ts += count; in tsa_of_parse_tdm_route()
416 serial_info->tx_fs_rate = tdm->l1tsync_clk ? in tsa_of_parse_tdm_route()
417 clk_get_rate(tdm->l1tsync_clk) : in tsa_of_parse_tdm_route()
418 clk_get_rate(tdm->l1rsync_clk); in tsa_of_parse_tdm_route()
419 serial_info->tx_bit_rate = tdm->l1tclk_clk ? in tsa_of_parse_tdm_route()
420 clk_get_rate(tdm->l1tclk_clk) : in tsa_of_parse_tdm_route()
421 clk_get_rate(tdm->l1rclk_clk); in tsa_of_parse_tdm_route()
422 serial_info->nb_tx_ts += count; in tsa_of_parse_tdm_route()
445 struct tsa_tdm *tdm; in tsa_of_parse_tdms() local
451 tsa->tdms = 0; in tsa_of_parse_tdms()
452 tsa->tdm[0].is_enable = false; in tsa_of_parse_tdms()
453 tsa->tdm[1].is_enable = false; in tsa_of_parse_tdms()
458 dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np); in tsa_of_parse_tdms()
464 tsa->tdms |= BIT(TSA_TDMA); in tsa_of_parse_tdms()
467 tsa->tdms |= BIT(TSA_TDMB); in tsa_of_parse_tdms()
470 dev_err(tsa->dev, "%pOF: Invalid tdm_id (%u)\n", tdm_np, in tsa_of_parse_tdms()
473 return -EINVAL; in tsa_of_parse_tdms()
480 dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np); in tsa_of_parse_tdms()
485 tdm = &tsa->tdm[tdm_id]; in tsa_of_parse_tdms()
486 tdm->simode_tdm = TSA_SIMODE_TDM_SDM_NORM; in tsa_of_parse_tdms()
489 ret = of_property_read_u32(tdm_np, "fsl,rx-frame-sync-delay-bits", in tsa_of_parse_tdms()
491 if (ret && ret != -EINVAL) { in tsa_of_parse_tdms()
492 dev_err(tsa->dev, in tsa_of_parse_tdms()
493 "%pOF: failed to read fsl,rx-frame-sync-delay-bits\n", in tsa_of_parse_tdms()
499 dev_err(tsa->dev, in tsa_of_parse_tdms()
500 "%pOF: Invalid fsl,rx-frame-sync-delay-bits (%u)\n", in tsa_of_parse_tdms()
503 return -EINVAL; in tsa_of_parse_tdms()
505 tdm->simode_tdm |= TSA_SIMODE_TDM_RFSD(val); in tsa_of_parse_tdms()
508 ret = of_property_read_u32(tdm_np, "fsl,tx-frame-sync-delay-bits", in tsa_of_parse_tdms()
510 if (ret && ret != -EINVAL) { in tsa_of_parse_tdms()
511 dev_err(tsa->dev, in tsa_of_parse_tdms()
512 "%pOF: failed to read fsl,tx-frame-sync-delay-bits\n", in tsa_of_parse_tdms()
518 dev_err(tsa->dev, in tsa_of_parse_tdms()
519 "%pOF: Invalid fsl,tx-frame-sync-delay-bits (%u)\n", in tsa_of_parse_tdms()
522 return -EINVAL; in tsa_of_parse_tdms()
524 tdm->simode_tdm |= TSA_SIMODE_TDM_TFSD(val); in tsa_of_parse_tdms()
526 if (of_property_read_bool(tdm_np, "fsl,common-rxtx-pins")) in tsa_of_parse_tdms()
527 tdm->simode_tdm |= TSA_SIMODE_TDM_CRT; in tsa_of_parse_tdms()
529 if (of_property_read_bool(tdm_np, "fsl,clock-falling-edge")) in tsa_of_parse_tdms()
530 tdm->simode_tdm |= TSA_SIMODE_TDM_CE; in tsa_of_parse_tdms()
532 if (of_property_read_bool(tdm_np, "fsl,fsync-rising-edge")) in tsa_of_parse_tdms()
533 tdm->simode_tdm |= TSA_SIMODE_TDM_FE; in tsa_of_parse_tdms()
535 if (of_property_read_bool(tdm_np, "fsl,double-speed-clock")) in tsa_of_parse_tdms()
536 tdm->simode_tdm |= TSA_SIMODE_TDM_DSC; in tsa_of_parse_tdms()
550 tdm->l1rsync_clk = clk; in tsa_of_parse_tdms()
564 tdm->l1rclk_clk = clk; in tsa_of_parse_tdms()
566 if (!(tdm->simode_tdm & TSA_SIMODE_TDM_CRT)) { in tsa_of_parse_tdms()
579 tdm->l1tsync_clk = clk; in tsa_of_parse_tdms()
593 tdm->l1tclk_clk = clk; in tsa_of_parse_tdms()
596 ret = tsa_of_parse_tdm_rx_route(tsa, tdm_np, tsa->tdms, tdm_id); in tsa_of_parse_tdms()
602 ret = tsa_of_parse_tdm_tx_route(tsa, tdm_np, tsa->tdms, tdm_id); in tsa_of_parse_tdms()
608 tdm->is_enable = true; in tsa_of_parse_tdms()
614 if (tsa->tdm[i].l1rsync_clk) { in tsa_of_parse_tdms()
615 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
616 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
618 if (tsa->tdm[i].l1rclk_clk) { in tsa_of_parse_tdms()
619 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
620 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
622 if (tsa->tdm[i].l1tsync_clk) { in tsa_of_parse_tdms()
623 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
624 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
626 if (tsa->tdm[i].l1tclk_clk) { in tsa_of_parse_tdms()
627 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
628 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
639 for (i = 0; i < tsa->si_ram_sz; i += 4) in tsa_init_si_ram()
640 tsa_write32(tsa->si_ram + i, TSA_SIRAM_ENTRY_LAST); in tsa_init_si_ram()
645 struct device_node *np = pdev->dev.of_node; in tsa_probe()
652 tsa = devm_kzalloc(&pdev->dev, sizeof(*tsa), GFP_KERNEL); in tsa_probe()
654 return -ENOMEM; in tsa_probe()
656 tsa->dev = &pdev->dev; in tsa_probe()
658 for (i = 0; i < ARRAY_SIZE(tsa->serials); i++) in tsa_probe()
659 tsa->serials[i].id = i; in tsa_probe()
661 spin_lock_init(&tsa->lock); in tsa_probe()
663 tsa->si_regs = devm_platform_ioremap_resource_byname(pdev, "si_regs"); in tsa_probe()
664 if (IS_ERR(tsa->si_regs)) in tsa_probe()
665 return PTR_ERR(tsa->si_regs); in tsa_probe()
669 dev_err(tsa->dev, "si_ram resource missing\n"); in tsa_probe()
670 return -EINVAL; in tsa_probe()
672 tsa->si_ram_sz = resource_size(res); in tsa_probe()
673 tsa->si_ram = devm_ioremap_resource(&pdev->dev, res); in tsa_probe()
674 if (IS_ERR(tsa->si_ram)) in tsa_probe()
675 return PTR_ERR(tsa->si_ram); in tsa_probe()
685 if (tsa->tdm[0].is_enable) in tsa_probe()
686 val |= TSA_SIMODE_TDMA(tsa->tdm[0].simode_tdm); in tsa_probe()
687 if (tsa->tdm[1].is_enable) in tsa_probe()
688 val |= TSA_SIMODE_TDMB(tsa->tdm[1].simode_tdm); in tsa_probe()
690 tsa_clrsetbits32(tsa->si_regs + TSA_SIMODE, in tsa_probe()
696 val = (tsa->tdms == BIT(TSA_TDMA)) ? in tsa_probe()
698 if (tsa->tdms & BIT(TSA_TDMA)) in tsa_probe()
700 if (tsa->tdms & BIT(TSA_TDMB)) in tsa_probe()
702 tsa_write8(tsa->si_regs + TSA_SIGMR, val); in tsa_probe()
715 if (tsa->tdm[i].l1rsync_clk) { in tsa_remove()
716 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_remove()
717 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_remove()
719 if (tsa->tdm[i].l1rclk_clk) { in tsa_remove()
720 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_remove()
721 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_remove()
723 if (tsa->tdm[i].l1tsync_clk) { in tsa_remove()
724 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_remove()
725 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_remove()
727 if (tsa->tdm[i].l1tclk_clk) { in tsa_remove()
728 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_remove()
729 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_remove()
736 { .compatible = "fsl,cpm1-tsa" },
743 .name = "fsl-tsa",
766 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
772 return ERR_PTR(-ENODEV); in tsa_serial_get_byphandle()
777 return ERR_PTR(-EPROBE_DEFER); in tsa_serial_get_byphandle()
782 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
785 if (out_args.args[0] >= ARRAY_SIZE(tsa->serials)) { in tsa_serial_get_byphandle()
787 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
790 tsa_serial = &tsa->serials[out_args.args[0]]; in tsa_serial_get_byphandle()
797 if (WARN_ON(tsa_serial->id != out_args.args[0])) { in tsa_serial_get_byphandle()
799 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
810 put_device(tsa->dev); in tsa_serial_put()
830 return ERR_PTR(-ENOMEM); in devm_tsa_serial_get_byphandle()