This concludes support for the Allwinner A133 SoC, the biggest chunk of
which is the DRAM init code. Also includes support for a devboard using
this SoC, the DT of which  got added to the kernel only recently. The
same is true for another H618 devboard, so add the respective devconfig
as well.

Gitlab CI passed, and I booted that briefly on those two boards.
This commit is contained in:
Tom Rini
2025-06-25 08:07:16 -06:00
22 changed files with 2263 additions and 16 deletions

View File

@@ -41,7 +41,7 @@ ENTRY(return_to_fel)
str w2, [x1]
ldr w0, =0xfa50392f // CPU hotplug magic
#ifdef CONFIG_MACH_SUN50I_H616
#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133)
ldr w2, =(SUNXI_R_CPUCFG_BASE + 0x1c0)
str w0, [x2], #0x4
#elif CONFIG_MACH_SUN50I_H6

View File

@@ -90,6 +90,13 @@
#define CCM_PLL6_DEFAULT 0xe8216300
#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002
#define CCM_APB1_DEFAULT 0x03000102
#elif CONFIG_MACH_SUN50I_A133 /* A133 */
#define CCM_PLL6_DEFAULT 0xb8003100
#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002
#define CCM_AHB3_DEFAULT 0x03000002
#define CCM_APB1_DEFAULT 0x03000102
#endif
/* apb2 bit field */

View File

@@ -29,6 +29,10 @@
#define SUNXI_DRAM_COM_BASE 0x047FA000
#define SUNXI_DRAM_CTL0_BASE 0x047FB000
#define SUNXI_DRAM_PHY0_BASE 0x04800000
#elif CONFIG_MACH_SUN50I_A133
#define SUNXI_DRAM_COM_BASE 0x04810000
#define SUNXI_DRAM_CTL0_BASE 0x04820000
#define SUNXI_DRAM_PHY0_BASE 0x04830000
#endif
#define SUNXI_TWI0_BASE 0x05002000

View File

@@ -31,6 +31,8 @@
#include <asm/arch/dram_sun50i_h6.h>
#elif defined(CONFIG_MACH_SUN50I_H616)
#include <asm/arch/dram_sun50i_h616.h>
#elif defined(CONFIG_DRAM_SUN50I_A133)
#include <asm/arch/dram_sun50i_a133.h>
#elif defined(CONFIG_MACH_SUNIV)
#include <asm/arch/dram_suniv.h>
#else

View File

