diff options
author | Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 2014-12-19 03:15:53 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-12-24 07:31:17 -0500 |
commit | 3110628d89f80fbafa085fd62e75afcb39fb764c (patch) | |
tree | ebab30303fbc275e5ab4f7dbb5d49e829435bdd1 | |
parent | 97bf6af1f928216fd6c5a66e8a57bfa95a659672 (diff) |
spi: sh-msiof: Configure MSIOF sync signal timing in device tree
The MSIOF controller has DTDL and SYNCDL in SITMDR1 register. So,
this patch adds new properties like the following commit:
d0fb47a5237d8b9576113568bacfd27892308b62
(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>
-rw-r--r-- | Documentation/devicetree/bindings/spi/sh-msiof.txt | 16 | ||||
-rw-r--r-- | drivers/spi/spi-sh-msiof.c | 47 | ||||
-rw-r--r-- | include/linux/spi/sh_msiof.h | 2 |
3 files changed, 65 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index d11c3721e7cd..4c388bb2f0a2 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt | |||
@@ -30,6 +30,22 @@ Optional properties: | |||
30 | specifiers, one for transmission, and one for | 30 | specifiers, one for transmission, and one for |
31 | reception. | 31 | reception. |
32 | - dma-names : Must contain a list of two DMA names, "tx" and "rx". | 32 | - dma-names : Must contain a list of two DMA names, "tx" and "rx". |
33 | - renesas,dtdl : delay sync signal (setup) in transmit mode. | ||
34 | Must contain one of the following values: | ||
35 | 0 (no bit delay) | ||
36 | 50 (0.5-clock-cycle delay) | ||
37 | 100 (1-clock-cycle delay) | ||
38 | 150 (1.5-clock-cycle delay) | ||
39 | 200 (2-clock-cycle delay) | ||
40 | |||
41 | - renesas,syncdl : delay sync signal (hold) in transmit mode. | ||
42 | Must contain one of the following values: | ||
43 | 0 (no bit delay) | ||
44 | 50 (0.5-clock-cycle delay) | ||
45 | 100 (1-clock-cycle delay) | ||
46 | 150 (1.5-clock-cycle delay) | ||
47 | 200 (2-clock-cycle delay) | ||
48 | 300 (3-clock-cycle delay) | ||
33 | 49 | ||
34 | Optional properties, deprecated for soctype-specific bindings: | 50 | Optional properties, deprecated for soctype-specific bindings: |
35 | - renesas,tx-fifo-size : Overrides the default tx fifo size given in words | 51 | - renesas,tx-fifo-size : Overrides the default tx fifo size given in words |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 239be7cbe5a8..2a87cb939f56 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
@@ -82,6 +82,8 @@ struct sh_msiof_spi_priv { | |||
82 | #define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */ | 82 | #define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */ |
83 | #define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */ | 83 | #define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */ |
84 | #define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */ | 84 | #define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */ |
85 | #define MDR1_DTDL_SHIFT 20 /* Data Pin Bit Delay for MSIOF_SYNC */ | ||
86 | #define MDR1_SYNCDL_SHIFT 16 /* Frame Sync Signal Timing Delay */ | ||
85 | #define MDR1_FLD_MASK 0x000000c0 /* Frame Sync Signal Interval (0-3) */ | 87 | #define MDR1_FLD_MASK 0x000000c0 /* Frame Sync Signal Interval (0-3) */ |
86 | #define MDR1_FLD_SHIFT 2 | 88 | #define MDR1_FLD_SHIFT 2 |
87 | #define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */ | 89 | #define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */ |
@@ -279,6 +281,48 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, | |||
279 | sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr); | 281 | sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr); |
280 | } | 282 | } |
281 | 283 | ||
284 | static u32 sh_msiof_get_delay_bit(u32 dtdl_or_syncdl) | ||
285 | { | ||
286 | /* | ||
287 | * DTDL/SYNCDL bit : p->info->dtdl or p->info->syncdl | ||
288 | * b'000 : 0 | ||
289 | * b'001 : 100 | ||
290 | * b'010 : 200 | ||
291 | * b'011 (SYNCDL only) : 300 | ||
292 | * b'101 : 50 | ||
293 | * b'110 : 150 | ||
294 | */ | ||
295 | if (dtdl_or_syncdl % 100) | ||
296 | return dtdl_or_syncdl / 100 + 5; | ||
297 | else | ||
298 | return dtdl_or_syncdl / 100; | ||
299 | } | ||
300 | |||
301 | static u32 sh_msiof_spi_get_dtdl_and_syncdl(struct sh_msiof_spi_priv *p) | ||
302 | { | ||
303 | u32 val; | ||
304 | |||
305 | if (!p->info) | ||
306 | return 0; | ||
307 | |||
308 | /* check if DTDL and SYNCDL is allowed value */ | ||
309 | if (p->info->dtdl > 200 || p->info->syncdl > 300) { | ||
310 | dev_warn(&p->pdev->dev, "DTDL or SYNCDL is too large\n"); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | /* check if the sum of DTDL and SYNCDL becomes an integer value */ | ||
315 | if ((p->info->dtdl + p->info->syncdl) % 100) { | ||
316 | dev_warn(&p->pdev->dev, "the sum of DTDL/SYNCDL is not good\n"); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | val = sh_msiof_get_delay_bit(p->info->dtdl) << MDR1_DTDL_SHIFT; | ||
321 | val |= sh_msiof_get_delay_bit(p->info->syncdl) << MDR1_SYNCDL_SHIFT; | ||
322 | |||
323 | return val; | ||
324 | } | ||
325 | |||
282 | static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | 326 | static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, |
283 | u32 cpol, u32 cpha, | 327 | u32 cpol, u32 cpha, |
284 | u32 tx_hi_z, u32 lsb_first, u32 cs_high) | 328 | u32 tx_hi_z, u32 lsb_first, u32 cs_high) |
@@ -296,6 +340,7 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | |||
296 | tmp = MDR1_SYNCMD_SPI | 1 << MDR1_FLD_SHIFT | MDR1_XXSTP; | 340 | tmp = MDR1_SYNCMD_SPI | 1 << MDR1_FLD_SHIFT | MDR1_XXSTP; |
297 | tmp |= !cs_high << MDR1_SYNCAC_SHIFT; | 341 | tmp |= !cs_high << MDR1_SYNCAC_SHIFT; |
298 | tmp |= lsb_first << MDR1_BITLSB_SHIFT; | 342 | tmp |= lsb_first << MDR1_BITLSB_SHIFT; |
343 | tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p); | ||
299 | sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); | 344 | sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); |
300 | if (p->chipdata->master_flags & SPI_MASTER_MUST_TX) { | 345 | if (p->chipdata->master_flags & SPI_MASTER_MUST_TX) { |
301 | /* These bits are reserved if RX needs TX */ | 346 | /* These bits are reserved if RX needs TX */ |
@@ -952,6 +997,8 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev) | |||
952 | &info->tx_fifo_override); | 997 | &info->tx_fifo_override); |
953 | of_property_read_u32(np, "renesas,rx-fifo-size", | 998 | of_property_read_u32(np, "renesas,rx-fifo-size", |
954 | &info->rx_fifo_override); | 999 | &info->rx_fifo_override); |
1000 | of_property_read_u32(np, "renesas,dtdl", &info->dtdl); | ||
1001 | of_property_read_u32(np, "renesas,syncdl", &info->syncdl); | ||
955 | 1002 | ||
956 | info->num_chipselect = num_cs; | 1003 | info->num_chipselect = num_cs; |
957 | 1004 | ||
diff --git a/include/linux/spi/sh_msiof.h b/include/linux/spi/sh_msiof.h index 88a14d81c49e..b087a85f5f72 100644 --- a/include/linux/spi/sh_msiof.h +++ b/include/linux/spi/sh_msiof.h | |||
@@ -7,6 +7,8 @@ struct sh_msiof_spi_info { | |||
7 | u16 num_chipselect; | 7 | u16 num_chipselect; |
8 | unsigned int dma_tx_id; | 8 | unsigned int dma_tx_id; |
9 | unsigned int dma_rx_id; | 9 | unsigned int dma_rx_id; |
10 | u32 dtdl; | ||
11 | u32 syncdl; | ||
10 | }; | 12 | }; |
11 | 13 | ||
12 | #endif /* __SPI_SH_MSIOF_H__ */ | 14 | #endif /* __SPI_SH_MSIOF_H__ */ |