iosm_ipc_mmio.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2020-21 Intel Corporation.
  4. */
  5. #include <linux/delay.h>
  6. #include <linux/device.h>
  7. #include <linux/io.h>
  8. #include <linux/io-64-nonatomic-lo-hi.h>
  9. #include <linux/slab.h>
  10. #include "iosm_ipc_mmio.h"
  11. #include "iosm_ipc_mux.h"
  12. /* Definition of MMIO offsets
  13. * note that MMIO_CI offsets are relative to end of chip info structure
  14. */
  15. /* MMIO chip info size in bytes */
  16. #define MMIO_CHIP_INFO_SIZE 60
  17. /* CP execution stage */
  18. #define MMIO_OFFSET_EXECUTION_STAGE 0x00
  19. /* Boot ROM Chip Info struct */
  20. #define MMIO_OFFSET_CHIP_INFO 0x04
  21. #define MMIO_OFFSET_ROM_EXIT_CODE 0x40
  22. #define MMIO_OFFSET_PSI_ADDRESS 0x54
  23. #define MMIO_OFFSET_PSI_SIZE 0x5C
  24. #define MMIO_OFFSET_IPC_STATUS 0x60
  25. #define MMIO_OFFSET_CONTEXT_INFO 0x64
  26. #define MMIO_OFFSET_BASE_ADDR 0x6C
  27. #define MMIO_OFFSET_END_ADDR 0x74
  28. #define MMIO_OFFSET_CP_VERSION 0xF0
  29. #define MMIO_OFFSET_CP_CAPABILITIES 0xF4
  30. /* Timeout in 50 msec to wait for the modem boot code to write a valid
  31. * execution stage into mmio area
  32. */
  33. #define IPC_MMIO_EXEC_STAGE_TIMEOUT 50
  34. /* check if exec stage has one of the valid values */
  35. static bool ipc_mmio_is_valid_exec_stage(enum ipc_mem_exec_stage stage)
  36. {
  37. switch (stage) {
  38. case IPC_MEM_EXEC_STAGE_BOOT:
  39. case IPC_MEM_EXEC_STAGE_PSI:
  40. case IPC_MEM_EXEC_STAGE_EBL:
  41. case IPC_MEM_EXEC_STAGE_RUN:
  42. case IPC_MEM_EXEC_STAGE_CRASH:
  43. case IPC_MEM_EXEC_STAGE_CD_READY:
  44. return true;
  45. default:
  46. return false;
  47. }
  48. }
  49. void ipc_mmio_update_cp_capability(struct iosm_mmio *ipc_mmio)
  50. {
  51. u32 cp_cap;
  52. unsigned int ver;
  53. ver = ipc_mmio_get_cp_version(ipc_mmio);
  54. cp_cap = ioread32(ipc_mmio->base + ipc_mmio->offset.cp_capability);
  55. ipc_mmio->mux_protocol = ((ver >= IOSM_CP_VERSION) && (cp_cap &
  56. (UL_AGGR | DL_AGGR))) ? MUX_AGGREGATION
  57. : MUX_LITE;
  58. ipc_mmio->has_ul_flow_credit =
  59. (ver >= IOSM_CP_VERSION) && (cp_cap & UL_FLOW_CREDIT);
  60. }
  61. struct iosm_mmio *ipc_mmio_init(void __iomem *mmio, struct device *dev)
  62. {
  63. struct iosm_mmio *ipc_mmio = kzalloc(sizeof(*ipc_mmio), GFP_KERNEL);
  64. int retries = IPC_MMIO_EXEC_STAGE_TIMEOUT;
  65. enum ipc_mem_exec_stage stage;
  66. if (!ipc_mmio)
  67. return NULL;
  68. ipc_mmio->dev = dev;
  69. ipc_mmio->base = mmio;
  70. ipc_mmio->offset.exec_stage = MMIO_OFFSET_EXECUTION_STAGE;
  71. /* Check for a valid execution stage to make sure that the boot code
  72. * has correctly initialized the MMIO area.
  73. */
  74. do {
  75. stage = ipc_mmio_get_exec_stage(ipc_mmio);
  76. if (ipc_mmio_is_valid_exec_stage(stage))
  77. break;
  78. msleep(20);
  79. } while (--retries > 0);
  80. if (!retries) {
  81. dev_err(ipc_mmio->dev, "invalid exec stage %X", stage);
  82. goto init_fail;
  83. }
  84. ipc_mmio->offset.chip_info = MMIO_OFFSET_CHIP_INFO;
  85. /* read chip info size and version from chip info structure */
  86. ipc_mmio->chip_info_version =
  87. ioread8(ipc_mmio->base + ipc_mmio->offset.chip_info);
  88. /* Increment of 2 is needed as the size value in the chip info
  89. * excludes the version and size field, which are always present
  90. */
  91. ipc_mmio->chip_info_size =
  92. ioread8(ipc_mmio->base + ipc_mmio->offset.chip_info + 1) + 2;
  93. if (ipc_mmio->chip_info_size != MMIO_CHIP_INFO_SIZE) {
  94. dev_err(ipc_mmio->dev, "Unexpected Chip Info");
  95. goto init_fail;
  96. }
  97. ipc_mmio->offset.rom_exit_code = MMIO_OFFSET_ROM_EXIT_CODE;
  98. ipc_mmio->offset.psi_address = MMIO_OFFSET_PSI_ADDRESS;
  99. ipc_mmio->offset.psi_size = MMIO_OFFSET_PSI_SIZE;
  100. ipc_mmio->offset.ipc_status = MMIO_OFFSET_IPC_STATUS;
  101. ipc_mmio->offset.context_info = MMIO_OFFSET_CONTEXT_INFO;
  102. ipc_mmio->offset.ap_win_base = MMIO_OFFSET_BASE_ADDR;
  103. ipc_mmio->offset.ap_win_end = MMIO_OFFSET_END_ADDR;
  104. ipc_mmio->offset.cp_version = MMIO_OFFSET_CP_VERSION;
  105. ipc_mmio->offset.cp_capability = MMIO_OFFSET_CP_CAPABILITIES;
  106. return ipc_mmio;
  107. init_fail:
  108. kfree(ipc_mmio);
  109. return NULL;
  110. }
  111. enum ipc_mem_exec_stage ipc_mmio_get_exec_stage(struct iosm_mmio *ipc_mmio)
  112. {
  113. if (!ipc_mmio)
  114. return IPC_MEM_EXEC_STAGE_INVALID;
  115. return (enum ipc_mem_exec_stage)ioread32(ipc_mmio->base +
  116. ipc_mmio->offset.exec_stage);
  117. }
  118. void ipc_mmio_copy_chip_info(struct iosm_mmio *ipc_mmio, void *dest,
  119. size_t size)
  120. {
  121. if (ipc_mmio && dest)
  122. memcpy_fromio(dest, ipc_mmio->base + ipc_mmio->offset.chip_info,
  123. size);
  124. }
  125. enum ipc_mem_device_ipc_state ipc_mmio_get_ipc_state(struct iosm_mmio *ipc_mmio)
  126. {
  127. if (!ipc_mmio)
  128. return IPC_MEM_DEVICE_IPC_INVALID;
  129. return (enum ipc_mem_device_ipc_state)ioread32(ipc_mmio->base +
  130. ipc_mmio->offset.ipc_status);
  131. }
  132. enum rom_exit_code ipc_mmio_get_rom_exit_code(struct iosm_mmio *ipc_mmio)
  133. {
  134. if (!ipc_mmio)
  135. return IMEM_ROM_EXIT_FAIL;
  136. return (enum rom_exit_code)ioread32(ipc_mmio->base +
  137. ipc_mmio->offset.rom_exit_code);
  138. }
  139. void ipc_mmio_config(struct iosm_mmio *ipc_mmio)
  140. {
  141. if (!ipc_mmio)
  142. return;
  143. /* AP memory window (full window is open and active so that modem checks
  144. * each AP address) 0 means don't check on modem side.
  145. */
  146. iowrite64(0, ipc_mmio->base + ipc_mmio->offset.ap_win_base);
  147. iowrite64(0, ipc_mmio->base + ipc_mmio->offset.ap_win_end);
  148. iowrite64(ipc_mmio->context_info_addr,
  149. ipc_mmio->base + ipc_mmio->offset.context_info);
  150. }
  151. void ipc_mmio_set_psi_addr_and_size(struct iosm_mmio *ipc_mmio, dma_addr_t addr,
  152. u32 size)
  153. {
  154. if (!ipc_mmio)
  155. return;
  156. iowrite64(addr, ipc_mmio->base + ipc_mmio->offset.psi_address);
  157. iowrite32(size, ipc_mmio->base + ipc_mmio->offset.psi_size);
  158. }
  159. void ipc_mmio_set_contex_info_addr(struct iosm_mmio *ipc_mmio, phys_addr_t addr)
  160. {
  161. if (!ipc_mmio)
  162. return;
  163. /* store context_info address. This will be stored in the mmio area
  164. * during IPC_MEM_DEVICE_IPC_INIT state via ipc_mmio_config()
  165. */
  166. ipc_mmio->context_info_addr = addr;
  167. }
  168. int ipc_mmio_get_cp_version(struct iosm_mmio *ipc_mmio)
  169. {
  170. if (ipc_mmio)
  171. return ioread32(ipc_mmio->base + ipc_mmio->offset.cp_version);
  172. return -EFAULT;
  173. }