@@ -0,0 +1,230 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* A133 dram controller register and constant defines
*
* (C) Copyright 2024 MasterR3C0RD <masterr3c0rd@epochal.quest>
*/
#ifndef _SUNXI_DRAM_SUN50I_A133_H
#define _SUNXI_DRAM_SUN50I_A133_H
#include <linux/bitops.h>
enum sunxi_dram_type {
SUNXI_DRAM_TYPE_DDR3 = 3,
SUNXI_DRAM_TYPE_DDR4,
SUNXI_DRAM_TYPE_LPDDR3 = 7,
SUNXI_DRAM_TYPE_LPDDR4
};
static inline int ns_to_t(int nanoseconds)
{
const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
}
/* MBUS part is largely the same as in H6, except for one special register */
#define MCTL_COM_UNK_008 0x008
/* NOTE: This register has the same importance as mctl_ctl->clken in H616 */
#define MCTL_COM_MAER0 0x020
/*
* Controller registers seems to be the same or at least very similar
* to those in H6.
*/
struct sunxi_mctl_ctl_reg {
u32 mstr; /* 0x000 */
u32 statr; /* 0x004 unused */
u32 mstr1; /* 0x008 unused */
u32 clken; /* 0x00c */
u32 mrctrl0; /* 0x010 unused */
u32 mrctrl1; /* 0x014 unused */
u32 mrstatr; /* 0x018 unused */
u32 mrctrl2; /* 0x01c unused */
u32 derateen; /* 0x020 unused */
u32 derateint; /* 0x024 unused */
u8 reserved_0x028[8]; /* 0x028 */
u32 pwrctl; /* 0x030 unused */
u32 pwrtmg; /* 0x034 unused */
u32 hwlpctl; /* 0x038 unused */
u8 reserved_0x03c[20]; /* 0x03c */
u32 rfshctl0; /* 0x050 unused */
u32 rfshctl1; /* 0x054 unused */
u8 reserved_0x058[8]; /* 0x05c */
u32 rfshctl3; /* 0x060 */
u32 rfshtmg; /* 0x064 */
u8 reserved_0x068[104]; /* 0x068 */
u32 init[8]; /* 0x0d0 */
u32 dimmctl; /* 0x0f0 unused */
u32 rankctl; /* 0x0f4 */
u8 reserved_0x0f8[8]; /* 0x0f8 */
u32 dramtmg[17]; /* 0x100 */
u8 reserved_0x144[60]; /* 0x144 */
u32 zqctl[3]; /* 0x180 */
u32 zqstat; /* 0x18c unused */
u32 dfitmg0; /* 0x190 */
u32 dfitmg1; /* 0x194 */
u32 dfilpcfg[2]; /* 0x198 unused */
u32 dfiupd[3]; /* 0x1a0 */
u32 reserved_0x1ac; /* 0x1ac */
u32 dfimisc; /* 0x1b0 */
u32 dfitmg2; /* 0x1b4 unused */
u32 dfitmg3; /* 0x1b8 unused */
u32 dfistat; /* 0x1bc */
u32 dbictl; /* 0x1c0 */
u8 reserved_0x1c4[60]; /* 0x1c4 */
u32 addrmap[12]; /* 0x200 */
u8 reserved_0x230[16]; /* 0x230 */
u32 odtcfg; /* 0x240 */
u32 odtmap; /* 0x244 */
u8 reserved_0x248[8]; /* 0x248 */
u32 sched[2]; /* 0x250 */
u8 reserved_0x258[180]; /* 0x258 */
u32 dbgcmd; /* 0x30c unused */
u32 dbgstat; /* 0x310 unused */
u8 reserved_0x314[12]; /* 0x314 */
u32 swctl; /* 0x320 */
u32 swstat; /* 0x324 */
u8 reserved_0x328[7768]; /* 0x328 */
u32 unk_0x2180; /* 0x2180 */
u8 reserved_0x2184[188]; /* 0x2184 */
u32 unk_0x2240; /* 0x2240 */
u8 reserved_0x2244[3900]; /* 0x2244 */
u32 unk_0x3180; /* 0x3180 */
u8 reserved_0x3184[188]; /* 0x3184 */
u32 unk_0x3240; /* 0x3240 */
u8 reserved_0x3244[3900]; /* 0x3244 */
u32 unk_0x4180; /* 0x4180 */
u8 reserved_0x4184[188]; /* 0x4184 */
u32 unk_0x4240; /* 0x4240 */
};
check_member(sunxi_mctl_ctl_reg, swstat, 0x324);
check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
#define MSTR_DEVICETYPE_DDR3 BIT(0)
#define MSTR_DEVICETYPE_LPDDR2 BIT(2)
#define MSTR_DEVICETYPE_LPDDR3 BIT(3)
#define MSTR_DEVICETYPE_DDR4 BIT(4)
#define MSTR_DEVICETYPE_LPDDR4 BIT(5)
#define MSTR_DEVICETYPE_MASK GENMASK(5, 0)
#define MSTR_GEARDOWNMODE BIT(0) /* Same as MSTR_DEVICETYPE_DDR3, only used for DDR4 */
#define MSTR_2TMODE BIT(10)
#define MSTR_BUSWIDTH_FULL (0 << 12)
#define MSTR_BUSWIDTH_HALF (1 << 12)
#define MSTR_ACTIVE_RANKS(x) (((x == 1) ? 3 : 1) << 24)
#define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16)
#define MSTR_DEVICECONFIG_X32 (3 << 30)
#define TPR10_CA_BIT_DELAY BIT(16)
#define TPR10_DX_BIT_DELAY0 BIT(17)
#define TPR10_DX_BIT_DELAY1 BIT(18)
#define TPR10_WRITE_LEVELING BIT(20)
#define TPR10_READ_CALIBRATION BIT(21)
#define TPR10_READ_TRAINING BIT(22)
#define TPR10_WRITE_TRAINING BIT(23)
/* MRCTRL constants */
#define MRCTRL0_MR_RANKS_ALL (3 << 4)
#define MRCTRL0_MR_ADDR(x) (x << 12)
#define MRCTRL0_MR_WR BIT(31)
#define MRCTRL1_MR_ADDR(x) (x << 8)
#define MRCTRL1_MR_DATA(x) (x)
/* ADDRMAP constants */
#define ADDRMAP_DISABLED_3F_B(b) (0x3f + b)
#define ADDRMAP_DISABLED_1F_B(b) (0x1f + b)
#define ADDRMAP_DISABLED_0F_B(b) (0x0f + b)
#define _ADDRMAP_VALUE(a,x,b) (((a) - b) << (x * 8))
/*
* Bx = internal base
* The selected HIF address bit for each address bit is determined
* by adding the internal base to the value of each field
* */
#define ADDRMAP0_CS0_B6(v) _ADDRMAP_VALUE(v, 0, 6)
#define ADDRMAP1_BANK0_B2(v) _ADDRMAP_VALUE(v, 0, 2)
#define ADDRMAP1_BANK1_B3(v) _ADDRMAP_VALUE(v, 1, 3)
#define ADDRMAP1_BANK2_B4(v) _ADDRMAP_VALUE(v, 2, 4)
#define ADDRMAP2_COL2_B2(v) _ADDRMAP_VALUE(v, 0, 2)
#define ADDRMAP2_COL3_B3(v) _ADDRMAP_VALUE(v, 1, 3)
#define ADDRMAP2_COL4_B4(v) _ADDRMAP_VALUE(v, 2, 4)
#define ADDRMAP2_COL5_B5(v) _ADDRMAP_VALUE(v, 3, 5)
#define ADDRMAP3_COL6_B6(v) _ADDRMAP_VALUE(v, 0, 6)
#define ADDRMAP3_COL7_B7(v) _ADDRMAP_VALUE(v, 1, 7)
#define ADDRMAP3_COL8_B8(v) _ADDRMAP_VALUE(v, 2, 8)
#define ADDRMAP3_COL9_B9(v) _ADDRMAP_VALUE(v, 3, 9)
#define ADDRMAP4_COL10_B10(v) _ADDRMAP_VALUE(v, 0, 10)
#define ADDRMAP4_COL11_B11(v) _ADDRMAP_VALUE(v, 1, 11)
#define ADDRMAP5_ROW0_B6(v) _ADDRMAP_VALUE(v, 0, 6)
#define ADDRMAP5_ROW1_B7(v) _ADDRMAP_VALUE(v, 1, 7)
#define ADDRMAP5_ROW2_10_B8(v) _ADDRMAP_VALUE(v, 2, 8)
#define ADDRMAP5_ROW11_B17(v) _ADDRMAP_VALUE(v, 3, 17)
#define ADDRMAP6_ROW12_B18(v) _ADDRMAP_VALUE(v, 0, 18)
#define ADDRMAP6_ROW13_B19(v) _ADDRMAP_VALUE(v, 1, 19)
#define ADDRMAP6_ROW14_B20(v) _ADDRMAP_VALUE(v, 2, 20)
#define ADDRMAP6_ROW15_B21(v) _ADDRMAP_VALUE(v, 3, 21)
#define ADDRMAP7_ROW16_B22(v) _ADDRMAP_VALUE(v, 0, 22)
#define ADDRMAP7_ROW17_B23(v) _ADDRMAP_VALUE(v, 1, 23)
#define ADDRMAP8_BG0_B2(v) _ADDRMAP_VALUE(v, 0, 2)
#define ADDRMAP8_BG1_B3(v) _ADDRMAP_VALUE(v, 1, 3)
/* These are only used if ADDRMAP5_ROW_BITS_2_10 = ADDRMAP_DISABLED_0F */
#define ADDRMAP9_ROW2_B8(v) _ADDRMAP_VALUE(v, 0, 8)
#define ADDRMAP9_ROW3_B9(v) _ADDRMAP_VALUE(v, 1, 9)
#define ADDRMAP9_ROW4_B10(v) _ADDRMAP_VALUE(v, 2, 10)
#define ADDRMAP9_ROW5_B11(v) _ADDRMAP_VALUE(v, 3, 11)
#define ADDRMAP10_ROW6_B12(v) _ADDRMAP_VALUE(v, 0, 12)
#define ADDRMAP10_ROW7_B13(v) _ADDRMAP_VALUE(v, 1, 13)
#define ADDRMAP10_ROW8_B14(v) _ADDRMAP_VALUE(v, 2, 14)
#define ADDRMAP10_ROW9_B15(v) _ADDRMAP_VALUE(v, 3, 15)
#define ADDRMAP11_ROW10_B16(v) _ADDRMAP_VALUE(v, 0, 16)
struct dram_para {
uint32_t clk;
enum sunxi_dram_type type;
uint32_t dx_odt;
uint32_t dx_dri;
uint32_t ca_dri;
uint32_t para0;
uint32_t mr11;
uint32_t mr12;
uint32_t mr13;
uint32_t mr14;
uint32_t tpr1;
uint32_t tpr2;
uint32_t tpr3;
uint32_t tpr6;
uint32_t tpr10;
uint32_t tpr11;
uint32_t tpr12;
uint32_t tpr13;
uint32_t tpr14;
};
void mctl_set_timing_params(const struct dram_para *para);
struct dram_config {
u8 cols; /* Column bits */
u8 rows; /* Row bits */
u8 ranks; /* Rank bits (different from H616!) */
u8 banks; /* Bank bits */
u8 bankgrps; /* Bank group bits */
u8 bus_full_width; /* 1 = x32, 0 = x16 */
};
#endif /* _SUNXI_DRAM_SUN50I_A133_H */

