183322Speter// SPDX-License-Identifier: GPL-2.0-or-later 283322Speter/* 383322Speter * MPC52xx PSC in SPI mode driver. 483322Speter * 583322Speter * Maintainer: Dragos Carp 683322Speter * 783322Speter * Copyright (C) 2006 TOPTICA Photonics AG. 883322Speter */ 983322Speter 1083322Speter#include <linux/module.h> 1183322Speter#include <linux/types.h> 1283322Speter#include <linux/errno.h> 1383322Speter#include <linux/interrupt.h> 1483322Speter#include <linux/platform_device.h> 1583322Speter#include <linux/property.h> 1683322Speter#include <linux/workqueue.h> 1783322Speter#include <linux/completion.h> 1883322Speter#include <linux/io.h> 1983322Speter#include <linux/delay.h> 2083322Speter#include <linux/spi/spi.h> 2183322Speter#include <linux/slab.h> 2283322Speter 2383322Speter#include <asm/mpc52xx.h> 2483322Speter#include <asm/mpc52xx_psc.h> 2583322Speter 2683322Speter#define MCLK 20000000 /* PSC port MClk in hz */ 2783322Speter 2883322Speterstruct mpc52xx_psc_spi { 2983322Speter /* driver internal data */ 3083322Speter struct mpc52xx_psc __iomem *psc; 3183322Speter struct mpc52xx_psc_fifo __iomem *fifo; 3283322Speter int irq; 3383322Speter u8 bits_per_word; 3483322Speter 3583322Speter struct completion done; 3683322Speter}; 3783322Speter 3883322Speter/* controller state */ 3983322Speterstruct mpc52xx_psc_spi_cs { 4083322Speter int bits_per_word; 4183322Speter int speed_hz; 4283322Speter}; 4383322Speter 4483322Speter/* set clock freq, clock ramp, bits per work 4583322Speter * if t is NULL then reset the values to the default values 4683322Speter */ 4783322Speterstatic int mpc52xx_psc_spi_transfer_setup(struct spi_device *spi, 4883322Speter struct spi_transfer *t) 4983322Speter{ 5083322Speter struct mpc52xx_psc_spi_cs *cs = spi->controller_state; 5187551Smikeh 5287551Smikeh cs->speed_hz = (t && t->speed_hz) 5387551Smikeh ? t->speed_hz : spi->max_speed_hz; 5487551Smikeh cs->bits_per_word = (t && t->bits_per_word) 5583322Speter ? t->bits_per_word : spi->bits_per_word; 5683322Speter cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8; 5783322Speter return 0; 5883322Speter} 5983322Speter 6083322Speterstatic void mpc52xx_psc_spi_activate_cs(struct spi_device *spi) 6183322Speter{ 6283322Speter struct mpc52xx_psc_spi_cs *cs = spi->controller_state; 6383322Speter struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(spi->controller); 6483322Speter struct mpc52xx_psc __iomem *psc = mps->psc; 6583322Speter u32 sicr; 6683322Speter u16 ccr; 6783322Speter 6883322Speter sicr = in_be32(&psc->sicr); 6983322Speter 7083322Speter /* Set clock phase and polarity */ 7183322Speter if (spi->mode & SPI_CPHA) 7283322Speter sicr |= 0x00001000; 7383322Speter else 7483322Speter sicr &= ~0x00001000; 7583322Speter if (spi->mode & SPI_CPOL) 7683322Speter sicr |= 0x00002000; 7783322Speter else 7883322Speter sicr &= ~0x00002000; 7983322Speter 8083322Speter if (spi->mode & SPI_LSB_FIRST) 8183322Speter sicr |= 0x10000000; 8283322Speter else 8383322Speter sicr &= ~0x10000000; 8483322Speter out_be32(&psc->sicr, sicr); 8583322Speter 8683322Speter /* Set clock frequency and bits per word 8783322Speter * Because psc->ccr is defined as 16bit register instead of 32bit 8883322Speter * just set the lower byte of BitClkDiv 8983322Speter */ 9083322Speter ccr = in_be16((u16 __iomem *)&psc->ccr); 9183322Speter ccr &= 0xFF00; 9283322Speter if (cs->speed_hz) 9383322Speter ccr |= (MCLK / cs->speed_hz - 1) & 0xFF; 9483322Speter else /* by default SPI Clk 1MHz */ 9583322Speter ccr |= (MCLK / 1000000 - 1) & 0xFF; 9683322Speter out_be16((u16 __iomem *)&psc->ccr, ccr); 9783322Speter mps->bits_per_word = cs->bits_per_word; 9883322Speter} 9983322Speter 10083322Speter#define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1) 10183322Speter/* wake up when 80% fifo full */ 10283322Speter#define MPC52xx_PSC_RFALARM (MPC52xx_PSC_BUFSIZE * 20 / 100) 10383322Speter 10483322Speterstatic int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, 10583322Speter struct spi_transfer *t) 10683322Speter{ 10783322Speter struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(spi->controller); 10883322Speter struct mpc52xx_psc __iomem *psc = mps->psc; 10983322Speter struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; 11083322Speter unsigned rb = 0; /* number of bytes receieved */ 11183322Speter unsigned sb = 0; /* number of bytes sent */ 11283322Speter unsigned char *rx_buf = (unsigned char *)t->rx_buf; 11383322Speter unsigned char *tx_buf = (unsigned char *)t->tx_buf; 11483322Speter unsigned rfalarm; 11583322Speter unsigned send_at_once = MPC52xx_PSC_BUFSIZE; 11683322Speter unsigned recv_at_once; 11783322Speter int last_block = 0; 11883322Speter 11983322Speter if (!t->tx_buf && !t->rx_buf && t->len) 12083322Speter return -EINVAL; 12183322Speter 12283322Speter /* enable transmiter/receiver */ 12383322Speter out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); 12483322Speter while (rb < t->len) { 12583322Speter if (t->len - rb > MPC52xx_PSC_BUFSIZE) { 12683322Speter rfalarm = MPC52xx_PSC_RFALARM; 12783322Speter last_block = 0; 12883322Speter } else { 12983322Speter send_at_once = t->len - sb; 13083322Speter rfalarm = MPC52xx_PSC_BUFSIZE - (t->len - rb); 13183322Speter last_block = 1; 13283322Speter } 13383322Speter 13483322Speter dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once); 13583322Speter for (; send_at_once; sb++, send_at_once--) { 13683322Speter /* set EOF flag before the last word is sent */ 13783322Speter if (send_at_once == 1 && last_block) 13883322Speter out_8(&psc->ircr2, 0x01); 13983322Speter 14083322Speter if (tx_buf) 14183322Speter out_8(&psc->mpc52xx_psc_buffer_8, tx_buf[sb]); 14283322Speter else 14383322Speter out_8(&psc->mpc52xx_psc_buffer_8, 0); 14483322Speter } 14583322Speter 14683322Speter 14783322Speter /* enable interrupts and wait for wake up 14883322Speter * if just one byte is expected the Rx FIFO genererates no 14983322Speter * FFULL interrupt, so activate the RxRDY interrupt 15083322Speter */ 15194414Speter out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); 15283322Speter if (t->len - rb == 1) { 15383322Speter out_8(&psc->mode, 0); 15483322Speter } else { 15583322Speter out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); 15683322Speter out_be16(&fifo->rfalarm, rfalarm); 15783322Speter } 15883322Speter out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY); 15983322Speter wait_for_completion(&mps->done); 16083322Speter recv_at_once = in_be16(&fifo->rfnum); 16183322Speter dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once); 16283322Speter 16383322Speter send_at_once = recv_at_once; 16483322Speter if (rx_buf) { 16583322Speter for (; recv_at_once; rb++, recv_at_once--) 16683322Speter rx_buf[rb] = in_8(&psc->mpc52xx_psc_buffer_8); 16783322Speter } else { 16894414Speter for (; recv_at_once; rb++, recv_at_once--) 16983322Speter in_8(&psc->mpc52xx_psc_buffer_8); 17083322Speter } 17183322Speter } 17283322Speter /* disable transmiter/receiver */ 17383322Speter out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); 17483322Speter 17583322Speter return 0; 17683322Speter} 17783322Speter 17883322Speterstatic int mpc52xx_psc_spi_transfer_one_message(struct spi_controller *ctlr, 17983322Speter struct spi_message *m) 18083322Speter{ 18183322Speter struct spi_device *spi; 18283322Speter struct spi_transfer *t = NULL; 18383322Speter unsigned cs_change; 18483322Speter int status; 18583322Speter 18683322Speter spi = m->spi; 18783322Speter cs_change = 1; 18883322Speter status = 0; 18983322Speter list_for_each_entry (t, &m->transfers, transfer_list) { 19083322Speter if (t->bits_per_word || t->speed_hz) { 19183322Speter status = mpc52xx_psc_spi_transfer_setup(spi, t); 19283322Speter if (status < 0) 19383322Speter break; 19483322Speter } 19583322Speter 19683322Speter if (cs_change) 19783322Speter mpc52xx_psc_spi_activate_cs(spi); 19883322Speter cs_change = t->cs_change; 19983322Speter 20083322Speter status = mpc52xx_psc_spi_transfer_rxtx(spi, t); 20183322Speter if (status) 20283322Speter break; 20383322Speter m->actual_length += t->len; 20483322Speter 20583322Speter spi_transfer_delay_exec(t); 20683322Speter } 20783322Speter 20883322Speter m->status = status; 20983322Speter 21083322Speter mpc52xx_psc_spi_transfer_setup(spi, NULL); 21183322Speter 21283322Speter spi_finalize_current_message(ctlr); 21383322Speter 21483322Speter return 0; 21583322Speter} 21683322Speter 21783322Speterstatic int mpc52xx_psc_spi_setup(struct spi_device *spi) 21883322Speter{ 21987551Smikeh struct mpc52xx_psc_spi_cs *cs = spi->controller_state; 22083322Speter 22187551Smikeh if (spi->bits_per_word%8) 22283322Speter return -EINVAL; 22383322Speter 22483322Speter if (!cs) { 22587551Smikeh cs = kzalloc(sizeof(*cs), GFP_KERNEL); 22687551Smikeh if (!cs) 22787551Smikeh return -ENOMEM; 22887551Smikeh spi->controller_state = cs; 22987551Smikeh } 23087551Smikeh 23183322Speter cs->bits_per_word = spi->bits_per_word; 23283322Speter cs->speed_hz = spi->max_speed_hz; 23383322Speter 23483322Speter return 0; 23583322Speter} 23683322Speter 23783322Speterstatic void mpc52xx_psc_spi_cleanup(struct spi_device *spi) 23883322Speter{ 23983322Speter kfree(spi->controller_state); 24083322Speter} 24183322Speter 24283322Speterstatic int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) 24383322Speter{ 24483322Speter struct mpc52xx_psc __iomem *psc = mps->psc; 24583322Speter struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; 24683322Speter u32 mclken_div; 24783322Speter int ret; 24883322Speter 24983322Speter /* default sysclk is 512MHz */ 25083322Speter mclken_div = 512000000 / MCLK; 25183322Speter ret = mpc52xx_set_psc_clkdiv(psc_id, mclken_div); 25283322Speter if (ret) 25383322Speter return ret; 25483322Speter 25583322Speter /* Reset the PSC into a known state */ 25683322Speter out_8(&psc->command, MPC52xx_PSC_RST_RX); 25783322Speter out_8(&psc->command, MPC52xx_PSC_RST_TX); 25883322Speter out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); 25983322Speter 26083322Speter /* Disable interrupts, interrupts are based on alarm level */ 26183322Speter out_be16(&psc->mpc52xx_psc_imr, 0); 26283322Speter out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); 26383322Speter out_8(&fifo->rfcntl, 0); 26483322Speter out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); 26583322Speter 26683322Speter /* Configure 8bit codec mode as a SPI host and use EOF flags */ 26783322Speter /* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */ 26883322Speter out_be32(&psc->sicr, 0x0180C800); 26983322Speter out_be16((u16 __iomem *)&psc->ccr, 0x070F); /* default SPI Clk 1MHz */ 27083322Speter 27183322Speter /* Set 2ms DTL delay */ 27283322Speter out_8(&psc->ctur, 0x00); 27383322Speter out_8(&psc->ctlr, 0x84); 27483322Speter 27583322Speter mps->bits_per_word = 8; 27683322Speter 27783322Speter return 0; 27883322Speter} 27983322Speter 28083322Speterstatic irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id) 28183322Speter{ 28283322Speter struct mpc52xx_psc_spi *mps = (struct mpc52xx_psc_spi *)dev_id; 28383322Speter struct mpc52xx_psc __iomem *psc = mps->psc; 28483322Speter 28583322Speter /* disable interrupt and wake up the work queue */ 28683322Speter if (in_be16(&psc->mpc52xx_psc_isr) & MPC52xx_PSC_IMR_RXRDY) { 28783322Speter out_be16(&psc->mpc52xx_psc_imr, 0); 28883322Speter complete(&mps->done); 28983322Speter return IRQ_HANDLED; 29083322Speter } 29183322Speter return IRQ_NONE; 29283322Speter} 29383322Speter 29483322Speterstatic int mpc52xx_psc_spi_of_probe(struct platform_device *pdev) 29583322Speter{ 29683322Speter struct device *dev = &pdev->dev; 29783322Speter struct mpc52xx_psc_spi *mps; 29883322Speter struct spi_controller *host; 29983322Speter u32 bus_num; 30083322Speter int ret; 30183322Speter 30283322Speter host = devm_spi_alloc_host(dev, sizeof(*mps)); 30383322Speter if (host == NULL) 30483322Speter return -ENOMEM; 30583322Speter 30683322Speter dev_set_drvdata(dev, host); 30783322Speter mps = spi_controller_get_devdata(host); 30883322Speter 30983322Speter /* the spi->mode bits understood by this driver: */ 31083322Speter host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; 31183322Speter 31283322Speter ret = device_property_read_u32(dev, "cell-index", &bus_num); 31383322Speter if (ret || bus_num > 5) 31483322Speter return dev_err_probe(dev, ret ? : -EINVAL, "Invalid cell-index property\n"); 31583322Speter host->bus_num = bus_num + 1; 31683322Speter 31783322Speter host->num_chipselect = 255; 31883322Speter host->setup = mpc52xx_psc_spi_setup; 31983322Speter host->transfer_one_message = mpc52xx_psc_spi_transfer_one_message; 32083322Speter host->cleanup = mpc52xx_psc_spi_cleanup; 32183322Speter 32283322Speter device_set_node(&host->dev, dev_fwnode(dev)); 32383322Speter 32483322Speter mps->psc = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 32583322Speter if (IS_ERR(mps->psc)) 32683322Speter return dev_err_probe(dev, PTR_ERR(mps->psc), "could not ioremap I/O port range\n"); 32783322Speter 32883322Speter /* On the 5200, fifo regs are immediately ajacent to the psc regs */ 32983322Speter mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc); 33083322Speter 33183322Speter mps->irq = platform_get_irq(pdev, 0); 33283322Speter if (mps->irq < 0) 33383322Speter return mps->irq; 33483322Speter 33583322Speter ret = devm_request_irq(dev, mps->irq, mpc52xx_psc_spi_isr, 0, 33683322Speter "mpc52xx-psc-spi", mps); 33783322Speter if (ret) 33883322Speter return ret; 33983322Speter 34083322Speter ret = mpc52xx_psc_spi_port_config(host->bus_num, mps); 34183322Speter if (ret < 0) 34283322Speter return dev_err_probe(dev, ret, "can't configure PSC! Is it capable of SPI?\n"); 34383322Speter 34483322Speter init_completion(&mps->done); 34583322Speter 34683322Speter return devm_spi_register_controller(dev, host); 34783322Speter} 34883322Speter 34983322Speterstatic const struct of_device_id mpc52xx_psc_spi_of_match[] = { 35083322Speter { .compatible = "fsl,mpc5200-psc-spi", }, 35183322Speter { .compatible = "mpc5200-psc-spi", }, /* old */ 35283322Speter {} 35383322Speter}; 35483322Speter 35583322SpeterMODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); 35683322Speter 35783322Speterstatic struct platform_driver mpc52xx_psc_spi_of_driver = { 35883322Speter .probe = mpc52xx_psc_spi_of_probe, 35983322Speter .driver = { 36083322Speter .name = "mpc52xx-psc-spi", 36183322Speter .of_match_table = mpc52xx_psc_spi_of_match, 36283322Speter }, 36383322Speter}; 36483322Spetermodule_platform_driver(mpc52xx_psc_spi_of_driver); 36583322Speter 36683322SpeterMODULE_AUTHOR("Dragos Carp"); 36783322SpeterMODULE_DESCRIPTION("MPC52xx PSC SPI Driver"); 36883322SpeterMODULE_LICENSE("GPL"); 36983322Speter