serial_lpuart.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2019 NXP
  4. * Copyright 2013 Freescale Semiconductor, Inc.
  5. */
  6. #include <common.h>
  7. #include <clk.h>
  8. #include <dm.h>
  9. #include <fsl_lpuart.h>
  10. #include <log.h>
  11. #include <watchdog.h>
  12. #include <asm/global_data.h>
  13. #include <asm/io.h>
  14. #include <serial.h>
  15. #include <dm/device_compat.h>
  16. #include <linux/bitops.h>
  17. #include <linux/compiler.h>
  18. #include <asm/arch/imx-regs.h>
  19. #include <asm/arch/clock.h>
  20. #define US1_TDRE (1 << 7)
  21. #define US1_RDRF (1 << 5)
  22. #define US1_OR (1 << 3)
  23. #define UC2_TE (1 << 3)
  24. #define UC2_RE (1 << 2)
  25. #define CFIFO_TXFLUSH (1 << 7)
  26. #define CFIFO_RXFLUSH (1 << 6)
  27. #define SFIFO_RXOF (1 << 2)
  28. #define SFIFO_RXUF (1 << 0)
  29. #define STAT_LBKDIF (1 << 31)
  30. #define STAT_RXEDGIF (1 << 30)
  31. #define STAT_TDRE (1 << 23)
  32. #define STAT_RDRF (1 << 21)
  33. #define STAT_IDLE (1 << 20)
  34. #define STAT_OR (1 << 19)
  35. #define STAT_NF (1 << 18)
  36. #define STAT_FE (1 << 17)
  37. #define STAT_PF (1 << 16)
  38. #define STAT_MA1F (1 << 15)
  39. #define STAT_MA2F (1 << 14)
  40. #define STAT_FLAGS (STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \
  41. STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)
  42. #define CTRL_TE (1 << 19)
  43. #define CTRL_RE (1 << 18)
  44. #define FIFO_RXFLUSH BIT(14)
  45. #define FIFO_TXFLUSH BIT(15)
  46. #define FIFO_TXSIZE_MASK 0x70
  47. #define FIFO_TXSIZE_OFF 4
  48. #define FIFO_RXSIZE_MASK 0x7
  49. #define FIFO_RXSIZE_OFF 0
  50. #define FIFO_TXFE 0x80
  51. #if defined(CONFIG_ARCH_IMX8) || defined(CONFIG_ARCH_IMXRT)
  52. #define FIFO_RXFE 0x08
  53. #else
  54. #define FIFO_RXFE 0x40
  55. #endif
  56. #define WATER_TXWATER_OFF 0
  57. #define WATER_RXWATER_OFF 16
  58. DECLARE_GLOBAL_DATA_PTR;
  59. #define LPUART_FLAG_REGMAP_32BIT_REG BIT(0)
  60. #define LPUART_FLAG_REGMAP_ENDIAN_BIG BIT(1)
  61. enum lpuart_devtype {
  62. DEV_VF610 = 1,
  63. DEV_LS1021A,
  64. DEV_MX7ULP,
  65. DEV_IMX8,
  66. DEV_IMXRT,
  67. };
  68. struct lpuart_serial_plat {
  69. void *reg;
  70. enum lpuart_devtype devtype;
  71. ulong flags;
  72. };
  73. static void lpuart_read32(u32 flags, u32 *addr, u32 *val)
  74. {
  75. if (flags & LPUART_FLAG_REGMAP_32BIT_REG) {
  76. if (flags & LPUART_FLAG_REGMAP_ENDIAN_BIG)
  77. *(u32 *)val = in_be32(addr);
  78. else
  79. *(u32 *)val = in_le32(addr);
  80. }
  81. }
  82. static void lpuart_write32(u32 flags, u32 *addr, u32 val)
  83. {
  84. if (flags & LPUART_FLAG_REGMAP_32BIT_REG) {
  85. if (flags & LPUART_FLAG_REGMAP_ENDIAN_BIG)
  86. out_be32(addr, val);
  87. else
  88. out_le32(addr, val);
  89. }
  90. }
  91. #ifndef CONFIG_SYS_CLK_FREQ
  92. #define CONFIG_SYS_CLK_FREQ 0
  93. #endif
  94. u32 __weak get_lpuart_clk(void)
  95. {
  96. return CONFIG_SYS_CLK_FREQ;
  97. }
  98. #if CONFIG_IS_ENABLED(CLK)
  99. static int get_lpuart_clk_rate(struct udevice *dev, u32 *clk)
  100. {
  101. struct clk per_clk;
  102. ulong rate;
  103. int ret;
  104. ret = clk_get_by_name(dev, "per", &per_clk);
  105. if (ret) {
  106. dev_err(dev, "Failed to get per clk: %d\n", ret);
  107. return ret;
  108. }
  109. rate = clk_get_rate(&per_clk);
  110. if ((long)rate <= 0) {
  111. dev_err(dev, "Failed to get per clk rate: %ld\n", (long)rate);
  112. return ret;
  113. }
  114. *clk = rate;
  115. return 0;
  116. }
  117. #else
  118. static inline int get_lpuart_clk_rate(struct udevice *dev, u32 *clk)
  119. { return -ENOSYS; }
  120. #endif
  121. static bool is_lpuart32(struct udevice *dev)
  122. {
  123. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  124. return plat->flags & LPUART_FLAG_REGMAP_32BIT_REG;
  125. }
  126. static void _lpuart_serial_setbrg(struct udevice *dev,
  127. int baudrate)
  128. {
  129. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  130. struct lpuart_fsl *base = plat->reg;
  131. u32 clk;
  132. u16 sbr;
  133. int ret;
  134. if (CONFIG_IS_ENABLED(CLK)) {
  135. ret = get_lpuart_clk_rate(dev, &clk);
  136. if (ret)
  137. return;
  138. } else {
  139. clk = get_lpuart_clk();
  140. }
  141. sbr = (u16)(clk / (16 * baudrate));
  142. /* place adjustment later - n/32 BRFA */
  143. __raw_writeb(sbr >> 8, &base->ubdh);
  144. __raw_writeb(sbr & 0xff, &base->ubdl);
  145. }
  146. static int _lpuart_serial_getc(struct lpuart_serial_plat *plat)
  147. {
  148. struct lpuart_fsl *base = plat->reg;
  149. while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR)))
  150. WATCHDOG_RESET();
  151. barrier();
  152. return __raw_readb(&base->ud);
  153. }
  154. static void _lpuart_serial_putc(struct lpuart_serial_plat *plat,
  155. const char c)
  156. {
  157. struct lpuart_fsl *base = plat->reg;
  158. while (!(__raw_readb(&base->us1) & US1_TDRE))
  159. WATCHDOG_RESET();
  160. __raw_writeb(c, &base->ud);
  161. }
  162. /* Test whether a character is in the RX buffer */
  163. static int _lpuart_serial_tstc(struct lpuart_serial_plat *plat)
  164. {
  165. struct lpuart_fsl *base = plat->reg;
  166. if (__raw_readb(&base->urcfifo) == 0)
  167. return 0;
  168. return 1;
  169. }
  170. /*
  171. * Initialise the serial port with the given baudrate. The settings
  172. * are always 8 data bits, no parity, 1 stop bit, no start bits.
  173. */
  174. static int _lpuart_serial_init(struct udevice *dev)
  175. {
  176. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  177. struct lpuart_fsl *base = (struct lpuart_fsl *)plat->reg;
  178. u8 ctrl;
  179. ctrl = __raw_readb(&base->uc2);
  180. ctrl &= ~UC2_RE;
  181. ctrl &= ~UC2_TE;
  182. __raw_writeb(ctrl, &base->uc2);
  183. __raw_writeb(0, &base->umodem);
  184. __raw_writeb(0, &base->uc1);
  185. /* Disable FIFO and flush buffer */
  186. __raw_writeb(0x0, &base->upfifo);
  187. __raw_writeb(0x0, &base->utwfifo);
  188. __raw_writeb(0x1, &base->urwfifo);
  189. __raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo);
  190. /* provide data bits, parity, stop bit, etc */
  191. _lpuart_serial_setbrg(dev, gd->baudrate);
  192. __raw_writeb(UC2_RE | UC2_TE, &base->uc2);
  193. return 0;
  194. }
  195. static void _lpuart32_serial_setbrg_7ulp(struct udevice *dev,
  196. int baudrate)
  197. {
  198. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  199. struct lpuart_fsl_reg32 *base = plat->reg;
  200. u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
  201. u32 clk;
  202. int ret;
  203. if (CONFIG_IS_ENABLED(CLK)) {
  204. ret = get_lpuart_clk_rate(dev, &clk);
  205. if (ret)
  206. return;
  207. } else {
  208. clk = get_lpuart_clk();
  209. }
  210. baud_diff = baudrate;
  211. osr = 0;
  212. sbr = 0;
  213. for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
  214. tmp_sbr = (clk / (baudrate * tmp_osr));
  215. if (tmp_sbr == 0)
  216. tmp_sbr = 1;
  217. /*calculate difference in actual buad w/ current values */
  218. tmp_diff = (clk / (tmp_osr * tmp_sbr));
  219. tmp_diff = tmp_diff - baudrate;
  220. /* select best values between sbr and sbr+1 */
  221. if (tmp_diff > (baudrate - (clk / (tmp_osr * (tmp_sbr + 1))))) {
  222. tmp_diff = baudrate - (clk / (tmp_osr * (tmp_sbr + 1)));
  223. tmp_sbr++;
  224. }
  225. if (tmp_diff <= baud_diff) {
  226. baud_diff = tmp_diff;
  227. osr = tmp_osr;
  228. sbr = tmp_sbr;
  229. }
  230. }
  231. /*
  232. * TODO: handle buadrate outside acceptable rate
  233. * if (baudDiff > ((config->baudRate_Bps / 100) * 3))
  234. * {
  235. * Unacceptable baud rate difference of more than 3%
  236. * return kStatus_LPUART_BaudrateNotSupport;
  237. * }
  238. */
  239. tmp = in_le32(&base->baud);
  240. if ((osr > 3) && (osr < 8))
  241. tmp |= LPUART_BAUD_BOTHEDGE_MASK;
  242. tmp &= ~LPUART_BAUD_OSR_MASK;
  243. tmp |= LPUART_BAUD_OSR(osr-1);
  244. tmp &= ~LPUART_BAUD_SBR_MASK;
  245. tmp |= LPUART_BAUD_SBR(sbr);
  246. /* explicitly disable 10 bit mode & set 1 stop bit */
  247. tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK);
  248. out_le32(&base->baud, tmp);
  249. }
  250. static void _lpuart32_serial_setbrg(struct udevice *dev,
  251. int baudrate)
  252. {
  253. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  254. struct lpuart_fsl_reg32 *base = plat->reg;
  255. u32 clk;
  256. u32 sbr;
  257. int ret;
  258. if (CONFIG_IS_ENABLED(CLK)) {
  259. ret = get_lpuart_clk_rate(dev, &clk);
  260. if (ret)
  261. return;
  262. } else {
  263. clk = get_lpuart_clk();
  264. }
  265. sbr = (clk / (16 * baudrate));
  266. /* place adjustment later - n/32 BRFA */
  267. lpuart_write32(plat->flags, &base->baud, sbr);
  268. }
  269. static int _lpuart32_serial_getc(struct lpuart_serial_plat *plat)
  270. {
  271. struct lpuart_fsl_reg32 *base = plat->reg;
  272. u32 stat, val;
  273. lpuart_read32(plat->flags, &base->stat, &stat);
  274. while ((stat & STAT_RDRF) == 0) {
  275. lpuart_write32(plat->flags, &base->stat, STAT_FLAGS);
  276. WATCHDOG_RESET();
  277. lpuart_read32(plat->flags, &base->stat, &stat);
  278. }
  279. lpuart_read32(plat->flags, &base->data, &val);
  280. lpuart_read32(plat->flags, &base->stat, &stat);
  281. if (stat & STAT_OR)
  282. lpuart_write32(plat->flags, &base->stat, STAT_OR);
  283. return val & 0x3ff;
  284. }
  285. static void _lpuart32_serial_putc(struct lpuart_serial_plat *plat,
  286. const char c)
  287. {
  288. struct lpuart_fsl_reg32 *base = plat->reg;
  289. u32 stat;
  290. if (c == '\n')
  291. serial_putc('\r');
  292. while (true) {
  293. lpuart_read32(plat->flags, &base->stat, &stat);
  294. if ((stat & STAT_TDRE))
  295. break;
  296. WATCHDOG_RESET();
  297. }
  298. lpuart_write32(plat->flags, &base->data, c);
  299. }
  300. /* Test whether a character is in the RX buffer */
  301. static int _lpuart32_serial_tstc(struct lpuart_serial_plat *plat)
  302. {
  303. struct lpuart_fsl_reg32 *base = plat->reg;
  304. u32 water;
  305. lpuart_read32(plat->flags, &base->water, &water);
  306. if ((water >> 24) == 0)
  307. return 0;
  308. return 1;
  309. }
  310. /*
  311. * Initialise the serial port with the given baudrate. The settings
  312. * are always 8 data bits, no parity, 1 stop bit, no start bits.
  313. */
  314. static int _lpuart32_serial_init(struct udevice *dev)
  315. {
  316. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  317. struct lpuart_fsl_reg32 *base = (struct lpuart_fsl_reg32 *)plat->reg;
  318. u32 val, tx_fifo_size;
  319. lpuart_read32(plat->flags, &base->ctrl, &val);
  320. val &= ~CTRL_RE;
  321. val &= ~CTRL_TE;
  322. lpuart_write32(plat->flags, &base->ctrl, val);
  323. lpuart_write32(plat->flags, &base->modir, 0);
  324. lpuart_read32(plat->flags, &base->fifo, &val);
  325. tx_fifo_size = (val & FIFO_TXSIZE_MASK) >> FIFO_TXSIZE_OFF;
  326. /* Set the TX water to half of FIFO size */
  327. if (tx_fifo_size > 1)
  328. tx_fifo_size = tx_fifo_size >> 1;
  329. /* Set RX water to 0, to be triggered by any receive data */
  330. lpuart_write32(plat->flags, &base->water,
  331. (tx_fifo_size << WATER_TXWATER_OFF));
  332. /* Enable TX and RX FIFO */
  333. val |= (FIFO_TXFE | FIFO_RXFE | FIFO_TXFLUSH | FIFO_RXFLUSH);
  334. lpuart_write32(plat->flags, &base->fifo, val);
  335. lpuart_write32(plat->flags, &base->match, 0);
  336. if (plat->devtype == DEV_MX7ULP || plat->devtype == DEV_IMX8 ||
  337. plat->devtype == DEV_IMXRT) {
  338. _lpuart32_serial_setbrg_7ulp(dev, gd->baudrate);
  339. } else {
  340. /* provide data bits, parity, stop bit, etc */
  341. _lpuart32_serial_setbrg(dev, gd->baudrate);
  342. }
  343. lpuart_write32(plat->flags, &base->ctrl, CTRL_RE | CTRL_TE);
  344. return 0;
  345. }
  346. static int lpuart_serial_setbrg(struct udevice *dev, int baudrate)
  347. {
  348. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  349. if (is_lpuart32(dev)) {
  350. if (plat->devtype == DEV_MX7ULP || plat->devtype == DEV_IMX8 ||
  351. plat->devtype == DEV_IMXRT)
  352. _lpuart32_serial_setbrg_7ulp(dev, baudrate);
  353. else
  354. _lpuart32_serial_setbrg(dev, baudrate);
  355. } else {
  356. _lpuart_serial_setbrg(dev, baudrate);
  357. }
  358. return 0;
  359. }
  360. static int lpuart_serial_getc(struct udevice *dev)
  361. {
  362. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  363. if (is_lpuart32(dev))
  364. return _lpuart32_serial_getc(plat);
  365. return _lpuart_serial_getc(plat);
  366. }
  367. static int lpuart_serial_putc(struct udevice *dev, const char c)
  368. {
  369. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  370. if (is_lpuart32(dev))
  371. _lpuart32_serial_putc(plat, c);
  372. else
  373. _lpuart_serial_putc(plat, c);
  374. return 0;
  375. }
  376. static int lpuart_serial_pending(struct udevice *dev, bool input)
  377. {
  378. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  379. struct lpuart_fsl *reg = plat->reg;
  380. struct lpuart_fsl_reg32 *reg32 = plat->reg;
  381. u32 stat;
  382. if (is_lpuart32(dev)) {
  383. if (input) {
  384. return _lpuart32_serial_tstc(plat);
  385. } else {
  386. lpuart_read32(plat->flags, &reg32->stat, &stat);
  387. return stat & STAT_TDRE ? 0 : 1;
  388. }
  389. }
  390. if (input)
  391. return _lpuart_serial_tstc(plat);
  392. else
  393. return __raw_readb(&reg->us1) & US1_TDRE ? 0 : 1;
  394. }
  395. static int lpuart_serial_probe(struct udevice *dev)
  396. {
  397. #if CONFIG_IS_ENABLED(CLK)
  398. struct clk per_clk;
  399. int ret;
  400. ret = clk_get_by_name(dev, "per", &per_clk);
  401. if (!ret) {
  402. ret = clk_enable(&per_clk);
  403. if (ret) {
  404. dev_err(dev, "Failed to get per clk: %d\n", ret);
  405. return ret;
  406. }
  407. } else {
  408. debug("%s: Failed to get per clk: %d\n", __func__, ret);
  409. }
  410. #endif
  411. if (is_lpuart32(dev))
  412. return _lpuart32_serial_init(dev);
  413. else
  414. return _lpuart_serial_init(dev);
  415. }
  416. static int lpuart_serial_of_to_plat(struct udevice *dev)
  417. {
  418. struct lpuart_serial_plat *plat = dev_get_plat(dev);
  419. const void *blob = gd->fdt_blob;
  420. int node = dev_of_offset(dev);
  421. fdt_addr_t addr;
  422. addr = dev_read_addr(dev);
  423. if (addr == FDT_ADDR_T_NONE)
  424. return -EINVAL;
  425. plat->reg = (void *)addr;
  426. plat->flags = dev_get_driver_data(dev);
  427. if (fdtdec_get_bool(blob, node, "little-endian"))
  428. plat->flags &= ~LPUART_FLAG_REGMAP_ENDIAN_BIG;
  429. if (!fdt_node_check_compatible(blob, node, "fsl,ls1021a-lpuart"))
  430. plat->devtype = DEV_LS1021A;
  431. else if (!fdt_node_check_compatible(blob, node, "fsl,imx7ulp-lpuart"))
  432. plat->devtype = DEV_MX7ULP;
  433. else if (!fdt_node_check_compatible(blob, node, "fsl,vf610-lpuart"))
  434. plat->devtype = DEV_VF610;
  435. else if (!fdt_node_check_compatible(blob, node, "fsl,imx8qm-lpuart"))
  436. plat->devtype = DEV_IMX8;
  437. else if (!fdt_node_check_compatible(blob, node, "fsl,imxrt-lpuart"))
  438. plat->devtype = DEV_IMXRT;
  439. return 0;
  440. }
  441. static const struct dm_serial_ops lpuart_serial_ops = {
  442. .putc = lpuart_serial_putc,
  443. .pending = lpuart_serial_pending,
  444. .getc = lpuart_serial_getc,
  445. .setbrg = lpuart_serial_setbrg,
  446. };
  447. static const struct udevice_id lpuart_serial_ids[] = {
  448. { .compatible = "fsl,ls1021a-lpuart", .data =
  449. LPUART_FLAG_REGMAP_32BIT_REG | LPUART_FLAG_REGMAP_ENDIAN_BIG },
  450. { .compatible = "fsl,imx7ulp-lpuart",
  451. .data = LPUART_FLAG_REGMAP_32BIT_REG },
  452. { .compatible = "fsl,vf610-lpuart"},
  453. { .compatible = "fsl,imx8qm-lpuart",
  454. .data = LPUART_FLAG_REGMAP_32BIT_REG },
  455. { .compatible = "fsl,imxrt-lpuart",
  456. .data = LPUART_FLAG_REGMAP_32BIT_REG },
  457. { }
  458. };
  459. U_BOOT_DRIVER(serial_lpuart) = {
  460. .name = "serial_lpuart",
  461. .id = UCLASS_SERIAL,
  462. .of_match = lpuart_serial_ids,
  463. .of_to_plat = lpuart_serial_of_to_plat,
  464. .plat_auto = sizeof(struct lpuart_serial_plat),
  465. .probe = lpuart_serial_probe,
  466. .ops = &lpuart_serial_ops,
  467. };