View File

@@ -51,7 +51,13 @@ config DRAM_SUN50I_H616
Select this dram controller driver for some sun50i platforms,
like H616.
if DRAM_SUN50I_H616
config DRAM_SUN50I_A133
bool
help
Select this dram controller driver for some sun50i platforms,
like A133.
if DRAM_SUN50I_H616 || DRAM_SUN50I_A133
config DRAM_SUNXI_DX_ODT
hex "DRAM DX ODT parameter"
help
@@ -73,18 +79,64 @@ config DRAM_SUNXI_ODT_EN
help
ODT EN value from vendor DRAM settings.
config DRAM_SUNXI_PARA0
hex "DRAM PARA0 parameter"
depends on DRAM_SUN50I_A133
help
PARA0 value from vendor DRAM settings.
config DRAM_SUNXI_MR11
hex "DRAM MR11 parameter"
depends on DRAM_SUN50I_A133
default 0x0
help
MR11 value from vendor DRAM settings.
config DRAM_SUNXI_MR12
hex "DRAM MR12 parameter"
depends on DRAM_SUN50I_A133
default 0x0
help
MR12 value from vendor DRAM settings.
config DRAM_SUNXI_MR13
hex "DRAM MR13 parameter"
depends on DRAM_SUN50I_A133
default 0x0
help
MR13 value from vendor DRAM settings.
config DRAM_SUNXI_MR14
hex "DRAM MR14 parameter"
depends on DRAM_SUN50I_A133
default 0x0
help
MR14 value from vendor DRAM settings.
config DRAM_SUNXI_TPR0
hex "DRAM TPR0 parameter"
default 0x0
help
TPR0 value from vendor DRAM settings.
config DRAM_SUNXI_TPR1
hex "DRAM TPR1 parameter"
default 0x0
help
TPR1 value from vendor DRAM settings.
config DRAM_SUNXI_TPR2
hex "DRAM TPR2 parameter"
default 0x0
help
TPR2 value from vendor DRAM settings.
config DRAM_SUNXI_TPR3
hex "DRAM TPR3 parameter"
default 0x0
help
TPR3 value from vendor DRAM settings.
config DRAM_SUNXI_TPR6
hex "DRAM TPR6 parameter"
default 0x3300c080
@@ -109,6 +161,20 @@ config DRAM_SUNXI_TPR12
help
TPR12 value from vendor DRAM settings.
config DRAM_SUNXI_TPR13
hex "DRAM TPR13 parameter"
depends on DRAM_SUN50I_A133
default 0x0
help
TPR13 value from vendor DRAM settings.
config DRAM_SUNXI_TPR14
hex "DRAM TPR14 parameter"
depends on DRAM_SUN50I_A133
default 0x0
help
TPR14 value from vendor DRAM settings.
choice
prompt "DRAM PHY pin mapping selection"
default DRAM_SUNXI_PHY_ADDR_MAP_0
@@ -116,7 +182,8 @@ choice
config DRAM_SUNXI_PHY_ADDR_MAP_0
bool "DRAM PHY address map 0"
help
This pin mapping selection should be used by the H313, H616, H618.
This pin mapping selection should be used by the H313, H616, H618,
and A133, R818 SoCs.
config DRAM_SUNXI_PHY_ADDR_MAP_1
bool "DRAM PHY address map 1"
@@ -153,6 +220,7 @@ config SUNXI_SRAM_ADDRESS
config SUNXI_RVBAR_ADDRESS
hex
depends on ARM64
default 0x08100040 if MACH_SUN50I_A133
default 0x09010040 if SUN50I_GEN_H6
default 0x017000a0
---help---
@@ -179,8 +247,8 @@ config SUNXI_RVBAR_ALTERNATIVE
config SUNXI_BL31_BASE
hex
default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5
default 0x00104000 if MACH_SUN50I_H6
default 0x40000000 if MACH_SUN50I_H616
default 0x00104000 if SUN50I_GEN_H6
default 0x0
help
Address where BL31 (TF-A) is loaded, or zero if BL31 is not used.
@@ -262,7 +330,7 @@ config MACH_SUNXI_H3_H5
# TODO: try out A80's 8GiB DRAM space
config SUNXI_DRAM_MAX_SIZE
hex
default 0x100000000 if MACH_SUN50I_H616
default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133
default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6
default 0x80000000
@@ -459,6 +527,10 @@ config MACH_SUN50I_H616
config MACH_SUN50I_A133
bool "sun50i (Allwinner A133)"
select ARM64
select DRAM_SUN50I_A133
select SUN50I_GEN_H6
imply OF_UPSTREAM
endchoice
@@ -497,7 +569,7 @@ config ARM_BOOT_HOOK_RMR
This allows both the SPL and the U-Boot proper to be entered in
either mode and switch to AArch64 if needed.
if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616
if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133
config SUNXI_DRAM_DDR3
bool
@@ -510,6 +582,9 @@ config SUNXI_DRAM_LPDDR3
config SUNXI_DRAM_LPDDR4
bool
config SUNXI_DRAM_DDR4
bool
choice
prompt "DRAM Type and Timing"
default SUNXI_DRAM_DDR3_1333 if !MACH_SUN8I_V3S
@@ -518,6 +593,7 @@ choice
config SUNXI_DRAM_DDR3_1333
bool "DDR3 1333"
select SUNXI_DRAM_DDR3
depends on !DRAM_SUN50I_A133
---help---
This option is the original only supported memory type, which suits
many H3/H5/A64 boards available now.
@@ -525,6 +601,7 @@ config SUNXI_DRAM_DDR3_1333
config SUNXI_DRAM_LPDDR3_STOCK
bool "LPDDR3 with Allwinner stock configuration"
select SUNXI_DRAM_LPDDR3
depends on !DRAM_SUN50I_A133
---help---
This option is the LPDDR3 timing used by the stock boot0 by
Allwinner.
@@ -548,7 +625,7 @@ config SUNXI_DRAM_H6_DDR3_1333
config SUNXI_DRAM_H616_LPDDR3
bool "LPDDR3 DRAM chips on the H616 DRAM controller"
select SUNXI_DRAM_LPDDR3
depends on DRAM_SUN50I_H616
depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133
help
This option is the LPDDR3 timing used by the stock boot0 by
Allwinner.
@@ -556,7 +633,7 @@ config SUNXI_DRAM_H616_LPDDR3
config SUNXI_DRAM_H616_LPDDR4
bool "LPDDR4 DRAM chips on the H616 DRAM controller"
select SUNXI_DRAM_LPDDR4
depends on DRAM_SUN50I_H616
depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133
help
This option is the LPDDR4 timing used by the stock boot0 by
Allwinner.
@@ -564,11 +641,27 @@ config SUNXI_DRAM_H616_LPDDR4
config SUNXI_DRAM_H616_DDR3_1333
bool "DDR3-1333 boot0 timings on the H616 DRAM controller"
select SUNXI_DRAM_DDR3
depends on DRAM_SUN50I_H616
depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133
help
This option is the DDR3 timing used by the boot0 on H616 TV boxes
which use a DDR3-1333 timing.
config SUNXI_DRAM_A133_DDR4
bool "DDR4 boot0 timings on the A133 DRAM controller"
select SUNXI_DRAM_DDR4
depends on DRAM_SUN50I_A133
help
This option is the DDR4 timing used by the boot0 on A133 devices
which use a DDR4 timing.
config SUNXI_DRAM_A133_LPDDR4
bool "LPDDR4 boot0 timings on the A133 DRAM controller"
select SUNXI_DRAM_LPDDR4
depends on DRAM_SUN50I_A133
help
This option is the LPDDR4 timing used by the boot0 on A133 devices
which use an LPDDR4 timing.
config SUNXI_DRAM_DDR2_V3S
bool "DDR2 found in V3s chip"
select SUNXI_DRAM_DDR2
@@ -596,7 +689,7 @@ config DRAM_CLK
MACH_SUN8I_V3S
default 672 if MACH_SUN50I
default 744 if MACH_SUN50I_H6
default 720 if MACH_SUN50I_H616
default 720 if MACH_SUN50I_H616 || MACH_SUN50I_A133
---help---
Set the dram clock speed, valid range 240 - 480 (prior to sun9i),
must be a multiple of 24. For the sun9i (A80), the tested values
@@ -613,7 +706,7 @@ endif
config DRAM_ZQ
int "sunxi dram zq value"
depends on !MACH_SUN50I_H616
depends on !MACH_SUN50I_H616 && !MACH_SUN50I_A133
default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \
MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T
default 127 if MACH_SUN7I
@@ -733,6 +826,7 @@ config SYS_CONFIG_NAME
default "sun50i" if MACH_SUN50I
default "sun50i" if MACH_SUN50I_H6
default "sun50i" if MACH_SUN50I_H616
default "sun50i" if MACH_SUN50I_A133
config SYS_BOARD
default "sunxi"

