cpld.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Stout board CPLD access support
  3. *
  4. * Copyright (C) 2015 Renesas Electronics Europe GmbH
  5. * Copyright (C) 2015 Renesas Electronics Corporation
  6. * Copyright (C) 2015 Cogent Embedded, Inc.
  7. *
  8. * SPDX-License-Identifier: GPL-2.0
  9. */
  10. #include <common.h>
  11. #include <asm/io.h>
  12. #include <asm/gpio.h>
  13. #include "cpld.h"
  14. #define SCLK GPIO_GP_3_24
  15. #define SSTBZ GPIO_GP_3_25
  16. #define MOSI GPIO_GP_3_26
  17. #define MISO GPIO_GP_3_27
  18. #define CPLD_ADDR_MODE 0x00 /* RW */
  19. #define CPLD_ADDR_MUX 0x01 /* RW */
  20. #define CPLD_ADDR_HDMI 0x02 /* RW */
  21. #define CPLD_ADDR_DIPSW 0x08 /* R */
  22. #define CPLD_ADDR_RESET 0x80 /* RW */
  23. #define CPLD_ADDR_VERSION 0xFF /* R */
  24. static u32 cpld_read(u8 addr)
  25. {
  26. int i;
  27. u32 data = 0;
  28. for (i = 0; i < 8; i++) {
  29. gpio_set_value(MOSI, addr & 0x80); /* MSB first */
  30. gpio_set_value(SCLK, 1);
  31. addr <<= 1;
  32. gpio_set_value(SCLK, 0);
  33. }
  34. gpio_set_value(MOSI, 0); /* READ */
  35. gpio_set_value(SSTBZ, 0);
  36. gpio_set_value(SCLK, 1);
  37. gpio_set_value(SCLK, 0);
  38. gpio_set_value(SSTBZ, 1);
  39. for (i = 0; i < 32; i++) {
  40. gpio_set_value(SCLK, 1);
  41. data <<= 1;
  42. data |= gpio_get_value(MISO); /* MSB first */
  43. gpio_set_value(SCLK, 0);
  44. }
  45. return data;
  46. }
  47. static void cpld_write(u8 addr, u32 data)
  48. {
  49. int i;
  50. for (i = 0; i < 32; i++) {
  51. gpio_set_value(MOSI, data & (1 << 31)); /* MSB first */
  52. gpio_set_value(SCLK, 1);
  53. data <<= 1;
  54. gpio_set_value(SCLK, 0);
  55. }
  56. for (i = 0; i < 8; i++) {
  57. gpio_set_value(MOSI, addr & 0x80); /* MSB first */
  58. gpio_set_value(SCLK, 1);
  59. addr <<= 1;
  60. gpio_set_value(SCLK, 0);
  61. }
  62. gpio_set_value(MOSI, 1); /* WRITE */
  63. gpio_set_value(SSTBZ, 0);
  64. gpio_set_value(SCLK, 1);
  65. gpio_set_value(SCLK, 0);
  66. gpio_set_value(SSTBZ, 1);
  67. }
  68. /* LSI pin pull-up control */
  69. #define PUPR3 0xe606010C
  70. #define PUPR3_SD3_DAT1 (1 << 27)
  71. void cpld_init(void)
  72. {
  73. u32 val;
  74. /* PULL-UP on MISO line */
  75. val = readl(PUPR3);
  76. val |= PUPR3_SD3_DAT1;
  77. writel(val, PUPR3);
  78. gpio_request(SCLK, NULL);
  79. gpio_request(SSTBZ, NULL);
  80. gpio_request(MOSI, NULL);
  81. gpio_request(MISO, NULL);
  82. gpio_direction_output(SCLK, 0);
  83. gpio_direction_output(SSTBZ, 1);
  84. gpio_direction_output(MOSI, 0);
  85. gpio_direction_input(MISO);
  86. /* dummy read */
  87. cpld_read(CPLD_ADDR_VERSION);
  88. printf("CPLD version: 0x%08x\n",
  89. cpld_read(CPLD_ADDR_VERSION));
  90. printf("H2 Mode setting (MD0..28): 0x%08x\n",
  91. cpld_read(CPLD_ADDR_MODE));
  92. printf("Multiplexer settings: 0x%08x\n",
  93. cpld_read(CPLD_ADDR_MUX));
  94. printf("HDMI setting: 0x%08x\n",
  95. cpld_read(CPLD_ADDR_HDMI));
  96. printf("DIPSW (SW3): 0x%08x\n",
  97. cpld_read(CPLD_ADDR_DIPSW));
  98. #ifdef CONFIG_SH_SDHI
  99. /* switch MUX to SD0 */
  100. val = cpld_read(CPLD_ADDR_MUX);
  101. val &= ~MUX_MSK_SD0;
  102. val |= MUX_VAL_SD0;
  103. cpld_write(CPLD_ADDR_MUX, val);
  104. #endif
  105. }
  106. static int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  107. {
  108. u32 addr, val;
  109. if (argc < 3)
  110. return CMD_RET_USAGE;
  111. addr = simple_strtoul(argv[2], NULL, 16);
  112. if (!(addr == CPLD_ADDR_VERSION || addr == CPLD_ADDR_MODE ||
  113. addr == CPLD_ADDR_MUX || addr == CPLD_ADDR_HDMI ||
  114. addr == CPLD_ADDR_DIPSW || addr == CPLD_ADDR_RESET)) {
  115. printf("cpld invalid addr\n");
  116. return CMD_RET_USAGE;
  117. }
  118. if (argc == 3 && strcmp(argv[1], "read") == 0) {
  119. printf("0x%x\n", cpld_read(addr));
  120. } else if (argc == 4 && strcmp(argv[1], "write") == 0) {
  121. val = simple_strtoul(argv[3], NULL, 16);
  122. if (addr == CPLD_ADDR_MUX) {
  123. /* never mask SCIFA0 console */
  124. val &= ~MUX_MSK_SCIFA0_USB;
  125. val |= MUX_VAL_SCIFA0_USB;
  126. }
  127. cpld_write(addr, val);
  128. }
  129. return 0;
  130. }
  131. U_BOOT_CMD(
  132. cpld, 4, 1, do_cpld,
  133. "CPLD access",
  134. "read addr\n"
  135. "cpld write addr val\n"
  136. );
  137. void reset_cpu(ulong addr)
  138. {
  139. cpld_write(CPLD_ADDR_RESET, 1);
  140. }