Skip to content

Commit

Permalink
spi: sh-msiof: Configure MSIOF sync signal timing in device tree
Browse files Browse the repository at this point in the history
The MSIOF controller has DTDL and SYNCDL in SITMDR1 register. So,
this patch adds new properties like the following commit:
  d0fb47a
  (spi: fsl-espi: Configure FSL eSPI CSBEF and CSAFT)

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Yoshihiro Shimoda authored and Mark Brown committed Dec 24, 2014
1 parent 97bf6af commit 3110628
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Documentation/devicetree/bindings/spi/sh-msiof.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ Optional properties:
specifiers, one for transmission, and one for
reception.
- dma-names : Must contain a list of two DMA names, "tx" and "rx".
- renesas,dtdl : delay sync signal (setup) in transmit mode.
Must contain one of the following values:
0 (no bit delay)
50 (0.5-clock-cycle delay)
100 (1-clock-cycle delay)
150 (1.5-clock-cycle delay)
200 (2-clock-cycle delay)

- renesas,syncdl : delay sync signal (hold) in transmit mode.
Must contain one of the following values:
0 (no bit delay)
50 (0.5-clock-cycle delay)
100 (1-clock-cycle delay)
150 (1.5-clock-cycle delay)
200 (2-clock-cycle delay)
300 (3-clock-cycle delay)

Optional properties, deprecated for soctype-specific bindings:
- renesas,tx-fifo-size : Overrides the default tx fifo size given in words
Expand Down
47 changes: 47 additions & 0 deletions drivers/spi/spi-sh-msiof.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ struct sh_msiof_spi_priv {
#define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */
#define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */
#define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */
#define MDR1_DTDL_SHIFT 20 /* Data Pin Bit Delay for MSIOF_SYNC */
#define MDR1_SYNCDL_SHIFT 16 /* Frame Sync Signal Timing Delay */
#define MDR1_FLD_MASK 0x000000c0 /* Frame Sync Signal Interval (0-3) */
#define MDR1_FLD_SHIFT 2
#define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */
Expand Down Expand Up @@ -279,6 +281,48 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr);
}

static u32 sh_msiof_get_delay_bit(u32 dtdl_or_syncdl)
{
/*
* DTDL/SYNCDL bit : p->info->dtdl or p->info->syncdl
* b'000 : 0
* b'001 : 100
* b'010 : 200
* b'011 (SYNCDL only) : 300
* b'101 : 50
* b'110 : 150
*/
if (dtdl_or_syncdl % 100)
return dtdl_or_syncdl / 100 + 5;
else
return dtdl_or_syncdl / 100;
}

static u32 sh_msiof_spi_get_dtdl_and_syncdl(struct sh_msiof_spi_priv *p)
{
u32 val;

if (!p->info)
return 0;

/* check if DTDL and SYNCDL is allowed value */
if (p->info->dtdl > 200 || p->info->syncdl > 300) {
dev_warn(&p->pdev->dev, "DTDL or SYNCDL is too large\n");
return 0;
}

/* check if the sum of DTDL and SYNCDL becomes an integer value */
if ((p->info->dtdl + p->info->syncdl) % 100) {
dev_warn(&p->pdev->dev, "the sum of DTDL/SYNCDL is not good\n");
return 0;
}

val = sh_msiof_get_delay_bit(p->info->dtdl) << MDR1_DTDL_SHIFT;
val |= sh_msiof_get_delay_bit(p->info->syncdl) << MDR1_SYNCDL_SHIFT;

return val;
}

static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
u32 cpol, u32 cpha,
u32 tx_hi_z, u32 lsb_first, u32 cs_high)
Expand All @@ -296,6 +340,7 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
tmp = MDR1_SYNCMD_SPI | 1 << MDR1_FLD_SHIFT | MDR1_XXSTP;
tmp |= !cs_high << MDR1_SYNCAC_SHIFT;
tmp |= lsb_first << MDR1_BITLSB_SHIFT;
tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p);
sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON);
if (p->chipdata->master_flags & SPI_MASTER_MUST_TX) {
/* These bits are reserved if RX needs TX */
Expand Down Expand Up @@ -952,6 +997,8 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
&info->tx_fifo_override);
of_property_read_u32(np, "renesas,rx-fifo-size",
&info->rx_fifo_override);
of_property_read_u32(np, "renesas,dtdl", &info->dtdl);
of_property_read_u32(np, "renesas,syncdl", &info->syncdl);

info->num_chipselect = num_cs;

Expand Down
2 changes: 2 additions & 0 deletions include/linux/spi/sh_msiof.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ struct sh_msiof_spi_info {
u16 num_chipselect;
unsigned int dma_tx_id;
unsigned int dma_rx_id;
u32 dtdl;
u32 syncdl;
};

#endif /* __SPI_SH_MSIOF_H__ */

0 comments on commit 3110628

Please sign in to comment.