1
0
Fork 0

Merge remote-tracking branches 'spi/topic/dw', 'spi/topic/fsl-espi', 'spi/topic/img-spfi' and 'spi/topic/mpc512x-psc' into spi-next

steinar/wifi_calib_4_9_kernel
Mark Brown 2015-08-31 14:45:32 +01:00
13 changed files with 198 additions and 114 deletions

View File

@ -6,14 +6,14 @@ PSC in UART mode
For PSC in UART mode the needed PSC serial devices
are specified by fsl,mpc5121-psc-uart nodes in the
fsl,mpc5121-immr SoC node. Additionally the PSC FIFO
Controller node fsl,mpc5121-psc-fifo is requered there:
Controller node fsl,mpc5121-psc-fifo is required there:
fsl,mpc5121-psc-uart nodes
fsl,mpc512x-psc-uart nodes
--------------------------
Required properties :
- compatible : Should contain "fsl,mpc5121-psc-uart" and "fsl,mpc5121-psc"
- cell-index : Index of the PSC in hardware
- compatible : Should contain "fsl,<soc>-psc-uart" and "fsl,<soc>-psc"
Supported <soc>s: mpc5121, mpc5125
- reg : Offset and length of the register set for the PSC device
- interrupts : <a b> where a is the interrupt number of the
PSC FIFO Controller and b is a field that represents an
@ -25,12 +25,21 @@ Recommended properties :
- fsl,rx-fifo-size : the size of the RX fifo slice (a multiple of 4)
- fsl,tx-fifo-size : the size of the TX fifo slice (a multiple of 4)
PSC in SPI mode
---------------
fsl,mpc5121-psc-fifo node
Similar to the UART mode a PSC can be operated in SPI mode. The compatible used
for that is fsl,mpc5121-psc-spi. It requires a fsl,mpc5121-psc-fifo as well.
The required and recommended properties are identical to the
fsl,mpc5121-psc-uart nodes, just use spi instead of uart in the compatible
string.
fsl,mpc512x-psc-fifo node
-------------------------
Required properties :
- compatible : Should be "fsl,mpc5121-psc-fifo"
- compatible : Should be "fsl,<soc>-psc-fifo"
Supported <soc>s: mpc5121, mpc5125
- reg : Offset and length of the register set for the PSC
FIFO Controller
- interrupts : <a b> where a is the interrupt number of the
@ -39,6 +48,9 @@ Required properties :
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.
Recommended properties :
- clocks : specifies the clock needed to operate the fifo controller
- clock-names : name(s) for the clock(s) listed in clocks
Example for a board using PSC0 and PSC1 devices in serial mode:

View File

@ -10,6 +10,8 @@ Required properties:
Optional properties:
- cs-gpios : Specifies the gpio pis to be used for chipselects.
- num-cs : The number of chipselects. If omitted, this will default to 4.
- reg-io-width : The I/O register width (in bytes) implemented by this
device. Supported values are 2 or 4 (the default).
Child nodes as per the generic SPI binding.

View File

@ -21,6 +21,7 @@ Required properties:
Optional properties:
- img,supports-quad-mode: Should be set if the interface supports quad mode
SPI transfers.
- spfi-max-frequency: Maximum speed supported by the spfi block.
Example:

View File

