io.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * This file is part of wl12xx
  4. *
  5. * Copyright (C) 2008 Nokia Corporation
  6. */
  7. #include "wl1251.h"
  8. #include "reg.h"
  9. #include "io.h"
  10. /* FIXME: this is static data nowadays and the table can be removed */
  11. static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
  12. [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474),
  13. [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478),
  14. [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494),
  15. [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498),
  16. [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C),
  17. [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
  18. [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4),
  19. [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8),
  20. [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000),
  21. [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C),
  22. [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804)
  23. };
  24. static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
  25. {
  26. /* If the address is lower than REGISTERS_BASE, it means that this is
  27. * a chip-specific register address, so look it up in the registers
  28. * table */
  29. if (addr < REGISTERS_BASE) {
  30. /* Make sure we don't go over the table */
  31. if (addr >= ACX_REG_TABLE_LEN) {
  32. wl1251_error("address out of range (%d)", addr);
  33. return -EINVAL;
  34. }
  35. addr = wl1251_io_reg_table[addr];
  36. }
  37. return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
  38. }
  39. static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
  40. {
  41. return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
  42. }
  43. void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
  44. {
  45. int physical;
  46. physical = wl1251_translate_mem_addr(wl, addr);
  47. wl->if_ops->read(wl, physical, buf, len);
  48. }
  49. void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
  50. {
  51. int physical;
  52. physical = wl1251_translate_mem_addr(wl, addr);
  53. wl->if_ops->write(wl, physical, buf, len);
  54. }
  55. u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
  56. {
  57. return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
  58. }
  59. void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
  60. {
  61. wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
  62. }
  63. u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
  64. {
  65. return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
  66. }
  67. void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
  68. {
  69. wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
  70. }
  71. /* Set the partitions to access the chip addresses.
  72. *
  73. * There are two VIRTUAL partitions (the memory partition and the
  74. * registers partition), which are mapped to two different areas of the
  75. * PHYSICAL (hardware) memory. This function also makes other checks to
  76. * ensure that the partitions are not overlapping. In the diagram below, the
  77. * memory partition comes before the register partition, but the opposite is
  78. * also supported.
  79. *
  80. * PHYSICAL address
  81. * space
  82. *
  83. * | |
  84. * ...+----+--> mem_start
  85. * VIRTUAL address ... | |
  86. * space ... | | [PART_0]
  87. * ... | |
  88. * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
  89. * | | ... | |
  90. * |MEM | ... | |
  91. * | | ... | |
  92. * part_size <--+----+... | | {unused area)
  93. * | | ... | |
  94. * |REG | ... | |
  95. * part_size | | ... | |
  96. * + <--+----+... ...+----+--> reg_start
  97. * reg_size ... | |
  98. * ... | | [PART_1]
  99. * ... | |
  100. * ...+----+--> reg_start + reg_size
  101. * | |
  102. *
  103. */
  104. void wl1251_set_partition(struct wl1251 *wl,
  105. u32 mem_start, u32 mem_size,
  106. u32 reg_start, u32 reg_size)
  107. {
  108. struct wl1251_partition_set *partition;
  109. partition = kmalloc(sizeof(*partition), GFP_KERNEL);
  110. if (!partition) {
  111. wl1251_error("can not allocate partition buffer");
  112. return;
  113. }
  114. wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
  115. mem_start, mem_size);
  116. wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
  117. reg_start, reg_size);
  118. /* Make sure that the two partitions together don't exceed the
  119. * address range */
  120. if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
  121. wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
  122. " address range. Truncating partition[0].");
  123. mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
  124. wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
  125. mem_start, mem_size);
  126. wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
  127. reg_start, reg_size);
  128. }
  129. if ((mem_start < reg_start) &&
  130. ((mem_start + mem_size) > reg_start)) {
  131. /* Guarantee that the memory partition doesn't overlap the
  132. * registers partition */
  133. wl1251_debug(DEBUG_SPI, "End of partition[0] is "
  134. "overlapping partition[1]. Adjusted.");
  135. mem_size = reg_start - mem_start;
  136. wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
  137. mem_start, mem_size);
  138. wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
  139. reg_start, reg_size);
  140. } else if ((reg_start < mem_start) &&
  141. ((reg_start + reg_size) > mem_start)) {
  142. /* Guarantee that the register partition doesn't overlap the
  143. * memory partition */
  144. wl1251_debug(DEBUG_SPI, "End of partition[1] is"
  145. " overlapping partition[0]. Adjusted.");
  146. reg_size = mem_start - reg_start;
  147. wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
  148. mem_start, mem_size);
  149. wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
  150. reg_start, reg_size);
  151. }
  152. partition->mem.start = mem_start;
  153. partition->mem.size = mem_size;
  154. partition->reg.start = reg_start;
  155. partition->reg.size = reg_size;
  156. wl->physical_mem_addr = mem_start;
  157. wl->physical_reg_addr = reg_start;
  158. wl->virtual_mem_addr = 0;
  159. wl->virtual_reg_addr = mem_size;
  160. wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
  161. sizeof(*partition));
  162. kfree(partition);
  163. }