View File

@@ -45,4 +45,6 @@ obj-$(CONFIG_DRAM_SUN50I_H6) += dram_sun50i_h6.o dram_dw_helpers.o
obj-$(CONFIG_DRAM_SUN50I_H6) += dram_timings/
obj-$(CONFIG_DRAM_SUN50I_H616) += dram_sun50i_h616.o dram_dw_helpers.o
obj-$(CONFIG_DRAM_SUN50I_H616) += dram_timings/
obj-$(CONFIG_DRAM_SUN50I_A133) += dram_sun50i_a133.o
obj-$(CONFIG_DRAM_SUN50I_A133) += dram_timings/
endif

View File

@@ -137,6 +137,10 @@ static int gpio_init(void)
sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_pull(SUNXI_GPH(1), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I_A133)
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T)
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0);

View File

@@ -87,7 +87,8 @@ void clock_set_pll1(unsigned int clk)
/* clk = 24*n/p, p is ignored if clock is >288MHz */
val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2;
val |= CCM_PLL1_CTRL_N(clk / 24000000);
if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
IS_ENABLED(CONFIG_MACH_SUN50I_A133))
val |= CCM_PLL1_OUT_EN;
if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN;

View File

@@ -104,6 +104,8 @@ int print_cpuinfo(void)
puts("CPU: Allwinner H6 (SUN50I)\n");
#elif defined CONFIG_MACH_SUN50I_H616
puts("CPU: Allwinner H616 (SUN50I)\n");
#elif defined CONFIG_MACH_SUN50I_A133
puts("CPU: Allwinner A133 (SUN50I)\n");
#else
#warning Please update cpu_info.c with correct CPU information
puts("CPU: SUNXI Family\n");

