uniphier_console_setup.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (c) 2019-2020, Socionext Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <drivers/console.h>
  8. #include <errno.h>
  9. #include <lib/mmio.h>
  10. #include <plat/common/platform.h>
  11. #include "uniphier.h"
  12. #include "uniphier_console.h"
  13. #define UNIPHIER_UART_OFFSET 0x100
  14. #define UNIPHIER_UART_NR_PORTS 4
  15. /* These callbacks are implemented in assembly to use crash_console_helpers.S */
  16. int uniphier_console_putc(int character, struct console *console);
  17. int uniphier_console_getc(struct console *console);
  18. void uniphier_console_flush(struct console *console);
  19. static console_t uniphier_console = {
  20. .flags = CONSOLE_FLAG_BOOT |
  21. #if DEBUG
  22. CONSOLE_FLAG_RUNTIME |
  23. #endif
  24. CONSOLE_FLAG_CRASH |
  25. CONSOLE_FLAG_TRANSLATE_CRLF,
  26. .putc = uniphier_console_putc,
  27. #if ENABLE_CONSOLE_GETC
  28. .getc = uniphier_console_getc,
  29. #endif
  30. .flush = uniphier_console_flush,
  31. };
  32. static const uintptr_t uniphier_uart_base[] = {
  33. [UNIPHIER_SOC_LD11] = 0x54006800,
  34. [UNIPHIER_SOC_LD20] = 0x54006800,
  35. [UNIPHIER_SOC_PXS3] = 0x54006800,
  36. };
  37. /*
  38. * There are 4 UART ports available on this platform. By default, we want to
  39. * use the same one as used in the previous firmware stage.
  40. */
  41. static uintptr_t uniphier_console_get_base(unsigned int soc)
  42. {
  43. uintptr_t base, end;
  44. uint32_t div;
  45. assert(soc < ARRAY_SIZE(uniphier_uart_base));
  46. base = uniphier_uart_base[soc];
  47. end = base + UNIPHIER_UART_OFFSET * UNIPHIER_UART_NR_PORTS;
  48. while (base < end) {
  49. div = mmio_read_32(base + UNIPHIER_UART_DLR);
  50. if (div)
  51. return base;
  52. base += UNIPHIER_UART_OFFSET;
  53. }
  54. return 0;
  55. }
  56. static void uniphier_console_init(uintptr_t base)
  57. {
  58. mmio_write_32(base + UNIPHIER_UART_FCR, UNIPHIER_UART_FCR_ENABLE_FIFO);
  59. mmio_write_32(base + UNIPHIER_UART_LCR_MCR,
  60. UNIPHIER_UART_LCR_WLEN8 << 8);
  61. }
  62. void uniphier_console_setup(unsigned int soc)
  63. {
  64. uintptr_t base;
  65. base = uniphier_console_get_base(soc);
  66. if (!base)
  67. plat_error_handler(-EINVAL);
  68. uniphier_console.base = base;
  69. console_register(&uniphier_console);
  70. /*
  71. * The hardware might be still printing characters queued up in the
  72. * previous firmware stage. Make sure the transmitter is empty before
  73. * any initialization. Otherwise, the console might get corrupted.
  74. */
  75. console_flush();
  76. uniphier_console_init(base);
  77. }