octeon_spi.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2018 Marvell International Ltd.
  4. */
  5. #include <clk.h>
  6. #include <dm.h>
  7. #include <malloc.h>
  8. #include <spi.h>
  9. #include <spi-mem.h>
  10. #include <watchdog.h>
  11. #include <asm/io.h>
  12. #include <asm/unaligned.h>
  13. #include <linux/bitfield.h>
  14. #include <linux/compat.h>
  15. #include <linux/delay.h>
  16. #define OCTEON_SPI_MAX_BYTES 9
  17. #define OCTEON_SPI_MAX_CLOCK_HZ 50000000
  18. #define OCTEON_SPI_NUM_CS 4
  19. #define OCTEON_SPI_CS_VALID(cs) ((cs) < OCTEON_SPI_NUM_CS)
  20. #define MPI_CFG 0x0000
  21. #define MPI_STS 0x0008
  22. #define MPI_TX 0x0010
  23. #define MPI_XMIT 0x0018
  24. #define MPI_WIDE_DAT 0x0040
  25. #define MPI_IO_CTL 0x0048
  26. #define MPI_DAT(X) (0x0080 + ((X) << 3))
  27. #define MPI_WIDE_BUF(X) (0x0800 + ((X) << 3))
  28. #define MPI_CYA_CFG 0x1000
  29. #define MPI_CLKEN 0x1080
  30. #define MPI_CFG_ENABLE BIT_ULL(0)
  31. #define MPI_CFG_IDLELO BIT_ULL(1)
  32. #define MPI_CFG_CLK_CONT BIT_ULL(2)
  33. #define MPI_CFG_WIREOR BIT_ULL(3)
  34. #define MPI_CFG_LSBFIRST BIT_ULL(4)
  35. #define MPI_CFG_CS_STICKY BIT_ULL(5)
  36. #define MPI_CFG_CSHI BIT_ULL(7)
  37. #define MPI_CFG_IDLECLKS GENMASK_ULL(9, 8)
  38. #define MPI_CFG_TRITX BIT_ULL(10)
  39. #define MPI_CFG_CSLATE BIT_ULL(11)
  40. #define MPI_CFG_CSENA0 BIT_ULL(12)
  41. #define MPI_CFG_CSENA1 BIT_ULL(13)
  42. #define MPI_CFG_CSENA2 BIT_ULL(14)
  43. #define MPI_CFG_CSENA3 BIT_ULL(15)
  44. #define MPI_CFG_CLKDIV GENMASK_ULL(28, 16)
  45. #define MPI_CFG_LEGACY_DIS BIT_ULL(31)
  46. #define MPI_CFG_IOMODE GENMASK_ULL(35, 34)
  47. #define MPI_CFG_TB100_EN BIT_ULL(49)
  48. #define MPI_DAT_DATA GENMASK_ULL(7, 0)
  49. #define MPI_STS_BUSY BIT_ULL(0)
  50. #define MPI_STS_MPI_INTR BIT_ULL(1)
  51. #define MPI_STS_RXNUM GENMASK_ULL(12, 8)
  52. #define MPI_TX_TOTNUM GENMASK_ULL(4, 0)
  53. #define MPI_TX_TXNUM GENMASK_ULL(12, 8)
  54. #define MPI_TX_LEAVECS BIT_ULL(16)
  55. #define MPI_TX_CSID GENMASK_ULL(21, 20)
  56. #define MPI_XMIT_TOTNUM GENMASK_ULL(10, 0)
  57. #define MPI_XMIT_TXNUM GENMASK_ULL(30, 20)
  58. #define MPI_XMIT_BUF_SEL BIT_ULL(59)
  59. #define MPI_XMIT_LEAVECS BIT_ULL(60)
  60. #define MPI_XMIT_CSID GENMASK_ULL(62, 61)
  61. /* Used on Octeon TX2 */
  62. void board_acquire_flash_arb(bool acquire);
  63. /* Local driver data structure */
  64. struct octeon_spi {
  65. void __iomem *base; /* Register base address */
  66. struct clk clk;
  67. u32 clkdiv; /* Clock divisor for device speed */
  68. };
  69. static u64 octeon_spi_set_mpicfg(struct udevice *dev)
  70. {
  71. struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
  72. struct udevice *bus = dev_get_parent(dev);
  73. struct octeon_spi *priv = dev_get_priv(bus);
  74. u64 mpi_cfg;
  75. uint max_speed = slave->max_hz;
  76. bool cpha, cpol;
  77. if (!max_speed)
  78. max_speed = 12500000;
  79. if (max_speed > OCTEON_SPI_MAX_CLOCK_HZ)
  80. max_speed = OCTEON_SPI_MAX_CLOCK_HZ;
  81. debug("\n slave params %d %d %d\n", slave->cs,
  82. slave->max_hz, slave->mode);
  83. cpha = !!(slave->mode & SPI_CPHA);
  84. cpol = !!(slave->mode & SPI_CPOL);
  85. mpi_cfg = FIELD_PREP(MPI_CFG_CLKDIV, priv->clkdiv & 0x1fff) |
  86. FIELD_PREP(MPI_CFG_CSHI, !!(slave->mode & SPI_CS_HIGH)) |
  87. FIELD_PREP(MPI_CFG_LSBFIRST, !!(slave->mode & SPI_LSB_FIRST)) |
  88. FIELD_PREP(MPI_CFG_WIREOR, !!(slave->mode & SPI_3WIRE)) |
  89. FIELD_PREP(MPI_CFG_IDLELO, cpha != cpol) |
  90. FIELD_PREP(MPI_CFG_CSLATE, cpha) |
  91. MPI_CFG_CSENA0 | MPI_CFG_CSENA1 |
  92. MPI_CFG_CSENA2 | MPI_CFG_CSENA1 |
  93. MPI_CFG_ENABLE;
  94. debug("\n mpi_cfg %llx\n", mpi_cfg);
  95. return mpi_cfg;
  96. }
  97. /**
  98. * Wait until the SPI bus is ready
  99. *
  100. * @param dev SPI device to wait for
  101. */
  102. static void octeon_spi_wait_ready(struct udevice *dev)
  103. {
  104. struct udevice *bus = dev_get_parent(dev);
  105. struct octeon_spi *priv = dev_get_priv(bus);
  106. void *base = priv->base;
  107. u64 mpi_sts;
  108. do {
  109. mpi_sts = readq(base + MPI_STS);
  110. WATCHDOG_RESET();
  111. } while (mpi_sts & MPI_STS_BUSY);
  112. debug("%s(%s)\n", __func__, dev->name);
  113. }
  114. /**
  115. * Claim the bus for a slave device
  116. *
  117. * @param dev SPI bus
  118. *
  119. * @return 0 for success, -EINVAL if chip select is invalid
  120. */
  121. static int octeon_spi_claim_bus(struct udevice *dev)
  122. {
  123. struct udevice *bus = dev_get_parent(dev);
  124. struct octeon_spi *priv = dev_get_priv(bus);
  125. void *base = priv->base;
  126. u64 mpi_cfg;
  127. debug("\n\n%s(%s)\n", __func__, dev->name);
  128. if (!OCTEON_SPI_CS_VALID(spi_chip_select(dev)))
  129. return -EINVAL;
  130. if (IS_ENABLED(CONFIG_ARCH_OCTEONTX2))
  131. board_acquire_flash_arb(true);
  132. mpi_cfg = readq(base + MPI_CFG);
  133. mpi_cfg &= ~MPI_CFG_TRITX;
  134. mpi_cfg |= MPI_CFG_ENABLE;
  135. writeq(mpi_cfg, base + MPI_CFG);
  136. mpi_cfg = readq(base + MPI_CFG);
  137. udelay(5); /** Wait for bus to settle */
  138. return 0;
  139. }
  140. /**
  141. * Release the bus to a slave device
  142. *
  143. * @param dev SPI bus
  144. *
  145. * @return 0 for success, -EINVAL if chip select is invalid
  146. */
  147. static int octeon_spi_release_bus(struct udevice *dev)
  148. {
  149. struct udevice *bus = dev_get_parent(dev);
  150. struct octeon_spi *priv = dev_get_priv(bus);
  151. void *base = priv->base;
  152. u64 mpi_cfg;
  153. debug("%s(%s)\n\n", __func__, dev->name);
  154. if (!OCTEON_SPI_CS_VALID(spi_chip_select(dev)))
  155. return -EINVAL;
  156. if (IS_ENABLED(CONFIG_ARCH_OCTEONTX2))
  157. board_acquire_flash_arb(false);
  158. mpi_cfg = readq(base + MPI_CFG);
  159. mpi_cfg &= ~MPI_CFG_ENABLE;
  160. writeq(mpi_cfg, base + MPI_CFG);
  161. mpi_cfg = readq(base + MPI_CFG);
  162. udelay(1);
  163. return 0;
  164. }
  165. static int octeon_spi_xfer(struct udevice *dev, unsigned int bitlen,
  166. const void *dout, void *din, unsigned long flags)
  167. {
  168. struct udevice *bus = dev_get_parent(dev);
  169. struct octeon_spi *priv = dev_get_priv(bus);
  170. void *base = priv->base;
  171. u64 mpi_tx;
  172. u64 mpi_cfg;
  173. u64 wide_dat = 0;
  174. int len = bitlen / 8;
  175. int i;
  176. const u8 *tx_data = dout;
  177. u8 *rx_data = din;
  178. int cs = spi_chip_select(dev);
  179. if (!OCTEON_SPI_CS_VALID(cs))
  180. return -EINVAL;
  181. debug("\n %s(%s, %u, %p, %p, 0x%lx), cs: %d\n",
  182. __func__, dev->name, bitlen, dout, din, flags, cs);
  183. mpi_cfg = octeon_spi_set_mpicfg(dev);
  184. if (mpi_cfg != readq(base + MPI_CFG)) {
  185. writeq(mpi_cfg, base + MPI_CFG);
  186. mpi_cfg = readq(base + MPI_CFG);
  187. udelay(10);
  188. }
  189. debug("\n mpi_cfg upd %llx\n", mpi_cfg);
  190. /*
  191. * Start by writing and reading 8 bytes at a time. While we can support
  192. * up to 10, it's easier to just use 8 with the MPI_WIDE_DAT register.
  193. */
  194. while (len > 8) {
  195. if (tx_data) {
  196. wide_dat = get_unaligned((u64 *)tx_data);
  197. debug(" tx: %016llx \t", (unsigned long long)wide_dat);
  198. tx_data += 8;
  199. writeq(wide_dat, base + MPI_WIDE_DAT);
  200. }
  201. mpi_tx = FIELD_PREP(MPI_TX_CSID, cs) |
  202. FIELD_PREP(MPI_TX_LEAVECS, 1) |
  203. FIELD_PREP(MPI_TX_TXNUM, tx_data ? 8 : 0) |
  204. FIELD_PREP(MPI_TX_TOTNUM, 8);
  205. writeq(mpi_tx, base + MPI_TX);
  206. octeon_spi_wait_ready(dev);
  207. debug("\n ");
  208. if (rx_data) {
  209. wide_dat = readq(base + MPI_WIDE_DAT);
  210. debug(" rx: %016llx\t", (unsigned long long)wide_dat);
  211. *(u64 *)rx_data = wide_dat;
  212. rx_data += 8;
  213. }
  214. len -= 8;
  215. }
  216. debug("\n ");
  217. /* Write and read the rest of the data */
  218. if (tx_data) {
  219. for (i = 0; i < len; i++) {
  220. debug(" tx: %02x\n", *tx_data);
  221. writeq(*tx_data++, base + MPI_DAT(i));
  222. }
  223. }
  224. mpi_tx = FIELD_PREP(MPI_TX_CSID, cs) |
  225. FIELD_PREP(MPI_TX_LEAVECS, !(flags & SPI_XFER_END)) |
  226. FIELD_PREP(MPI_TX_TXNUM, tx_data ? len : 0) |
  227. FIELD_PREP(MPI_TX_TOTNUM, len);
  228. writeq(mpi_tx, base + MPI_TX);
  229. octeon_spi_wait_ready(dev);
  230. debug("\n ");
  231. if (rx_data) {
  232. for (i = 0; i < len; i++) {
  233. *rx_data = readq(base + MPI_DAT(i)) & 0xff;
  234. debug(" rx: %02x\n", *rx_data);
  235. rx_data++;
  236. }
  237. }
  238. return 0;
  239. }
  240. static int octeontx2_spi_xfer(struct udevice *dev, unsigned int bitlen,
  241. const void *dout, void *din, unsigned long flags)
  242. {
  243. struct udevice *bus = dev_get_parent(dev);
  244. struct octeon_spi *priv = dev_get_priv(bus);
  245. void *base = priv->base;
  246. u64 mpi_xmit;
  247. u64 mpi_cfg;
  248. u64 wide_dat = 0;
  249. int len = bitlen / 8;
  250. int rem;
  251. int i;
  252. const u8 *tx_data = dout;
  253. u8 *rx_data = din;
  254. int cs = spi_chip_select(dev);
  255. if (!OCTEON_SPI_CS_VALID(cs))
  256. return -EINVAL;
  257. debug("\n %s(%s, %u, %p, %p, 0x%lx), cs: %d\n",
  258. __func__, dev->name, bitlen, dout, din, flags, cs);
  259. mpi_cfg = octeon_spi_set_mpicfg(dev);
  260. mpi_cfg |= MPI_CFG_TRITX | MPI_CFG_LEGACY_DIS | MPI_CFG_CS_STICKY |
  261. MPI_CFG_TB100_EN;
  262. mpi_cfg &= ~MPI_CFG_IOMODE;
  263. if (flags & (SPI_TX_DUAL | SPI_RX_DUAL))
  264. mpi_cfg |= FIELD_PREP(MPI_CFG_IOMODE, 2);
  265. if (flags & (SPI_TX_QUAD | SPI_RX_QUAD))
  266. mpi_cfg |= FIELD_PREP(MPI_CFG_IOMODE, 3);
  267. if (mpi_cfg != readq(base + MPI_CFG)) {
  268. writeq(mpi_cfg, base + MPI_CFG);
  269. mpi_cfg = readq(base + MPI_CFG);
  270. udelay(10);
  271. }
  272. debug("\n mpi_cfg upd %llx\n\n", mpi_cfg);
  273. /* Start by writing or reading 1024 bytes at a time. */
  274. while (len > 1024) {
  275. if (tx_data) {
  276. /* 8 bytes per iteration */
  277. for (i = 0; i < 128; i++) {
  278. wide_dat = get_unaligned((u64 *)tx_data);
  279. debug(" tx: %016llx \t",
  280. (unsigned long long)wide_dat);
  281. if ((i % 4) == 3)
  282. debug("\n");
  283. tx_data += 8;
  284. writeq(wide_dat, base + MPI_WIDE_BUF(i));
  285. }
  286. }
  287. mpi_xmit = FIELD_PREP(MPI_XMIT_CSID, cs) | MPI_XMIT_LEAVECS |
  288. FIELD_PREP(MPI_XMIT_TXNUM, tx_data ? 1024 : 0) |
  289. FIELD_PREP(MPI_XMIT_TOTNUM, 1024);
  290. writeq(mpi_xmit, base + MPI_XMIT);
  291. octeon_spi_wait_ready(dev);
  292. debug("\n ");
  293. if (rx_data) {
  294. /* 8 bytes per iteration */
  295. for (i = 0; i < 128; i++) {
  296. wide_dat = readq(base + MPI_WIDE_BUF(i));
  297. debug(" rx: %016llx\t",
  298. (unsigned long long)wide_dat);
  299. if ((i % 4) == 3)
  300. debug("\n");
  301. *(u64 *)rx_data = wide_dat;
  302. rx_data += 8;
  303. }
  304. }
  305. len -= 1024;
  306. }
  307. if (tx_data) {
  308. rem = len % 8;
  309. /* 8 bytes per iteration */
  310. for (i = 0; i < len / 8; i++) {
  311. wide_dat = get_unaligned((u64 *)tx_data);
  312. debug(" tx: %016llx \t",
  313. (unsigned long long)wide_dat);
  314. if ((i % 4) == 3)
  315. debug("\n");
  316. tx_data += 8;
  317. writeq(wide_dat, base + MPI_WIDE_BUF(i));
  318. }
  319. if (rem) {
  320. memcpy(&wide_dat, tx_data, rem);
  321. debug(" rtx: %016llx\t", wide_dat);
  322. writeq(wide_dat, base + MPI_WIDE_BUF(i));
  323. }
  324. }
  325. mpi_xmit = FIELD_PREP(MPI_XMIT_CSID, cs) |
  326. FIELD_PREP(MPI_XMIT_LEAVECS, !(flags & SPI_XFER_END)) |
  327. FIELD_PREP(MPI_XMIT_TXNUM, tx_data ? len : 0) |
  328. FIELD_PREP(MPI_XMIT_TOTNUM, len);
  329. writeq(mpi_xmit, base + MPI_XMIT);
  330. octeon_spi_wait_ready(dev);
  331. debug("\n ");
  332. if (rx_data) {
  333. rem = len % 8;
  334. /* 8 bytes per iteration */
  335. for (i = 0; i < len / 8; i++) {
  336. wide_dat = readq(base + MPI_WIDE_BUF(i));
  337. debug(" rx: %016llx\t",
  338. (unsigned long long)wide_dat);
  339. if ((i % 4) == 3)
  340. debug("\n");
  341. *(u64 *)rx_data = wide_dat;
  342. rx_data += 8;
  343. }
  344. if (rem) {
  345. wide_dat = readq(base + MPI_WIDE_BUF(i));
  346. debug(" rrx: %016llx\t",
  347. (unsigned long long)wide_dat);
  348. memcpy(rx_data, &wide_dat, rem);
  349. rx_data += rem;
  350. }
  351. }
  352. return 0;
  353. }
  354. static bool octeon_spi_supports_op(struct spi_slave *slave,
  355. const struct spi_mem_op *op)
  356. {
  357. /* For now, support only below combinations
  358. * 1-1-1
  359. * 1-1-2 1-2-2
  360. * 1-1-4 1-4-4
  361. */
  362. if (op->cmd.buswidth != 1)
  363. return false;
  364. return true;
  365. }
  366. static int octeon_spi_exec_op(struct spi_slave *slave,
  367. const struct spi_mem_op *op)
  368. {
  369. unsigned long flags = SPI_XFER_BEGIN;
  370. const void *tx;
  371. void *rx;
  372. u8 opcode, *buf;
  373. u8 *addr;
  374. int i, temp, ret;
  375. if (op->cmd.buswidth != 1)
  376. return -ENOTSUPP;
  377. /* Send CMD */
  378. i = 0;
  379. opcode = op->cmd.opcode;
  380. if (!op->data.nbytes && !op->addr.nbytes && !op->dummy.nbytes)
  381. flags |= SPI_XFER_END;
  382. ret = octeontx2_spi_xfer(slave->dev, 8, (void *)&opcode, NULL, flags);
  383. if (ret < 0)
  384. return ret;
  385. /* Send Address and dummy */
  386. if (op->addr.nbytes) {
  387. /* Alloc buffer for address+dummy */
  388. buf = (u8 *)calloc(1, op->addr.nbytes + op->dummy.nbytes);
  389. if (!buf) {
  390. printf("%s Out of memory\n", __func__);
  391. return -ENOMEM;
  392. }
  393. addr = (u8 *)&op->addr.val;
  394. for (temp = 0; temp < op->addr.nbytes; temp++)
  395. buf[i++] = *(u8 *)(addr + op->addr.nbytes - 1 - temp);
  396. for (temp = 0; temp < op->dummy.nbytes; temp++)
  397. buf[i++] = 0xff;
  398. if (op->addr.buswidth == 2)
  399. flags |= SPI_RX_DUAL;
  400. if (op->addr.buswidth == 4)
  401. flags |= SPI_RX_QUAD;
  402. if (!op->data.nbytes)
  403. flags |= SPI_XFER_END;
  404. ret = octeontx2_spi_xfer(slave->dev, i * 8, (void *)buf, NULL,
  405. flags);
  406. free(buf);
  407. if (ret < 0)
  408. return ret;
  409. }
  410. if (!op->data.nbytes)
  411. return 0;
  412. /* Send/Receive Data */
  413. flags |= SPI_XFER_END;
  414. if (op->data.buswidth == 2)
  415. flags |= SPI_RX_DUAL;
  416. if (op->data.buswidth == 4)
  417. flags |= SPI_RX_QUAD;
  418. rx = (op->data.dir == SPI_MEM_DATA_IN) ? op->data.buf.in : NULL;
  419. tx = (op->data.dir == SPI_MEM_DATA_OUT) ? op->data.buf.out : NULL;
  420. ret = octeontx2_spi_xfer(slave->dev, (op->data.nbytes * 8), tx, rx,
  421. flags);
  422. return ret;
  423. }
  424. static const struct spi_controller_mem_ops octeontx2_spi_mem_ops = {
  425. .supports_op = octeon_spi_supports_op,
  426. .exec_op = octeon_spi_exec_op,
  427. };
  428. /**
  429. * Set the speed of the SPI bus
  430. *
  431. * @param bus bus to set
  432. * @param max_hz maximum speed supported
  433. */
  434. static int octeon_spi_set_speed(struct udevice *bus, uint max_hz)
  435. {
  436. struct octeon_spi *priv = dev_get_priv(bus);
  437. ulong clk_rate;
  438. u32 calc_hz;
  439. if (max_hz > OCTEON_SPI_MAX_CLOCK_HZ)
  440. max_hz = OCTEON_SPI_MAX_CLOCK_HZ;
  441. if (device_is_compatible(bus, "cavium,thunderx-spi"))
  442. clk_rate = 100000000;
  443. else
  444. clk_rate = clk_get_rate(&priv->clk);
  445. if (IS_ERR_VALUE(clk_rate))
  446. return -EINVAL;
  447. debug("%s(%s, %u, %lu)\n", __func__, bus->name, max_hz, clk_rate);
  448. priv->clkdiv = clk_rate / (2 * max_hz);
  449. while (1) {
  450. calc_hz = clk_rate / (2 * priv->clkdiv);
  451. if (calc_hz <= max_hz)
  452. break;
  453. priv->clkdiv += 1;
  454. }
  455. if (priv->clkdiv > 8191)
  456. return -EINVAL;
  457. debug("%s: clkdiv=%d\n", __func__, priv->clkdiv);
  458. return 0;
  459. }
  460. static int octeon_spi_set_mode(struct udevice *bus, uint mode)
  461. {
  462. /* We don't set it here */
  463. return 0;
  464. }
  465. static struct dm_spi_ops octeon_spi_ops = {
  466. .claim_bus = octeon_spi_claim_bus,
  467. .release_bus = octeon_spi_release_bus,
  468. .set_speed = octeon_spi_set_speed,
  469. .set_mode = octeon_spi_set_mode,
  470. .xfer = octeon_spi_xfer,
  471. };
  472. static int octeon_spi_probe(struct udevice *dev)
  473. {
  474. struct octeon_spi *priv = dev_get_priv(dev);
  475. int ret;
  476. /* Octeon TX & TX2 use PCI based probing */
  477. if (device_is_compatible(dev, "cavium,thunder-8190-spi")) {
  478. pci_dev_t bdf = dm_pci_get_bdf(dev);
  479. debug("SPI PCI device: %x\n", bdf);
  480. priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
  481. PCI_REGION_MEM);
  482. /* Add base offset */
  483. priv->base += 0x1000;
  484. /*
  485. * Octeon TX2 needs a different xfer function and supports
  486. * mem_ops
  487. */
  488. if (device_is_compatible(dev, "cavium,thunderx-spi")) {
  489. octeon_spi_ops.xfer = octeontx2_spi_xfer;
  490. octeon_spi_ops.mem_ops = &octeontx2_spi_mem_ops;
  491. }
  492. } else {
  493. priv->base = dev_remap_addr(dev);
  494. }
  495. ret = clk_get_by_index(dev, 0, &priv->clk);
  496. if (ret < 0)
  497. return ret;
  498. ret = clk_enable(&priv->clk);
  499. if (ret)
  500. return ret;
  501. debug("SPI bus %s %d at %p\n", dev->name, dev->seq, priv->base);
  502. return 0;
  503. }
  504. static const struct udevice_id octeon_spi_ids[] = {
  505. /* MIPS Octeon */
  506. { .compatible = "cavium,octeon-3010-spi" },
  507. /* ARM Octeon TX / TX2 */
  508. { .compatible = "cavium,thunder-8190-spi" },
  509. { }
  510. };
  511. U_BOOT_DRIVER(octeon_spi) = {
  512. .name = "spi_octeon",
  513. .id = UCLASS_SPI,
  514. .of_match = octeon_spi_ids,
  515. .probe = octeon_spi_probe,
  516. .priv_auto_alloc_size = sizeof(struct octeon_spi),
  517. .ops = &octeon_spi_ops,
  518. };