dcc_console.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright (c) 2015-2021, Xilinx Inc.
  3. * Written by Michal Simek.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * Redistributions of source code must retain the above copyright notice, this
  11. * list of conditions and the following disclaimer.
  12. *
  13. * Redistributions in binary form must reproduce the above copyright notice,
  14. * this list of conditions and the following disclaimer in the documentation
  15. * and/or other materials provided with the distribution.
  16. *
  17. * Neither the name of ARM nor the names of its contributors may be used
  18. * to endorse or promote products derived from this software without specific
  19. * prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  25. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. * POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #include <errno.h>
  34. #include <stddef.h>
  35. #include <arch_helpers.h>
  36. #include <drivers/arm/dcc.h>
  37. #include <drivers/console.h>
  38. #include <drivers/delay_timer.h>
  39. #include <lib/mmio.h>
  40. /* DCC Status Bits */
  41. #define DCC_STATUS_RX BIT(30)
  42. #define DCC_STATUS_TX BIT(29)
  43. #define TIMEOUT_COUNT_US U(0x10624)
  44. struct dcc_console {
  45. struct console console;
  46. };
  47. static inline uint32_t __dcc_getstatus(void)
  48. {
  49. return read_mdccsr_el0();
  50. }
  51. static inline char __dcc_getchar(void)
  52. {
  53. char c;
  54. c = read_dbgdtrrx_el0();
  55. return c;
  56. }
  57. static inline void __dcc_putchar(char c)
  58. {
  59. /*
  60. * The typecast is to make absolutely certain that 'c' is
  61. * zero-extended.
  62. */
  63. write_dbgdtrtx_el0((unsigned char)c);
  64. }
  65. static int32_t dcc_status_timeout(uint32_t mask)
  66. {
  67. const unsigned int timeout_count = TIMEOUT_COUNT_US;
  68. uint64_t timeout;
  69. unsigned int status;
  70. timeout = timeout_init_us(timeout_count);
  71. do {
  72. status = (__dcc_getstatus() & mask);
  73. if (timeout_elapsed(timeout)) {
  74. return -ETIMEDOUT;
  75. }
  76. } while ((status != 0U));
  77. return 0;
  78. }
  79. static int32_t dcc_console_putc(int32_t ch, struct console *console)
  80. {
  81. unsigned int status;
  82. status = dcc_status_timeout(DCC_STATUS_TX);
  83. if (status != 0U) {
  84. return status;
  85. }
  86. __dcc_putchar(ch);
  87. return ch;
  88. }
  89. static int32_t dcc_console_getc(struct console *console)
  90. {
  91. unsigned int status;
  92. status = dcc_status_timeout(DCC_STATUS_RX);
  93. if (status != 0U) {
  94. return status;
  95. }
  96. return __dcc_getchar();
  97. }
  98. int32_t dcc_console_init(unsigned long base_addr, uint32_t uart_clk,
  99. uint32_t baud_rate)
  100. {
  101. return 0; /* No init needed */
  102. }
  103. /**
  104. * dcc_console_flush() - Function to force a write of all buffered data
  105. * that hasn't been output.
  106. * @console Console struct
  107. *
  108. */
  109. static void dcc_console_flush(struct console *console)
  110. {
  111. unsigned int status;
  112. status = dcc_status_timeout(DCC_STATUS_TX);
  113. if (status != 0U) {
  114. return;
  115. }
  116. }
  117. static struct dcc_console dcc_console = {
  118. .console = {
  119. .flags = CONSOLE_FLAG_BOOT |
  120. CONSOLE_FLAG_RUNTIME,
  121. .putc = dcc_console_putc,
  122. .getc = dcc_console_getc,
  123. .flush = dcc_console_flush,
  124. },
  125. };
  126. int console_dcc_register(void)
  127. {
  128. return console_register(&dcc_console.console);
  129. }