serial_intel_mid.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2017 Intel Corporation
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <ns16550.h>
  8. #include <serial.h>
  9. /*
  10. * The UART clock is calculated as
  11. *
  12. * UART clock = XTAL * UART_MUL / UART_DIV
  13. *
  14. * The baudrate is calculated as
  15. *
  16. * baud rate = UART clock / UART_PS / DLAB
  17. */
  18. #define UART_PS 0x30
  19. #define UART_MUL 0x34
  20. #define UART_DIV 0x38
  21. static void mid_writel(struct ns16550_platdata *plat, int offset, int value)
  22. {
  23. unsigned char *addr;
  24. offset *= 1 << plat->reg_shift;
  25. addr = (unsigned char *)plat->base + offset;
  26. writel(value, addr + plat->reg_offset);
  27. }
  28. static int mid_serial_probe(struct udevice *dev)
  29. {
  30. struct ns16550_platdata *plat = dev_get_platdata(dev);
  31. /*
  32. * Initialize fractional divider correctly for Intel Edison
  33. * platform.
  34. *
  35. * For backward compatibility we have to set initial DLAB value
  36. * to 16 and speed to 115200 baud, where initial frequency is
  37. * 29491200Hz, and XTAL frequency is 38.4MHz.
  38. */
  39. mid_writel(plat, UART_MUL, 96);
  40. mid_writel(plat, UART_DIV, 125);
  41. mid_writel(plat, UART_PS, 16);
  42. return ns16550_serial_probe(dev);
  43. }
  44. static const struct udevice_id mid_serial_ids[] = {
  45. { .compatible = "intel,mid-uart" },
  46. {}
  47. };
  48. U_BOOT_DRIVER(serial_intel_mid) = {
  49. .name = "serial_intel_mid",
  50. .id = UCLASS_SERIAL,
  51. .of_match = mid_serial_ids,
  52. .ofdata_to_platdata = ns16550_serial_ofdata_to_platdata,
  53. .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
  54. .priv_auto_alloc_size = sizeof(struct NS16550),
  55. .probe = mid_serial_probe,
  56. .ops = &ns16550_serial_ops,
  57. };