@ -150,7 +150,10 @@
/* Structure of the hardware registers */
struct mpc52xx_psc {
u8 mode; /* PSC + 0x00 */
union {
u8 mode; /* PSC + 0x00 */
u8 mr2;
};
u8 reserved0[3];
union { /* PSC + 0x04 */
u16 status;

View File

@ -74,6 +74,9 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
dws->max_freq = clk_get_rate(dwsmmio->clk);
of_property_read_u32(pdev->dev.of_node, "reg-io-width",
&dws->reg_io_width);
num_cs = 4;
if (pdev->dev.of_node)

View File

@ -194,7 +194,7 @@ static void dw_writer(struct dw_spi *dws)
else
txw = *(u16 *)(dws->tx);
}
dw_writel(dws, DW_SPI_DR, txw);
dw_write_io_reg(dws, DW_SPI_DR, txw);
dws->tx += dws->n_bytes;
}
}
@ -205,7 +205,7 @@ static void dw_reader(struct dw_spi *dws)
u16 rxw;
while (max--) {
rxw = dw_readl(dws, DW_SPI_DR);
rxw = dw_read_io_reg(dws, DW_SPI_DR);
/* Care rx only if the transfer's original "rx" is not null */
if (dws->rx_end - dws->len) {
if (dws->n_bytes == 1)

View File

@ -109,6 +109,7 @@ struct dw_spi {
u32 fifo_len; /* depth of the FIFO buffer */
u32 max_freq; /* max bus freq supported */
u32 reg_io_width; /* DR I/O width in bytes */
u16 bus_num;
u16 num_cs; /* supported slave numbers */
@ -145,11 +146,45 @@ static inline u32 dw_readl(struct dw_spi *dws, u32 offset)
return __raw_readl(dws->regs + offset);
}
static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
{
return __raw_readw(dws->regs + offset);
}
static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 val)
{
__raw_writel(val, dws->regs + offset);
}
static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 val)
{
__raw_writew(val, dws->regs + offset);
}
static inline u32 dw_read_io_reg(struct dw_spi *dws, u32 offset)
{
switch (dws->reg_io_width) {
case 2:
return dw_readw(dws, offset);
case 4:
default:
return dw_readl(dws, offset);
}
}
static inline void dw_write_io_reg(struct dw_spi *dws, u32 offset, u32 val)
{
switch (dws->reg_io_width) {
case 2:
dw_writew(dws, offset, val);
break;
case 4:
default:
dw_writel(dws, offset, val);
break;
}
}
static inline void spi_enable_chip(struct dw_spi *dws, int enable)
{
dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));

View File

