Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
reform-boundary-uboot
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jack Humbert
reform-boundary-uboot
Commits
130aec77
Commit
130aec77
authored
10 years ago
by
Tom Rini
Browse files
Options
Downloads
Plain Diff
Merge branch 'master' of
git://git.denx.de/u-boot-spi
parents
2c54cb55
027a9a00
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
doc/SPI/README.altera_spi
+6
-0
6 additions, 0 deletions
doc/SPI/README.altera_spi
drivers/spi/altera_spi.c
+74
-58
74 additions, 58 deletions
drivers/spi/altera_spi.c
drivers/spi/mxc_spi.c
+21
-19
21 additions, 19 deletions
drivers/spi/mxc_spi.c
with
101 additions
and
77 deletions
doc/SPI/README.altera_spi
0 → 100644
+
6
−
0
View file @
130aec77
SoCFPGA EPCS/EPCQx1 mini howto:
- Instantiate EPCS/EPCQx1 Serial flash controller in QSys and rebuild
- The controller base address is the "Base" in QSys + 0x400
- Set MSEL[4:0]=10010 (AS Standard)
- Load the bitstream into FPGA, enable bridges
- Only then will the driver work
This diff is collapsed.
Click to expand it.
drivers/spi/altera_spi.c
+
74
−
58
View file @
130aec77
...
@@ -12,58 +12,62 @@
...
@@ -12,58 +12,62 @@
#include
<malloc.h>
#include
<malloc.h>
#include
<spi.h>
#include
<spi.h>
#define ALTERA_SPI_RXDATA 0
#ifndef CONFIG_ALTERA_SPI_IDLE_VAL
#define ALTERA_SPI_TXDATA 4
#define CONFIG_ALTERA_SPI_IDLE_VAL 0xff
#define ALTERA_SPI_STATUS 8
#endif
#define ALTERA_SPI_CONTROL 12
#define ALTERA_SPI_SLAVE_SEL 20
#define ALTERA_SPI_STATUS_ROE_MSK (0x8)
#define ALTERA_SPI_STATUS_TOE_MSK (0x10)
#define ALTERA_SPI_STATUS_TMT_MSK (0x20)
#define ALTERA_SPI_STATUS_TRDY_MSK (0x40)
#define ALTERA_SPI_STATUS_RRDY_MSK (0x80)
#define ALTERA_SPI_STATUS_E_MSK (0x100)
#define ALTERA_SPI_CONTROL_IROE_MSK (0x8)
#define ALTERA_SPI_CONTROL_ITOE_MSK (0x10)
#define ALTERA_SPI_CONTROL_ITRDY_MSK (0x40)
#define ALTERA_SPI_CONTROL_IRRDY_MSK (0x80)
#define ALTERA_SPI_CONTROL_IE_MSK (0x100)
#define ALTERA_SPI_CONTROL_SSO_MSK (0x400)
#ifndef CONFIG_SYS_ALTERA_SPI_LIST
#ifndef CONFIG_SYS_ALTERA_SPI_LIST
#define CONFIG_SYS_ALTERA_SPI_LIST { CONFIG_SYS_SPI_BASE }
#define CONFIG_SYS_ALTERA_SPI_LIST { CONFIG_SYS_SPI_BASE }
#endif
#endif
struct
altera_spi_regs
{
u32
rxdata
;
u32
txdata
;
u32
status
;
u32
control
;
u32
_reserved
;
u32
slave_sel
;
};
#define ALTERA_SPI_STATUS_ROE_MSK (1 << 3)
#define ALTERA_SPI_STATUS_TOE_MSK (1 << 4)
#define ALTERA_SPI_STATUS_TMT_MSK (1 << 5)
#define ALTERA_SPI_STATUS_TRDY_MSK (1 << 6)
#define ALTERA_SPI_STATUS_RRDY_MSK (1 << 7)
#define ALTERA_SPI_STATUS_E_MSK (1 << 8)
#define ALTERA_SPI_CONTROL_IROE_MSK (1 << 3)
#define ALTERA_SPI_CONTROL_ITOE_MSK (1 << 4)
#define ALTERA_SPI_CONTROL_ITRDY_MSK (1 << 6)
#define ALTERA_SPI_CONTROL_IRRDY_MSK (1 << 7)
#define ALTERA_SPI_CONTROL_IE_MSK (1 << 8)
#define ALTERA_SPI_CONTROL_SSO_MSK (1 << 10)
static
ulong
altera_spi_base_list
[]
=
CONFIG_SYS_ALTERA_SPI_LIST
;
static
ulong
altera_spi_base_list
[]
=
CONFIG_SYS_ALTERA_SPI_LIST
;
struct
altera_spi_slave
{
struct
altera_spi_slave
{
struct
spi_slave
slave
;
struct
spi_slave
slave
;
ulong
base
;
struct
altera_spi_regs
*
regs
;
};
};
#define to_altera_spi_slave(s) container_of(s, struct altera_spi_slave, slave)
#define to_altera_spi_slave(s) container_of(s, struct altera_spi_slave, slave)
__attribute__
((
weak
))
__weak
int
spi_cs_is_valid
(
unsigned
int
bus
,
unsigned
int
cs
)
int
spi_cs_is_valid
(
unsigned
int
bus
,
unsigned
int
cs
)
{
{
return
bus
<
ARRAY_SIZE
(
altera_spi_base_list
)
&&
cs
<
32
;
return
bus
<
ARRAY_SIZE
(
altera_spi_base_list
)
&&
cs
<
32
;
}
}
__attribute__
((
weak
))
__weak
void
spi_cs_activate
(
struct
spi_slave
*
slave
)
void
spi_cs_activate
(
struct
spi_slave
*
slave
)
{
{
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
writel
(
1
<<
slave
->
cs
,
altspi
->
base
+
ALTERA_SPI_SLAVE_SEL
);
writel
(
1
<<
slave
->
cs
,
&
altspi
->
regs
->
slave_sel
);
writel
(
ALTERA_SPI_CONTROL_SSO_MSK
,
altspi
->
base
+
ALTERA_SPI_CONTROL
);
writel
(
ALTERA_SPI_CONTROL_SSO_MSK
,
&
altspi
->
regs
->
control
);
}
}
__attribute__
((
weak
))
__weak
void
spi_cs_deactivate
(
struct
spi_slave
*
slave
)
void
spi_cs_deactivate
(
struct
spi_slave
*
slave
)
{
{
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
writel
(
0
,
altspi
->
base
+
ALTERA_SPI_CONTROL
);
writel
(
0
,
&
altspi
->
regs
->
control
);
writel
(
0
,
altspi
->
base
+
ALTERA_SPI_SLAVE_SEL
);
writel
(
0
,
&
altspi
->
regs
->
slave_sel
);
}
}
void
spi_init
(
void
)
void
spi_init
(
void
)
...
@@ -87,9 +91,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
...
@@ -87,9 +91,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if
(
!
altspi
)
if
(
!
altspi
)
return
NULL
;
return
NULL
;
altspi
->
base
=
altera_spi_base_list
[
bus
];
altspi
->
regs
=
(
struct
altera_spi_regs
*
)
altera_spi_base_list
[
bus
];
debug
(
"%s: bus:%i cs:%i base:%lx
\n
"
,
__func__
,
debug
(
"%s: bus:%i cs:%i base:%p
\n
"
,
__func__
,
bus
,
cs
,
altspi
->
regs
);
bus
,
cs
,
altspi
->
base
);
return
&
altspi
->
slave
;
return
&
altspi
->
slave
;
}
}
...
@@ -105,8 +108,8 @@ int spi_claim_bus(struct spi_slave *slave)
...
@@ -105,8 +108,8 @@ int spi_claim_bus(struct spi_slave *slave)
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
debug
(
"%s: bus:%i cs:%i
\n
"
,
__func__
,
slave
->
bus
,
slave
->
cs
);
debug
(
"%s: bus:%i cs:%i
\n
"
,
__func__
,
slave
->
bus
,
slave
->
cs
);
writel
(
0
,
altspi
->
base
+
ALTERA_SPI_CONTROL
);
writel
(
0
,
&
altspi
->
regs
->
control
);
writel
(
0
,
altspi
->
base
+
ALTERA_SPI_SLAVE_SEL
);
writel
(
0
,
&
altspi
->
regs
->
slave_sel
);
return
0
;
return
0
;
}
}
...
@@ -115,24 +118,22 @@ void spi_release_bus(struct spi_slave *slave)
...
@@ -115,24 +118,22 @@ void spi_release_bus(struct spi_slave *slave)
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
debug
(
"%s: bus:%i cs:%i
\n
"
,
__func__
,
slave
->
bus
,
slave
->
cs
);
debug
(
"%s: bus:%i cs:%i
\n
"
,
__func__
,
slave
->
bus
,
slave
->
cs
);
writel
(
0
,
altspi
->
base
+
ALTERA_SPI_SLAVE_SEL
);
writel
(
0
,
&
altspi
->
regs
->
slave_sel
);
}
}
#ifndef CONFIG_ALTERA_SPI_IDLE_VAL
# define CONFIG_ALTERA_SPI_IDLE_VAL 0xff
#endif
int
spi_xfer
(
struct
spi_slave
*
slave
,
unsigned
int
bitlen
,
const
void
*
dout
,
int
spi_xfer
(
struct
spi_slave
*
slave
,
unsigned
int
bitlen
,
const
void
*
dout
,
void
*
din
,
unsigned
long
flags
)
void
*
din
,
unsigned
long
flags
)
{
{
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
struct
altera_spi_slave
*
altspi
=
to_altera_spi_slave
(
slave
);
/* assume spi core configured to do 8 bit transfers */
/* assume spi core configured to do 8 bit transfers */
uint
bytes
=
bitlen
/
8
;
unsigned
int
bytes
=
bitlen
/
8
;
const
uchar
*
txp
=
dout
;
const
unsigned
char
*
txp
=
dout
;
uchar
*
rxp
=
din
;
unsigned
char
*
rxp
=
din
;
uint32_t
reg
,
data
,
start
;
debug
(
"%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx
\n
"
,
__func__
,
debug
(
"%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx
\n
"
,
__func__
,
slave
->
bus
,
slave
->
cs
,
bitlen
,
bytes
,
flags
);
slave
->
bus
,
slave
->
cs
,
bitlen
,
bytes
,
flags
);
if
(
bitlen
==
0
)
if
(
bitlen
==
0
)
goto
done
;
goto
done
;
...
@@ -142,25 +143,40 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
...
@@ -142,25 +143,40 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
}
}
/* empty read buffer */
/* empty read buffer */
if
(
readl
(
altspi
->
base
+
ALTERA_SPI_STATUS
)
&
if
(
readl
(
&
altspi
->
regs
->
status
)
&
ALTERA_SPI_STATUS
_RRDY_MSK
)
ALTERA_SPI_STATUS_RRDY_MSK
)
readl
(
&
altspi
->
regs
->
rxdata
);
readl
(
altspi
->
base
+
ALTERA_SPI_RXDATA
);
if
(
flags
&
SPI_XFER_BEGIN
)
if
(
flags
&
SPI_XFER_BEGIN
)
spi_cs_activate
(
slave
);
spi_cs_activate
(
slave
);
while
(
bytes
--
)
{
while
(
bytes
--
)
{
uchar
d
=
txp
?
*
txp
++
:
CONFIG_ALTERA_SPI_IDLE_VAL
;
if
(
txp
)
debug
(
"%s: tx:%x "
,
__func__
,
d
);
data
=
*
txp
++
;
writel
(
d
,
altspi
->
base
+
ALTERA_SPI_TXDATA
);
else
while
(
!
(
readl
(
altspi
->
base
+
ALTERA_SPI_STATUS
)
&
data
=
CONFIG_ALTERA_SPI_IDLE_VAL
;
ALTERA_SPI_STATUS_RRDY_MSK
))
;
debug
(
"%s: tx:%x "
,
__func__
,
data
);
d
=
readl
(
altspi
->
base
+
ALTERA_SPI_RXDATA
);
writel
(
data
,
&
altspi
->
regs
->
txdata
);
start
=
get_timer
(
0
);
while
(
1
)
{
reg
=
readl
(
&
altspi
->
regs
->
status
);
if
(
reg
&
ALTERA_SPI_STATUS_RRDY_MSK
)
break
;
if
(
get_timer
(
start
)
>
(
CONFIG_SYS_HZ
/
1000
))
{
printf
(
"%s: Transmission timed out!
\n
"
,
__func__
);
goto
done
;
}
}
data
=
readl
(
&
altspi
->
regs
->
rxdata
);
if
(
rxp
)
if
(
rxp
)
*
rxp
++
=
d
;
*
rxp
++
=
data
&
0xff
;
debug
(
"rx:%x
\n
"
,
d
);
debug
(
"rx:%x
\n
"
,
data
);
}
}
done:
done:
if
(
flags
&
SPI_XFER_END
)
if
(
flags
&
SPI_XFER_END
)
spi_cs_deactivate
(
slave
);
spi_cs_deactivate
(
slave
);
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/mxc_spi.c
+
21
−
19
View file @
130aec77
...
@@ -49,6 +49,8 @@ struct mxc_spi_slave {
...
@@ -49,6 +49,8 @@ struct mxc_spi_slave {
#endif
#endif
int
gpio
;
int
gpio
;
int
ss_pol
;
int
ss_pol
;
unsigned
int
max_hz
;
unsigned
int
mode
;
};
};
static
inline
struct
mxc_spi_slave
*
to_mxc_spi_slave
(
struct
spi_slave
*
slave
)
static
inline
struct
mxc_spi_slave
*
to_mxc_spi_slave
(
struct
spi_slave
*
slave
)
...
@@ -83,12 +85,13 @@ u32 get_cspi_div(u32 div)
...
@@ -83,12 +85,13 @@ u32 get_cspi_div(u32 div)
}
}
#ifdef MXC_CSPI
#ifdef MXC_CSPI
static
s32
spi_cfg_mxc
(
struct
mxc_spi_slave
*
mxcs
,
unsigned
int
cs
,
static
s32
spi_cfg_mxc
(
struct
mxc_spi_slave
*
mxcs
,
unsigned
int
cs
)
unsigned
int
max_hz
,
unsigned
int
mode
)
{
{
unsigned
int
ctrl_reg
;
unsigned
int
ctrl_reg
;
u32
clk_src
;
u32
clk_src
;
u32
div
;
u32
div
;
unsigned
int
max_hz
=
mxcs
->
max_hz
;
unsigned
int
mode
=
mxcs
->
mode
;
clk_src
=
mxc_get_clock
(
MXC_CSPI_CLK
);
clk_src
=
mxc_get_clock
(
MXC_CSPI_CLK
);
...
@@ -120,19 +123,15 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
...
@@ -120,19 +123,15 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
#endif
#endif
#ifdef MXC_ECSPI
#ifdef MXC_ECSPI
static
s32
spi_cfg_mxc
(
struct
mxc_spi_slave
*
mxcs
,
unsigned
int
cs
,
static
s32
spi_cfg_mxc
(
struct
mxc_spi_slave
*
mxcs
,
unsigned
int
cs
)
unsigned
int
max_hz
,
unsigned
int
mode
)
{
{
u32
clk_src
=
mxc_get_clock
(
MXC_CSPI_CLK
);
u32
clk_src
=
mxc_get_clock
(
MXC_CSPI_CLK
);
s32
reg_ctrl
,
reg_config
;
s32
reg_ctrl
,
reg_config
;
u32
ss_pol
=
0
,
sclkpol
=
0
,
sclkpha
=
0
,
sclkctl
=
0
;
u32
ss_pol
=
0
,
sclkpol
=
0
,
sclkpha
=
0
,
sclkctl
=
0
;
u32
pre_div
=
0
,
post_div
=
0
;
u32
pre_div
=
0
,
post_div
=
0
;
struct
cspi_regs
*
regs
=
(
struct
cspi_regs
*
)
mxcs
->
base
;
struct
cspi_regs
*
regs
=
(
struct
cspi_regs
*
)
mxcs
->
base
;
unsigned
int
max_hz
=
mxcs
->
max_hz
;
if
(
max_hz
==
0
)
{
unsigned
int
mode
=
mxcs
->
mode
;
printf
(
"Error: desired clock is 0
\n
"
);
return
-
1
;
}
/*
/*
* Reset SPI and set all CSs to master mode, if toggling
* Reset SPI and set all CSs to master mode, if toggling
...
@@ -169,9 +168,6 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
...
@@ -169,9 +168,6 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
reg_ctrl
=
(
reg_ctrl
&
~
MXC_CSPICTRL_POSTDIV
(
0x0F
))
|
reg_ctrl
=
(
reg_ctrl
&
~
MXC_CSPICTRL_POSTDIV
(
0x0F
))
|
MXC_CSPICTRL_POSTDIV
(
post_div
);
MXC_CSPICTRL_POSTDIV
(
post_div
);
/* We need to disable SPI before changing registers */
reg_ctrl
&=
~
MXC_CSPICTRL_EN
;
if
(
mode
&
SPI_CS_HIGH
)
if
(
mode
&
SPI_CS_HIGH
)
ss_pol
=
1
;
ss_pol
=
1
;
...
@@ -412,6 +408,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
...
@@ -412,6 +408,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if
(
bus
>=
ARRAY_SIZE
(
spi_bases
))
if
(
bus
>=
ARRAY_SIZE
(
spi_bases
))
return
NULL
;
return
NULL
;
if
(
max_hz
==
0
)
{
printf
(
"Error: desired clock is 0
\n
"
);
return
NULL
;
}
mxcs
=
spi_alloc_slave
(
struct
mxc_spi_slave
,
bus
,
cs
);
mxcs
=
spi_alloc_slave
(
struct
mxc_spi_slave
,
bus
,
cs
);
if
(
!
mxcs
)
{
if
(
!
mxcs
)
{
puts
(
"mxc_spi: SPI Slave not allocated !
\n
"
);
puts
(
"mxc_spi: SPI Slave not allocated !
\n
"
);
...
@@ -427,13 +428,9 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
...
@@ -427,13 +428,9 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
}
}
mxcs
->
base
=
spi_bases
[
bus
];
mxcs
->
base
=
spi_bases
[
bus
];
mxcs
->
max_hz
=
max_hz
;
mxcs
->
mode
=
mode
;
ret
=
spi_cfg_mxc
(
mxcs
,
cs
,
max_hz
,
mode
);
if
(
ret
)
{
printf
(
"mxc_spi: cannot setup SPI controller
\n
"
);
free
(
mxcs
);
return
NULL
;
}
return
&
mxcs
->
slave
;
return
&
mxcs
->
slave
;
}
}
...
@@ -446,12 +443,17 @@ void spi_free_slave(struct spi_slave *slave)
...
@@ -446,12 +443,17 @@ void spi_free_slave(struct spi_slave *slave)
int
spi_claim_bus
(
struct
spi_slave
*
slave
)
int
spi_claim_bus
(
struct
spi_slave
*
slave
)
{
{
int
ret
;
struct
mxc_spi_slave
*
mxcs
=
to_mxc_spi_slave
(
slave
);
struct
mxc_spi_slave
*
mxcs
=
to_mxc_spi_slave
(
slave
);
struct
cspi_regs
*
regs
=
(
struct
cspi_regs
*
)
mxcs
->
base
;
struct
cspi_regs
*
regs
=
(
struct
cspi_regs
*
)
mxcs
->
base
;
reg_write
(
&
regs
->
rxdata
,
1
);
reg_write
(
&
regs
->
rxdata
,
1
);
udelay
(
1
);
udelay
(
1
);
reg_write
(
&
regs
->
ctrl
,
mxcs
->
ctrl_reg
);
ret
=
spi_cfg_mxc
(
mxcs
,
slave
->
cs
);
if
(
ret
)
{
printf
(
"mxc_spi: cannot setup SPI controller
\n
"
);
return
ret
;
}
reg_write
(
&
regs
->
period
,
MXC_CSPIPERIOD_32KHZ
);
reg_write
(
&
regs
->
period
,
MXC_CSPIPERIOD_32KHZ
);
reg_write
(
&
regs
->
intr
,
0
);
reg_write
(
&
regs
->
intr
,
0
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment