ocelot-spi.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // SPDX-License-Identifier: (GPL-2.0 OR MIT)
  2. /*
  3. * SPI core driver for the Ocelot chip family.
  4. *
  5. * This driver will handle everything necessary to allow for communication over
  6. * SPI to the VSC7511, VSC7512, VSC7513 and VSC7514 chips. The main functions
  7. * are to prepare the chip's SPI interface for a specific bus speed, and a host
  8. * processor's endianness. This will create and distribute regmaps for any
  9. * children.
  10. *
  11. * Copyright 2021-2022 Innovative Advantage Inc.
  12. *
  13. * Author: Colin Foster <[email protected]>
  14. */
  15. #include <linux/device.h>
  16. #include <linux/err.h>
  17. #include <linux/errno.h>
  18. #include <linux/export.h>
  19. #include <linux/ioport.h>
  20. #include <linux/mod_devicetable.h>
  21. #include <linux/module.h>
  22. #include <linux/regmap.h>
  23. #include <linux/spi/spi.h>
  24. #include <linux/types.h>
  25. #include <linux/units.h>
  26. #include "ocelot.h"
  27. #define REG_DEV_CPUORG_IF_CTRL 0x0000
  28. #define REG_DEV_CPUORG_IF_CFGSTAT 0x0004
  29. #define CFGSTAT_IF_NUM_VCORE (0 << 24)
  30. #define CFGSTAT_IF_NUM_VRAP (1 << 24)
  31. #define CFGSTAT_IF_NUM_SI (2 << 24)
  32. #define CFGSTAT_IF_NUM_MIIM (3 << 24)
  33. #define VSC7512_DEVCPU_ORG_RES_START 0x71000000
  34. #define VSC7512_DEVCPU_ORG_RES_SIZE 0x38
  35. #define VSC7512_CHIP_REGS_RES_START 0x71070000
  36. #define VSC7512_CHIP_REGS_RES_SIZE 0x14
  37. static const struct resource vsc7512_dev_cpuorg_resource =
  38. DEFINE_RES_REG_NAMED(VSC7512_DEVCPU_ORG_RES_START,
  39. VSC7512_DEVCPU_ORG_RES_SIZE,
  40. "devcpu_org");
  41. static const struct resource vsc7512_gcb_resource =
  42. DEFINE_RES_REG_NAMED(VSC7512_CHIP_REGS_RES_START,
  43. VSC7512_CHIP_REGS_RES_SIZE,
  44. "devcpu_gcb_chip_regs");
  45. static int ocelot_spi_initialize(struct device *dev)
  46. {
  47. struct ocelot_ddata *ddata = dev_get_drvdata(dev);
  48. u32 val, check;
  49. int err;
  50. val = OCELOT_SPI_BYTE_ORDER;
  51. /*
  52. * The SPI address must be big-endian, but we want the payload to match
  53. * our CPU. These are two bits (0 and 1) but they're repeated such that
  54. * the write from any configuration will be valid. The four
  55. * configurations are:
  56. *
  57. * 0b00: little-endian, MSB first
  58. * | 111111 | 22221111 | 33222222 |
  59. * | 76543210 | 54321098 | 32109876 | 10987654 |
  60. *
  61. * 0b01: big-endian, MSB first
  62. * | 33222222 | 22221111 | 111111 | |
  63. * | 10987654 | 32109876 | 54321098 | 76543210 |
  64. *
  65. * 0b10: little-endian, LSB first
  66. * | 111111 | 11112222 | 22222233 |
  67. * | 01234567 | 89012345 | 67890123 | 45678901 |
  68. *
  69. * 0b11: big-endian, LSB first
  70. * | 22222233 | 11112222 | 111111 | |
  71. * | 45678901 | 67890123 | 89012345 | 01234567 |
  72. */
  73. err = regmap_write(ddata->cpuorg_regmap, REG_DEV_CPUORG_IF_CTRL, val);
  74. if (err)
  75. return err;
  76. /*
  77. * Apply the number of padding bytes between a read request and the data
  78. * payload. Some registers have access times of up to 1us, so if the
  79. * first payload bit is shifted out too quickly, the read will fail.
  80. */
  81. val = ddata->spi_padding_bytes;
  82. err = regmap_write(ddata->cpuorg_regmap, REG_DEV_CPUORG_IF_CFGSTAT, val);
  83. if (err)
  84. return err;
  85. /*
  86. * After we write the interface configuration, read it back here. This
  87. * will verify several different things. The first is that the number of
  88. * padding bytes actually got written correctly. These are found in bits
  89. * 0:3.
  90. *
  91. * The second is that bit 16 is cleared. Bit 16 is IF_CFGSTAT:IF_STAT,
  92. * and will be set if the register access is too fast. This would be in
  93. * the condition that the number of padding bytes is insufficient for
  94. * the SPI bus frequency.
  95. *
  96. * The last check is for bits 31:24, which define the interface by which
  97. * the registers are being accessed. Since we're accessing them via the
  98. * serial interface, it must return IF_NUM_SI.
  99. */
  100. check = val | CFGSTAT_IF_NUM_SI;
  101. err = regmap_read(ddata->cpuorg_regmap, REG_DEV_CPUORG_IF_CFGSTAT, &val);
  102. if (err)
  103. return err;
  104. if (check != val)
  105. return -ENODEV;
  106. return 0;
  107. }
  108. static const struct regmap_config ocelot_spi_regmap_config = {
  109. .reg_bits = 24,
  110. .reg_stride = 4,
  111. .reg_downshift = 2,
  112. .val_bits = 32,
  113. .write_flag_mask = 0x80,
  114. .use_single_read = true,
  115. .use_single_write = true,
  116. .can_multi_write = false,
  117. .reg_format_endian = REGMAP_ENDIAN_BIG,
  118. .val_format_endian = REGMAP_ENDIAN_NATIVE,
  119. };
  120. static int ocelot_spi_regmap_bus_read(void *context, const void *reg, size_t reg_size,
  121. void *val, size_t val_size)
  122. {
  123. struct spi_transfer xfers[3] = {0};
  124. struct device *dev = context;
  125. struct ocelot_ddata *ddata;
  126. struct spi_device *spi;
  127. struct spi_message msg;
  128. unsigned int index = 0;
  129. ddata = dev_get_drvdata(dev);
  130. spi = to_spi_device(dev);
  131. xfers[index].tx_buf = reg;
  132. xfers[index].len = reg_size;
  133. index++;
  134. if (ddata->spi_padding_bytes) {
  135. xfers[index].len = ddata->spi_padding_bytes;
  136. xfers[index].tx_buf = ddata->dummy_buf;
  137. xfers[index].dummy_data = 1;
  138. index++;
  139. }
  140. xfers[index].rx_buf = val;
  141. xfers[index].len = val_size;
  142. index++;
  143. spi_message_init_with_transfers(&msg, xfers, index);
  144. return spi_sync(spi, &msg);
  145. }
  146. static int ocelot_spi_regmap_bus_write(void *context, const void *data, size_t count)
  147. {
  148. struct device *dev = context;
  149. struct spi_device *spi = to_spi_device(dev);
  150. return spi_write(spi, data, count);
  151. }
  152. static const struct regmap_bus ocelot_spi_regmap_bus = {
  153. .write = ocelot_spi_regmap_bus_write,
  154. .read = ocelot_spi_regmap_bus_read,
  155. };
  156. struct regmap *ocelot_spi_init_regmap(struct device *dev, const struct resource *res)
  157. {
  158. struct regmap_config regmap_config;
  159. memcpy(&regmap_config, &ocelot_spi_regmap_config, sizeof(regmap_config));
  160. regmap_config.name = res->name;
  161. regmap_config.max_register = resource_size(res) - 1;
  162. regmap_config.reg_base = res->start;
  163. return devm_regmap_init(dev, &ocelot_spi_regmap_bus, dev, &regmap_config);
  164. }
  165. EXPORT_SYMBOL_NS(ocelot_spi_init_regmap, MFD_OCELOT_SPI);
  166. static int ocelot_spi_probe(struct spi_device *spi)
  167. {
  168. struct device *dev = &spi->dev;
  169. struct ocelot_ddata *ddata;
  170. struct regmap *r;
  171. int err;
  172. ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
  173. if (!ddata)
  174. return -ENOMEM;
  175. spi_set_drvdata(spi, ddata);
  176. if (spi->max_speed_hz <= 500000) {
  177. ddata->spi_padding_bytes = 0;
  178. } else {
  179. /*
  180. * Calculation taken from the manual for IF_CFGSTAT:IF_CFG.
  181. * Register access time is 1us, so we need to configure and send
  182. * out enough padding bytes between the read request and data
  183. * transmission that lasts at least 1 microsecond.
  184. */
  185. ddata->spi_padding_bytes = 1 + (spi->max_speed_hz / HZ_PER_MHZ + 2) / 8;
  186. ddata->dummy_buf = devm_kzalloc(dev, ddata->spi_padding_bytes, GFP_KERNEL);
  187. if (!ddata->dummy_buf)
  188. return -ENOMEM;
  189. }
  190. spi->bits_per_word = 8;
  191. err = spi_setup(spi);
  192. if (err)
  193. return dev_err_probe(&spi->dev, err, "Error performing SPI setup\n");
  194. r = ocelot_spi_init_regmap(dev, &vsc7512_dev_cpuorg_resource);
  195. if (IS_ERR(r))
  196. return PTR_ERR(r);
  197. ddata->cpuorg_regmap = r;
  198. r = ocelot_spi_init_regmap(dev, &vsc7512_gcb_resource);
  199. if (IS_ERR(r))
  200. return PTR_ERR(r);
  201. ddata->gcb_regmap = r;
  202. /*
  203. * The chip must be set up for SPI before it gets initialized and reset.
  204. * This must be done before calling init, and after a chip reset is
  205. * performed.
  206. */
  207. err = ocelot_spi_initialize(dev);
  208. if (err)
  209. return dev_err_probe(dev, err, "Error initializing SPI bus\n");
  210. err = ocelot_chip_reset(dev);
  211. if (err)
  212. return dev_err_probe(dev, err, "Error resetting device\n");
  213. /*
  214. * A chip reset will clear the SPI configuration, so it needs to be done
  215. * again before we can access any registers.
  216. */
  217. err = ocelot_spi_initialize(dev);
  218. if (err)
  219. return dev_err_probe(dev, err, "Error initializing SPI bus after reset\n");
  220. err = ocelot_core_init(dev);
  221. if (err)
  222. return dev_err_probe(dev, err, "Error initializing Ocelot core\n");
  223. return 0;
  224. }
  225. static const struct spi_device_id ocelot_spi_ids[] = {
  226. { "vsc7512", 0 },
  227. { }
  228. };
  229. MODULE_DEVICE_TABLE(spi, ocelot_spi_ids);
  230. static const struct of_device_id ocelot_spi_of_match[] = {
  231. { .compatible = "mscc,vsc7512" },
  232. { }
  233. };
  234. MODULE_DEVICE_TABLE(of, ocelot_spi_of_match);
  235. static struct spi_driver ocelot_spi_driver = {
  236. .driver = {
  237. .name = "ocelot-soc",
  238. .of_match_table = ocelot_spi_of_match,
  239. },
  240. .id_table = ocelot_spi_ids,
  241. .probe = ocelot_spi_probe,
  242. };
  243. module_spi_driver(ocelot_spi_driver);
  244. MODULE_DESCRIPTION("SPI Controlled Ocelot Chip Driver");
  245. MODULE_AUTHOR("Colin Foster <[email protected]>");
  246. MODULE_LICENSE("Dual MIT/GPL");
  247. MODULE_IMPORT_NS(MFD_OCELOT);