The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring <robh@kernel.org> Link: https://lore.kernel.org/r/20230803-dt-header-cleanups-for-soc-v2-23-d8de2cc88bff@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
218 lines
5.2 KiB
C
218 lines
5.2 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (C) 2015 Freescale Semiconductor, Inc. All rights reserved.
|
|
*
|
|
* Authors: Zhao Qiang <qiang.zhao@nxp.com>
|
|
*
|
|
* Description:
|
|
* QE TDM API Set - TDM specific routines implementations.
|
|
*/
|
|
#include <linux/io.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/of.h>
|
|
#include <soc/fsl/qe/qe_tdm.h>
|
|
|
|
static int set_tdm_framer(const char *tdm_framer_type)
|
|
{
|
|
if (strcmp(tdm_framer_type, "e1") == 0)
|
|
return TDM_FRAMER_E1;
|
|
else if (strcmp(tdm_framer_type, "t1") == 0)
|
|
return TDM_FRAMER_T1;
|
|
else
|
|
return -EINVAL;
|
|
}
|
|
|
|
static void set_si_param(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info)
|
|
{
|
|
struct si_mode_info *si_info = &ut_info->si_info;
|
|
|
|
if (utdm->tdm_mode == TDM_INTERNAL_LOOPBACK) {
|
|
si_info->simr_crt = 1;
|
|
si_info->simr_rfsd = 0;
|
|
}
|
|
}
|
|
|
|
int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm,
|
|
struct ucc_tdm_info *ut_info)
|
|
{
|
|
const char *sprop;
|
|
int ret = 0;
|
|
u32 val;
|
|
|
|
sprop = of_get_property(np, "fsl,rx-sync-clock", NULL);
|
|
if (sprop) {
|
|
ut_info->uf_info.rx_sync = qe_clock_source(sprop);
|
|
if ((ut_info->uf_info.rx_sync < QE_CLK_NONE) ||
|
|
(ut_info->uf_info.rx_sync > QE_RSYNC_PIN)) {
|
|
pr_err("QE-TDM: Invalid rx-sync-clock property\n");
|
|
return -EINVAL;
|
|
}
|
|
} else {
|
|
pr_err("QE-TDM: Invalid rx-sync-clock property\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
sprop = of_get_property(np, "fsl,tx-sync-clock", NULL);
|
|
if (sprop) {
|
|
ut_info->uf_info.tx_sync = qe_clock_source(sprop);
|
|
if ((ut_info->uf_info.tx_sync < QE_CLK_NONE) ||
|
|
(ut_info->uf_info.tx_sync > QE_TSYNC_PIN)) {
|
|
pr_err("QE-TDM: Invalid tx-sync-clock property\n");
|
|
return -EINVAL;
|
|
}
|
|
} else {
|
|
pr_err("QE-TDM: Invalid tx-sync-clock property\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = of_property_read_u32_index(np, "fsl,tx-timeslot-mask", 0, &val);
|
|
if (ret) {
|
|
pr_err("QE-TDM: Invalid tx-timeslot-mask property\n");
|
|
return -EINVAL;
|
|
}
|
|
utdm->tx_ts_mask = val;
|
|
|
|
ret = of_property_read_u32_index(np, "fsl,rx-timeslot-mask", 0, &val);
|
|
if (ret) {
|
|
ret = -EINVAL;
|
|
pr_err("QE-TDM: Invalid rx-timeslot-mask property\n");
|
|
return ret;
|
|
}
|
|
utdm->rx_ts_mask = val;
|
|
|
|
ret = of_property_read_u32_index(np, "fsl,tdm-id", 0, &val);
|
|
if (ret) {
|
|
ret = -EINVAL;
|
|
pr_err("QE-TDM: No fsl,tdm-id property for this UCC\n");
|
|
return ret;
|
|
}
|
|
utdm->tdm_port = val;
|
|
ut_info->uf_info.tdm_num = utdm->tdm_port;
|
|
|
|
if (of_property_read_bool(np, "fsl,tdm-internal-loopback"))
|
|
utdm->tdm_mode = TDM_INTERNAL_LOOPBACK;
|
|
else
|
|
utdm->tdm_mode = TDM_NORMAL;
|
|
|
|
sprop = of_get_property(np, "fsl,tdm-framer-type", NULL);
|
|
if (!sprop) {
|
|
ret = -EINVAL;
|
|
pr_err("QE-TDM: No tdm-framer-type property for UCC\n");
|
|
return ret;
|
|
}
|
|
ret = set_tdm_framer(sprop);
|
|
if (ret < 0)
|
|
return -EINVAL;
|
|
utdm->tdm_framer_type = ret;
|
|
|
|
ret = of_property_read_u32_index(np, "fsl,siram-entry-id", 0, &val);
|
|
if (ret) {
|
|
ret = -EINVAL;
|
|
pr_err("QE-TDM: No siram entry id for UCC\n");
|
|
return ret;
|
|
}
|
|
utdm->siram_entry_id = val;
|
|
|
|
set_si_param(utdm, ut_info);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(ucc_of_parse_tdm);
|
|
|
|
void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info)
|
|
{
|
|
struct si1 __iomem *si_regs;
|
|
u16 __iomem *siram;
|
|
u16 siram_entry_valid;
|
|
u16 siram_entry_closed;
|
|
u16 ucc_num;
|
|
u8 csel;
|
|
u16 sixmr;
|
|
u16 tdm_port;
|
|
u32 siram_entry_id;
|
|
u32 mask;
|
|
int i;
|
|
|
|
si_regs = utdm->si_regs;
|
|
siram = utdm->siram;
|
|
ucc_num = ut_info->uf_info.ucc_num;
|
|
tdm_port = utdm->tdm_port;
|
|
siram_entry_id = utdm->siram_entry_id;
|
|
|
|
if (utdm->tdm_framer_type == TDM_FRAMER_T1)
|
|
utdm->num_of_ts = 24;
|
|
if (utdm->tdm_framer_type == TDM_FRAMER_E1)
|
|
utdm->num_of_ts = 32;
|
|
|
|
/* set siram table */
|
|
csel = (ucc_num < 4) ? ucc_num + 9 : ucc_num - 3;
|
|
|
|
siram_entry_valid = SIR_CSEL(csel) | SIR_BYTE | SIR_CNT(0);
|
|
siram_entry_closed = SIR_IDLE | SIR_BYTE | SIR_CNT(0);
|
|
|
|
for (i = 0; i < utdm->num_of_ts; i++) {
|
|
mask = 0x01 << i;
|
|
|
|
if (utdm->tx_ts_mask & mask)
|
|
iowrite16be(siram_entry_valid,
|
|
&siram[siram_entry_id * 32 + i]);
|
|
else
|
|
iowrite16be(siram_entry_closed,
|
|
&siram[siram_entry_id * 32 + i]);
|
|
|
|
if (utdm->rx_ts_mask & mask)
|
|
iowrite16be(siram_entry_valid,
|
|
&siram[siram_entry_id * 32 + 0x200 + i]);
|
|
else
|
|
iowrite16be(siram_entry_closed,
|
|
&siram[siram_entry_id * 32 + 0x200 + i]);
|
|
}
|
|
|
|
qe_setbits_be16(&siram[(siram_entry_id * 32) + (utdm->num_of_ts - 1)],
|
|
SIR_LAST);
|
|
qe_setbits_be16(&siram[(siram_entry_id * 32) + 0x200 + (utdm->num_of_ts - 1)],
|
|
SIR_LAST);
|
|
|
|
/* Set SIxMR register */
|
|
sixmr = SIMR_SAD(siram_entry_id);
|
|
|
|
sixmr &= ~SIMR_SDM_MASK;
|
|
|
|
if (utdm->tdm_mode == TDM_INTERNAL_LOOPBACK)
|
|
sixmr |= SIMR_SDM_INTERNAL_LOOPBACK;
|
|
else
|
|
sixmr |= SIMR_SDM_NORMAL;
|
|
|
|
sixmr |= SIMR_RFSD(ut_info->si_info.simr_rfsd) |
|
|
SIMR_TFSD(ut_info->si_info.simr_tfsd);
|
|
|
|
if (ut_info->si_info.simr_crt)
|
|
sixmr |= SIMR_CRT;
|
|
if (ut_info->si_info.simr_sl)
|
|
sixmr |= SIMR_SL;
|
|
if (ut_info->si_info.simr_ce)
|
|
sixmr |= SIMR_CE;
|
|
if (ut_info->si_info.simr_fe)
|
|
sixmr |= SIMR_FE;
|
|
if (ut_info->si_info.simr_gm)
|
|
sixmr |= SIMR_GM;
|
|
|
|
switch (tdm_port) {
|
|
case 0:
|
|
iowrite16be(sixmr, &si_regs->sixmr1[0]);
|
|
break;
|
|
case 1:
|
|
iowrite16be(sixmr, &si_regs->sixmr1[1]);
|
|
break;
|
|
case 2:
|
|
iowrite16be(sixmr, &si_regs->sixmr1[2]);
|
|
break;
|
|
case 3:
|
|
iowrite16be(sixmr, &si_regs->sixmr1[3]);
|
|
break;
|
|
default:
|
|
pr_err("QE-TDM: can not find tdm sixmr reg\n");
|
|
break;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(ucc_tdm_init);
|