Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Sunxi Tools
Commits
7cc37c88
Unverified
Commit
7cc37c88
authored
Sep 29, 2020
by
Chen-Yu Tsai
Committed by
GitHub
Sep 29, 2020
Browse files
Merge pull request #140 from Icenowy/v831
V831 SoC support
parents
e334ccf5
eac43cf7
Changes
3
Show whitespace changes
Inline
Side-by-side
fel-spiflash.c
View file @
7cc37c88
...
...
@@ -81,6 +81,10 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val);
#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0)
#define SUN6I_SPI0_RST (1 << 20)
#define H6_CCM_SPI0_CLK (0x03001000 + 0x940)
#define H6_CCM_SPI_BGR (0x03001000 + 0x96C)
#define H6_CCM_SPI0_GATE_RESET (1 << 0 | 1 << 16)
#define SUNXI_GPC_SPI0 (3)
#define SUN50I_GPC_SPI0 (4)
...
...
@@ -92,35 +96,61 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val);
#define SUN6I_TCR_XCH (1 << 31)
#define SUN4I_SPI0_CCTL (
0x01C05000
+ 0x1C)
#define SUN4I_SPI0_CTL (
0x01C05000
+ 0x08)
#define SUN4I_SPI0_RX (
0x01C05000
+ 0x00)
#define SUN4I_SPI0_TX (
0x01C05000
+ 0x04)
#define SUN4I_SPI0_FIFO_STA (
0x01C05000
+ 0x28)
#define SUN4I_SPI0_BC (
0x01C05000
+ 0x20)
#define SUN4I_SPI0_TC (
0x01C05000
+ 0x24)
#define SUN6I_SPI0_CCTL (
0x01C68000
+ 0x24)
#define SUN6I_SPI0_GCR (
0x01C68000
+ 0x04)
#define SUN6I_SPI0_TCR (
0x01C68000
+ 0x08)
#define SUN6I_SPI0_FIFO_STA (
0x01C68000
+ 0x1C)
#define SUN6I_SPI0_MBC (
0x01C68000
+ 0x30)
#define SUN6I_SPI0_MTC (
0x01C68000
+ 0x34)
#define SUN6I_SPI0_BCC (
0x01C68000
+ 0x38)
#define SUN6I_SPI0_TXD (
0x01C68000
+ 0x200)
#define SUN6I_SPI0_RXD (
0x01C68000
+ 0x300)
#define SUN4I_SPI0_CCTL (
spi_base(dev)
+ 0x1C)
#define SUN4I_SPI0_CTL (
spi_base(dev)
+ 0x08)
#define SUN4I_SPI0_RX (
spi_base(dev)
+ 0x00)
#define SUN4I_SPI0_TX (
spi_base(dev)
+ 0x04)
#define SUN4I_SPI0_FIFO_STA (
spi_base(dev)
+ 0x28)
#define SUN4I_SPI0_BC (
spi_base(dev)
+ 0x20)
#define SUN4I_SPI0_TC (
spi_base(dev)
+ 0x24)
#define SUN6I_SPI0_CCTL (
spi_base(dev)
+ 0x24)
#define SUN6I_SPI0_GCR (
spi_base(dev)
+ 0x04)
#define SUN6I_SPI0_TCR (
spi_base(dev)
+ 0x08)
#define SUN6I_SPI0_FIFO_STA (
spi_base(dev)
+ 0x1C)
#define SUN6I_SPI0_MBC (
spi_base(dev)
+ 0x30)
#define SUN6I_SPI0_MTC (
spi_base(dev)
+ 0x34)
#define SUN6I_SPI0_BCC (
spi_base(dev)
+ 0x38)
#define SUN6I_SPI0_TXD (
spi_base(dev)
+ 0x200)
#define SUN6I_SPI0_RXD (
spi_base(dev)
+ 0x300)
#define CCM_SPI0_CLK_DIV_BY_2 (0x1000)
#define CCM_SPI0_CLK_DIV_BY_4 (0x1001)
#define CCM_SPI0_CLK_DIV_BY_6 (0x1002)
static
uint32_t
gpio_base
(
feldev_handle
*
dev
)
{
soc_info_t
*
soc_info
=
dev
->
soc_info
;
switch
(
soc_info
->
soc_id
)
{
case
0x1817
:
/* V831 */
return
0x0300B000
;
default:
return
0x01C28000
;
}
}
static
uint32_t
spi_base
(
feldev_handle
*
dev
)
{
soc_info_t
*
soc_info
=
dev
->
soc_info
;
switch
(
soc_info
->
soc_id
)
{
case
0x1623
:
/* A10 */
case
0x1625
:
/* A13 */
case
0x1651
:
/* A20 */
return
0x01C05000
;
case
0x1817
:
/* V831 */
return
0x05010000
;
default:
return
0x01C68000
;
}
}
/*
* Configure pin function on a GPIO port
*/
static
void
gpio_set_cfgpin
(
feldev_handle
*
dev
,
int
port_num
,
int
pin_num
,
int
val
)
{
uint32_t
port_base
=
0x01C20800
+
port_num
*
0x24
;
uint32_t
port_base
=
gpio_base
(
dev
)
+
port_num
*
0x24
;
uint32_t
cfg_reg
=
port_base
+
4
*
(
pin_num
/
8
);
uint32_t
pin_idx
=
pin_num
%
8
;
uint32_t
x
=
readl
(
cfg_reg
);
...
...
@@ -142,6 +172,17 @@ static bool spi_is_sun6i(feldev_handle *dev)
}
}
static
bool
soc_is_h6_style
(
feldev_handle
*
dev
)
{
soc_info_t
*
soc_info
=
dev
->
soc_info
;
switch
(
soc_info
->
soc_id
)
{
case
0x1817
:
/* V831 */
return
true
;
default:
return
false
;
}
}
/*
* Init the SPI0 controller and setup pins muxing.
*/
...
...
@@ -179,27 +220,46 @@ static bool spi0_init(feldev_handle *dev)
gpio_set_cfgpin
(
dev
,
PC
,
2
,
SUN50I_GPC_SPI0
);
gpio_set_cfgpin
(
dev
,
PC
,
3
,
SUN50I_GPC_SPI0
);
break
;
case
0x1817
:
/* Allwinner V831 */
gpio_set_cfgpin
(
dev
,
PC
,
0
,
SUN50I_GPC_SPI0
);
gpio_set_cfgpin
(
dev
,
PC
,
1
,
SUN50I_GPC_SPI0
);
gpio_set_cfgpin
(
dev
,
PC
,
2
,
SUN50I_GPC_SPI0
);
gpio_set_cfgpin
(
dev
,
PC
,
3
,
SUN50I_GPC_SPI0
);
break
;
default:
/* Unknown/Unsupported SoC */
printf
(
"SPI support not implemented yet for %x (%s)!
\n
"
,
soc_info
->
soc_id
,
soc_info
->
name
);
return
false
;
}
if
(
soc_is_h6_style
(
dev
))
{
reg_val
=
readl
(
H6_CCM_SPI_BGR
);
reg_val
|=
H6_CCM_SPI0_GATE_RESET
;
writel
(
reg_val
,
H6_CCM_SPI_BGR
);
/* 24MHz from OSC24M */
writel
((
1
<<
31
),
H6_CCM_SPI0_CLK
);
}
else
{
reg_val
=
readl
(
CCM_AHB_GATING0
);
reg_val
|=
CCM_AHB_GATE_SPI0
;
writel
(
reg_val
,
CCM_AHB_GATING0
);
if
(
spi_is_sun6i
(
dev
))
{
/* Deassert SPI0 reset */
reg_val
=
readl
(
SUN6I_BUS_SOFT_RST_REG0
);
reg_val
|=
SUN6I_SPI0_RST
;
writel
(
reg_val
,
SUN6I_BUS_SOFT_RST_REG0
);
}
/* 24MHz from OSC24M */
writel
((
1
<<
31
),
CCM_SPI0_CLK
);
}
/* divide by 4 */
writel
(
CCM_SPI0_CLK_DIV_BY_4
,
spi_is_sun6i
(
dev
)
?
SUN6I_SPI0_CCTL
:
SUN4I_SPI0_CCTL
);
if
(
spi_is_sun6i
(
dev
))
{
/* Deassert SPI0 reset */
reg_val
=
readl
(
SUN6I_BUS_SOFT_RST_REG0
);
reg_val
|=
SUN6I_SPI0_RST
;
writel
(
reg_val
,
SUN6I_BUS_SOFT_RST_REG0
);
/* Enable SPI in the master mode and do a soft reset */
reg_val
=
readl
(
SUN6I_SPI0_GCR
);
reg_val
|=
(
1
<<
31
)
|
3
;
...
...
soc_info.c
View file @
7cc37c88
...
...
@@ -110,6 +110,21 @@ sram_swap_buffers h6_sram_swap_buffers[] = {
{
.
size
=
0
}
/* End of the table */
};
/*
* V831 has 96KiB SRAM A1 at 0x20000 where the SPL has to be loaded to.
* SRAM C is continuous with SRAM A1, and both SRAMs are tried to be used
* by BROM. Memory space is allocated both from the start of SRAM A1 and
* the end of SRAM C.
* The start of SRAM C is in between these areas, and can serve as backup
* of IRQ stack, which is inside the first 32KiB of SRAM A1. Other areas
* that are critical on older SoCs seem to be already in SRAM C, which
* we do not need to preserve.
*/
sram_swap_buffers
v831_sram_swap_buffers
[]
=
{
{
.
buf1
=
0x21000
,
.
buf2
=
0x38000
,
.
size
=
0x1000
},
{
.
size
=
0
}
/* End of the table */
};
const
watchdog_info
wd_a10_compat
=
{
.
reg_mode
=
0x01C20C94
,
.
reg_mode_value
=
3
,
...
...
@@ -250,6 +265,15 @@ soc_info_t soc_info_table[] = {
.
rvbar_reg
=
0x09010040
,
/* Check L.NOP in the OpenRISC reset vector */
.
needs_smc_workaround_if_zero_word_at_addr
=
0x100004
,
},{
.
soc_id
=
0x1817
,
/* Allwinner V831 */
.
name
=
"V831"
,
.
spl_addr
=
0x20000
,
.
scratch_addr
=
0x21000
,
.
thunk_addr
=
0x2A200
,
.
thunk_size
=
0x200
,
.
swap_buffers
=
v831_sram_swap_buffers
,
.
sid_base
=
0x03006000
,
.
sid_offset
=
0x200
,
},{
.
swap_buffers
=
NULL
/* End of the table */
}
...
...
uart0-helloworld-sdboot.c
View file @
7cc37c88
...
...
@@ -144,6 +144,7 @@ enum sunxi_gpio_number {
#define SUN6I_GPH_UART0 (2)
#define SUN8I_H3_GPA_UART0 (2)
#define SUN8I_V3S_GPB_UART0 (3)
#define SUN8I_V831_GPH_UART0 (5)
#define SUN50I_H5_GPA_UART0 (2)
#define SUN50I_H6_GPH_UART0 (2)
#define SUN50I_A64_GPB_UART0 (4)
...
...
@@ -307,6 +308,7 @@ void soc_detection_init(void)
#define soc_is_h6() (soc_id == 0x1728)
#define soc_is_r40() (soc_id == 0x1701)
#define soc_is_v3s() (soc_id == 0x1681)
#define soc_is_v831() (soc_id == 0x1817)
/* A10s and A13 share the same ID, so we need a little more effort on those */
...
...
@@ -382,7 +384,7 @@ void clock_init_uart_h6(void)
void
clock_init_uart
(
void
)
{
if
(
soc_is_h6
())
if
(
soc_is_h6
()
||
soc_is_v831
()
)
clock_init_uart_h6
();
else
clock_init_uart_legacy
();
...
...
@@ -436,6 +438,10 @@ void gpio_init(void)
sunxi_gpio_set_cfgpin
(
SUNXI_GPB
(
8
),
SUN8I_V3S_GPB_UART0
);
sunxi_gpio_set_cfgpin
(
SUNXI_GPB
(
9
),
SUN8I_V3S_GPB_UART0
);
sunxi_gpio_set_pull
(
SUNXI_GPB
(
9
),
SUNXI_GPIO_PULL_UP
);
}
else
if
(
soc_is_v831
())
{
sunxi_gpio_set_cfgpin
(
SUNXI_GPH
(
9
),
SUN8I_V831_GPH_UART0
);
sunxi_gpio_set_cfgpin
(
SUNXI_GPH
(
10
),
SUN8I_V831_GPH_UART0
);
sunxi_gpio_set_pull
(
SUNXI_GPH
(
10
),
SUNXI_GPIO_PULL_UP
);
}
else
{
/* Unknown SoC */
while
(
1
)
{}
...
...
@@ -512,7 +518,7 @@ int get_boot_device(void)
u32
*
spl_signature
=
(
void
*
)
0x4
;
if
(
soc_is_a64
()
||
soc_is_a80
()
||
soc_is_h5
())
spl_signature
=
(
void
*
)
0x10004
;
if
(
soc_is_h6
())
if
(
soc_is_h6
()
||
soc_is_v831
()
)
spl_signature
=
(
void
*
)
0x20004
;
/* Check the eGON.BT0 magic in the SPL header */
...
...
@@ -530,7 +536,7 @@ int get_boot_device(void)
void
bases_init
(
void
)
{
if
(
soc_is_h6
())
{
if
(
soc_is_h6
()
||
soc_is_v831
()
)
{
pio_base
=
H6_PIO_BASE
;
uart0_base
=
H6_UART0_BASE
;
}
else
{
...
...
@@ -571,6 +577,8 @@ int main(void)
uart0_puts
(
"Allwinner R40!
\n
"
);
else
if
(
soc_is_v3s
())
uart0_puts
(
"Allwinner V3s!
\n
"
);
else
if
(
soc_is_v831
())
uart0_puts
(
"Allwinner V831!
\n
"
);
else
uart0_puts
(
"unknown Allwinner SoC!
\n
"
);
...
...
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