@ -21,6 +21,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/pm_runtime.h>
#include <sysdev/fsl_soc.h>
#include "spi-fsl-lib.h"
@ -85,6 +86,8 @@ struct fsl_espi_transfer {
#define SPCOM_TRANLEN(x) ((x) << 0)
#define SPCOM_TRANLEN_MAX 0xFFFF /* Max transaction length */
#define AUTOSUSPEND_TIMEOUT 2000
static void fsl_espi_change_mode(struct spi_device *spi)
{
struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
@ -485,6 +488,8 @@ static int fsl_espi_setup(struct spi_device *spi)
mpc8xxx_spi = spi_master_get_devdata(spi->master);
reg_base = mpc8xxx_spi->reg_base;
pm_runtime_get_sync(mpc8xxx_spi->dev);
hw_mode = cs->hw_mode; /* Save original settings */
cs->hw_mode = mpc8xxx_spi_read_reg(
&reg_base->csmode[spi->chip_select]);
@ -507,6 +512,10 @@ static int fsl_espi_setup(struct spi_device *spi)
mpc8xxx_spi_write_reg(&reg_base->mode, loop_mode);
retval = fsl_espi_setup_transfer(spi, NULL);
pm_runtime_mark_last_busy(mpc8xxx_spi->dev);
pm_runtime_put_autosuspend(mpc8xxx_spi->dev);
if (retval < 0) {
cs->hw_mode = hw_mode; /* Restore settings */
return retval;
@ -604,20 +613,14 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
return ret;
}
static void fsl_espi_remove(struct mpc8xxx_spi *mspi)
#ifdef CONFIG_PM
static int fsl_espi_runtime_suspend(struct device *dev)
{
iounmap(mspi->reg_base);
}
static int fsl_espi_suspend(struct spi_master *master)
{
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
struct spi_master *master = dev_get_drvdata(dev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base;
u32 regval;
mpc8xxx_spi = spi_master_get_devdata(master);
reg_base = mpc8xxx_spi->reg_base;
regval = mpc8xxx_spi_read_reg(&reg_base->mode);
regval &= ~SPMODE_ENABLE;
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
@ -625,21 +628,20 @@ static int fsl_espi_suspend(struct spi_master *master)
return 0;
}
static int fsl_espi_resume(struct spi_master *master)
static int fsl_espi_runtime_resume(struct device *dev)
{
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
struct spi_master *master = dev_get_drvdata(dev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base;
u32 regval;
mpc8xxx_spi = spi_master_get_devdata(master);
reg_base = mpc8xxx_spi->reg_base;
regval = mpc8xxx_spi_read_reg(&reg_base->mode);
regval |= SPMODE_ENABLE;
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
return 0;
}
#endif
static struct spi_master * fsl_espi_probe(struct device *dev,
struct resource *mem, unsigned int irq)
@ -667,25 +669,23 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
master->setup = fsl_espi_setup;
master->cleanup = fsl_espi_cleanup;
master->transfer_one_message = fsl_espi_do_one_msg;
master->prepare_transfer_hardware = fsl_espi_resume;
master->unprepare_transfer_hardware = fsl_espi_suspend;
master->auto_runtime_pm = true;
mpc8xxx_spi = spi_master_get_devdata(master);
mpc8xxx_spi->spi_remove = fsl_espi_remove;
mpc8xxx_spi->reg_base = ioremap(mem->start, resource_size(mem));
if (!mpc8xxx_spi->reg_base) {
ret = -ENOMEM;
mpc8xxx_spi->reg_base = devm_ioremap_resource(dev, mem);
if (IS_ERR(mpc8xxx_spi->reg_base)) {
ret = PTR_ERR(mpc8xxx_spi->reg_base);
goto err_probe;
}
reg_base = mpc8xxx_spi->reg_base;
/* Register for SPI Interrupt */
ret = request_irq(mpc8xxx_spi->irq, fsl_espi_irq,
ret = devm_request_irq(dev, mpc8xxx_spi->irq, fsl_espi_irq,
0, "fsl_espi", mpc8xxx_spi);
if (ret)
goto free_irq;
goto err_probe;
if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
mpc8xxx_spi->rx_shift = 16;
@ -731,18 +731,27 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
ret = spi_register_master(master);
pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
ret = devm_spi_register_master(dev, master);
if (ret < 0)
goto unreg_master;
goto err_pm;
dev_info(dev, "at 0x%p (irq = %d)\n", reg_base, mpc8xxx_spi->irq);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return master;
unreg_master:
free_irq(mpc8xxx_spi->irq, mpc8xxx_spi);
free_irq:
iounmap(mpc8xxx_spi->reg_base);
err_pm:
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
err_probe:
spi_master_put(master);
err:
@ -809,7 +818,9 @@ err:
static int of_fsl_espi_remove(struct platform_device *dev)
{
return mpc8xxx_spi_remove(&dev->dev);
pm_runtime_disable(&dev->dev);
return 0;
}
#ifdef CONFIG_PM_SLEEP
@ -824,7 +835,11 @@ static int of_fsl_espi_suspend(struct device *dev)
return ret;
}
return fsl_espi_suspend(master);
ret = pm_runtime_force_suspend(dev);
if (ret < 0)
return ret;
return 0;
}
static int of_fsl_espi_resume(struct device *dev)
@ -834,7 +849,7 @@ static int of_fsl_espi_resume(struct device *dev)
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
u32 regval;
int i;
int i, ret;
mpc8xxx_spi = spi_master_get_devdata(master);
reg_base = mpc8xxx_spi->reg_base;
@ -854,11 +869,17 @@ static int of_fsl_espi_resume(struct device *dev)
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
ret = pm_runtime_force_resume(dev);
if (ret < 0)
return ret;
return spi_master_resume(master);
}
#endif /* CONFIG_PM_SLEEP */
static const struct dev_pm_ops espi_pm = {
SET_RUNTIME_PM_OPS(fsl_espi_runtime_suspend,
fsl_espi_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(of_fsl_espi_suspend, of_fsl_espi_resume)
};

View File

@ -114,25 +114,6 @@ void mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
}
EXPORT_SYMBOL_GPL(mpc8xxx_spi_probe);
int mpc8xxx_spi_remove(struct device *dev)
{
struct mpc8xxx_spi *mpc8xxx_spi;
struct spi_master *master;
master = dev_get_drvdata(dev);
mpc8xxx_spi = spi_master_get_devdata(master);
spi_unregister_master(master);
free_irq(mpc8xxx_spi->irq, mpc8xxx_spi);
if (mpc8xxx_spi->spi_remove)
mpc8xxx_spi->spi_remove(mpc8xxx_spi);
return 0;
}
EXPORT_SYMBOL_GPL(mpc8xxx_spi_remove);
int of_mpc8xxx_spi_probe(struct platform_device *ofdev)
{
struct device *dev = &ofdev->dev;

View File

@ -54,9 +54,6 @@ struct mpc8xxx_spi {
void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *);
u32(*get_tx) (struct mpc8xxx_spi *);
/* hooks for different controller driver */
void (*spi_remove) (struct mpc8xxx_spi *mspi);
unsigned int count;
unsigned int irq;

View File

@ -559,12 +559,6 @@ static irqreturn_t fsl_spi_irq(s32 irq, void *context_data)
return ret;
}
static void fsl_spi_remove(struct mpc8xxx_spi *mspi)
{
iounmap(mspi->reg_base);
fsl_spi_cpm_free(mspi);
}
static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on)
{
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
@ -631,7 +625,6 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
master->transfer_one_message = fsl_spi_do_one_msg;
mpc8xxx_spi = spi_master_get_devdata(master);
mpc8xxx_spi->spi_remove = fsl_spi_remove;
mpc8xxx_spi->max_bits_per_word = 32;
mpc8xxx_spi->type = fsl_spi_get_type(dev);
@ -639,10 +632,10 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
if (ret)
goto err_cpm_init;
mpc8xxx_spi->reg_base = ioremap(mem->start, resource_size(mem));
if (mpc8xxx_spi->reg_base == NULL) {
ret = -ENOMEM;
goto err_ioremap;
mpc8xxx_spi->reg_base = devm_ioremap_resource(dev, mem);
if (IS_ERR(mpc8xxx_spi->reg_base)) {
ret = PTR_ERR(mpc8xxx_spi->reg_base);
goto err_probe;
}
if (mpc8xxx_spi->type == TYPE_GRLIB)
@ -661,11 +654,11 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
&mpc8xxx_spi->tx_shift, 8, 1);
/* Register for SPI Interrupt */
ret = request_irq(mpc8xxx_spi->irq, fsl_spi_irq,
0, "fsl_spi", mpc8xxx_spi);
ret = devm_request_irq(dev, mpc8xxx_spi->irq, fsl_spi_irq,
0, "fsl_spi", mpc8xxx_spi);
if (ret != 0)
goto free_irq;
goto err_probe;
reg_base = mpc8xxx_spi->reg_base;
@ -686,20 +679,16 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
ret = spi_register_master(master);
ret = devm_spi_register_master(dev, master);
if (ret < 0)
goto unreg_master;
goto err_probe;
dev_info(dev, "at 0x%p (irq = %d), %s mode\n", reg_base,
mpc8xxx_spi->irq, mpc8xxx_spi_strmode(mpc8xxx_spi->flags));
return master;
unreg_master:
free_irq(mpc8xxx_spi->irq, mpc8xxx_spi);
free_irq:
iounmap(mpc8xxx_spi->reg_base);
err_ioremap:
err_probe:
fsl_spi_cpm_free(mpc8xxx_spi);
err_cpm_init:
spi_master_put(master);
@ -866,11 +855,8 @@ static int of_fsl_spi_remove(struct platform_device *ofdev)
{
struct spi_master *master = platform_get_drvdata(ofdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
int ret;
ret = mpc8xxx_spi_remove(&ofdev->dev);
if (ret)
return ret;
fsl_spi_cpm_free(mpc8xxx_spi);
if (mpc8xxx_spi->type == TYPE_FSL)
of_fsl_spi_free_chipselects(&ofdev->dev);
return 0;
@ -916,7 +902,12 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev)
static int plat_mpc8xxx_spi_remove(struct platform_device *pdev)
{
return mpc8xxx_spi_remove(&pdev->dev);
struct spi_master *master = platform_get_drvdata(pdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
fsl_spi_cpm_free(mpc8xxx_spi);
return 0;
}
MODULE_ALIAS("platform:mpc8xxx_spi");

View File

@ -581,6 +581,7 @@ static int img_spfi_probe(struct platform_device *pdev)
struct img_spfi *spfi;
struct resource *res;
int ret;
u32 max_speed_hz;
master = spi_alloc_master(&pdev->dev, sizeof(*spfi));
if (!master)
@ -645,6 +646,19 @@ static int img_spfi_probe(struct platform_device *pdev)
master->max_speed_hz = clk_get_rate(spfi->spfi_clk) / 4;
master->min_speed_hz = clk_get_rate(spfi->spfi_clk) / 512;
/*
* Maximum speed supported by spfi is limited to the lower value
* between 1/4 of the SPFI clock or to "spfi-max-frequency"
* defined in the device tree.
* If no value is defined in the device tree assume the maximum
* speed supported to be 1/4 of the SPFI clock.
*/
if (!of_property_read_u32(spfi->dev->of_node, "spfi-max-frequency",
&max_speed_hz)) {
if (master->max_speed_hz > max_speed_hz)
master->max_speed_hz = max_speed_hz;
}
master->setup = img_spfi_setup;
master->cleanup = img_spfi_cleanup;
master->transfer_one = img_spfi_transfer_one;

View File

@ -30,11 +30,37 @@
#include <linux/gpio.h>
#include <asm/mpc52xx_psc.h>
enum {
TYPE_MPC5121,
TYPE_MPC5125,
};
/*
* This macro abstracts the differences in the PSC register layout between
* MPC5121 (which uses a struct mpc52xx_psc) and MPC5125 (using mpc5125_psc).
*/
#define psc_addr(mps, regname) ({ \
void *__ret = NULL; \
switch (mps->type) { \
case TYPE_MPC5121: { \
struct mpc52xx_psc __iomem *psc = mps->psc; \
__ret = &psc->regname; \
}; \
break; \
case TYPE_MPC5125: { \
struct mpc5125_psc __iomem *psc = mps->psc; \
__ret = &psc->regname; \
}; \
break; \
} \
__ret; })
struct mpc512x_psc_spi {
void (*cs_control)(struct spi_device *spi, bool on);
/* driver internal data */
struct mpc52xx_psc __iomem *psc;
int type;
void __iomem *psc;
struct mpc512x_psc_fifo __iomem *fifo;
unsigned int irq;
u8 bits_per_word;
@ -71,13 +97,12 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
{
struct mpc512x_psc_spi_cs *cs = spi->controller_state;
struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
struct mpc52xx_psc __iomem *psc = mps->psc;
u32 sicr;
u32 ccr;
int speed;
u16 bclkdiv;
sicr = in_be32(&psc->sicr);
sicr = in_be32(psc_addr(mps, sicr));
/* Set clock phase and polarity */
if (spi->mode & SPI_CPHA)
@ -94,9 +119,9 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
sicr |= 0x10000000;
else
sicr &= ~0x10000000;
out_be32(&psc->sicr, sicr);
out_be32(psc_addr(mps, sicr), sicr);
ccr = in_be32(&psc->ccr);
ccr = in_be32(psc_addr(mps, ccr));
ccr &= 0xFF000000;
speed = cs->speed_hz;
if (!speed)
@ -104,7 +129,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
bclkdiv = (mps->mclk_rate / speed) - 1;
ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
out_be32(&psc->ccr, ccr);
out_be32(psc_addr(mps, ccr), ccr);
mps->bits_per_word = cs->bits_per_word;
if (mps->cs_control && gpio_is_valid(spi->cs_gpio))
@ -315,16 +340,15 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
static int mpc512x_psc_spi_prep_xfer_hw(struct spi_master *master)
{
struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
struct mpc52xx_psc __iomem *psc = mps->psc;
dev_dbg(&master->dev, "%s()\n", __func__);
/* Zero MR2 */
in_8(&psc->mode);
out_8(&psc->mode, 0x0);
in_8(psc_addr(mps, mr2));
out_8(psc_addr(mps, mr2), 0x0);
/* enable transmitter/receiver */
out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
out_8(psc_addr(mps, command), MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
return 0;
}
@ -332,13 +356,12 @@ static int mpc512x_psc_spi_prep_xfer_hw(struct spi_master *master)
static int mpc512x_psc_spi_unprep_xfer_hw(struct spi_master *master)
{
struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
dev_dbg(&master->dev, "%s()\n", __func__);
/* disable transmitter/receiver and fifo interrupt */
out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
out_8(psc_addr(mps, command), MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
out_be32(&fifo->tximr, 0);
return 0;
@ -388,7 +411,6 @@ static void mpc512x_psc_spi_cleanup(struct spi_device *spi)
static int mpc512x_psc_spi_port_config(struct spi_master *master,
struct mpc512x_psc_spi *mps)
{
struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
u32 sicr;
u32 ccr;
@ -396,12 +418,12 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
u16 bclkdiv;
/* Reset the PSC into a known state */
out_8(&psc->command, MPC52xx_PSC_RST_RX);
out_8(&psc->command, MPC52xx_PSC_RST_TX);
out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
out_8(psc_addr(mps, command), MPC52xx_PSC_RST_RX);
out_8(psc_addr(mps, command), MPC52xx_PSC_RST_TX);
out_8(psc_addr(mps, command), MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
/* Disable psc interrupts all useful interrupts are in fifo */
out_be16(&psc->isr_imr.imr, 0);
out_be16(psc_addr(mps, isr_imr.imr), 0);
/* Disable fifo interrupts, will be enabled later */
out_be32(&fifo->tximr, 0);
@ -417,18 +439,18 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
0x00004000 | /* MSTR = 1 -- SPI master */
0x00000800; /* UseEOF = 1 -- SS low until EOF */
out_be32(&psc->sicr, sicr);
out_be32(psc_addr(mps, sicr), sicr);
ccr = in_be32(&psc->ccr);
ccr = in_be32(psc_addr(mps, ccr));
ccr &= 0xFF000000;
speed = 1000000; /* default 1MHz */
bclkdiv = (mps->mclk_rate / speed) - 1;
ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
out_be32(&psc->ccr, ccr);
out_be32(psc_addr(mps, ccr), ccr);
/* Set 2ms DTL delay */
out_8(&psc->ctur, 0x00);
out_8(&psc->ctlr, 0x82);
out_8(psc_addr(mps, ctur), 0x00);
out_8(psc_addr(mps, ctlr), 0x82);
/* we don't use the alarms */
out_be32(&fifo->rxalarm, 0xfff);
@ -482,6 +504,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
dev_set_drvdata(dev, master);
mps = spi_master_get_devdata(master);
mps->type = (int)of_device_get_match_data(dev);
mps->irq = irq;
if (pdata == NULL) {
@ -589,7 +612,8 @@ static int mpc512x_psc_spi_of_remove(struct platform_device *op)
}
static const struct of_device_id mpc512x_psc_spi_of_match[] = {
{ .compatible = "fsl,mpc5121-psc-spi", },
{ .compatible = "fsl,mpc5121-psc-spi", .data = (void *)TYPE_MPC5121 },
{ .compatible = "fsl,mpc5125-psc-spi", .data = (void *)TYPE_MPC5125 },
{},
};