File diff suppressed because it is too large Load Diff

View File

@@ -6,3 +6,5 @@ obj-$(CONFIG_SUNXI_DRAM_H6_DDR3_1333) += h6_ddr3_1333.o
obj-$(CONFIG_SUNXI_DRAM_H616_DDR3_1333) += h616_ddr3_1333.o
obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR3) += h616_lpddr3.o
obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR4) += h616_lpddr4_2133.o
obj-$(CONFIG_SUNXI_DRAM_A133_DDR4) += a133_ddr4.o
obj-$(CONFIG_SUNXI_DRAM_A133_LPDDR4) += a133_lpddr4.o

View File

@@ -0,0 +1,80 @@
#include <asm/arch/cpu.h>
#include <asm/arch/dram.h>
void mctl_set_timing_params(const struct dram_para *para)
{
struct sunxi_mctl_ctl_reg *const mctl_ctl =
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
u8 txsr = 4;
u8 tccd = 3;
u8 rd2wr = 5;
u8 tmrd = 4;
u8 tmrw = 0;
u8 wrlat = 5;
u8 rdlat = 7;
u8 wr2pre = 14;
u8 dfi_tphy_wrlat = 6;
u8 dfi_trddata_en = 10;
u8 tfaw = ns_to_t(35);
u8 trrd = max(ns_to_t(8), 2);
u8 txp = max(ns_to_t(6), 2);
u8 tmrd_pda = max(ns_to_t(10), 8);
u8 trp = ns_to_t(15);
u8 trc = ns_to_t(49);
u8 wr2rd_s = max(ns_to_t(3), 1) + 7;
u8 tras_min = ns_to_t(34);
u16 trefi_x32 = ns_to_t(7800) / 32;
u16 trfc_min = ns_to_t(350);
u16 txs_x32 = ns_to_t(360) / 32;
u16 tmod = max(ns_to_t(15), 12);
u8 tcke = max(ns_to_t(5), 2);
u8 tcksrx = max(ns_to_t(10), 3);
u8 txs_abort_x32 = ns_to_t(170) / 32;
u8 tras_max = ns_to_t(70200) / 1024;
u8 rd2pre = (trp < 5 ? 9 - trp : 4);
u8 wr2rd = trrd + 7;
u8 tckesr = tcke + 1;
u8 trcd = trp;
u8 trrd_s = txp;
u8 tcksre = tcksrx;
writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24,
&mctl_ctl->dramtmg[0]);
writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]);
writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24,
&mctl_ctl->dramtmg[2]);
writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]);
writel(trp | trrd << 8 | tccd << 16 | trcd << 24,
&mctl_ctl->dramtmg[4]);
writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24,
&mctl_ctl->dramtmg[5]);
writel((txp + 2) | 0x20 << 16 | 0x20 << 24,
&mctl_ctl->dramtmg[6]);
writel(txs_x32 | 0x10 << 8 | txs_abort_x32 << 16 | txs_abort_x32 << 24,
&mctl_ctl->dramtmg[8]);
writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]);
writel(0xe0c05, &mctl_ctl->dramtmg[10]);
writel(0x440c021c, &mctl_ctl->dramtmg[11]);
writel(tmrd_pda, &mctl_ctl->dramtmg[12]);
writel(0xa100002, &mctl_ctl->dramtmg[13]);
writel(txsr, &mctl_ctl->dramtmg[14]);
clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008);
writel(0x1f20000, &mctl_ctl->init[1]);
clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05);
writel(0, &mctl_ctl->dfimisc);
writel(0x840 << 16 | 0x601, &mctl_ctl->init[3]); /* MR0 / MR1 */
writel(0x8 << 16 | 0x0, &mctl_ctl->init[4]); /* MR2 / MR3 */
writel(0x0 << 16 | 0x400, &mctl_ctl->init[6]); /* MR4 / MR5 */
writel(0x826, &mctl_ctl->init[7]); /* MR6 */
clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
writel((dfi_tphy_wrlat - 1) | 0x2000000 | (dfi_trddata_en - 1) << 16 |
0x808000, &mctl_ctl->dfitmg0);
writel(0x100202, &mctl_ctl->dfitmg1);
writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg);
}

View File

