0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/io.h>
0011 #include <linux/kernel.h>
0012 #include <linux/of_address.h>
0013 #include <linux/of_irq.h>
0014 #include <linux/of_platform.h>
0015 #include <soc/fsl/qe/qe_tdm.h>
0016
0017 static int set_tdm_framer(const char *tdm_framer_type)
0018 {
0019 if (strcmp(tdm_framer_type, "e1") == 0)
0020 return TDM_FRAMER_E1;
0021 else if (strcmp(tdm_framer_type, "t1") == 0)
0022 return TDM_FRAMER_T1;
0023 else
0024 return -EINVAL;
0025 }
0026
0027 static void set_si_param(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info)
0028 {
0029 struct si_mode_info *si_info = &ut_info->si_info;
0030
0031 if (utdm->tdm_mode == TDM_INTERNAL_LOOPBACK) {
0032 si_info->simr_crt = 1;
0033 si_info->simr_rfsd = 0;
0034 }
0035 }
0036
0037 int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm,
0038 struct ucc_tdm_info *ut_info)
0039 {
0040 const char *sprop;
0041 int ret = 0;
0042 u32 val;
0043
0044 sprop = of_get_property(np, "fsl,rx-sync-clock", NULL);
0045 if (sprop) {
0046 ut_info->uf_info.rx_sync = qe_clock_source(sprop);
0047 if ((ut_info->uf_info.rx_sync < QE_CLK_NONE) ||
0048 (ut_info->uf_info.rx_sync > QE_RSYNC_PIN)) {
0049 pr_err("QE-TDM: Invalid rx-sync-clock property\n");
0050 return -EINVAL;
0051 }
0052 } else {
0053 pr_err("QE-TDM: Invalid rx-sync-clock property\n");
0054 return -EINVAL;
0055 }
0056
0057 sprop = of_get_property(np, "fsl,tx-sync-clock", NULL);
0058 if (sprop) {
0059 ut_info->uf_info.tx_sync = qe_clock_source(sprop);
0060 if ((ut_info->uf_info.tx_sync < QE_CLK_NONE) ||
0061 (ut_info->uf_info.tx_sync > QE_TSYNC_PIN)) {
0062 pr_err("QE-TDM: Invalid tx-sync-clock property\n");
0063 return -EINVAL;
0064 }
0065 } else {
0066 pr_err("QE-TDM: Invalid tx-sync-clock property\n");
0067 return -EINVAL;
0068 }
0069
0070 ret = of_property_read_u32_index(np, "fsl,tx-timeslot-mask", 0, &val);
0071 if (ret) {
0072 pr_err("QE-TDM: Invalid tx-timeslot-mask property\n");
0073 return -EINVAL;
0074 }
0075 utdm->tx_ts_mask = val;
0076
0077 ret = of_property_read_u32_index(np, "fsl,rx-timeslot-mask", 0, &val);
0078 if (ret) {
0079 ret = -EINVAL;
0080 pr_err("QE-TDM: Invalid rx-timeslot-mask property\n");
0081 return ret;
0082 }
0083 utdm->rx_ts_mask = val;
0084
0085 ret = of_property_read_u32_index(np, "fsl,tdm-id", 0, &val);
0086 if (ret) {
0087 ret = -EINVAL;
0088 pr_err("QE-TDM: No fsl,tdm-id property for this UCC\n");
0089 return ret;
0090 }
0091 utdm->tdm_port = val;
0092 ut_info->uf_info.tdm_num = utdm->tdm_port;
0093
0094 if (of_property_read_bool(np, "fsl,tdm-internal-loopback"))
0095 utdm->tdm_mode = TDM_INTERNAL_LOOPBACK;
0096 else
0097 utdm->tdm_mode = TDM_NORMAL;
0098
0099 sprop = of_get_property(np, "fsl,tdm-framer-type", NULL);
0100 if (!sprop) {
0101 ret = -EINVAL;
0102 pr_err("QE-TDM: No tdm-framer-type property for UCC\n");
0103 return ret;
0104 }
0105 ret = set_tdm_framer(sprop);
0106 if (ret < 0)
0107 return -EINVAL;
0108 utdm->tdm_framer_type = ret;
0109
0110 ret = of_property_read_u32_index(np, "fsl,siram-entry-id", 0, &val);
0111 if (ret) {
0112 ret = -EINVAL;
0113 pr_err("QE-TDM: No siram entry id for UCC\n");
0114 return ret;
0115 }
0116 utdm->siram_entry_id = val;
0117
0118 set_si_param(utdm, ut_info);
0119 return ret;
0120 }
0121 EXPORT_SYMBOL(ucc_of_parse_tdm);
0122
0123 void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info)
0124 {
0125 struct si1 __iomem *si_regs;
0126 u16 __iomem *siram;
0127 u16 siram_entry_valid;
0128 u16 siram_entry_closed;
0129 u16 ucc_num;
0130 u8 csel;
0131 u16 sixmr;
0132 u16 tdm_port;
0133 u32 siram_entry_id;
0134 u32 mask;
0135 int i;
0136
0137 si_regs = utdm->si_regs;
0138 siram = utdm->siram;
0139 ucc_num = ut_info->uf_info.ucc_num;
0140 tdm_port = utdm->tdm_port;
0141 siram_entry_id = utdm->siram_entry_id;
0142
0143 if (utdm->tdm_framer_type == TDM_FRAMER_T1)
0144 utdm->num_of_ts = 24;
0145 if (utdm->tdm_framer_type == TDM_FRAMER_E1)
0146 utdm->num_of_ts = 32;
0147
0148
0149 csel = (ucc_num < 4) ? ucc_num + 9 : ucc_num - 3;
0150
0151 siram_entry_valid = SIR_CSEL(csel) | SIR_BYTE | SIR_CNT(0);
0152 siram_entry_closed = SIR_IDLE | SIR_BYTE | SIR_CNT(0);
0153
0154 for (i = 0; i < utdm->num_of_ts; i++) {
0155 mask = 0x01 << i;
0156
0157 if (utdm->tx_ts_mask & mask)
0158 iowrite16be(siram_entry_valid,
0159 &siram[siram_entry_id * 32 + i]);
0160 else
0161 iowrite16be(siram_entry_closed,
0162 &siram[siram_entry_id * 32 + i]);
0163
0164 if (utdm->rx_ts_mask & mask)
0165 iowrite16be(siram_entry_valid,
0166 &siram[siram_entry_id * 32 + 0x200 + i]);
0167 else
0168 iowrite16be(siram_entry_closed,
0169 &siram[siram_entry_id * 32 + 0x200 + i]);
0170 }
0171
0172 qe_setbits_be16(&siram[(siram_entry_id * 32) + (utdm->num_of_ts - 1)],
0173 SIR_LAST);
0174 qe_setbits_be16(&siram[(siram_entry_id * 32) + 0x200 + (utdm->num_of_ts - 1)],
0175 SIR_LAST);
0176
0177
0178 sixmr = SIMR_SAD(siram_entry_id);
0179
0180 sixmr &= ~SIMR_SDM_MASK;
0181
0182 if (utdm->tdm_mode == TDM_INTERNAL_LOOPBACK)
0183 sixmr |= SIMR_SDM_INTERNAL_LOOPBACK;
0184 else
0185 sixmr |= SIMR_SDM_NORMAL;
0186
0187 sixmr |= SIMR_RFSD(ut_info->si_info.simr_rfsd) |
0188 SIMR_TFSD(ut_info->si_info.simr_tfsd);
0189
0190 if (ut_info->si_info.simr_crt)
0191 sixmr |= SIMR_CRT;
0192 if (ut_info->si_info.simr_sl)
0193 sixmr |= SIMR_SL;
0194 if (ut_info->si_info.simr_ce)
0195 sixmr |= SIMR_CE;
0196 if (ut_info->si_info.simr_fe)
0197 sixmr |= SIMR_FE;
0198 if (ut_info->si_info.simr_gm)
0199 sixmr |= SIMR_GM;
0200
0201 switch (tdm_port) {
0202 case 0:
0203 iowrite16be(sixmr, &si_regs->sixmr1[0]);
0204 break;
0205 case 1:
0206 iowrite16be(sixmr, &si_regs->sixmr1[1]);
0207 break;
0208 case 2:
0209 iowrite16be(sixmr, &si_regs->sixmr1[2]);
0210 break;
0211 case 3:
0212 iowrite16be(sixmr, &si_regs->sixmr1[3]);
0213 break;
0214 default:
0215 pr_err("QE-TDM: can not find tdm sixmr reg\n");
0216 break;
0217 }
0218 }
0219 EXPORT_SYMBOL(ucc_tdm_init);