Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
81306d53
Commit
81306d53
authored
Feb 08, 2015
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'spi/topic/sh-msiof' into spi-next
parents
f69c22ed
19f0ad09
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
84 additions
and
25 deletions
+84
-25
Documentation/devicetree/bindings/spi/sh-msiof.txt
Documentation/devicetree/bindings/spi/sh-msiof.txt
+16
-0
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-sh-msiof.c
+66
-25
include/linux/spi/sh_msiof.h
include/linux/spi/sh_msiof.h
+2
-0
No files found.
Documentation/devicetree/bindings/spi/sh-msiof.txt
View file @
81306d53
...
...
@@ -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
...
...
drivers/spi/spi-sh-msiof.c
View file @
81306d53
...
...
@@ -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 0x0000000c
/* Frame Sync Signal Interval (0-3) */
#define MDR1_FLD_SHIFT 2
#define MDR1_XXSTP 0x00000001
/* Transmission/Reception Stop on FIFO */
...
...
@@ -241,42 +243,80 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
static
struct
{
unsigned
short
div
;
unsigned
short
scr
;
}
const
sh_msiof_spi_clk_table
[]
=
{
{
1
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_1
},
{
2
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_2
},
{
4
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_4
},
{
8
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_8
},
{
16
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_16
},
{
32
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_32
},
{
64
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_2
},
{
128
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_4
},
{
256
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_8
},
{
512
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_16
},
{
1024
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_32
},
unsigned
short
brdv
;
}
const
sh_msiof_spi_div_table
[]
=
{
{
1
,
SCR_BRDV_DIV_1
},
{
2
,
SCR_BRDV_DIV_2
},
{
4
,
SCR_BRDV_DIV_4
},
{
8
,
SCR_BRDV_DIV_8
},
{
16
,
SCR_BRDV_DIV_16
},
{
32
,
SCR_BRDV_DIV_32
},
};
static
void
sh_msiof_spi_set_clk_regs
(
struct
sh_msiof_spi_priv
*
p
,
unsigned
long
parent_rate
,
u32
spi_hz
)
{
unsigned
long
div
=
1024
;
u32
brps
,
scr
;
size_t
k
;
if
(
!
WARN_ON
(
!
spi_hz
||
!
parent_rate
))
div
=
DIV_ROUND_UP
(
parent_rate
,
spi_hz
);
/* TODO: make more fine grained */
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
sh_msiof_spi_clk_table
);
k
++
)
{
if
(
sh_msiof_spi_clk_table
[
k
].
div
>=
div
)
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
sh_msiof_spi_div_table
);
k
++
)
{
brps
=
DIV_ROUND_UP
(
div
,
sh_msiof_spi_div_table
[
k
].
div
);
if
(
brps
<=
32
)
/* max of brdv is 32 */
break
;
}
k
=
min_t
(
int
,
k
,
ARRAY_SIZE
(
sh_msiof_spi_
clk
_table
)
-
1
);
k
=
min_t
(
int
,
k
,
ARRAY_SIZE
(
sh_msiof_spi_
div
_table
)
-
1
);
sh_msiof_write
(
p
,
TSCR
,
sh_msiof_spi_clk_table
[
k
].
scr
);
scr
=
sh_msiof_spi_div_table
[
k
].
brdv
|
SCR_BRPS
(
brps
);
sh_msiof_write
(
p
,
TSCR
,
scr
);
if
(
!
(
p
->
chipdata
->
master_flags
&
SPI_MASTER_MUST_TX
))
sh_msiof_write
(
p
,
RSCR
,
sh_msiof_spi_clk_table
[
k
].
scr
);
sh_msiof_write
(
p
,
RSCR
,
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
,
...
...
@@ -296,6 +336,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 */
...
...
@@ -501,7 +542,7 @@ static int sh_msiof_spi_setup(struct spi_device *spi)
gpio_set_value
(
spi
->
cs_gpio
,
!
(
spi
->
mode
&
SPI_CS_HIGH
));
pm_runtime_put
_sync
(
&
p
->
pdev
->
dev
);
pm_runtime_put
(
&
p
->
pdev
->
dev
);
return
0
;
}
...
...
@@ -595,8 +636,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
}
/* wait for tx fifo to be emptied / rx fifo to be filled */
ret
=
wait_for_completion_timeout
(
&
p
->
done
,
HZ
);
if
(
!
ret
)
{
if
(
!
wait_for_completion_timeout
(
&
p
->
done
,
HZ
))
{
dev_err
(
&
p
->
pdev
->
dev
,
"PIO timeout
\n
"
);
ret
=
-
ETIMEDOUT
;
goto
stop_reset
;
...
...
@@ -706,8 +746,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
}
/* wait for tx fifo to be emptied / rx fifo to be filled */
ret
=
wait_for_completion_timeout
(
&
p
->
done
,
HZ
);
if
(
!
ret
)
{
if
(
!
wait_for_completion_timeout
(
&
p
->
done
,
HZ
))
{
dev_err
(
&
p
->
pdev
->
dev
,
"DMA timeout
\n
"
);
ret
=
-
ETIMEDOUT
;
goto
stop_reset
;
...
...
@@ -957,6 +996,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
;
...
...
include/linux/spi/sh_msiof.h
View file @
81306d53
...
...
@@ -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__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment