1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * TSA driver 4 * 5 * Copyright 2022 CS GROUP France 6 * 7 * Author: Herve Codina <herve.codina@bootlin.com> 8 */ 9 10 #include "tsa.h" 11 #include <dt-bindings/soc/cpm1-fsl,tsa.h> 12 #include <linux/bitfield.h> 13 #include <linux/clk.h> 14 #include <linux/io.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/of_platform.h> 18 #include <linux/platform_device.h> 19 #include <linux/slab.h> 20 21 /* TSA SI RAM routing tables entry (CPM1) */ 22 #define TSA_CPM1_SIRAM_ENTRY_LAST BIT(16) 23 #define TSA_CPM1_SIRAM_ENTRY_BYTE BIT(17) 24 #define TSA_CPM1_SIRAM_ENTRY_CNT_MASK GENMASK(21, 18) 25 #define TSA_CPM1_SIRAM_ENTRY_CNT(x) FIELD_PREP(TSA_CPM1_SIRAM_ENTRY_CNT_MASK, x) 26 #define TSA_CPM1_SIRAM_ENTRY_CSEL_MASK GENMASK(24, 22) 27 #define TSA_CPM1_SIRAM_ENTRY_CSEL_NU FIELD_PREP_CONST(TSA_CPM1_SIRAM_ENTRY_CSEL_MASK, 0x0) 28 #define TSA_CPM1_SIRAM_ENTRY_CSEL_SCC2 FIELD_PREP_CONST(TSA_CPM1_SIRAM_ENTRY_CSEL_MASK, 0x2) 29 #define TSA_CPM1_SIRAM_ENTRY_CSEL_SCC3 FIELD_PREP_CONST(TSA_CPM1_SIRAM_ENTRY_CSEL_MASK, 0x3) 30 #define TSA_CPM1_SIRAM_ENTRY_CSEL_SCC4 FIELD_PREP_CONST(TSA_CPM1_SIRAM_ENTRY_CSEL_MASK, 0x4) 31 #define TSA_CPM1_SIRAM_ENTRY_CSEL_SMC1 FIELD_PREP_CONST(TSA_CPM1_SIRAM_ENTRY_CSEL_MASK, 0x5) 32 #define TSA_CPM1_SIRAM_ENTRY_CSEL_SMC2 FIELD_PREP_CONST(TSA_CPM1_SIRAM_ENTRY_CSEL_MASK, 0x6) 33 34 /* SI mode register (32 bits) */ 35 #define TSA_CPM1_SIMODE 0x00 36 #define TSA_CPM1_SIMODE_SMC2 BIT(31) 37 #define TSA_CPM1_SIMODE_SMC1 BIT(15) 38 #define TSA_CPM1_SIMODE_TDMA_MASK GENMASK(11, 0) 39 #define TSA_CPM1_SIMODE_TDMA(x) FIELD_PREP(TSA_CPM1_SIMODE_TDMA_MASK, x) 40 #define TSA_CPM1_SIMODE_TDMB_MASK GENMASK(27, 16) 41 #define TSA_CPM1_SIMODE_TDMB(x) FIELD_PREP(TSA_CPM1_SIMODE_TDMB_MASK, x) 42 #define TSA_CPM1_SIMODE_TDM_MASK GENMASK(11, 0) 43 #define TSA_SIMODE_TDM_SDM_MASK GENMASK(11, 10) 44 #define TSA_SIMODE_TDM_SDM_NORM FIELD_PREP_CONST(TSA_SIMODE_TDM_SDM_MASK, 0x0) 45 #define TSA_SIMODE_TDM_SDM_ECHO FIELD_PREP_CONST(TSA_SIMODE_TDM_SDM_MASK, 0x1) 46 #define TSA_SIMODE_TDM_SDM_INTL_LOOP FIELD_PREP_CONST(TSA_SIMODE_TDM_SDM_MASK, 0x2) 47 #define TSA_SIMODE_TDM_SDM_LOOP_CTRL FIELD_PREP_CONST(TSA_SIMODE_TDM_SDM_MASK, 0x3) 48 #define TSA_SIMODE_TDM_RFSD_MASK GENMASK(9, 8) 49 #define TSA_SIMODE_TDM_RFSD(x) FIELD_PREP(TSA_SIMODE_TDM_RFSD_MASK, x) 50 #define TSA_SIMODE_TDM_DSC BIT(7) 51 #define TSA_SIMODE_TDM_CRT BIT(6) 52 #define TSA_CPM1_SIMODE_TDM_STZ BIT(5) 53 #define TSA_SIMODE_TDM_CE BIT(4) 54 #define TSA_SIMODE_TDM_FE BIT(3) 55 #define TSA_SIMODE_TDM_GM BIT(2) 56 #define TSA_SIMODE_TDM_TFSD_MASK GENMASK(1, 0) 57 #define TSA_SIMODE_TDM_TFSD(x) FIELD_PREP(TSA_SIMODE_TDM_TFSD_MASK, x) 58 59 /* CPM SI global mode register (8 bits) */ 60 #define TSA_CPM1_SIGMR 0x04 61 #define TSA_CPM1_SIGMR_ENB BIT(3) 62 #define TSA_CPM1_SIGMR_ENA BIT(2) 63 #define TSA_CPM1_SIGMR_RDM_MASK GENMASK(1, 0) 64 #define TSA_CPM1_SIGMR_RDM_STATIC_TDMA FIELD_PREP_CONST(TSA_CPM1_SIGMR_RDM_MASK, 0x0) 65 #define TSA_CPM1_SIGMR_RDM_DYN_TDMA FIELD_PREP_CONST(TSA_CPM1_SIGMR_RDM_MASK, 0x1) 66 #define TSA_CPM1_SIGMR_RDM_STATIC_TDMAB FIELD_PREP_CONST(TSA_CPM1_SIGMR_RDM_MASK, 0x2) 67 #define TSA_CPM1_SIGMR_RDM_DYN_TDMAB FIELD_PREP_CONST(TSA_CPM1_SIGMR_RDM_MASK, 0x3) 68 69 /* SI clock route register (32 bits) */ 70 #define TSA_CPM1_SICR 0x0C 71 #define TSA_CPM1_SICR_SCC2_MASK GENMASK(15, 8) 72 #define TSA_CPM1_SICR_SCC2(x) FIELD_PREP(TSA_CPM1_SICR_SCC2_MASK, x) 73 #define TSA_CPM1_SICR_SCC3_MASK GENMASK(23, 16) 74 #define TSA_CPM1_SICR_SCC3(x) FIELD_PREP(TSA_CPM1_SICR_SCC3_MASK, x) 75 #define TSA_CPM1_SICR_SCC4_MASK GENMASK(31, 24) 76 #define TSA_CPM1_SICR_SCC4(x) FIELD_PREP(TSA_CPM1_SICR_SCC4_MASK, x) 77 #define TSA_CPM1_SICR_SCC_MASK GENMASK(7, 0) 78 #define TSA_CPM1_SICR_SCC_GRX BIT(7) 79 #define TSA_CPM1_SICR_SCC_SCX_TSA BIT(6) 80 #define TSA_CPM1_SICR_SCC_RXCS_MASK GENMASK(5, 3) 81 #define TSA_CPM1_SICR_SCC_RXCS_BRG1 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x0) 82 #define TSA_CPM1_SICR_SCC_RXCS_BRG2 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x1) 83 #define TSA_CPM1_SICR_SCC_RXCS_BRG3 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x2) 84 #define TSA_CPM1_SICR_SCC_RXCS_BRG4 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x3) 85 #define TSA_CPM1_SICR_SCC_RXCS_CLK15 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x4) 86 #define TSA_CPM1_SICR_SCC_RXCS_CLK26 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x5) 87 #define TSA_CPM1_SICR_SCC_RXCS_CLK37 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x6) 88 #define TSA_CPM1_SICR_SCC_RXCS_CLK48 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_RXCS_MASK, 0x7) 89 #define TSA_CPM1_SICR_SCC_TXCS_MASK GENMASK(2, 0) 90 #define TSA_CPM1_SICR_SCC_TXCS_BRG1 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x0) 91 #define TSA_CPM1_SICR_SCC_TXCS_BRG2 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x1) 92 #define TSA_CPM1_SICR_SCC_TXCS_BRG3 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x2) 93 #define TSA_CPM1_SICR_SCC_TXCS_BRG4 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x3) 94 #define TSA_CPM1_SICR_SCC_TXCS_CLK15 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x4) 95 #define TSA_CPM1_SICR_SCC_TXCS_CLK26 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x5) 96 #define TSA_CPM1_SICR_SCC_TXCS_CLK37 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x6) 97 #define TSA_CPM1_SICR_SCC_TXCS_CLK48 FIELD_PREP_CONST(TSA_CPM1_SICR_SCC_TXCS_MASK, 0x7) 98 99 struct tsa_entries_area { 100 void __iomem *entries_start; 101 void __iomem *entries_next; 102 void __iomem *last_entry; 103 }; 104 105 struct tsa_tdm { 106 bool is_enable; 107 struct clk *l1rclk_clk; 108 struct clk *l1rsync_clk; 109 struct clk *l1tclk_clk; 110 struct clk *l1tsync_clk; 111 u32 simode_tdm; 112 }; 113 114 #define TSA_TDMA 0 115 #define TSA_TDMB 1 116 117 struct tsa { 118 struct device *dev; 119 void __iomem *si_regs; 120 void __iomem *si_ram; 121 resource_size_t si_ram_sz; 122 spinlock_t lock; /* Lock for read/modify/write sequence */ 123 int tdms; /* TSA_TDMx ORed */ 124 struct tsa_tdm tdm[2]; /* TDMa and TDMb */ 125 struct tsa_serial { 126 unsigned int id; 127 struct tsa_serial_info info; 128 } serials[6]; 129 }; 130 131 static inline struct tsa *tsa_serial_get_tsa(struct tsa_serial *tsa_serial) 132 { 133 /* The serials table is indexed by the serial id */ 134 return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]); 135 } 136 137 static inline void tsa_write32(void __iomem *addr, u32 val) 138 { 139 iowrite32be(val, addr); 140 } 141 142 static inline void tsa_write8(void __iomem *addr, u8 val) 143 { 144 iowrite8(val, addr); 145 } 146 147 static inline u32 tsa_read32(void __iomem *addr) 148 { 149 return ioread32be(addr); 150 } 151 152 static inline void tsa_clrbits32(void __iomem *addr, u32 clr) 153 { 154 tsa_write32(addr, tsa_read32(addr) & ~clr); 155 } 156 157 static inline void tsa_clrsetbits32(void __iomem *addr, u32 clr, u32 set) 158 { 159 tsa_write32(addr, (tsa_read32(addr) & ~clr) | set); 160 } 161 162 static int tsa_cpm1_serial_connect(struct tsa_serial *tsa_serial, bool connect) 163 { 164 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); 165 unsigned long flags; 166 u32 clear; 167 u32 set; 168 169 switch (tsa_serial->id) { 170 case FSL_CPM_TSA_SCC2: 171 clear = TSA_CPM1_SICR_SCC2(TSA_CPM1_SICR_SCC_MASK); 172 set = TSA_CPM1_SICR_SCC2(TSA_CPM1_SICR_SCC_SCX_TSA); 173 break; 174 case FSL_CPM_TSA_SCC3: 175 clear = TSA_CPM1_SICR_SCC3(TSA_CPM1_SICR_SCC_MASK); 176 set = TSA_CPM1_SICR_SCC3(TSA_CPM1_SICR_SCC_SCX_TSA); 177 break; 178 case FSL_CPM_TSA_SCC4: 179 clear = TSA_CPM1_SICR_SCC4(TSA_CPM1_SICR_SCC_MASK); 180 set = TSA_CPM1_SICR_SCC4(TSA_CPM1_SICR_SCC_SCX_TSA); 181 break; 182 default: 183 dev_err(tsa->dev, "Unsupported serial id %u\n", tsa_serial->id); 184 return -EINVAL; 185 } 186 187 spin_lock_irqsave(&tsa->lock, flags); 188 tsa_clrsetbits32(tsa->si_regs + TSA_CPM1_SICR, clear, 189 connect ? set : 0); 190 spin_unlock_irqrestore(&tsa->lock, flags); 191 192 return 0; 193 } 194 195 int tsa_serial_connect(struct tsa_serial *tsa_serial) 196 { 197 return tsa_cpm1_serial_connect(tsa_serial, true); 198 } 199 EXPORT_SYMBOL(tsa_serial_connect); 200 201 int tsa_serial_disconnect(struct tsa_serial *tsa_serial) 202 { 203 return tsa_cpm1_serial_connect(tsa_serial, false); 204 } 205 EXPORT_SYMBOL(tsa_serial_disconnect); 206 207 int tsa_serial_get_info(struct tsa_serial *tsa_serial, struct tsa_serial_info *info) 208 { 209 memcpy(info, &tsa_serial->info, sizeof(*info)); 210 return 0; 211 } 212 EXPORT_SYMBOL(tsa_serial_get_info); 213 214 static void tsa_cpm1_init_entries_area(struct tsa *tsa, struct tsa_entries_area *area, 215 u32 tdms, u32 tdm_id, bool is_rx) 216 { 217 resource_size_t quarter; 218 resource_size_t half; 219 220 quarter = tsa->si_ram_sz / 4; 221 half = tsa->si_ram_sz / 2; 222 223 if (tdms == BIT(TSA_TDMA)) { 224 /* Only TDMA */ 225 if (is_rx) { 226 /* First half of si_ram */ 227 area->entries_start = tsa->si_ram; 228 area->entries_next = area->entries_start + half; 229 area->last_entry = NULL; 230 } else { 231 /* Second half of si_ram */ 232 area->entries_start = tsa->si_ram + half; 233 area->entries_next = area->entries_start + half; 234 area->last_entry = NULL; 235 } 236 } else { 237 /* Only TDMB or both TDMs */ 238 if (tdm_id == TSA_TDMA) { 239 if (is_rx) { 240 /* First half of first half of si_ram */ 241 area->entries_start = tsa->si_ram; 242 area->entries_next = area->entries_start + quarter; 243 area->last_entry = NULL; 244 } else { 245 /* First half of second half of si_ram */ 246 area->entries_start = tsa->si_ram + (2 * quarter); 247 area->entries_next = area->entries_start + quarter; 248 area->last_entry = NULL; 249 } 250 } else { 251 if (is_rx) { 252 /* Second half of first half of si_ram */ 253 area->entries_start = tsa->si_ram + quarter; 254 area->entries_next = area->entries_start + quarter; 255 area->last_entry = NULL; 256 } else { 257 /* Second half of second half of si_ram */ 258 area->entries_start = tsa->si_ram + (3 * quarter); 259 area->entries_next = area->entries_start + quarter; 260 area->last_entry = NULL; 261 } 262 } 263 } 264 } 265 266 static void tsa_init_entries_area(struct tsa *tsa, struct tsa_entries_area *area, 267 u32 tdms, u32 tdm_id, bool is_rx) 268 { 269 tsa_cpm1_init_entries_area(tsa, area, tdms, tdm_id, is_rx); 270 } 271 272 static const char *tsa_cpm1_serial_id2name(struct tsa *tsa, u32 serial_id) 273 { 274 switch (serial_id) { 275 case FSL_CPM_TSA_NU: return "Not used"; 276 case FSL_CPM_TSA_SCC2: return "SCC2"; 277 case FSL_CPM_TSA_SCC3: return "SCC3"; 278 case FSL_CPM_TSA_SCC4: return "SCC4"; 279 case FSL_CPM_TSA_SMC1: return "SMC1"; 280 case FSL_CPM_TSA_SMC2: return "SMC2"; 281 default: 282 break; 283 } 284 return NULL; 285 } 286 287 static const char *tsa_serial_id2name(struct tsa *tsa, u32 serial_id) 288 { 289 return tsa_cpm1_serial_id2name(tsa, serial_id); 290 } 291 292 static u32 tsa_cpm1_serial_id2csel(struct tsa *tsa, u32 serial_id) 293 { 294 switch (serial_id) { 295 case FSL_CPM_TSA_SCC2: return TSA_CPM1_SIRAM_ENTRY_CSEL_SCC2; 296 case FSL_CPM_TSA_SCC3: return TSA_CPM1_SIRAM_ENTRY_CSEL_SCC3; 297 case FSL_CPM_TSA_SCC4: return TSA_CPM1_SIRAM_ENTRY_CSEL_SCC4; 298 case FSL_CPM_TSA_SMC1: return TSA_CPM1_SIRAM_ENTRY_CSEL_SMC1; 299 case FSL_CPM_TSA_SMC2: return TSA_CPM1_SIRAM_ENTRY_CSEL_SMC2; 300 default: 301 break; 302 } 303 return TSA_CPM1_SIRAM_ENTRY_CSEL_NU; 304 } 305 306 static int tsa_cpm1_add_entry(struct tsa *tsa, struct tsa_entries_area *area, 307 u32 count, u32 serial_id) 308 { 309 void __iomem *addr; 310 u32 left; 311 u32 val; 312 u32 cnt; 313 u32 nb; 314 315 addr = area->last_entry ? area->last_entry + 4 : area->entries_start; 316 317 nb = DIV_ROUND_UP(count, 8); 318 if ((addr + (nb * 4)) > area->entries_next) { 319 dev_err(tsa->dev, "si ram area full\n"); 320 return -ENOSPC; 321 } 322 323 if (area->last_entry) { 324 /* Clear last flag */ 325 tsa_clrbits32(area->last_entry, TSA_CPM1_SIRAM_ENTRY_LAST); 326 } 327 328 left = count; 329 while (left) { 330 val = TSA_CPM1_SIRAM_ENTRY_BYTE | tsa_cpm1_serial_id2csel(tsa, serial_id); 331 332 if (left > 16) { 333 cnt = 16; 334 } else { 335 cnt = left; 336 val |= TSA_CPM1_SIRAM_ENTRY_LAST; 337 area->last_entry = addr; 338 } 339 val |= TSA_CPM1_SIRAM_ENTRY_CNT(cnt - 1); 340 341 tsa_write32(addr, val); 342 addr += 4; 343 left -= cnt; 344 } 345 346 return 0; 347 } 348 349 static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area, 350 u32 count, u32 serial_id) 351 { 352 return tsa_cpm1_add_entry(tsa, area, count, serial_id); 353 } 354 355 static int tsa_of_parse_tdm_route(struct tsa *tsa, struct device_node *tdm_np, 356 u32 tdms, u32 tdm_id, bool is_rx) 357 { 358 struct tsa_entries_area area; 359 const char *route_name; 360 u32 serial_id; 361 int len, i; 362 u32 count; 363 const char *serial_name; 364 struct tsa_serial_info *serial_info; 365 struct tsa_tdm *tdm; 366 int ret; 367 u32 ts; 368 369 route_name = is_rx ? "fsl,rx-ts-routes" : "fsl,tx-ts-routes"; 370 371 len = of_property_count_u32_elems(tdm_np, route_name); 372 if (len < 0) { 373 dev_err(tsa->dev, "%pOF: failed to read %s\n", tdm_np, route_name); 374 return len; 375 } 376 if (len % 2 != 0) { 377 dev_err(tsa->dev, "%pOF: wrong %s format\n", tdm_np, route_name); 378 return -EINVAL; 379 } 380 381 tsa_init_entries_area(tsa, &area, tdms, tdm_id, is_rx); 382 ts = 0; 383 for (i = 0; i < len; i += 2) { 384 of_property_read_u32_index(tdm_np, route_name, i, &count); 385 of_property_read_u32_index(tdm_np, route_name, i + 1, &serial_id); 386 387 if (serial_id >= ARRAY_SIZE(tsa->serials)) { 388 dev_err(tsa->dev, "%pOF: invalid serial id (%u)\n", 389 tdm_np, serial_id); 390 return -EINVAL; 391 } 392 393 serial_name = tsa_serial_id2name(tsa, serial_id); 394 if (!serial_name) { 395 dev_err(tsa->dev, "%pOF: unsupported serial id (%u)\n", 396 tdm_np, serial_id); 397 return -EINVAL; 398 } 399 400 dev_dbg(tsa->dev, "tdm_id=%u, %s ts %u..%u -> %s\n", 401 tdm_id, route_name, ts, ts + count - 1, serial_name); 402 ts += count; 403 404 ret = tsa_add_entry(tsa, &area, count, serial_id); 405 if (ret) 406 return ret; 407 408 serial_info = &tsa->serials[serial_id].info; 409 tdm = &tsa->tdm[tdm_id]; 410 if (is_rx) { 411 serial_info->rx_fs_rate = clk_get_rate(tdm->l1rsync_clk); 412 serial_info->rx_bit_rate = clk_get_rate(tdm->l1rclk_clk); 413 serial_info->nb_rx_ts += count; 414 } else { 415 serial_info->tx_fs_rate = tdm->l1tsync_clk ? 416 clk_get_rate(tdm->l1tsync_clk) : 417 clk_get_rate(tdm->l1rsync_clk); 418 serial_info->tx_bit_rate = tdm->l1tclk_clk ? 419 clk_get_rate(tdm->l1tclk_clk) : 420 clk_get_rate(tdm->l1rclk_clk); 421 serial_info->nb_tx_ts += count; 422 } 423 } 424 return 0; 425 } 426 427 static inline int tsa_of_parse_tdm_rx_route(struct tsa *tsa, 428 struct device_node *tdm_np, 429 u32 tdms, u32 tdm_id) 430 { 431 return tsa_of_parse_tdm_route(tsa, tdm_np, tdms, tdm_id, true); 432 } 433 434 static inline int tsa_of_parse_tdm_tx_route(struct tsa *tsa, 435 struct device_node *tdm_np, 436 u32 tdms, u32 tdm_id) 437 { 438 return tsa_of_parse_tdm_route(tsa, tdm_np, tdms, tdm_id, false); 439 } 440 441 static int tsa_of_parse_tdms(struct tsa *tsa, struct device_node *np) 442 { 443 struct device_node *tdm_np; 444 struct tsa_tdm *tdm; 445 struct clk *clk; 446 u32 tdm_id, val; 447 int ret; 448 int i; 449 450 tsa->tdms = 0; 451 for (i = 0; i < ARRAY_SIZE(tsa->tdm); i++) 452 tsa->tdm[i].is_enable = false; 453 454 for_each_available_child_of_node(np, tdm_np) { 455 ret = of_property_read_u32(tdm_np, "reg", &tdm_id); 456 if (ret) { 457 dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np); 458 of_node_put(tdm_np); 459 return ret; 460 } 461 switch (tdm_id) { 462 case 0: 463 tsa->tdms |= BIT(TSA_TDMA); 464 break; 465 case 1: 466 tsa->tdms |= BIT(TSA_TDMB); 467 break; 468 default: 469 dev_err(tsa->dev, "%pOF: Invalid tdm_id (%u)\n", tdm_np, 470 tdm_id); 471 of_node_put(tdm_np); 472 return -EINVAL; 473 } 474 } 475 476 for_each_available_child_of_node(np, tdm_np) { 477 ret = of_property_read_u32(tdm_np, "reg", &tdm_id); 478 if (ret) { 479 dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np); 480 of_node_put(tdm_np); 481 return ret; 482 } 483 484 tdm = &tsa->tdm[tdm_id]; 485 tdm->simode_tdm = TSA_SIMODE_TDM_SDM_NORM; 486 487 val = 0; 488 ret = of_property_read_u32(tdm_np, "fsl,rx-frame-sync-delay-bits", 489 &val); 490 if (ret && ret != -EINVAL) { 491 dev_err(tsa->dev, 492 "%pOF: failed to read fsl,rx-frame-sync-delay-bits\n", 493 tdm_np); 494 of_node_put(tdm_np); 495 return ret; 496 } 497 if (val > 3) { 498 dev_err(tsa->dev, 499 "%pOF: Invalid fsl,rx-frame-sync-delay-bits (%u)\n", 500 tdm_np, val); 501 of_node_put(tdm_np); 502 return -EINVAL; 503 } 504 tdm->simode_tdm |= TSA_SIMODE_TDM_RFSD(val); 505 506 val = 0; 507 ret = of_property_read_u32(tdm_np, "fsl,tx-frame-sync-delay-bits", 508 &val); 509 if (ret && ret != -EINVAL) { 510 dev_err(tsa->dev, 511 "%pOF: failed to read fsl,tx-frame-sync-delay-bits\n", 512 tdm_np); 513 of_node_put(tdm_np); 514 return ret; 515 } 516 if (val > 3) { 517 dev_err(tsa->dev, 518 "%pOF: Invalid fsl,tx-frame-sync-delay-bits (%u)\n", 519 tdm_np, val); 520 of_node_put(tdm_np); 521 return -EINVAL; 522 } 523 tdm->simode_tdm |= TSA_SIMODE_TDM_TFSD(val); 524 525 if (of_property_read_bool(tdm_np, "fsl,common-rxtx-pins")) 526 tdm->simode_tdm |= TSA_SIMODE_TDM_CRT; 527 528 if (of_property_read_bool(tdm_np, "fsl,clock-falling-edge")) 529 tdm->simode_tdm |= TSA_SIMODE_TDM_CE; 530 531 if (of_property_read_bool(tdm_np, "fsl,fsync-rising-edge")) 532 tdm->simode_tdm |= TSA_SIMODE_TDM_FE; 533 534 if (of_property_read_bool(tdm_np, "fsl,double-speed-clock")) 535 tdm->simode_tdm |= TSA_SIMODE_TDM_DSC; 536 537 clk = of_clk_get_by_name(tdm_np, "l1rsync"); 538 if (IS_ERR(clk)) { 539 ret = PTR_ERR(clk); 540 of_node_put(tdm_np); 541 goto err; 542 } 543 ret = clk_prepare_enable(clk); 544 if (ret) { 545 clk_put(clk); 546 of_node_put(tdm_np); 547 goto err; 548 } 549 tdm->l1rsync_clk = clk; 550 551 clk = of_clk_get_by_name(tdm_np, "l1rclk"); 552 if (IS_ERR(clk)) { 553 ret = PTR_ERR(clk); 554 of_node_put(tdm_np); 555 goto err; 556 } 557 ret = clk_prepare_enable(clk); 558 if (ret) { 559 clk_put(clk); 560 of_node_put(tdm_np); 561 goto err; 562 } 563 tdm->l1rclk_clk = clk; 564 565 if (!(tdm->simode_tdm & TSA_SIMODE_TDM_CRT)) { 566 clk = of_clk_get_by_name(tdm_np, "l1tsync"); 567 if (IS_ERR(clk)) { 568 ret = PTR_ERR(clk); 569 of_node_put(tdm_np); 570 goto err; 571 } 572 ret = clk_prepare_enable(clk); 573 if (ret) { 574 clk_put(clk); 575 of_node_put(tdm_np); 576 goto err; 577 } 578 tdm->l1tsync_clk = clk; 579 580 clk = of_clk_get_by_name(tdm_np, "l1tclk"); 581 if (IS_ERR(clk)) { 582 ret = PTR_ERR(clk); 583 of_node_put(tdm_np); 584 goto err; 585 } 586 ret = clk_prepare_enable(clk); 587 if (ret) { 588 clk_put(clk); 589 of_node_put(tdm_np); 590 goto err; 591 } 592 tdm->l1tclk_clk = clk; 593 } 594 595 ret = tsa_of_parse_tdm_rx_route(tsa, tdm_np, tsa->tdms, tdm_id); 596 if (ret) { 597 of_node_put(tdm_np); 598 goto err; 599 } 600 601 ret = tsa_of_parse_tdm_tx_route(tsa, tdm_np, tsa->tdms, tdm_id); 602 if (ret) { 603 of_node_put(tdm_np); 604 goto err; 605 } 606 607 tdm->is_enable = true; 608 } 609 return 0; 610 611 err: 612 for (i = 0; i < ARRAY_SIZE(tsa->tdm); i++) { 613 if (tsa->tdm[i].l1rsync_clk) { 614 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); 615 clk_put(tsa->tdm[i].l1rsync_clk); 616 } 617 if (tsa->tdm[i].l1rclk_clk) { 618 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); 619 clk_put(tsa->tdm[i].l1rclk_clk); 620 } 621 if (tsa->tdm[i].l1tsync_clk) { 622 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); 623 clk_put(tsa->tdm[i].l1rsync_clk); 624 } 625 if (tsa->tdm[i].l1tclk_clk) { 626 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); 627 clk_put(tsa->tdm[i].l1rclk_clk); 628 } 629 } 630 return ret; 631 } 632 633 static void tsa_init_si_ram(struct tsa *tsa) 634 { 635 resource_size_t i; 636 637 /* Fill all entries as the last one */ 638 for (i = 0; i < tsa->si_ram_sz; i += 4) 639 tsa_write32(tsa->si_ram + i, TSA_CPM1_SIRAM_ENTRY_LAST); 640 } 641 642 static int tsa_cpm1_setup(struct tsa *tsa) 643 { 644 u32 val; 645 646 /* Set SIMODE */ 647 val = 0; 648 if (tsa->tdm[0].is_enable) 649 val |= TSA_CPM1_SIMODE_TDMA(tsa->tdm[0].simode_tdm); 650 if (tsa->tdm[1].is_enable) 651 val |= TSA_CPM1_SIMODE_TDMB(tsa->tdm[1].simode_tdm); 652 653 tsa_clrsetbits32(tsa->si_regs + TSA_CPM1_SIMODE, 654 TSA_CPM1_SIMODE_TDMA(TSA_CPM1_SIMODE_TDM_MASK) | 655 TSA_CPM1_SIMODE_TDMB(TSA_CPM1_SIMODE_TDM_MASK), 656 val); 657 658 /* Set SIGMR */ 659 val = (tsa->tdms == BIT(TSA_TDMA)) ? 660 TSA_CPM1_SIGMR_RDM_STATIC_TDMA : TSA_CPM1_SIGMR_RDM_STATIC_TDMAB; 661 if (tsa->tdms & BIT(TSA_TDMA)) 662 val |= TSA_CPM1_SIGMR_ENA; 663 if (tsa->tdms & BIT(TSA_TDMB)) 664 val |= TSA_CPM1_SIGMR_ENB; 665 tsa_write8(tsa->si_regs + TSA_CPM1_SIGMR, val); 666 667 return 0; 668 } 669 670 static int tsa_setup(struct tsa *tsa) 671 { 672 return tsa_cpm1_setup(tsa); 673 } 674 675 static int tsa_probe(struct platform_device *pdev) 676 { 677 struct device_node *np = pdev->dev.of_node; 678 struct resource *res; 679 struct tsa *tsa; 680 unsigned int i; 681 int ret; 682 683 tsa = devm_kzalloc(&pdev->dev, sizeof(*tsa), GFP_KERNEL); 684 if (!tsa) 685 return -ENOMEM; 686 687 tsa->dev = &pdev->dev; 688 689 for (i = 0; i < ARRAY_SIZE(tsa->serials); i++) 690 tsa->serials[i].id = i; 691 692 spin_lock_init(&tsa->lock); 693 694 tsa->si_regs = devm_platform_ioremap_resource_byname(pdev, "si_regs"); 695 if (IS_ERR(tsa->si_regs)) 696 return PTR_ERR(tsa->si_regs); 697 698 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "si_ram"); 699 if (!res) { 700 dev_err(tsa->dev, "si_ram resource missing\n"); 701 return -EINVAL; 702 } 703 tsa->si_ram_sz = resource_size(res); 704 tsa->si_ram = devm_ioremap_resource(&pdev->dev, res); 705 if (IS_ERR(tsa->si_ram)) 706 return PTR_ERR(tsa->si_ram); 707 708 tsa_init_si_ram(tsa); 709 710 ret = tsa_of_parse_tdms(tsa, np); 711 if (ret) 712 return ret; 713 714 ret = tsa_setup(tsa); 715 if (ret) 716 return ret; 717 718 platform_set_drvdata(pdev, tsa); 719 720 return 0; 721 } 722 723 static void tsa_remove(struct platform_device *pdev) 724 { 725 struct tsa *tsa = platform_get_drvdata(pdev); 726 int i; 727 728 for (i = 0; i < ARRAY_SIZE(tsa->tdm); i++) { 729 if (tsa->tdm[i].l1rsync_clk) { 730 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); 731 clk_put(tsa->tdm[i].l1rsync_clk); 732 } 733 if (tsa->tdm[i].l1rclk_clk) { 734 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); 735 clk_put(tsa->tdm[i].l1rclk_clk); 736 } 737 if (tsa->tdm[i].l1tsync_clk) { 738 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); 739 clk_put(tsa->tdm[i].l1rsync_clk); 740 } 741 if (tsa->tdm[i].l1tclk_clk) { 742 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); 743 clk_put(tsa->tdm[i].l1rclk_clk); 744 } 745 } 746 } 747 748 static const struct of_device_id tsa_id_table[] = { 749 { .compatible = "fsl,cpm1-tsa" }, 750 {} /* sentinel */ 751 }; 752 MODULE_DEVICE_TABLE(of, tsa_id_table); 753 754 static struct platform_driver tsa_driver = { 755 .driver = { 756 .name = "fsl-tsa", 757 .of_match_table = of_match_ptr(tsa_id_table), 758 }, 759 .probe = tsa_probe, 760 .remove_new = tsa_remove, 761 }; 762 module_platform_driver(tsa_driver); 763 764 struct tsa_serial *tsa_serial_get_byphandle(struct device_node *np, 765 const char *phandle_name) 766 { 767 struct of_phandle_args out_args; 768 struct platform_device *pdev; 769 struct tsa_serial *tsa_serial; 770 struct tsa *tsa; 771 int ret; 772 773 ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0, &out_args); 774 if (ret < 0) 775 return ERR_PTR(ret); 776 777 if (!of_match_node(tsa_driver.driver.of_match_table, out_args.np)) { 778 of_node_put(out_args.np); 779 return ERR_PTR(-EINVAL); 780 } 781 782 pdev = of_find_device_by_node(out_args.np); 783 of_node_put(out_args.np); 784 if (!pdev) 785 return ERR_PTR(-ENODEV); 786 787 tsa = platform_get_drvdata(pdev); 788 if (!tsa) { 789 platform_device_put(pdev); 790 return ERR_PTR(-EPROBE_DEFER); 791 } 792 793 if (out_args.args_count != 1) { 794 platform_device_put(pdev); 795 return ERR_PTR(-EINVAL); 796 } 797 798 if (out_args.args[0] >= ARRAY_SIZE(tsa->serials)) { 799 platform_device_put(pdev); 800 return ERR_PTR(-EINVAL); 801 } 802 803 tsa_serial = &tsa->serials[out_args.args[0]]; 804 805 /* 806 * Be sure that the serial id matches the phandle arg. 807 * The tsa_serials table is indexed by serial ids. The serial id is set 808 * during the probe() call and needs to be coherent. 809 */ 810 if (WARN_ON(tsa_serial->id != out_args.args[0])) { 811 platform_device_put(pdev); 812 return ERR_PTR(-EINVAL); 813 } 814 815 return tsa_serial; 816 } 817 EXPORT_SYMBOL(tsa_serial_get_byphandle); 818 819 void tsa_serial_put(struct tsa_serial *tsa_serial) 820 { 821 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); 822 823 put_device(tsa->dev); 824 } 825 EXPORT_SYMBOL(tsa_serial_put); 826 827 static void devm_tsa_serial_release(struct device *dev, void *res) 828 { 829 struct tsa_serial **tsa_serial = res; 830 831 tsa_serial_put(*tsa_serial); 832 } 833 834 struct tsa_serial *devm_tsa_serial_get_byphandle(struct device *dev, 835 struct device_node *np, 836 const char *phandle_name) 837 { 838 struct tsa_serial *tsa_serial; 839 struct tsa_serial **dr; 840 841 dr = devres_alloc(devm_tsa_serial_release, sizeof(*dr), GFP_KERNEL); 842 if (!dr) 843 return ERR_PTR(-ENOMEM); 844 845 tsa_serial = tsa_serial_get_byphandle(np, phandle_name); 846 if (!IS_ERR(tsa_serial)) { 847 *dr = tsa_serial; 848 devres_add(dev, dr); 849 } else { 850 devres_free(dr); 851 } 852 853 return tsa_serial; 854 } 855 EXPORT_SYMBOL(devm_tsa_serial_get_byphandle); 856 857 MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>"); 858 MODULE_DESCRIPTION("CPM TSA driver"); 859 MODULE_LICENSE("GPL"); 860