host_soc.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Sonics Silicon Backplane SoC host related functions.
  3. * Subsystem core
  4. *
  5. * Copyright 2005, Broadcom Corporation
  6. * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
  7. *
  8. * Licensed under the GNU/GPL. See COPYING for details.
  9. */
  10. #include <linux/ssb/ssb.h>
  11. #include "ssb_private.h"
  12. static u8 ssb_host_soc_read8(struct ssb_device *dev, u16 offset)
  13. {
  14. struct ssb_bus *bus = dev->bus;
  15. offset += dev->core_index * SSB_CORE_SIZE;
  16. return readb(bus->mmio + offset);
  17. }
  18. static u16 ssb_host_soc_read16(struct ssb_device *dev, u16 offset)
  19. {
  20. struct ssb_bus *bus = dev->bus;
  21. offset += dev->core_index * SSB_CORE_SIZE;
  22. return readw(bus->mmio + offset);
  23. }
  24. static u32 ssb_host_soc_read32(struct ssb_device *dev, u16 offset)
  25. {
  26. struct ssb_bus *bus = dev->bus;
  27. offset += dev->core_index * SSB_CORE_SIZE;
  28. return readl(bus->mmio + offset);
  29. }
  30. #ifdef CONFIG_SSB_BLOCKIO
  31. static void ssb_host_soc_block_read(struct ssb_device *dev, void *buffer,
  32. size_t count, u16 offset, u8 reg_width)
  33. {
  34. struct ssb_bus *bus = dev->bus;
  35. void __iomem *addr;
  36. offset += dev->core_index * SSB_CORE_SIZE;
  37. addr = bus->mmio + offset;
  38. switch (reg_width) {
  39. case sizeof(u8): {
  40. u8 *buf = buffer;
  41. while (count) {
  42. *buf = __raw_readb(addr);
  43. buf++;
  44. count--;
  45. }
  46. break;
  47. }
  48. case sizeof(u16): {
  49. __le16 *buf = buffer;
  50. SSB_WARN_ON(count & 1);
  51. while (count) {
  52. *buf = (__force __le16)__raw_readw(addr);
  53. buf++;
  54. count -= 2;
  55. }
  56. break;
  57. }
  58. case sizeof(u32): {
  59. __le32 *buf = buffer;
  60. SSB_WARN_ON(count & 3);
  61. while (count) {
  62. *buf = (__force __le32)__raw_readl(addr);
  63. buf++;
  64. count -= 4;
  65. }
  66. break;
  67. }
  68. default:
  69. SSB_WARN_ON(1);
  70. }
  71. }
  72. #endif /* CONFIG_SSB_BLOCKIO */
  73. static void ssb_host_soc_write8(struct ssb_device *dev, u16 offset, u8 value)
  74. {
  75. struct ssb_bus *bus = dev->bus;
  76. offset += dev->core_index * SSB_CORE_SIZE;
  77. writeb(value, bus->mmio + offset);
  78. }
  79. static void ssb_host_soc_write16(struct ssb_device *dev, u16 offset, u16 value)
  80. {
  81. struct ssb_bus *bus = dev->bus;
  82. offset += dev->core_index * SSB_CORE_SIZE;
  83. writew(value, bus->mmio + offset);
  84. }
  85. static void ssb_host_soc_write32(struct ssb_device *dev, u16 offset, u32 value)
  86. {
  87. struct ssb_bus *bus = dev->bus;
  88. offset += dev->core_index * SSB_CORE_SIZE;
  89. writel(value, bus->mmio + offset);
  90. }
  91. #ifdef CONFIG_SSB_BLOCKIO
  92. static void ssb_host_soc_block_write(struct ssb_device *dev, const void *buffer,
  93. size_t count, u16 offset, u8 reg_width)
  94. {
  95. struct ssb_bus *bus = dev->bus;
  96. void __iomem *addr;
  97. offset += dev->core_index * SSB_CORE_SIZE;
  98. addr = bus->mmio + offset;
  99. switch (reg_width) {
  100. case sizeof(u8): {
  101. const u8 *buf = buffer;
  102. while (count) {
  103. __raw_writeb(*buf, addr);
  104. buf++;
  105. count--;
  106. }
  107. break;
  108. }
  109. case sizeof(u16): {
  110. const __le16 *buf = buffer;
  111. SSB_WARN_ON(count & 1);
  112. while (count) {
  113. __raw_writew((__force u16)(*buf), addr);
  114. buf++;
  115. count -= 2;
  116. }
  117. break;
  118. }
  119. case sizeof(u32): {
  120. const __le32 *buf = buffer;
  121. SSB_WARN_ON(count & 3);
  122. while (count) {
  123. __raw_writel((__force u32)(*buf), addr);
  124. buf++;
  125. count -= 4;
  126. }
  127. break;
  128. }
  129. default:
  130. SSB_WARN_ON(1);
  131. }
  132. }
  133. #endif /* CONFIG_SSB_BLOCKIO */
  134. /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
  135. const struct ssb_bus_ops ssb_host_soc_ops = {
  136. .read8 = ssb_host_soc_read8,
  137. .read16 = ssb_host_soc_read16,
  138. .read32 = ssb_host_soc_read32,
  139. .write8 = ssb_host_soc_write8,
  140. .write16 = ssb_host_soc_write16,
  141. .write32 = ssb_host_soc_write32,
  142. #ifdef CONFIG_SSB_BLOCKIO
  143. .block_read = ssb_host_soc_block_read,
  144. .block_write = ssb_host_soc_block_write,
  145. #endif
  146. };