imx8m_ccm.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * Copyright (c) 2023, Pengutronix. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <lib/mmio.h>
  7. #include <platform_def.h>
  8. #define UCR1 0x80
  9. #define UCR1_UARTEN BIT(0)
  10. #define DOMAIN0_RUNNING(d) (((d) & 0x3) != 0)
  11. static struct imx_uart {
  12. unsigned int ccm_reg;
  13. unsigned int uart_base;
  14. } imx8m_uart_info[] = {
  15. { /* UART 1 */
  16. .ccm_reg = 0x4490,
  17. .uart_base = IMX_UART1_BASE,
  18. }, { /* UART 2 */
  19. .ccm_reg = 0x44a0,
  20. .uart_base = IMX_UART2_BASE,
  21. }, { /* UART 3 */
  22. .ccm_reg = 0x44b0,
  23. .uart_base = IMX_UART3_BASE,
  24. }, { /* UART 4 */
  25. .ccm_reg = 0x44c0,
  26. .uart_base = IMX_UART4_BASE,
  27. }
  28. };
  29. unsigned int imx8m_uart_get_base(void)
  30. {
  31. unsigned int i;
  32. for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
  33. uint32_t val;
  34. /*
  35. * At least check that the clock-gate is ungated before we
  36. * access the UART register.
  37. */
  38. val = mmio_read_32(IMX_CCM_BASE + imx8m_uart_info[i].ccm_reg);
  39. if (DOMAIN0_RUNNING(val)) {
  40. val = mmio_read_32(imx8m_uart_info[i].uart_base + UCR1);
  41. if (val & UCR1_UARTEN) {
  42. return imx8m_uart_info[i].uart_base;
  43. }
  44. }
  45. }
  46. /*
  47. * We should return an error and inform the user but we can't do it
  48. * this early.
  49. */
  50. return 0;
  51. }