1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2015 Freescale Semiconductor, Inc. All rights reserved.
5 * Authors: Zhao Qiang <qiang.zhao@nxp.com>
8 * QE TDM API Set - TDM specific routines implementations.
11 #include <linux/kernel.h>
12 #include <linux/of_address.h>
13 #include <linux/of_irq.h>
14 #include <linux/of_platform.h>
15 #include <soc/fsl/qe/qe_tdm.h>
17 static int set_tdm_framer(const char *tdm_framer_type
)
19 if (strcmp(tdm_framer_type
, "e1") == 0)
21 else if (strcmp(tdm_framer_type
, "t1") == 0)
27 static void set_si_param(struct ucc_tdm
*utdm
, struct ucc_tdm_info
*ut_info
)
29 struct si_mode_info
*si_info
= &ut_info
->si_info
;
31 if (utdm
->tdm_mode
== TDM_INTERNAL_LOOPBACK
) {
32 si_info
->simr_crt
= 1;
33 si_info
->simr_rfsd
= 0;
37 int ucc_of_parse_tdm(struct device_node
*np
, struct ucc_tdm
*utdm
,
38 struct ucc_tdm_info
*ut_info
)
44 sprop
= of_get_property(np
, "fsl,rx-sync-clock", NULL
);
46 ut_info
->uf_info
.rx_sync
= qe_clock_source(sprop
);
47 if ((ut_info
->uf_info
.rx_sync
< QE_CLK_NONE
) ||
48 (ut_info
->uf_info
.rx_sync
> QE_RSYNC_PIN
)) {
49 pr_err("QE-TDM: Invalid rx-sync-clock property\n");
53 pr_err("QE-TDM: Invalid rx-sync-clock property\n");
57 sprop
= of_get_property(np
, "fsl,tx-sync-clock", NULL
);
59 ut_info
->uf_info
.tx_sync
= qe_clock_source(sprop
);
60 if ((ut_info
->uf_info
.tx_sync
< QE_CLK_NONE
) ||
61 (ut_info
->uf_info
.tx_sync
> QE_TSYNC_PIN
)) {
62 pr_err("QE-TDM: Invalid tx-sync-clock property\n");
66 pr_err("QE-TDM: Invalid tx-sync-clock property\n");
70 ret
= of_property_read_u32_index(np
, "fsl,tx-timeslot-mask", 0, &val
);
72 pr_err("QE-TDM: Invalid tx-timeslot-mask property\n");
75 utdm
->tx_ts_mask
= val
;
77 ret
= of_property_read_u32_index(np
, "fsl,rx-timeslot-mask", 0, &val
);
80 pr_err("QE-TDM: Invalid rx-timeslot-mask property\n");
83 utdm
->rx_ts_mask
= val
;
85 ret
= of_property_read_u32_index(np
, "fsl,tdm-id", 0, &val
);
88 pr_err("QE-TDM: No fsl,tdm-id property for this UCC\n");
92 ut_info
->uf_info
.tdm_num
= utdm
->tdm_port
;
94 if (of_property_read_bool(np
, "fsl,tdm-internal-loopback"))
95 utdm
->tdm_mode
= TDM_INTERNAL_LOOPBACK
;
97 utdm
->tdm_mode
= TDM_NORMAL
;
99 sprop
= of_get_property(np
, "fsl,tdm-framer-type", NULL
);
102 pr_err("QE-TDM: No tdm-framer-type property for UCC\n");
105 ret
= set_tdm_framer(sprop
);
108 utdm
->tdm_framer_type
= ret
;
110 ret
= of_property_read_u32_index(np
, "fsl,siram-entry-id", 0, &val
);
113 pr_err("QE-TDM: No siram entry id for UCC\n");
116 utdm
->siram_entry_id
= val
;
118 set_si_param(utdm
, ut_info
);
121 EXPORT_SYMBOL(ucc_of_parse_tdm
);
123 void ucc_tdm_init(struct ucc_tdm
*utdm
, struct ucc_tdm_info
*ut_info
)
125 struct si1 __iomem
*si_regs
;
127 u16 siram_entry_valid
;
128 u16 siram_entry_closed
;
137 si_regs
= utdm
->si_regs
;
139 ucc_num
= ut_info
->uf_info
.ucc_num
;
140 tdm_port
= utdm
->tdm_port
;
141 siram_entry_id
= utdm
->siram_entry_id
;
143 if (utdm
->tdm_framer_type
== TDM_FRAMER_T1
)
144 utdm
->num_of_ts
= 24;
145 if (utdm
->tdm_framer_type
== TDM_FRAMER_E1
)
146 utdm
->num_of_ts
= 32;
148 /* set siram table */
149 csel
= (ucc_num
< 4) ? ucc_num
+ 9 : ucc_num
- 3;
151 siram_entry_valid
= SIR_CSEL(csel
) | SIR_BYTE
| SIR_CNT(0);
152 siram_entry_closed
= SIR_IDLE
| SIR_BYTE
| SIR_CNT(0);
154 for (i
= 0; i
< utdm
->num_of_ts
; i
++) {
157 if (utdm
->tx_ts_mask
& mask
)
158 iowrite16be(siram_entry_valid
,
159 &siram
[siram_entry_id
* 32 + i
]);
161 iowrite16be(siram_entry_closed
,
162 &siram
[siram_entry_id
* 32 + i
]);
164 if (utdm
->rx_ts_mask
& mask
)
165 iowrite16be(siram_entry_valid
,
166 &siram
[siram_entry_id
* 32 + 0x200 + i
]);
168 iowrite16be(siram_entry_closed
,
169 &siram
[siram_entry_id
* 32 + 0x200 + i
]);
172 setbits16(&siram
[(siram_entry_id
* 32) + (utdm
->num_of_ts
- 1)],
174 setbits16(&siram
[(siram_entry_id
* 32) + 0x200 + (utdm
->num_of_ts
- 1)],
177 /* Set SIxMR register */
178 sixmr
= SIMR_SAD(siram_entry_id
);
180 sixmr
&= ~SIMR_SDM_MASK
;
182 if (utdm
->tdm_mode
== TDM_INTERNAL_LOOPBACK
)
183 sixmr
|= SIMR_SDM_INTERNAL_LOOPBACK
;
185 sixmr
|= SIMR_SDM_NORMAL
;
187 sixmr
|= SIMR_RFSD(ut_info
->si_info
.simr_rfsd
) |
188 SIMR_TFSD(ut_info
->si_info
.simr_tfsd
);
190 if (ut_info
->si_info
.simr_crt
)
192 if (ut_info
->si_info
.simr_sl
)
194 if (ut_info
->si_info
.simr_ce
)
196 if (ut_info
->si_info
.simr_fe
)
198 if (ut_info
->si_info
.simr_gm
)
203 iowrite16be(sixmr
, &si_regs
->sixmr1
[0]);
206 iowrite16be(sixmr
, &si_regs
->sixmr1
[1]);
209 iowrite16be(sixmr
, &si_regs
->sixmr1
[2]);
212 iowrite16be(sixmr
, &si_regs
->sixmr1
[3]);
215 pr_err("QE-TDM: can not find tdm sixmr reg\n");
219 EXPORT_SYMBOL(ucc_tdm_init
);