@@ -0,0 +1,102 @@
#include <asm/arch/cpu.h>
#include <asm/arch/dram.h>
void mctl_set_timing_params(const struct dram_para *para)
{
struct sunxi_mctl_ctl_reg *const mctl_ctl =
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
bool tpr13_flag1 = para->tpr13 & BIT(28);
bool tpr13_flag2 = para->tpr13 & BIT(3);
bool tpr13_flag3 = para->tpr13 & BIT(5);
u8 tccd = 4;
u8 tfaw = ns_to_t(40);
u8 trrd = max(ns_to_t(10), 2);
u8 trcd = max(ns_to_t(18), 2);
u8 trc = ns_to_t(65);
u8 txp = max(ns_to_t(8), 2);
u8 trp = ns_to_t(21);
u8 tras_min = ns_to_t(42);
u16 trefi_x32 = ns_to_t(3904) / 32;
u16 trfc_min = ns_to_t(180);
u16 txsr = ns_to_t(190);
u8 tmrw = max(ns_to_t(14), 5);
u8 tmrd = max(ns_to_t(14), 5);
u8 tmod = 12;
u8 tcke = max(ns_to_t(15), 2);
u8 tcksrx = max(ns_to_t(2), 2);
u8 tcksre = max(ns_to_t(5), 2);
u8 tckesr = max(ns_to_t(15), 2);
u8 tras_max = (trefi_x32 * 9) / 32;
u8 txs_x32 = 4;
u8 txsabort_x32 = 4;
u8 wrlat = 5;
u8 wr2rd_s = 8;
u8 trrd_s = 2;
u8 tmrd_pda = 8;
u8 wr2pre = 24;
u8 rd2pre = 4;
u8 wr2rd = 14 + max(ns_to_t(tpr13_flag1 ? 10 : 12), 4);
u8 rd2wr = 17 + ns_to_t(4) - ns_to_t(1);
u8 tphy_wrlat = 5;
u8 rdlat = 10;
u8 trddata_en = 17;
if (tpr13_flag1) {
rdlat = 11;
trddata_en = 19;
}
writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24,
&mctl_ctl->dramtmg[0]);
writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]);
writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24,
&mctl_ctl->dramtmg[2]);
writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]);
writel(trp | trrd << 8 | tccd << 16 | trcd << 24,
&mctl_ctl->dramtmg[4]);
writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24,
&mctl_ctl->dramtmg[5]);
writel((txp + 2) | 0x20 << 16 | 0x20 << 24, &mctl_ctl->dramtmg[6]);
writel(txs_x32 | 0x10 << 8 | txsabort_x32 << 16 | txsabort_x32 << 24,
&mctl_ctl->dramtmg[8]);
writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]);
writel(0xe0c05, &mctl_ctl->dramtmg[10]);
writel(0x440c021c, &mctl_ctl->dramtmg[11]);
writel(tmrd_pda, &mctl_ctl->dramtmg[12]);
writel(0xa100002, &mctl_ctl->dramtmg[13]);
writel(txsr, &mctl_ctl->dramtmg[14]);
clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008);
if (tpr13_flag2)
writel(0x420000, &mctl_ctl->init[1]);
else
writel(0x1f20000, &mctl_ctl->init[1]);
clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05);
writel(0, &mctl_ctl->dfimisc);
writel(0x34 << 16 | 0x1b, &mctl_ctl->init[3]); /* MR1/MR2 */
writel(0x33 << 16, &mctl_ctl->init[4]); /* MR3 */
writel(para->mr11 << 16 | para->mr12, &mctl_ctl->init[6]);
writel(para->tpr1 << 16 | para->mr14, &mctl_ctl->init[7]);
clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
if (!tpr13_flag3) {
tphy_wrlat -= 1;
trddata_en -= 1;
}
writel(tphy_wrlat | trddata_en << 16 | 0x808000 | 0x2000000,
&mctl_ctl->dfitmg0);
writel(0x100202, &mctl_ctl->dfitmg1);
writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg);
}

View File

@@ -296,6 +296,11 @@ M: Adam Sampson <ats@offog.org>
S: Maintained
F: configs/Linksprite_pcDuino3_Nano_defconfig
LIONTRON H-A133L BOARD
M: Andre Przywara <andre.przywara@arm.com>
S: Maintained
F: configs/liontron-h-a133l_defconfig
MARSBOARD-A10 BOARD
M: Aleksei Mamlin <mamlinav@gmail.com>
S: Maintained
@@ -596,6 +601,11 @@ M: Peter Korsgaard <peter@korsgaard.com>
S: Maintained
F: configs/Yones_Toptech_BS1078_V2_defconfig
YUZUKIHD CHAMELEON BOARD
M: Andre Przywara <andre.przywara@arm.com>
S: Maintained
F: configs/yuzukihd-chameleon_defconfig
ZEROPI BOARD
M: Yu-Tung Chang <mtwget@gmail.com>
S: Maintained

View File

@@ -114,7 +114,7 @@ void i2c_init_board(void)
clock_twi_onoff(5, 1);
sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI);
sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI);
#elif CONFIG_MACH_SUN50I_H616
#elif defined(CONFIG_MACH_SUN50I_H616)
clock_twi_onoff(5, 1);
sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI);
sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI);
@@ -435,7 +435,7 @@ static void mmc_pinmux_setup(int sdc)
sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
sunxi_gpio_set_drv(pin, 2);
}
#elif defined(CONFIG_MACH_SUN50I_H616)
#elif defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133)
/* SDC2: PC0-PC1, PC5-PC6, PC8-PC11, PC13-PC16 */
for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(16); pin++) {
if (pin > SUNXI_GPC(1) && pin < SUNXI_GPC(5))

View File

@@ -80,7 +80,7 @@ config SPL_MAX_SIZE
default 0x1b000 if AM33XX && !TI_SECURE_DEVICE
default 0xec00 if OMAP34XX
default 0x10000 if ARCH_MX6 && !MX6_OCRAM_256KB
default 0xbfa0 if MACH_SUN50I_H616
default 0xbfa0 if MACH_SUN50I_H616 || MACH_SUN50I_A133
default 0x7000 if RCAR_GEN3
default 0x5fa0 if SUNXI_SRAM_ADDRESS = 0x0
default 0x7fa0 if ARCH_SUNXI
@@ -423,7 +423,7 @@ config SPL_STACK
default 0x91ffb8 if ARCH_MX6 && !MX6_OCRAM_256KB
default 0x118000 if MACH_SUN50I_H6
default 0x52a00 if MACH_SUN50I_H616
default 0x40000 if MACH_SUN8I_R528
default 0x40000 if MACH_SUN8I_R528 || MACH_SUN50I_A133
default 0x54000 if MACH_SUN50I || MACH_SUN50I_H5
default 0x18000 if MACH_SUN9I
default 0x8000 if ARCH_SUNXI

View File

@@ -0,0 +1,37 @@
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun50i-a133-liontron-h-a133l"
CONFIG_SPL=y
CONFIG_DRAM_SUNXI_DX_ODT=0x7070707
CONFIG_DRAM_SUNXI_DX_DRI=0xd0d0d0d
CONFIG_DRAM_SUNXI_CA_DRI=0xe0e
CONFIG_DRAM_SUNXI_PARA0=0xd0a050c
CONFIG_DRAM_SUNXI_MR11=0x4
CONFIG_DRAM_SUNXI_MR12=0x72
CONFIG_DRAM_SUNXI_MR13=0x0
CONFIG_DRAM_SUNXI_MR14=0x7
CONFIG_DRAM_SUNXI_TPR1=0x26
CONFIG_DRAM_SUNXI_TPR2=0x6060606
CONFIG_DRAM_SUNXI_TPR3=0x84040404
CONFIG_DRAM_SUNXI_TPR6=0x48000000
CONFIG_DRAM_SUNXI_TPR10=0x273333
CONFIG_DRAM_SUNXI_TPR11=0x231d151c
CONFIG_DRAM_SUNXI_TPR12=0x1212110e
CONFIG_DRAM_SUNXI_TPR13=0x7521
CONFIG_DRAM_SUNXI_TPR14=0x2023211f
CONFIG_MACH_SUN50I_A133=y
CONFIG_DRAM_CLK=792
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_SUNXI_DRAM_A133_LPDDR4=y
CONFIG_R_I2C_ENABLE=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL_I2C=y
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x7f
CONFIG_SYS_I2C_SPEED=400000
CONFIG_AXP803_POWER=y
CONFIG_AXP_DCDC5_VOLT=1100
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y

View File

@@ -0,0 +1,30 @@
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun50i-h618-yuzukihd-chameleon"
CONFIG_SPL=y
CONFIG_DRAM_SUNXI_DX_ODT=0x03030303
CONFIG_DRAM_SUNXI_DX_DRI=0x0e0e0e0e
CONFIG_DRAM_SUNXI_CA_DRI=0x1c12
CONFIG_DRAM_SUNXI_ODT_EN=0x1
CONFIG_DRAM_SUNXI_TPR6=0x33808080
CONFIG_DRAM_SUNXI_TPR10=0x002f0006
CONFIG_DRAM_SUNXI_TPR11=0xddddcccc
CONFIG_DRAM_SUNXI_TPR12=0xeddc7564
CONFIG_MACH_SUN50I_H616=y
CONFIG_SUNXI_DRAM_H616_DDR3_1333=y
CONFIG_DRAM_CLK=648
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_R_I2C_ENABLE=y
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL_I2C=y
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x7f
CONFIG_SYS_I2C_SPEED=400000
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_AXP313_POWER=y
CONFIG_AXP_DCDC3_VOLT=1500
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y

View File

@@ -252,6 +252,7 @@
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins>;
max-frequency = <150000000>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
@@ -267,6 +268,7 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
max-frequency = <150000000>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
@@ -282,6 +284,7 @@
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&mmc2_pins>;
max-frequency = <150000000>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;

View File

@@ -0,0 +1,211 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Arm Ltd.
*/
/dts-v1/;
#include "sun50i-a100.dtsi"
#include "sun50i-a100-cpu-opp.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
/{
model = "Liontron H-A133L";
compatible = "liontron,h-a133l", "allwinner,sun50i-a100";
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
leds {
compatible = "gpio-leds";
led {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_BLUE>;
gpios = <&pio 7 16 GPIO_ACTIVE_LOW>; /* PH16 */
};
};
reg_vcc5v: vcc5v {
/* board wide 5V supply from a 12V->5V regulator */
compatible = "regulator-fixed";
regulator-name = "vcc-5v";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
reg_usb1_vbus: regulator-usb1-vbus {
compatible = "regulator-fixed";
regulator-name = "usb1-vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&reg_vcc5v>;
enable-active-high;
gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
};
};
&cpu0 {
cpu-supply = <&reg_dcdc2>;
};
&ehci0 {
status = "okay";
};
&ehci1 {
status = "okay";
};
&mmc0 {
vmmc-supply = <&reg_dcdc1>;
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
bus-width = <4>;
status = "okay";
};
&mmc2 {
vmmc-supply = <&reg_dcdc1>;
vqmmc-supply = <&reg_eldo1>;
cap-mmc-hw-reset;
non-removable;
bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
status = "okay";
};
&ohci0 {
status = "okay";
};
&ohci1 {
status = "okay";
};
&pio {
vcc-pb-supply = <&reg_dcdc1>;
vcc-pc-supply = <&reg_eldo1>;
vcc-pf-supply = <&reg_dcdc1>;
vcc-ph-supply = <&reg_dcdc1>;
};
&r_i2c0 {
status = "okay";
axp803: pmic@34 {
compatible = "x-powers,axp803";
reg = <0x34>;
interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
};
};
#include "axp803.dtsi"
&ac_power_supply {
status = "okay";
};
&reg_aldo1 {
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-codec-avcc";
};
&reg_aldo2 {
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-dram-1";
};
&reg_aldo3 {
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-usb-pl";
};
&reg_dcdc1 {
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-io-usb-pd-emmc";
};
&reg_dcdc2 {
regulator-always-on;
regulator-min-microvolt = <810000>;
regulator-max-microvolt = <1200000>;
regulator-name = "vdd-cpux";
};
&reg_dcdc3 {
regulator-always-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
regulator-name = "vdd-usb-cpus";
};
&reg_dcdc4 {
regulator-always-on;
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <950000>;
regulator-name = "vdd-sys";
};
&reg_dcdc5 {
regulator-always-on;
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-name = "vcc-dram";
};
/* DCDC6 unused */
/* DLDO3 unused */
/* DLDO4 unused */
&reg_eldo1 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-pc-emmc";
};
/* ELDO2 unused */
/* ELDO3 unused */
&reg_fldo1 {
regulator-always-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
regulator-name = "vdd-cpus-usb";
};
/* reg_drivevbus unused */
/* dc1sw unused */
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pb_pins>;
status = "okay";
};
&usb_otg {
dr_mode = "host"; /* USB A type receptacle, always powered */
status = "okay";
};
&usbphy {
usb1_vbus-supply = <&reg_usb1_vbus>;
status = "okay";
};

View File

@@ -0,0 +1,222 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2024 Arm Ltd.
*/
/dts-v1/;
#include "sun50i-h616.dtsi"
#include "sun50i-h616-cpu-opp.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
model = "Yuzuki Chameleon";
compatible = "yuzukihd,chameleon", "allwinner,sun50i-h618";
aliases {
ethernet1 = &sdio_wifi;
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
reg_vcc5v: vcc5v {
/* board wide 5V supply directly from the USB-C socket */
compatible = "regulator-fixed";
regulator-name = "vcc-5v";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
wifi_pwrseq: pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&rtc CLK_OSC32K_FANOUT>;
clock-names = "ext_clock";
pinctrl-0 = <&x32clk_fanout_pin>;
pinctrl-names = "default";
reset-gpios = <&pio 6 11 GPIO_ACTIVE_LOW>; /* PG11 */
};
};
&codec {
allwinner,audio-routing = "Line Out", "LINEOUT";
status = "okay";
};
&cpu0 {
cpu-supply = <&reg_dcdc2>;
};
&ehci0 {
status = "okay";
};
&ehci1 {
status = "okay";
};
&ehci2 {
status = "okay";
};
&ehci3 {
status = "okay";
};
&mmc0 {
bus-width = <4>;
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
disable-wp;
vmmc-supply = <&reg_dldo1>;
status = "okay";
};
&mmc1 {
bus-width = <4>;
mmc-pwrseq = <&wifi_pwrseq>;
non-removable;
vmmc-supply = <&reg_dldo1>;
vqmmc-supply = <&reg_dldo1>;
status = "okay";
sdio_wifi: wifi@1 {
reg = <1>;
interrupt-parent = <&pio>;
interrupts = <6 12 IRQ_TYPE_LEVEL_LOW>; /* PG12 */
interrupt-names = "host-wake";
};
};
&mmc2 {
bus-width = <8>;
cap-mmc-hw-reset;
mmc-ddr-3_3v;
non-removable;
vmmc-supply = <&reg_dldo1>;
vqmmc-supply = <&reg_dldo1>;
status = "okay";
};
&ohci0 {
status = "okay";
};
&ohci1 {
status = "okay";
};
&ohci2 {
status = "okay";
};
&ohci3 {
status = "okay";
};
&pio {
vcc-pc-supply = <&reg_dldo1>;
vcc-pf-supply = <&reg_dldo1>; /* via VCC_IO */
vcc-pg-supply = <&reg_dldo1>;
vcc-ph-supply = <&reg_dldo1>; /* via VCC_IO */
vcc-pi-supply = <&reg_dldo1>;
};
&r_i2c {
status = "okay";
axp313: pmic@36 {
compatible = "x-powers,axp313a";
reg = <0x36>;
#interrupt-cells = <1>;
interrupt-controller;
interrupt-parent = <&pio>;
interrupts = <2 2 IRQ_TYPE_LEVEL_LOW>; /* PC2 */
vin1-supply = <&reg_vcc5v>;
vin2-supply = <&reg_vcc5v>;
vin3-supply = <&reg_vcc5v>;
regulators {
/* Supplies VCC-PLL, so needs to be always on. */
reg_aldo1: aldo1 {
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc1v8";
};
/* Supplies VCC-IO, so needs to be always on. */
reg_dldo1: dldo1 {
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc3v3";
};
reg_dcdc1: dcdc1 {
regulator-always-on;
regulator-min-microvolt = <810000>;
regulator-max-microvolt = <990000>;
regulator-name = "vdd-gpu-sys";
};
reg_dcdc2: dcdc2 {
regulator-always-on;
regulator-min-microvolt = <810000>;
regulator-max-microvolt = <1100000>;
regulator-name = "vdd-cpu";
};
reg_dcdc3: dcdc3 {
regulator-always-on;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-name = "vdd-dram";
};
};
};
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_ph_pins>;
status = "okay";
};
/* Connected to the Bluetooth UART pins of the XR829 Wifi/BT chip. */
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
uart-has-rtscts;
status = "okay";
};
&usbotg {
/*
* PHY0 pins are connected to a USB-C socket, but a role switch
* is not implemented: both CC pins are pulled to GND.
* The VBUS pins power the device, so a fixed peripheral mode
* is the best choice.
* The board can be powered via GPIOs, in this case port0 *can*
* act as a host (with a cable/adapter ignoring CC), as VBUS is
* then provided by the GPIOs. Any user of this setup would
* need to adjust the DT accordingly: dr_mode set to "host",
* enabling OHCI0 and EHCI0.
*/
dr_mode = "peripheral";
status = "okay";
};
&usbphy {
usb0_id_det-gpios = <&pio 6 18 GPIO_ACTIVE_HIGH>; /* PG18 */
usb0_vbus-supply = <&reg_vcc5v>;
usb1_vbus-supply = <&reg_vcc5v>;
usb2_vbus-supply = <&reg_vcc5v>;
usb3_vbus-supply = <&reg_vcc5v>;
status = "okay";
};