- H6 dts(i) sync (Clément) - H6 PIO (Icenowy) - Fix pll1 clock calculation (Stefan) - H6 dram, half DQ (Jernej) - A64 OLinuXino eMMC (Sunil)
This commit is contained in:
@@ -540,6 +540,7 @@ dtb-$(CONFIG_MACH_SUN50I) += \
|
||||
sun50i-a64-nanopi-a64.dtb \
|
||||
sun50i-a64-oceanic-5205-5inmfd.dtb \
|
||||
sun50i-a64-olinuxino.dtb \
|
||||
sun50i-a64-olinuxino-emmc.dtb \
|
||||
sun50i-a64-orangepi-win.dtb \
|
||||
sun50i-a64-pine64-lts.dtb \
|
||||
sun50i-a64-pine64-plus.dtb \
|
||||
|
||||
23
arch/arm/dts/sun50i-a64-olinuxino-emmc.dts
Normal file
23
arch/arm/dts/sun50i-a64-olinuxino-emmc.dts
Normal file
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2018 Martin Ayotte <martinayotte@gmail.com>
|
||||
* Copyright (C) 2019 Sunil Mohan Adapa <sunil@medhas.org>
|
||||
*/
|
||||
|
||||
#include "sun50i-a64-olinuxino.dts"
|
||||
|
||||
/ {
|
||||
model = "Olimex A64-Olinuxino-eMMC";
|
||||
compatible = "olimex,a64-olinuxino-emmc", "allwinner,sun50i-a64";
|
||||
};
|
||||
|
||||
&mmc2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc2_pins>;
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
vqmmc-supply = <®_dcdc1>;
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
cap-mmc-hw-reset;
|
||||
status = "okay";
|
||||
};
|
||||
12
arch/arm/dts/sun50i-a64-sopine-baseboard-u-boot.dtsi
Normal file
12
arch/arm/dts/sun50i-a64-sopine-baseboard-u-boot.dtsi
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
|
||||
*/
|
||||
|
||||
#include "sunxi-u-boot.dtsi"
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
spi0 = &spi0;
|
||||
};
|
||||
};
|
||||
@@ -14,6 +14,7 @@
|
||||
compatible = "azw,beelink-gs1", "allwinner,sun50i-h6";
|
||||
|
||||
aliases {
|
||||
ethernet0 = &emac;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@@ -21,6 +22,17 @@
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
connector {
|
||||
compatible = "hdmi-connector";
|
||||
type = "a";
|
||||
|
||||
port {
|
||||
hdmi_con_in: endpoint {
|
||||
remote-endpoint = <&hdmi_out_con>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
@@ -41,6 +53,40 @@
|
||||
};
|
||||
};
|
||||
|
||||
&de {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&emac {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ext_rgmii_pins>;
|
||||
phy-mode = "rgmii";
|
||||
phy-handle = <&ext_rgmii_phy>;
|
||||
phy-supply = <®_aldo2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hdmi {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hdmi_out {
|
||||
hdmi_out_con: endpoint {
|
||||
remote-endpoint = <&hdmi_con_in>;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio {
|
||||
ext_rgmii_phy: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_cldo1>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
|
||||
@@ -57,6 +103,15 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pio {
|
||||
vcc-pd-supply = <®_cldo1>;
|
||||
vcc-pg-supply = <®_aldo1>;
|
||||
};
|
||||
|
||||
&r_i2c {
|
||||
status = "okay";
|
||||
|
||||
@@ -177,8 +232,29 @@
|
||||
};
|
||||
};
|
||||
|
||||
&r_pio {
|
||||
/*
|
||||
* PL0 and PL1 are used for PMIC I2C
|
||||
* don't enable the pl-supply else
|
||||
* it will fail at boot
|
||||
*
|
||||
* vcc-pl-supply = <®_aldo1>;
|
||||
*/
|
||||
vcc-pm-supply = <®_aldo1>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_ph_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2otg {
|
||||
dr_mode = "host";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2phy {
|
||||
usb0_vbus-supply = <®_vcc5v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -127,6 +127,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pio {
|
||||
vcc-pc-supply = <®_bldo2>;
|
||||
vcc-pd-supply = <®_cldo1>;
|
||||
vcc-pg-supply = <®_aldo1>;
|
||||
};
|
||||
|
||||
&r_i2c {
|
||||
status = "okay";
|
||||
|
||||
@@ -243,10 +249,16 @@
|
||||
pcf8563: rtc@51 {
|
||||
compatible = "nxp,pcf8563";
|
||||
reg = <0x51>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&r_pio {
|
||||
vcc-pm-supply = <®_aldo1>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_ph_pins>;
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-engine@1000000 {
|
||||
bus@1000000 {
|
||||
compatible = "allwinner,sun50i-h6-de3",
|
||||
"allwinner,sun50i-a64-de2";
|
||||
reg = <0x1000000 0x400000>;
|
||||
@@ -203,11 +203,32 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
dma: dma-controller@3002000 {
|
||||
compatible = "allwinner,sun50i-h6-dma";
|
||||
reg = <0x03002000 0x1000>;
|
||||
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>;
|
||||
clock-names = "bus", "mbus";
|
||||
dma-channels = <16>;
|
||||
dma-requests = <46>;
|
||||
resets = <&ccu RST_BUS_DMA>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
sid: sid@3006000 {
|
||||
compatible = "allwinner,sun50i-h6-sid";
|
||||
reg = <0x03006000 0x400>;
|
||||
};
|
||||
|
||||
watchdog: watchdog@30090a0 {
|
||||
compatible = "allwinner,sun50i-h6-wdt",
|
||||
"allwinner,sun6i-a31-wdt";
|
||||
reg = <0x030090a0 0x20>;
|
||||
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
|
||||
/* Broken on some H6 boards */
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pio: pinctrl@300b000 {
|
||||
compatible = "allwinner,sun50i-h6-pinctrl";
|
||||
reg = <0x0300b000 0x400>;
|
||||
@@ -243,6 +264,18 @@
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
/*
|
||||
* /omit-if-no-ref/ isn't supported by U-boot
|
||||
* keep this comment to avoid bad sync with Linux
|
||||
*/
|
||||
mmc1_pins: mmc1-pins {
|
||||
pins = "PG0", "PG1", "PG2", "PG3",
|
||||
"PG4", "PG5";
|
||||
function = "mmc1";
|
||||
drive-strength = <30>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
mmc2_pins: mmc2-pins {
|
||||
pins = "PC1", "PC4", "PC5", "PC6",
|
||||
"PC7", "PC8", "PC9", "PC10",
|
||||
@@ -294,6 +327,8 @@
|
||||
resets = <&ccu RST_BUS_MMC1>;
|
||||
reset-names = "ahb";
|
||||
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc1_pins>;
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -445,7 +480,6 @@
|
||||
resets = <&ccu RST_BUS_OHCI3>,
|
||||
<&ccu RST_BUS_EHCI3>;
|
||||
phys = <&usb2phy 3>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -457,7 +491,6 @@
|
||||
<&ccu CLK_USB_OHCI3>;
|
||||
resets = <&ccu RST_BUS_OHCI3>;
|
||||
phys = <&usb2phy 3>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -613,6 +646,13 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
r_watchdog: watchdog@7020400 {
|
||||
compatible = "allwinner,sun50i-h6-wdt",
|
||||
"allwinner,sun6i-a31-wdt";
|
||||
reg = <0x07020400 0x20>;
|
||||
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
r_intc: interrupt-controller@7021000 {
|
||||
compatible = "allwinner,sun50i-h6-r-intc",
|
||||
"allwinner,sun6i-a31-r-intc";
|
||||
|
||||
@@ -315,6 +315,7 @@ struct dram_para {
|
||||
u8 cols;
|
||||
u8 rows;
|
||||
u8 ranks;
|
||||
u8 bus_full_width;
|
||||
const u8 dx_read_delays[NR_OF_BYTE_LANES][RD_LINES_PER_BYTE_LANE];
|
||||
const u8 dx_write_delays[NR_OF_BYTE_LANES][WR_LINES_PER_BYTE_LANE];
|
||||
};
|
||||
|
||||
@@ -73,6 +73,9 @@ struct sunxi_gpio_reg {
|
||||
struct sunxi_gpio_int gpio_int;
|
||||
};
|
||||
|
||||
#define SUN50I_H6_GPIO_POW_MOD_SEL 0x340
|
||||
#define SUN50I_H6_GPIO_POW_MOD_VAL 0x348
|
||||
|
||||
#define BANK_TO_GPIO(bank) (((bank) < SUNXI_GPIO_L) ? \
|
||||
&((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \
|
||||
&((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
|
||||
|
||||
@@ -275,7 +275,10 @@ config MACH_SUN9I
|
||||
config MACH_SUN50I
|
||||
bool "sun50i (Allwinner A64)"
|
||||
select ARM64
|
||||
select SPI
|
||||
select DM_I2C
|
||||
select DM_SPI if SPI
|
||||
select DM_SPI_FLASH
|
||||
select PHY_SUN4I_USB
|
||||
select SUN6I_PRCM
|
||||
select SUNXI_DE2
|
||||
|
||||
@@ -65,6 +65,7 @@ struct mm_region *mem_map = sunxi_mem_map;
|
||||
|
||||
static int gpio_init(void)
|
||||
{
|
||||
__maybe_unused uint val;
|
||||
#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
|
||||
#if defined(CONFIG_MACH_SUN4I) || \
|
||||
defined(CONFIG_MACH_SUN7I) || \
|
||||
@@ -139,6 +140,14 @@ static int gpio_init(void)
|
||||
#error Unsupported console port number. Please fix pin mux settings in board.c
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_SUN50I_H6
|
||||
/* Update PIO power bias configuration by copy hardware detected value */
|
||||
val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
|
||||
writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
|
||||
val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
|
||||
writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ void clock_set_pll1(unsigned int clk)
|
||||
if (clk > 1152000000) {
|
||||
k = 2;
|
||||
} else if (clk > 768000000) {
|
||||
k = 3;
|
||||
k = 4;
|
||||
m = 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,9 @@ static void mctl_set_addrmap(struct dram_para *para)
|
||||
u8 rows = para->rows;
|
||||
u8 ranks = para->ranks;
|
||||
|
||||
if (!para->bus_full_width)
|
||||
cols -= 1;
|
||||
|
||||
/* Ranks */
|
||||
if (ranks == 2)
|
||||
mctl_ctl->addrmap[0] = rows + cols - 3;
|
||||
@@ -213,6 +216,10 @@ static void mctl_set_addrmap(struct dram_para *para)
|
||||
/* Columns */
|
||||
mctl_ctl->addrmap[2] = 0;
|
||||
switch (cols) {
|
||||
case 7:
|
||||
mctl_ctl->addrmap[3] = 0x1F1F1F00;
|
||||
mctl_ctl->addrmap[4] = 0x1F1F;
|
||||
break;
|
||||
case 8:
|
||||
mctl_ctl->addrmap[3] = 0x1F1F0000;
|
||||
mctl_ctl->addrmap[4] = 0x1F1F;
|
||||
@@ -300,13 +307,16 @@ static void mctl_com_init(struct dram_para *para)
|
||||
reg_val = 0x3f00;
|
||||
clrsetbits_le32(&mctl_com->unk_0x008, 0x3f00, reg_val);
|
||||
|
||||
/* TODO: half DQ, DDR4 */
|
||||
reg_val = MSTR_BUSWIDTH_FULL | MSTR_BURST_LENGTH(8) |
|
||||
MSTR_ACTIVE_RANKS(para->ranks);
|
||||
/* TODO: DDR4 */
|
||||
reg_val = MSTR_BURST_LENGTH(8) | MSTR_ACTIVE_RANKS(para->ranks);
|
||||
if (para->type == SUNXI_DRAM_TYPE_LPDDR3)
|
||||
reg_val |= MSTR_DEVICETYPE_LPDDR3;
|
||||
if (para->type == SUNXI_DRAM_TYPE_DDR3)
|
||||
reg_val |= MSTR_DEVICETYPE_DDR3 | MSTR_2TMODE;
|
||||
if (para->bus_full_width)
|
||||
reg_val |= MSTR_BUSWIDTH_FULL;
|
||||
else
|
||||
reg_val |= MSTR_BUSWIDTH_HALF;
|
||||
writel(reg_val | BIT(31), &mctl_ctl->mstr);
|
||||
|
||||
if (para->type == SUNXI_DRAM_TYPE_LPDDR3)
|
||||
@@ -333,7 +343,10 @@ static void mctl_com_init(struct dram_para *para)
|
||||
}
|
||||
writel(reg_val, &mctl_ctl->odtcfg);
|
||||
|
||||
/* TODO: half DQ */
|
||||
if (!para->bus_full_width) {
|
||||
writel(0x0, &mctl_phy->dx[2].gcr[0]);
|
||||
writel(0x0, &mctl_phy->dx[3].gcr[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void mctl_bit_delay_set(struct dram_para *para)
|
||||
@@ -514,22 +527,35 @@ static void mctl_channel_init(struct dram_para *para)
|
||||
|
||||
if (readl(&mctl_phy->pgsr[0]) & 0x400000)
|
||||
{
|
||||
/*
|
||||
* Detect single rank.
|
||||
* TODO: also detect half DQ.
|
||||
*/
|
||||
/* Check for single rank and optionally half DQ. */
|
||||
if ((readl(&mctl_phy->dx[0].rsr[0]) & 0x3) == 2 &&
|
||||
(readl(&mctl_phy->dx[1].rsr[0]) & 0x3) == 2 &&
|
||||
(readl(&mctl_phy->dx[2].rsr[0]) & 0x3) == 2 &&
|
||||
(readl(&mctl_phy->dx[3].rsr[0]) & 0x3) == 2) {
|
||||
(readl(&mctl_phy->dx[1].rsr[0]) & 0x3) == 2) {
|
||||
para->ranks = 1;
|
||||
|
||||
if ((readl(&mctl_phy->dx[2].rsr[0]) & 0x3) != 2 ||
|
||||
(readl(&mctl_phy->dx[3].rsr[0]) & 0x3) != 2)
|
||||
para->bus_full_width = 0;
|
||||
|
||||
/* Restart DRAM initialization from scratch. */
|
||||
mctl_core_init(para);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
panic("This DRAM setup is currently not supported.\n");
|
||||
|
||||
/*
|
||||
* Check for dual rank and half DQ. NOTE: This combination
|
||||
* is highly unlikely and was not tested. Condition is the
|
||||
* same as in libdram, though.
|
||||
*/
|
||||
if ((readl(&mctl_phy->dx[0].rsr[0]) & 0x3) == 0 &&
|
||||
(readl(&mctl_phy->dx[1].rsr[0]) & 0x3) == 0) {
|
||||
para->bus_full_width = 0;
|
||||
|
||||
/* Restart DRAM initialization from scratch. */
|
||||
mctl_core_init(para);
|
||||
return;
|
||||
}
|
||||
|
||||
panic("This DRAM setup is currently not supported.\n");
|
||||
}
|
||||
|
||||
if (readl(&mctl_phy->pgsr[0]) & 0xff00000) {
|
||||
@@ -557,11 +583,8 @@ static void mctl_channel_init(struct dram_para *para)
|
||||
|
||||
static void mctl_auto_detect_dram_size(struct dram_para *para)
|
||||
{
|
||||
/* TODO: non-LPDDR3, half DQ */
|
||||
/*
|
||||
* Detect rank number by the code in mctl_channel_init. Furtherly
|
||||
* when DQ detection is available it will also be executed there.
|
||||
*/
|
||||
/* TODO: non-(LP)DDR3 */
|
||||
/* Detect rank number and half DQ by the code in mctl_channel_init. */
|
||||
mctl_core_init(para);
|
||||
|
||||
/* detect row address bits */
|
||||
@@ -570,8 +593,9 @@ static void mctl_auto_detect_dram_size(struct dram_para *para)
|
||||
mctl_core_init(para);
|
||||
|
||||
for (para->rows = 13; para->rows < 18; para->rows++) {
|
||||
/* 8 banks, 8 bit per byte and 32 bit width */
|
||||
if (mctl_mem_matches((1 << (para->rows + para->cols + 5))))
|
||||
/* 8 banks, 8 bit per byte and 16/32 bit width */
|
||||
if (mctl_mem_matches((1 << (para->rows + para->cols +
|
||||
4 + para->bus_full_width))))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -580,18 +604,21 @@ static void mctl_auto_detect_dram_size(struct dram_para *para)
|
||||
mctl_core_init(para);
|
||||
|
||||
for (para->cols = 8; para->cols < 11; para->cols++) {
|
||||
/* 8 bits per byte and 32 bit width */
|
||||
if (mctl_mem_matches(1 << (para->cols + 2)))
|
||||
/* 8 bits per byte and 16/32 bit width */
|
||||
if (mctl_mem_matches(1 << (para->cols + 1 +
|
||||
para->bus_full_width)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long mctl_calc_size(struct dram_para *para)
|
||||
{
|
||||
/* TODO: non-LPDDR3, half DQ */
|
||||
u8 width = para->bus_full_width ? 4 : 2;
|
||||
|
||||
/* 8 banks, 32-bit (4 byte) data width */
|
||||
return (1ULL << (para->cols + para->rows + 3)) * 4 * para->ranks;
|
||||
/* TODO: non-(LP)DDR3 */
|
||||
|
||||
/* 8 banks */
|
||||
return (1ULL << (para->cols + para->rows + 3)) * width * para->ranks;
|
||||
}
|
||||
|
||||
#define SUN50I_H6_LPDDR3_DX_WRITE_DELAYS \
|
||||
@@ -625,6 +652,7 @@ unsigned long sunxi_dram_init(void)
|
||||
.ranks = 2,
|
||||
.cols = 11,
|
||||
.rows = 14,
|
||||
.bus_full_width = 1,
|
||||
#ifdef CONFIG_SUNXI_DRAM_H6_LPDDR3
|
||||
.type = SUNXI_DRAM_TYPE_LPDDR3,
|
||||
.dx_read_delays = SUN50I_H6_LPDDR3_DX_READ_DELAYS,
|
||||
|
||||
Reference in New Issue
Block a user