^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Broadcom BCM63XX High Speed SPI Controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2000-2010 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2012-2013 Jonas Gorski <jogo@openwrt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Licensed under the GNU/GPL. See COPYING for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define HSSPI_GLOBAL_CTRL_REG 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define GLOBAL_CTRL_CS_POLARITY_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define GLOBAL_CTRL_CS_POLARITY_MASK 0x000000ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define GLOBAL_CTRL_PLL_CLK_CTRL_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define GLOBAL_CTRL_PLL_CLK_CTRL_MASK 0x0000ff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define GLOBAL_CTRL_CLK_GATE_SSOFF BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define GLOBAL_CTRL_CLK_POLARITY BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define GLOBAL_CTRL_MOSI_IDLE BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define HSSPI_GLOBAL_EXT_TRIGGER_REG 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define HSSPI_INT_STATUS_REG 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define HSSPI_INT_STATUS_MASKED_REG 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define HSSPI_INT_MASK_REG 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define HSSPI_PINGx_CMD_DONE(i) BIT((i * 8) + 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define HSSPI_PINGx_RX_OVER(i) BIT((i * 8) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define HSSPI_PINGx_TX_UNDER(i) BIT((i * 8) + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define HSSPI_PINGx_POLL_TIMEOUT(i) BIT((i * 8) + 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define HSSPI_PINGx_CTRL_INVAL(i) BIT((i * 8) + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define HSSPI_INT_CLEAR_ALL 0xff001f1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define HSSPI_PINGPONG_COMMAND_REG(x) (0x80 + (x) * 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PINGPONG_CMD_COMMAND_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PINGPONG_COMMAND_NOOP 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PINGPONG_COMMAND_START_NOW 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PINGPONG_COMMAND_START_TRIGGER 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PINGPONG_COMMAND_HALT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PINGPONG_COMMAND_FLUSH 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PINGPONG_CMD_PROFILE_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PINGPONG_CMD_SS_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define HSSPI_PINGPONG_STATUS_REG(x) (0x84 + (x) * 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define HSSPI_PROFILE_CLK_CTRL_REG(x) (0x100 + (x) * 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define CLK_CTRL_FREQ_CTRL_MASK 0x0000ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define CLK_CTRL_SPI_CLK_2X_SEL BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define CLK_CTRL_ACCUM_RST_ON_LOOP BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define HSSPI_PROFILE_SIGNAL_CTRL_REG(x) (0x104 + (x) * 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SIGNAL_CTRL_LATCH_RISING BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SIGNAL_CTRL_LAUNCH_RISING BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SIGNAL_CTRL_ASYNC_INPUT_PATH BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define HSSPI_PROFILE_MODE_CTRL_REG(x) (0x108 + (x) * 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define MODE_CTRL_MULTIDATA_RD_STRT_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define MODE_CTRL_MULTIDATA_WR_STRT_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define MODE_CTRL_MODE_3WIRE BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define MODE_CTRL_PREPENDBYTE_CNT_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define HSSPI_FIFO_REG(x) (0x200 + (x) * 0x200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define HSSPI_OP_MULTIBIT BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define HSSPI_OP_CODE_SHIFT 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define HSSPI_OP_SLEEP (0 << HSSPI_OP_CODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define HSSPI_OP_READ_WRITE (1 << HSSPI_OP_CODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define HSSPI_OP_WRITE (2 << HSSPI_OP_CODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define HSSPI_OP_READ (3 << HSSPI_OP_CODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define HSSPI_OP_SETIRQ (4 << HSSPI_OP_CODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define HSSPI_BUFFER_LEN 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define HSSPI_OPCODE_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define HSSPI_MAX_PREPEND_LEN 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define HSSPI_MAX_SYNC_CLOCK 30000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define HSSPI_SPI_MAX_CS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define HSSPI_BUS_NUM 1 /* 0 is legacy SPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct bcm63xx_hsspi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct completion done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct mutex bus_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct clk *pll_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 __iomem *fifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u8 cs_polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned int cs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bool active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mutex_lock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) reg &= ~BIT(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (active == !(bs->cs_polarity & BIT(cs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) reg |= BIT(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mutex_unlock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct spi_device *spi, int hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned int profile = spi->chip_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __raw_writel(CLK_CTRL_ACCUM_RST_ON_LOOP | reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) bs->regs + HSSPI_PROFILE_CLK_CTRL_REG(profile));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) reg = __raw_readl(bs->regs + HSSPI_PROFILE_SIGNAL_CTRL_REG(profile));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (hz > HSSPI_MAX_SYNC_CLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) reg |= SIGNAL_CTRL_ASYNC_INPUT_PATH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) reg &= ~SIGNAL_CTRL_ASYNC_INPUT_PATH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) __raw_writel(reg, bs->regs + HSSPI_PROFILE_SIGNAL_CTRL_REG(profile));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mutex_lock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* setup clock polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) reg &= ~GLOBAL_CTRL_CLK_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (spi->mode & SPI_CPOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) reg |= GLOBAL_CTRL_CLK_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mutex_unlock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned int chip_select = spi->chip_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u16 opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int pending = t->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int step_size = HSSPI_BUFFER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) const u8 *tx = t->tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 *rx = t->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) bcm63xx_hsspi_set_cs(bs, spi->chip_select, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (tx && rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) opcode = HSSPI_OP_READ_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) else if (tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) opcode = HSSPI_OP_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) else if (rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) opcode = HSSPI_OP_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (opcode != HSSPI_OP_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) step_size -= HSSPI_OPCODE_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) opcode |= HSSPI_OP_MULTIBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) while (pending > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int curr_step = min_t(int, step_size, pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) reinit_completion(&bs->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN, tx, curr_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) tx += curr_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) __raw_writew(opcode | curr_step, bs->fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* enable interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) __raw_writel(HSSPI_PINGx_CMD_DONE(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) bs->regs + HSSPI_INT_MASK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* start the transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) __raw_writel(!chip_select << PINGPONG_CMD_SS_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) chip_select << PINGPONG_CMD_PROFILE_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) PINGPONG_COMMAND_START_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) bs->regs + HSSPI_PINGPONG_COMMAND_REG(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (wait_for_completion_timeout(&bs->done, HZ) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_err(&bs->pdev->dev, "transfer timed out!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) memcpy_fromio(rx, bs->fifo, curr_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) rx += curr_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pending -= curr_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int bcm63xx_hsspi_setup(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) reg = __raw_readl(bs->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (spi->mode & SPI_CPHA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) reg |= SIGNAL_CTRL_LAUNCH_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) reg |= SIGNAL_CTRL_LATCH_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) __raw_writel(reg, bs->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_lock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* only change actual polarities if there is no transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if ((reg & GLOBAL_CTRL_CS_POLARITY_MASK) == bs->cs_polarity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (spi->mode & SPI_CS_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) reg |= BIT(spi->chip_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) reg &= ~BIT(spi->chip_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (spi->mode & SPI_CS_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) bs->cs_polarity |= BIT(spi->chip_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) bs->cs_polarity &= ~BIT(spi->chip_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mutex_unlock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int bcm63xx_hsspi_transfer_one(struct spi_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct spi_message *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct spi_transfer *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct spi_device *spi = msg->spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int dummy_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* This controller does not support keeping CS active during idle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * To work around this, we use the following ugly hack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * a. Invert the target chip select's polarity so it will be active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * b. Select a "dummy" chip select to use as the hardware target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * c. Invert the dummy chip select's polarity so it will be inactive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * during the actual transfers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * d. Tell the hardware to send to the dummy chip select. Thanks to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * the multiplexed nature of SPI the actual target will receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * the transfer and we see its response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * e. At the end restore the polarities again to their default values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) dummy_cs = !spi->chip_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) bcm63xx_hsspi_set_cs(bs, dummy_cs, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) list_for_each_entry(t, &msg->transfers, transfer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) status = bcm63xx_hsspi_do_txrx(spi, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) msg->actual_length += t->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) spi_transfer_delay_exec(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (t->cs_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) bcm63xx_hsspi_set_cs(bs, spi->chip_select, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) mutex_lock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) reg &= ~GLOBAL_CTRL_CS_POLARITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) reg |= bs->cs_polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mutex_unlock(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) msg->status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) spi_finalize_current_message(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static irqreturn_t bcm63xx_hsspi_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct bcm63xx_hsspi *bs = (struct bcm63xx_hsspi *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (__raw_readl(bs->regs + HSSPI_INT_STATUS_MASKED_REG) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) __raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) complete(&bs->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int bcm63xx_hsspi_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct spi_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct bcm63xx_hsspi *bs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct clk *clk, *pll_clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int irq, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u32 reg, rate, num_cs = HSSPI_SPI_MAX_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct reset_control *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) regs = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) clk = devm_clk_get(dev, "hsspi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) reset = devm_reset_control_get_optional_exclusive(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (IS_ERR(reset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return PTR_ERR(reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ret = reset_control_reset(reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dev_err(dev, "unable to reset device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) goto out_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) pll_clk = devm_clk_get(dev, "pll");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (IS_ERR(pll_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = PTR_ERR(pll_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto out_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = clk_prepare_enable(pll_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto out_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) rate = clk_get_rate(pll_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto out_disable_pll_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) master = spi_alloc_master(&pdev->dev, sizeof(*bs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!master) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) goto out_disable_pll_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) bs = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bs->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) bs->clk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) bs->pll_clk = pll_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) bs->regs = regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) bs->speed_hz = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) mutex_init(&bs->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) init_completion(&bs->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) master->dev.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (!dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) master->bus_num = HSSPI_BUS_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) of_property_read_u32(dev->of_node, "num-cs", &num_cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (num_cs > 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) num_cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) num_cs = HSSPI_SPI_MAX_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) master->num_chipselect = num_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) master->setup = bcm63xx_hsspi_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) master->transfer_one_message = bcm63xx_hsspi_transfer_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) SPI_RX_DUAL | SPI_TX_DUAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) master->bits_per_word_mask = SPI_BPW_MASK(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) master->auto_runtime_pm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) platform_set_drvdata(pdev, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Initialize the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* clean up any pending interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) __raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* read out default CS polarities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) bs->cs_polarity = reg & GLOBAL_CTRL_CS_POLARITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) __raw_writel(reg | GLOBAL_CTRL_CLK_GATE_SSOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) bs->regs + HSSPI_GLOBAL_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = devm_request_irq(dev, irq, bcm63xx_hsspi_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pdev->name, bs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto out_put_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* register and we are done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ret = devm_spi_register_master(dev, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) goto out_put_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) out_put_master:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) spi_master_put(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) out_disable_pll_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) clk_disable_unprepare(pll_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) out_disable_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) clk_disable_unprepare(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int bcm63xx_hsspi_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct spi_master *master = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* reset the hardware and block queue progress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) clk_disable_unprepare(bs->pll_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) clk_disable_unprepare(bs->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int bcm63xx_hsspi_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct spi_master *master = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) spi_master_suspend(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) clk_disable_unprepare(bs->pll_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) clk_disable_unprepare(bs->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int bcm63xx_hsspi_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct spi_master *master = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ret = clk_prepare_enable(bs->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (bs->pll_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = clk_prepare_enable(bs->pll_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) clk_disable_unprepare(bs->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) spi_master_resume(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static SIMPLE_DEV_PM_OPS(bcm63xx_hsspi_pm_ops, bcm63xx_hsspi_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) bcm63xx_hsspi_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static const struct of_device_id bcm63xx_hsspi_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) { .compatible = "brcm,bcm6328-hsspi", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) MODULE_DEVICE_TABLE(of, bcm63xx_hsspi_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static struct platform_driver bcm63xx_hsspi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .name = "bcm63xx-hsspi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .pm = &bcm63xx_hsspi_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .of_match_table = bcm63xx_hsspi_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .probe = bcm63xx_hsspi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .remove = bcm63xx_hsspi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) module_platform_driver(bcm63xx_hsspi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) MODULE_ALIAS("platform:bcm63xx_hsspi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) MODULE_DESCRIPTION("Broadcom BCM63xx High Speed SPI Controller driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) MODULE_LICENSE("GPL");