Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: Add Meson SPICC driver

The SPICC hardware block on the Amlogic SoCs is Communication oriented and
can do Full-Duplex 8- to 32-bit width SPI transfers up to 30MHz.

The current driver only supportd the PIO transfer mode since the DMA seems
broken on available hardware.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Neil Armstrong and committed by
Mark Brown
454fa271 01a330da

+627
+7
drivers/spi/Kconfig
··· 393 393 From MPC8536, 85xx platform uses the controller, and all P10xx, 394 394 P20xx, P30xx,P40xx, P50xx uses this controller. 395 395 396 + config SPI_MESON_SPICC 397 + tristate "Amlogic Meson SPICC controller" 398 + depends on ARCH_MESON || COMPILE_TEST 399 + help 400 + This enables master mode support for the SPICC (SPI communication 401 + controller) available in Amlogic Meson SoCs. 402 + 396 403 config SPI_MESON_SPIFC 397 404 tristate "Amlogic Meson SPIFC controller" 398 405 depends on ARCH_MESON || COMPILE_TEST
+1
drivers/spi/Makefile
··· 53 53 obj-$(CONFIG_SPI_JCORE) += spi-jcore.o 54 54 obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o 55 55 obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o 56 + obj-$(CONFIG_SPI_MESON_SPICC) += spi-meson-spicc.o 56 57 obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o 57 58 obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o 58 59 obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
+619
drivers/spi/spi-meson-spicc.c
··· 1 + /* 2 + * Driver for Amlogic Meson SPI communication controller (SPICC) 3 + * 4 + * Copyright (C) BayLibre, SAS 5 + * Author: Neil Armstrong <narmstrong@baylibre.com> 6 + * 7 + * SPDX-License-Identifier: GPL-2.0+ 8 + */ 9 + 10 + #include <linux/bitfield.h> 11 + #include <linux/clk.h> 12 + #include <linux/device.h> 13 + #include <linux/io.h> 14 + #include <linux/kernel.h> 15 + #include <linux/module.h> 16 + #include <linux/of.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/spi/spi.h> 19 + #include <linux/types.h> 20 + #include <linux/interrupt.h> 21 + #include <linux/reset.h> 22 + #include <linux/gpio.h> 23 + 24 + /* 25 + * The Meson SPICC controller could support DMA based transfers, but is not 26 + * implemented by the vendor code, and while having the registers documentation 27 + * it has never worked on the GXL Hardware. 28 + * The PIO mode is the only mode implemented, and due to badly designed HW : 29 + * - all transfers are cutted in 16 words burst because the FIFO hangs on 30 + * TX underflow, and there is no TX "Half-Empty" interrupt, so we go by 31 + * FIFO max size chunk only 32 + * - CS management is dumb, and goes UP between every burst, so is really a 33 + * "Data Valid" signal than a Chip Select, GPIO link should be used instead 34 + * to have a CS go down over the full transfer 35 + */ 36 + 37 + #define SPICC_MAX_FREQ 30000000 38 + #define SPICC_MAX_BURST 128 39 + 40 + /* Register Map */ 41 + #define SPICC_RXDATA 0x00 42 + 43 + #define SPICC_TXDATA 0x04 44 + 45 + #define SPICC_CONREG 0x08 46 + #define SPICC_ENABLE BIT(0) 47 + #define SPICC_MODE_MASTER BIT(1) 48 + #define SPICC_XCH BIT(2) 49 + #define SPICC_SMC BIT(3) 50 + #define SPICC_POL BIT(4) 51 + #define SPICC_PHA BIT(5) 52 + #define SPICC_SSCTL BIT(6) 53 + #define SPICC_SSPOL BIT(7) 54 + #define SPICC_DRCTL_MASK GENMASK(9, 8) 55 + #define SPICC_DRCTL_IGNORE 0 56 + #define SPICC_DRCTL_FALLING 1 57 + #define SPICC_DRCTL_LOWLEVEL 2 58 + #define SPICC_CS_MASK GENMASK(13, 12) 59 + #define SPICC_DATARATE_MASK GENMASK(18, 16) 60 + #define SPICC_DATARATE_DIV4 0 61 + #define SPICC_DATARATE_DIV8 1 62 + #define SPICC_DATARATE_DIV16 2 63 + #define SPICC_DATARATE_DIV32 3 64 + #define SPICC_BITLENGTH_MASK GENMASK(24, 19) 65 + #define SPICC_BURSTLENGTH_MASK GENMASK(31, 25) 66 + 67 + #define SPICC_INTREG 0x0c 68 + #define SPICC_TE_EN BIT(0) /* TX FIFO Empty Interrupt */ 69 + #define SPICC_TH_EN BIT(1) /* TX FIFO Half-Full Interrupt */ 70 + #define SPICC_TF_EN BIT(2) /* TX FIFO Full Interrupt */ 71 + #define SPICC_RR_EN BIT(3) /* RX FIFO Ready Interrupt */ 72 + #define SPICC_RH_EN BIT(4) /* RX FIFO Half-Full Interrupt */ 73 + #define SPICC_RF_EN BIT(5) /* RX FIFO Full Interrupt */ 74 + #define SPICC_RO_EN BIT(6) /* RX FIFO Overflow Interrupt */ 75 + #define SPICC_TC_EN BIT(7) /* Transfert Complete Interrupt */ 76 + 77 + #define SPICC_DMAREG 0x10 78 + #define SPICC_DMA_ENABLE BIT(0) 79 + #define SPICC_TXFIFO_THRESHOLD_MASK GENMASK(5, 1) 80 + #define SPICC_RXFIFO_THRESHOLD_MASK GENMASK(10, 6) 81 + #define SPICC_READ_BURST_MASK GENMASK(14, 11) 82 + #define SPICC_WRITE_BURST_MASK GENMASK(18, 15) 83 + #define SPICC_DMA_URGENT BIT(19) 84 + #define SPICC_DMA_THREADID_MASK GENMASK(25, 20) 85 + #define SPICC_DMA_BURSTNUM_MASK GENMASK(31, 26) 86 + 87 + #define SPICC_STATREG 0x14 88 + #define SPICC_TE BIT(0) /* TX FIFO Empty Interrupt */ 89 + #define SPICC_TH BIT(1) /* TX FIFO Half-Full Interrupt */ 90 + #define SPICC_TF BIT(2) /* TX FIFO Full Interrupt */ 91 + #define SPICC_RR BIT(3) /* RX FIFO Ready Interrupt */ 92 + #define SPICC_RH BIT(4) /* RX FIFO Half-Full Interrupt */ 93 + #define SPICC_RF BIT(5) /* RX FIFO Full Interrupt */ 94 + #define SPICC_RO BIT(6) /* RX FIFO Overflow Interrupt */ 95 + #define SPICC_TC BIT(7) /* Transfert Complete Interrupt */ 96 + 97 + #define SPICC_PERIODREG 0x18 98 + #define SPICC_PERIOD GENMASK(14, 0) /* Wait cycles */ 99 + 100 + #define SPICC_TESTREG 0x1c 101 + #define SPICC_TXCNT_MASK GENMASK(4, 0) /* TX FIFO Counter */ 102 + #define SPICC_RXCNT_MASK GENMASK(9, 5) /* RX FIFO Counter */ 103 + #define SPICC_SMSTATUS_MASK GENMASK(12, 10) /* State Machine Status */ 104 + #define SPICC_LBC_RO BIT(13) /* Loop Back Control Read-Only */ 105 + #define SPICC_LBC_W1 BIT(14) /* Loop Back Control Write-Only */ 106 + #define SPICC_SWAP_RO BIT(14) /* RX FIFO Data Swap Read-Only */ 107 + #define SPICC_SWAP_W1 BIT(15) /* RX FIFO Data Swap Write-Only */ 108 + #define SPICC_DLYCTL_RO_MASK GENMASK(20, 15) /* Delay Control Read-Only */ 109 + #define SPICC_DLYCTL_W1_MASK GENMASK(21, 16) /* Delay Control Write-Only */ 110 + #define SPICC_FIFORST_RO_MASK GENMASK(22, 21) /* FIFO Softreset Read-Only */ 111 + #define SPICC_FIFORST_W1_MASK GENMASK(23, 22) /* FIFO Softreset Write-Only */ 112 + 113 + #define SPICC_DRADDR 0x20 /* Read Address of DMA */ 114 + 115 + #define SPICC_DWADDR 0x24 /* Write Address of DMA */ 116 + 117 + #define writel_bits_relaxed(mask, val, addr) \ 118 + writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr) 119 + 120 + #define SPICC_BURST_MAX 16 121 + #define SPICC_FIFO_HALF 10 122 + 123 + struct meson_spicc_device { 124 + struct spi_master *master; 125 + struct platform_device *pdev; 126 + void __iomem *base; 127 + struct clk *core; 128 + struct spi_message *message; 129 + struct spi_transfer *xfer; 130 + u8 *tx_buf; 131 + u8 *rx_buf; 132 + unsigned int bytes_per_word; 133 + unsigned long tx_remain; 134 + unsigned long txb_remain; 135 + unsigned long rx_remain; 136 + unsigned long rxb_remain; 137 + unsigned long xfer_remain; 138 + bool is_burst_end; 139 + bool is_last_burst; 140 + }; 141 + 142 + static inline bool meson_spicc_txfull(struct meson_spicc_device *spicc) 143 + { 144 + return !!FIELD_GET(SPICC_TF, 145 + readl_relaxed(spicc->base + SPICC_STATREG)); 146 + } 147 + 148 + static inline bool meson_spicc_rxready(struct meson_spicc_device *spicc) 149 + { 150 + return FIELD_GET(SPICC_RH | SPICC_RR | SPICC_RF_EN, 151 + readl_relaxed(spicc->base + SPICC_STATREG)); 152 + } 153 + 154 + static inline u32 meson_spicc_pull_data(struct meson_spicc_device *spicc) 155 + { 156 + unsigned int bytes = spicc->bytes_per_word; 157 + unsigned int byte_shift = 0; 158 + u32 data = 0; 159 + u8 byte; 160 + 161 + while (bytes--) { 162 + byte = *spicc->tx_buf++; 163 + data |= (byte & 0xff) << byte_shift; 164 + byte_shift += 8; 165 + } 166 + 167 + spicc->tx_remain--; 168 + return data; 169 + } 170 + 171 + static inline void meson_spicc_push_data(struct meson_spicc_device *spicc, 172 + u32 data) 173 + { 174 + unsigned int bytes = spicc->bytes_per_word; 175 + unsigned int byte_shift = 0; 176 + u8 byte; 177 + 178 + while (bytes--) { 179 + byte = (data >> byte_shift) & 0xff; 180 + *spicc->rx_buf++ = byte; 181 + byte_shift += 8; 182 + } 183 + 184 + spicc->rx_remain--; 185 + } 186 + 187 + static inline void meson_spicc_rx(struct meson_spicc_device *spicc) 188 + { 189 + /* Empty RX FIFO */ 190 + while (spicc->rx_remain && 191 + meson_spicc_rxready(spicc)) 192 + meson_spicc_push_data(spicc, 193 + readl_relaxed(spicc->base + SPICC_RXDATA)); 194 + } 195 + 196 + static inline void meson_spicc_tx(struct meson_spicc_device *spicc) 197 + { 198 + /* Fill Up TX FIFO */ 199 + while (spicc->tx_remain && 200 + !meson_spicc_txfull(spicc)) 201 + writel_relaxed(meson_spicc_pull_data(spicc), 202 + spicc->base + SPICC_TXDATA); 203 + } 204 + 205 + static inline u32 meson_spicc_setup_rx_irq(struct meson_spicc_device *spicc, 206 + u32 irq_ctrl) 207 + { 208 + if (spicc->rx_remain > SPICC_FIFO_HALF) 209 + irq_ctrl |= SPICC_RH_EN; 210 + else 211 + irq_ctrl |= SPICC_RR_EN; 212 + 213 + return irq_ctrl; 214 + } 215 + 216 + static inline void meson_spicc_setup_burst(struct meson_spicc_device *spicc, 217 + unsigned int burst_len) 218 + { 219 + /* Setup Xfer variables */ 220 + spicc->tx_remain = burst_len; 221 + spicc->rx_remain = burst_len; 222 + spicc->xfer_remain -= burst_len * spicc->bytes_per_word; 223 + spicc->is_burst_end = false; 224 + if (burst_len < SPICC_BURST_MAX || !spicc->xfer_remain) 225 + spicc->is_last_burst = true; 226 + else 227 + spicc->is_last_burst = false; 228 + 229 + /* Setup burst length */ 230 + writel_bits_relaxed(SPICC_BURSTLENGTH_MASK, 231 + FIELD_PREP(SPICC_BURSTLENGTH_MASK, 232 + burst_len), 233 + spicc->base + SPICC_CONREG); 234 + 235 + /* Fill TX FIFO */ 236 + meson_spicc_tx(spicc); 237 + } 238 + 239 + static irqreturn_t meson_spicc_irq(int irq, void *data) 240 + { 241 + struct meson_spicc_device *spicc = (void *) data; 242 + u32 ctrl = readl_relaxed(spicc->base + SPICC_INTREG); 243 + u32 stat = readl_relaxed(spicc->base + SPICC_STATREG) & ctrl; 244 + 245 + ctrl &= ~(SPICC_RH_EN | SPICC_RR_EN); 246 + 247 + /* Empty RX FIFO */ 248 + meson_spicc_rx(spicc); 249 + 250 + /* Enable TC interrupt since we transferred everything */ 251 + if (!spicc->tx_remain && !spicc->rx_remain) { 252 + spicc->is_burst_end = true; 253 + 254 + /* Enable TC interrupt */ 255 + ctrl |= SPICC_TC_EN; 256 + 257 + /* Reload IRQ status */ 258 + stat = readl_relaxed(spicc->base + SPICC_STATREG) & ctrl; 259 + } 260 + 261 + /* Check transfer complete */ 262 + if ((stat & SPICC_TC) && spicc->is_burst_end) { 263 + unsigned int burst_len; 264 + 265 + /* Clear TC bit */ 266 + writel_relaxed(SPICC_TC, spicc->base + SPICC_STATREG); 267 + 268 + /* Disable TC interrupt */ 269 + ctrl &= ~SPICC_TC_EN; 270 + 271 + if (spicc->is_last_burst) { 272 + /* Disable all IRQs */ 273 + writel(0, spicc->base + SPICC_INTREG); 274 + 275 + spi_finalize_current_transfer(spicc->master); 276 + 277 + return IRQ_HANDLED; 278 + } 279 + 280 + burst_len = min_t(unsigned int, 281 + spicc->xfer_remain / spicc->bytes_per_word, 282 + SPICC_BURST_MAX); 283 + 284 + /* Setup burst */ 285 + meson_spicc_setup_burst(spicc, burst_len); 286 + 287 + /* Restart burst */ 288 + writel_bits_relaxed(SPICC_XCH, SPICC_XCH, 289 + spicc->base + SPICC_CONREG); 290 + } 291 + 292 + /* Setup RX interrupt trigger */ 293 + ctrl = meson_spicc_setup_rx_irq(spicc, ctrl); 294 + 295 + /* Reconfigure interrupts */ 296 + writel(ctrl, spicc->base + SPICC_INTREG); 297 + 298 + return IRQ_HANDLED; 299 + } 300 + 301 + static u32 meson_spicc_setup_speed(struct meson_spicc_device *spicc, u32 conf, 302 + u32 speed) 303 + { 304 + unsigned long parent, value; 305 + unsigned int i, div; 306 + 307 + parent = clk_get_rate(spicc->core); 308 + 309 + /* Find closest inferior/equal possible speed */ 310 + for (i = 0 ; i < 7 ; ++i) { 311 + /* 2^(data_rate+2) */ 312 + value = parent >> (i + 2); 313 + 314 + if (value <= speed) 315 + break; 316 + } 317 + 318 + /* If provided speed it lower than max divider, use max divider */ 319 + if (i > 7) { 320 + div = 7; 321 + dev_warn_once(&spicc->pdev->dev, "unable to get close to speed %u\n", 322 + speed); 323 + } else 324 + div = i; 325 + 326 + dev_dbg(&spicc->pdev->dev, "parent %lu, speed %u -> %lu (%u)\n", 327 + parent, speed, value, div); 328 + 329 + conf &= ~SPICC_DATARATE_MASK; 330 + conf |= FIELD_PREP(SPICC_DATARATE_MASK, div); 331 + 332 + return conf; 333 + } 334 + 335 + static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc, 336 + struct spi_transfer *xfer) 337 + { 338 + u32 conf, conf_orig; 339 + 340 + /* Read original configuration */ 341 + conf = conf_orig = readl_relaxed(spicc->base + SPICC_CONREG); 342 + 343 + /* Select closest divider */ 344 + conf = meson_spicc_setup_speed(spicc, conf, xfer->speed_hz); 345 + 346 + /* Setup word width */ 347 + conf &= ~SPICC_BITLENGTH_MASK; 348 + conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 349 + (spicc->bytes_per_word << 3) - 1); 350 + 351 + /* Ignore if unchanged */ 352 + if (conf != conf_orig) 353 + writel_relaxed(conf, spicc->base + SPICC_CONREG); 354 + } 355 + 356 + static int meson_spicc_transfer_one(struct spi_master *master, 357 + struct spi_device *spi, 358 + struct spi_transfer *xfer) 359 + { 360 + struct meson_spicc_device *spicc = spi_master_get_devdata(master); 361 + unsigned int burst_len; 362 + u32 irq = 0; 363 + 364 + /* Store current transfer */ 365 + spicc->xfer = xfer; 366 + 367 + /* Setup transfer parameters */ 368 + spicc->tx_buf = (u8 *)xfer->tx_buf; 369 + spicc->rx_buf = (u8 *)xfer->rx_buf; 370 + spicc->xfer_remain = xfer->len; 371 + 372 + /* Pre-calculate word size */ 373 + spicc->bytes_per_word = 374 + DIV_ROUND_UP(spicc->xfer->bits_per_word, 8); 375 + 376 + /* Setup transfer parameters */ 377 + meson_spicc_setup_xfer(spicc, xfer); 378 + 379 + burst_len = min_t(unsigned int, 380 + spicc->xfer_remain / spicc->bytes_per_word, 381 + SPICC_BURST_MAX); 382 + 383 + meson_spicc_setup_burst(spicc, burst_len); 384 + 385 + irq = meson_spicc_setup_rx_irq(spicc, irq); 386 + 387 + /* Start burst */ 388 + writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); 389 + 390 + /* Enable interrupts */ 391 + writel_relaxed(irq, spicc->base + SPICC_INTREG); 392 + 393 + return 1; 394 + } 395 + 396 + static int meson_spicc_prepare_message(struct spi_master *master, 397 + struct spi_message *message) 398 + { 399 + struct meson_spicc_device *spicc = spi_master_get_devdata(master); 400 + struct spi_device *spi = message->spi; 401 + u32 conf = 0; 402 + 403 + /* Store current message */ 404 + spicc->message = message; 405 + 406 + /* Enable Master */ 407 + conf |= SPICC_ENABLE; 408 + conf |= SPICC_MODE_MASTER; 409 + 410 + /* SMC = 0 */ 411 + 412 + /* Setup transfer mode */ 413 + if (spi->mode & SPI_CPOL) 414 + conf |= SPICC_POL; 415 + else 416 + conf &= ~SPICC_POL; 417 + 418 + if (spi->mode & SPI_CPHA) 419 + conf |= SPICC_PHA; 420 + else 421 + conf &= ~SPICC_PHA; 422 + 423 + /* SSCTL = 0 */ 424 + 425 + if (spi->mode & SPI_CS_HIGH) 426 + conf |= SPICC_SSPOL; 427 + else 428 + conf &= ~SPICC_SSPOL; 429 + 430 + if (spi->mode & SPI_READY) 431 + conf |= FIELD_PREP(SPICC_DRCTL_MASK, SPICC_DRCTL_LOWLEVEL); 432 + else 433 + conf |= FIELD_PREP(SPICC_DRCTL_MASK, SPICC_DRCTL_IGNORE); 434 + 435 + /* Select CS */ 436 + conf |= FIELD_PREP(SPICC_CS_MASK, spi->chip_select); 437 + 438 + /* Default Clock rate core/4 */ 439 + 440 + /* Default 8bit word */ 441 + conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 8 - 1); 442 + 443 + writel_relaxed(conf, spicc->base + SPICC_CONREG); 444 + 445 + /* Setup no wait cycles by default */ 446 + writel_relaxed(0, spicc->base + SPICC_PERIODREG); 447 + 448 + writel_bits_relaxed(BIT(24), BIT(24), spicc->base + SPICC_TESTREG); 449 + 450 + return 0; 451 + } 452 + 453 + static int meson_spicc_unprepare_transfer(struct spi_master *master) 454 + { 455 + struct meson_spicc_device *spicc = spi_master_get_devdata(master); 456 + 457 + /* Disable all IRQs */ 458 + writel(0, spicc->base + SPICC_INTREG); 459 + 460 + /* Disable controller */ 461 + writel_bits_relaxed(SPICC_ENABLE, 0, spicc->base + SPICC_CONREG); 462 + 463 + device_reset_optional(&spicc->pdev->dev); 464 + 465 + return 0; 466 + } 467 + 468 + static int meson_spicc_setup(struct spi_device *spi) 469 + { 470 + int ret = 0; 471 + 472 + if (!spi->controller_state) 473 + spi->controller_state = spi_master_get_devdata(spi->master); 474 + else if (gpio_is_valid(spi->cs_gpio)) 475 + goto out_gpio; 476 + else if (spi->cs_gpio == -ENOENT) 477 + return 0; 478 + 479 + if (gpio_is_valid(spi->cs_gpio)) { 480 + ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev)); 481 + if (ret) { 482 + dev_err(&spi->dev, "failed to request cs gpio\n"); 483 + return ret; 484 + } 485 + } 486 + 487 + out_gpio: 488 + ret = gpio_direction_output(spi->cs_gpio, 489 + !(spi->mode & SPI_CS_HIGH)); 490 + 491 + return ret; 492 + } 493 + 494 + static void meson_spicc_cleanup(struct spi_device *spi) 495 + { 496 + if (gpio_is_valid(spi->cs_gpio)) 497 + gpio_free(spi->cs_gpio); 498 + 499 + spi->controller_state = NULL; 500 + } 501 + 502 + static int meson_spicc_probe(struct platform_device *pdev) 503 + { 504 + struct spi_master *master; 505 + struct meson_spicc_device *spicc; 506 + struct resource *res; 507 + int ret, irq, rate; 508 + 509 + master = spi_alloc_master(&pdev->dev, sizeof(*spicc)); 510 + if (!master) { 511 + dev_err(&pdev->dev, "master allocation failed\n"); 512 + return -ENOMEM; 513 + } 514 + spicc = spi_master_get_devdata(master); 515 + spicc->master = master; 516 + 517 + spicc->pdev = pdev; 518 + platform_set_drvdata(pdev, spicc); 519 + 520 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 521 + spicc->base = devm_ioremap_resource(&pdev->dev, res); 522 + if (IS_ERR(spicc->base)) { 523 + dev_err(&pdev->dev, "io resource mapping failed\n"); 524 + ret = PTR_ERR(spicc->base); 525 + goto out_master; 526 + } 527 + 528 + /* Disable all IRQs */ 529 + writel_relaxed(0, spicc->base + SPICC_INTREG); 530 + 531 + irq = platform_get_irq(pdev, 0); 532 + ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq, 533 + 0, NULL, spicc); 534 + if (ret) { 535 + dev_err(&pdev->dev, "irq request failed\n"); 536 + goto out_master; 537 + } 538 + 539 + spicc->core = devm_clk_get(&pdev->dev, "core"); 540 + if (IS_ERR(spicc->core)) { 541 + dev_err(&pdev->dev, "core clock request failed\n"); 542 + ret = PTR_ERR(spicc->core); 543 + goto out_master; 544 + } 545 + 546 + ret = clk_prepare_enable(spicc->core); 547 + if (ret) { 548 + dev_err(&pdev->dev, "core clock enable failed\n"); 549 + goto out_master; 550 + } 551 + rate = clk_get_rate(spicc->core); 552 + 553 + device_reset_optional(&pdev->dev); 554 + 555 + master->num_chipselect = 4; 556 + master->dev.of_node = pdev->dev.of_node; 557 + master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH; 558 + master->bits_per_word_mask = SPI_BPW_MASK(32) | 559 + SPI_BPW_MASK(24) | 560 + SPI_BPW_MASK(16) | 561 + SPI_BPW_MASK(8); 562 + master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); 563 + master->min_speed_hz = rate >> 9; 564 + master->setup = meson_spicc_setup; 565 + master->cleanup = meson_spicc_cleanup; 566 + master->prepare_message = meson_spicc_prepare_message; 567 + master->unprepare_transfer_hardware = meson_spicc_unprepare_transfer; 568 + master->transfer_one = meson_spicc_transfer_one; 569 + 570 + /* Setup max rate according to the Meson GX datasheet */ 571 + if ((rate >> 2) > SPICC_MAX_FREQ) 572 + master->max_speed_hz = SPICC_MAX_FREQ; 573 + else 574 + master->max_speed_hz = rate >> 2; 575 + 576 + ret = devm_spi_register_master(&pdev->dev, master); 577 + if (!ret) 578 + return 0; 579 + 580 + dev_err(&pdev->dev, "spi master registration failed\n"); 581 + 582 + out_master: 583 + spi_master_put(master); 584 + 585 + return ret; 586 + } 587 + 588 + static int meson_spicc_remove(struct platform_device *pdev) 589 + { 590 + struct meson_spicc_device *spicc = platform_get_drvdata(pdev); 591 + 592 + /* Disable SPI */ 593 + writel(0, spicc->base + SPICC_CONREG); 594 + 595 + clk_disable_unprepare(spicc->core); 596 + 597 + return 0; 598 + } 599 + 600 + static const struct of_device_id meson_spicc_of_match[] = { 601 + { .compatible = "amlogic,meson-gx-spicc", }, 602 + { /* sentinel */ } 603 + }; 604 + MODULE_DEVICE_TABLE(of, meson_spicc_of_match); 605 + 606 + static struct platform_driver meson_spicc_driver = { 607 + .probe = meson_spicc_probe, 608 + .remove = meson_spicc_remove, 609 + .driver = { 610 + .name = "meson-spicc", 611 + .of_match_table = of_match_ptr(meson_spicc_of_match), 612 + }, 613 + }; 614 + 615 + module_platform_driver(meson_spicc_driver); 616 + 617 + MODULE_DESCRIPTION("Meson SPI Communication Controller driver"); 618 + MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 619 + MODULE_LICENSE("GPL");