mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sunxi
The biggest change is some refactoring of the H616 DRAM driver, which allows better fine-tuning for each board, and is the base for pending LPDDR3 and LPDDR4 support, needed by new boards. The sun8i-emac Ethernet driver sees some refactoring that enables it for the Allwinner D1 EMAC IP. The sunxi HDMI driver is now using more DT properties. Also the early SPL code now supports some odd H616 SoC variant. There are some more patches pending, that require the final review touches and some testing, I will send a separate PR for them later. The gitlab CI completed successfully, and I boot tested a few boards with different SoCs, via FEL and SD card, into Linux.
This commit is contained in:
commit
75f415b326
19 changed files with 573 additions and 283 deletions
|
@ -6,6 +6,9 @@
|
|||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
#include "sun6i-a31.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -19,6 +22,15 @@
|
|||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
reg_usb1_vbus: usb1-vbus {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "usb1-vbus";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
enable-active-high;
|
||||
gpio = <&pio 7 24 GPIO_ACTIVE_HIGH>; /* PH24 */
|
||||
};
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
|
@ -56,3 +68,8 @@
|
|||
pinctrl-0 = <&uart0_ph_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbphy {
|
||||
usb1_vbus-supply = <®_usb1_vbus>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
b reset
|
||||
.space 0x7c
|
||||
|
||||
.word 0xe28f0058 // add r0, pc, #88
|
||||
.word 0xe59f1054 // ldr r1, [pc, #84]
|
||||
.word 0xe28f0070 // add r0, pc, #112 // @(fel_stash - .)
|
||||
.word 0xe59f106c // ldr r1, [pc, #108] // fel_stash - .
|
||||
.word 0xe0800001 // add r0, r0, r1
|
||||
.word 0xe580d000 // str sp, [r0]
|
||||
.word 0xe580e004 // str lr, [r0, #4]
|
||||
|
@ -28,8 +28,12 @@
|
|||
.word 0xee1cef10 // mrc 15, 0, lr, cr12, cr0, {0}
|
||||
.word 0xe580e010 // str lr, [r0, #16]
|
||||
|
||||
.word 0xe59f1024 // ldr r1, [pc, #36] ; 0x170000a0
|
||||
.word 0xe59f0024 // ldr r0, [pc, #36] ; CONFIG_*_TEXT_BASE
|
||||
.word 0xe59f1034 // ldr r1, [pc, #52] ; RVBAR_ADDRESS
|
||||
.word 0xe59f0034 // ldr r0, [pc, #52] ; SUNXI_SRAMC_BASE
|
||||
.word 0xe5900024 // ldr r0, [r0, #36] ; SRAM_VER_REG
|
||||
.word 0xe21000ff // ands r0, r0, #255 ; 0xff
|
||||
.word 0x159f102c // ldrne r1, [pc, #44] ; RVBAR_ALTERNATIVE
|
||||
.word 0xe59f002c // ldr r0, [pc, #44] ; CONFIG_*TEXT_BASE
|
||||
.word 0xe5810000 // str r0, [r1]
|
||||
.word 0xf57ff04f // dsb sy
|
||||
.word 0xf57ff06f // isb sy
|
||||
|
@ -39,11 +43,10 @@
|
|||
.word 0xf57ff06f // isb sy
|
||||
.word 0xe320f003 // wfi
|
||||
.word 0xeafffffd // b @wfi
|
||||
#ifndef CONFIG_SUN50I_GEN_H6
|
||||
.word 0x017000a0 // writeable RVBAR mapping address
|
||||
#else
|
||||
.word 0x09010040 // writeable RVBAR mapping address
|
||||
#endif
|
||||
|
||||
.word CONFIG_SUNXI_RVBAR_ADDRESS // writable RVBAR mapping addr
|
||||
.word SUNXI_SRAMC_BASE
|
||||
.word CONFIG_SUNXI_RVBAR_ALTERNATIVE // address for die variant
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
.word CONFIG_SPL_TEXT_BASE
|
||||
#else
|
||||
|
|
|
@ -137,6 +137,14 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
|
|||
#define MSTR_ACTIVE_RANKS(x) (((x == 2) ? 3 : 1) << 24)
|
||||
#define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16)
|
||||
|
||||
#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)
|
||||
|
||||
struct dram_para {
|
||||
u32 clk;
|
||||
enum sunxi_dram_type type;
|
||||
|
@ -144,6 +152,15 @@ struct dram_para {
|
|||
u8 rows;
|
||||
u8 ranks;
|
||||
u8 bus_full_width;
|
||||
u32 dx_odt;
|
||||
u32 dx_dri;
|
||||
u32 ca_dri;
|
||||
u32 odt_en;
|
||||
u32 tpr0;
|
||||
u32 tpr2;
|
||||
u32 tpr10;
|
||||
u32 tpr11;
|
||||
u32 tpr12;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -52,37 +52,56 @@ config DRAM_SUN50I_H616
|
|||
like H616.
|
||||
|
||||
if DRAM_SUN50I_H616
|
||||
config DRAM_SUN50I_H616_WRITE_LEVELING
|
||||
bool "H616 DRAM write leveling"
|
||||
---help---
|
||||
Select this when DRAM on your H616 board needs write leveling.
|
||||
config DRAM_SUN50I_H616_DX_ODT
|
||||
hex "H616 DRAM DX ODT parameter"
|
||||
help
|
||||
DX ODT value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_READ_CALIBRATION
|
||||
bool "H616 DRAM read calibration"
|
||||
---help---
|
||||
Select this when DRAM on your H616 board needs read calibration.
|
||||
config DRAM_SUN50I_H616_DX_DRI
|
||||
hex "H616 DRAM DX DRI parameter"
|
||||
help
|
||||
DX DRI value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_READ_TRAINING
|
||||
bool "H616 DRAM read training"
|
||||
---help---
|
||||
Select this when DRAM on your H616 board needs read training.
|
||||
config DRAM_SUN50I_H616_CA_DRI
|
||||
hex "H616 DRAM CA DRI parameter"
|
||||
help
|
||||
CA DRI value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_WRITE_TRAINING
|
||||
bool "H616 DRAM write training"
|
||||
---help---
|
||||
Select this when DRAM on your H616 board needs write training.
|
||||
config DRAM_SUN50I_H616_ODT_EN
|
||||
hex "H616 DRAM ODT EN parameter"
|
||||
default 0x1
|
||||
help
|
||||
ODT EN value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION
|
||||
bool "H616 DRAM bit delay compensation"
|
||||
---help---
|
||||
Select this when DRAM on your H616 board needs bit delay
|
||||
compensation.
|
||||
config DRAM_SUN50I_H616_TPR0
|
||||
hex "H616 DRAM TPR0 parameter"
|
||||
default 0x0
|
||||
help
|
||||
TPR0 value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_UNKNOWN_FEATURE
|
||||
bool "H616 DRAM unknown feature"
|
||||
---help---
|
||||
Select this when DRAM on your H616 board needs this unknown
|
||||
feature.
|
||||
config DRAM_SUN50I_H616_TPR2
|
||||
hex "H616 DRAM TPR2 parameter"
|
||||
default 0x0
|
||||
help
|
||||
TPR2 value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_TPR10
|
||||
hex "H616 DRAM TPR10 parameter"
|
||||
help
|
||||
TPR10 value from vendor DRAM settings. It tells which features
|
||||
should be configured, like write leveling, read calibration, etc.
|
||||
|
||||
config DRAM_SUN50I_H616_TPR11
|
||||
hex "H616 DRAM TPR11 parameter"
|
||||
default 0x0
|
||||
help
|
||||
TPR11 value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_TPR12
|
||||
hex "H616 DRAM TPR12 parameter"
|
||||
default 0x0
|
||||
help
|
||||
TPR12 value from vendor DRAM settings.
|
||||
endif
|
||||
|
||||
config SUN6I_PRCM
|
||||
|
@ -110,6 +129,32 @@ config SUNXI_SRAM_ADDRESS
|
|||
Some newer SoCs map the boot ROM at address 0 instead and move the
|
||||
SRAM to a different address.
|
||||
|
||||
config SUNXI_RVBAR_ADDRESS
|
||||
hex
|
||||
depends on ARM64
|
||||
default 0x09010040 if SUN50I_GEN_H6
|
||||
default 0x017000a0
|
||||
---help---
|
||||
The read-only RVBAR system register holds the address of the first
|
||||
instruction to execute after a reset. Allwinner cores provide a
|
||||
writable MMIO backing store for this register, to allow to set the
|
||||
entry point when switching to AArch64. This store is on different
|
||||
addresses, depending on the SoC.
|
||||
|
||||
config SUNXI_RVBAR_ALTERNATIVE
|
||||
hex
|
||||
depends on ARM64
|
||||
default 0x08100040 if MACH_SUN50I_H616
|
||||
default SUNXI_RVBAR_ADDRESS
|
||||
---help---
|
||||
The H616 die exists in at least two variants, with one having the
|
||||
RVBAR registers at a different address. If the SoC variant ID
|
||||
(stored in SRAM_VER_REG[7:0]) is not 0, we need to use the
|
||||
other address.
|
||||
Set this alternative address to the same as the normal address
|
||||
for all other SoCs, so the content of the SRAM_VER_REG becomes
|
||||
irrelevant there, and we can use the same code.
|
||||
|
||||
config SUNXI_A64_TIMER_ERRATUM
|
||||
bool
|
||||
|
||||
|
@ -499,12 +544,12 @@ config DRAM_ZQ
|
|||
|
||||
config DRAM_ODT_EN
|
||||
bool "sunxi dram odt enable"
|
||||
depends on !MACH_SUN50I_H616
|
||||
default y if MACH_SUN8I_A23
|
||||
default y if MACH_SUNXI_H3_H5
|
||||
default y if MACH_SUN8I_R40
|
||||
default y if MACH_SUN50I
|
||||
default y if MACH_SUN50I_H6
|
||||
default y if MACH_SUN50I_H616
|
||||
---help---
|
||||
Select this to enable dram odt (on die termination).
|
||||
|
||||
|
|
|
@ -234,37 +234,49 @@ static const u8 phy_init[] = {
|
|||
0x09, 0x05, 0x18
|
||||
};
|
||||
|
||||
static void mctl_phy_configure_odt(void)
|
||||
static void mctl_phy_configure_odt(struct dram_para *para)
|
||||
{
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x388);
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x38c);
|
||||
unsigned int val;
|
||||
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x3c8);
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x3cc);
|
||||
val = para->dx_dri & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x388);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x38c);
|
||||
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x408);
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x40c);
|
||||
val = (para->dx_dri >> 8) & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c8);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3cc);
|
||||
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x448);
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x44c);
|
||||
val = (para->dx_dri >> 16) & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x408);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x40c);
|
||||
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x340);
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x344);
|
||||
val = (para->dx_dri >> 24) & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x448);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x44c);
|
||||
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x348);
|
||||
writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x34c);
|
||||
val = para->ca_dri & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x340);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x344);
|
||||
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x380);
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x384);
|
||||
val = (para->ca_dri >> 8) & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x348);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x34c);
|
||||
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x3c0);
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x3c4);
|
||||
val = para->dx_odt & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x380);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x384);
|
||||
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x400);
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x404);
|
||||
val = (para->dx_odt >> 8) & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c0);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c4);
|
||||
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x440);
|
||||
writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x444);
|
||||
val = (para->dx_odt >> 16) & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x400);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x404);
|
||||
|
||||
val = (para->dx_odt >> 24) & 0x1f;
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x440);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x444);
|
||||
|
||||
dmb();
|
||||
}
|
||||
|
@ -285,7 +297,7 @@ static bool mctl_phy_write_leveling(struct dram_para *para)
|
|||
else
|
||||
val = 3;
|
||||
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
|
||||
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
|
||||
|
||||
|
@ -314,7 +326,7 @@ static bool mctl_phy_write_leveling(struct dram_para *para)
|
|||
else
|
||||
val = 3;
|
||||
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
|
||||
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
|
||||
}
|
||||
|
@ -398,26 +410,26 @@ static bool mctl_phy_read_training(struct dram_para *para)
|
|||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
|
||||
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
|
||||
result = false;
|
||||
|
||||
if (para->bus_full_width) {
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
|
||||
result = false;
|
||||
}
|
||||
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x898);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x850);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x898);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x850);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
if (val1 - val2 <= 6)
|
||||
result = false;
|
||||
}
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x8bc);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x874);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8bc);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x874);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
|
@ -426,8 +438,8 @@ static bool mctl_phy_read_training(struct dram_para *para)
|
|||
}
|
||||
|
||||
if (para->bus_full_width) {
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa98);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa50);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa98);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa50);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
|
@ -435,8 +447,8 @@ static bool mctl_phy_read_training(struct dram_para *para)
|
|||
result = false;
|
||||
}
|
||||
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xabc);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa74);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xabc);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa74);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
|
@ -454,12 +466,12 @@ static bool mctl_phy_read_training(struct dram_para *para)
|
|||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
|
||||
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
|
||||
result = false;
|
||||
|
||||
if (para->bus_full_width) {
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
|
||||
result = false;
|
||||
}
|
||||
|
@ -488,26 +500,26 @@ static bool mctl_phy_write_training(struct dram_para *para)
|
|||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
|
||||
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
|
||||
result = false;
|
||||
|
||||
if (para->bus_full_width) {
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
|
||||
result = false;
|
||||
}
|
||||
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x938);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x8f0);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x938);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8f0);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
if (val1 - val2 <= 6)
|
||||
result = false;
|
||||
}
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x95c);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x914);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x95c);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x914);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
|
@ -516,16 +528,16 @@ static bool mctl_phy_write_training(struct dram_para *para)
|
|||
}
|
||||
|
||||
if (para->bus_full_width) {
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb38);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xaf0);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb38);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xaf0);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
if (val1 - val2 <= 6)
|
||||
result = false;
|
||||
}
|
||||
ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb5c);
|
||||
ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb14);
|
||||
ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb5c);
|
||||
ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb14);
|
||||
for (i = 0; i < 9; i++) {
|
||||
val1 = readl(&ptr1[i]);
|
||||
val2 = readl(&ptr2[i]);
|
||||
|
@ -542,12 +554,12 @@ static bool mctl_phy_write_training(struct dram_para *para)
|
|||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
|
||||
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
|
||||
result = false;
|
||||
|
||||
if (para->bus_full_width) {
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
|
||||
if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
|
||||
result = false;
|
||||
}
|
||||
|
@ -560,116 +572,254 @@ static bool mctl_phy_write_training(struct dram_para *para)
|
|||
return result;
|
||||
}
|
||||
|
||||
static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
|
||||
static void mctl_phy_bit_delay_compensation(struct dram_para *para)
|
||||
{
|
||||
u32 *ptr;
|
||||
u32 *ptr, val;
|
||||
int i;
|
||||
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
|
||||
if (para->tpr10 & TPR10_DX_BIT_DELAY1) {
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x484);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x16, ptr);
|
||||
writel_relaxed(0x16, ptr + 0x30);
|
||||
ptr += 2;
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = para->tpr11 & 0x3f;
|
||||
else
|
||||
val = (para->tpr11 & 0xf) << 1;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en >> 15) & 0x1e;
|
||||
else
|
||||
val = (para->tpr11 >> 15) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4d0);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x590);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4cc);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x58c);
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->tpr11 >> 8) & 0x3f;
|
||||
else
|
||||
val = (para->tpr11 >> 3) & 0x1e;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en >> 19) & 0x1e;
|
||||
else
|
||||
val = (para->tpr11 >> 19) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x524);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e4);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x520);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e0);
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->tpr11 >> 16) & 0x3f;
|
||||
else
|
||||
val = (para->tpr11 >> 7) & 0x1e;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en >> 23) & 0x1e;
|
||||
else
|
||||
val = (para->tpr11 >> 23) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x650);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x710);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x64c);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x70c);
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->tpr11 >> 24) & 0x3f;
|
||||
else
|
||||
val = (para->tpr11 >> 11) & 0x1e;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en >> 27) & 0x1e;
|
||||
else
|
||||
val = (para->tpr11 >> 27) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a4);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x764);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a0);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x760);
|
||||
|
||||
dmb();
|
||||
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
|
||||
}
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x1a, ptr);
|
||||
writel_relaxed(0x1a, ptr + 0x30);
|
||||
ptr += 2;
|
||||
if (para->tpr10 & TPR10_DX_BIT_DELAY0) {
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = para->tpr12 & 0x3f;
|
||||
else
|
||||
val = (para->tpr12 & 0xf) << 1;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en << 1) & 0x1e;
|
||||
else
|
||||
val = (para->tpr12 >> 15) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x528);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e8);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4c8);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x588);
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->tpr12 >> 8) & 0x3f;
|
||||
else
|
||||
val = (para->tpr12 >> 3) & 0x1e;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en >> 3) & 0x1e;
|
||||
else
|
||||
val = (para->tpr12 >> 19) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x52c);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5ec);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x51c);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5dc);
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->tpr12 >> 16) & 0x3f;
|
||||
else
|
||||
val = (para->tpr12 >> 7) & 0x1e;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en >> 7) & 0x1e;
|
||||
else
|
||||
val = (para->tpr12 >> 23) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a8);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x768);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x648);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x708);
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->tpr12 >> 24) & 0x3f;
|
||||
else
|
||||
val = (para->tpr12 >> 11) & 0x1e;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(val, ptr);
|
||||
writel_relaxed(val, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
if (para->tpr10 & BIT(30))
|
||||
val = (para->odt_en >> 11) & 0x1e;
|
||||
else
|
||||
val = (para->tpr12 >> 27) & 0x1e;
|
||||
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6ac);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x76c);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x69c);
|
||||
writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x75c);
|
||||
|
||||
dmb();
|
||||
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
|
||||
}
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
|
||||
}
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x604);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x1a, ptr);
|
||||
writel_relaxed(0x1a, ptr + 0x30);
|
||||
ptr += 2;
|
||||
static void mctl_phy_ca_bit_delay_compensation(struct dram_para *para)
|
||||
{
|
||||
u32 val, *ptr;
|
||||
int i;
|
||||
|
||||
if (para->tpr0 & BIT(30))
|
||||
val = (para->tpr0 >> 7) & 0x3e;
|
||||
else
|
||||
val = (para->tpr10 >> 3) & 0x1e;
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
|
||||
for (i = 0; i < 32; i++)
|
||||
writel(val, &ptr[i]);
|
||||
|
||||
val = (para->tpr10 << 1) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d8);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7f4);
|
||||
|
||||
/* following configuration is DDR3 specific */
|
||||
val = (para->tpr10 >> 7) & 0x1e;
|
||||
if (para->tpr2 & 1) {
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
|
||||
if (para->ranks == 2) {
|
||||
val = (para->tpr10 >> 11) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e4);
|
||||
}
|
||||
if (para->tpr0 & BIT(31)) {
|
||||
val = (para->tpr0 << 1) & 0x3e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x790);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7cc);
|
||||
}
|
||||
} else {
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
|
||||
if (para->ranks == 2) {
|
||||
val = (para->tpr10 >> 11) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
|
||||
}
|
||||
if (para->tpr0 & BIT(31)) {
|
||||
val = (para->tpr0 << 1) & 0x3e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x78c);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7a4);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
|
||||
}
|
||||
}
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x658);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x1a, ptr);
|
||||
writel_relaxed(0x1a, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
|
||||
writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
|
||||
|
||||
dmb();
|
||||
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
|
||||
|
||||
/* second part */
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x480);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x10, ptr);
|
||||
writel_relaxed(0x10, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
|
||||
writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
|
||||
writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
|
||||
writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x12, ptr);
|
||||
writel_relaxed(0x12, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x600);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x12, ptr);
|
||||
writel_relaxed(0x12, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
|
||||
writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x654);
|
||||
for (i = 0; i < 9; i++) {
|
||||
writel_relaxed(0x14, ptr);
|
||||
writel_relaxed(0x14, ptr + 0x30);
|
||||
ptr += 2;
|
||||
}
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
|
||||
writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
|
||||
|
||||
dmb();
|
||||
|
||||
setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mctl_phy_init(struct dram_para *para)
|
||||
|
@ -678,7 +828,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
|
||||
struct sunxi_mctl_ctl_reg * const mctl_ctl =
|
||||
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
|
||||
u32 val, *ptr;
|
||||
u32 val, val2, *ptr, mr0, mr2;
|
||||
int i;
|
||||
|
||||
if (para->bus_full_width)
|
||||
|
@ -687,42 +837,40 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
val = 3;
|
||||
clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x3c, 0xf, val);
|
||||
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x14);
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x35c);
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x368);
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x374);
|
||||
if (para->tpr2 & 0x100) {
|
||||
val = 9;
|
||||
val2 = 7;
|
||||
} else {
|
||||
val = 13;
|
||||
val2 = 9;
|
||||
}
|
||||
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x14);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x35c);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x368);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x374);
|
||||
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x18);
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x360);
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x36c);
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x378);
|
||||
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x1c);
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x364);
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x370);
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x37c);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x1c);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x364);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x370);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x37c);
|
||||
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xc0);
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0);
|
||||
for (i = 0; i < ARRAY_SIZE(phy_init); i++)
|
||||
writel(phy_init[i], &ptr[i]);
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
|
||||
ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x780);
|
||||
for (i = 0; i < 32; i++)
|
||||
writel(0x16, &ptr[i]);
|
||||
writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x78c);
|
||||
writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7a4);
|
||||
writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7b8);
|
||||
writel(0x8, SUNXI_DRAM_PHY0_BASE + 0x7d4);
|
||||
writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7dc);
|
||||
writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7e0);
|
||||
}
|
||||
if (para->tpr10 & TPR10_CA_BIT_DELAY)
|
||||
mctl_phy_ca_bit_delay_compensation(para);
|
||||
|
||||
writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
|
||||
writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRAM_ODT_EN))
|
||||
mctl_phy_configure_odt();
|
||||
mctl_phy_configure_odt(para);
|
||||
|
||||
clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 7, 0xa);
|
||||
|
||||
|
@ -738,7 +886,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 8);
|
||||
|
||||
mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x180), 4, 4);
|
||||
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x180), 4, 4);
|
||||
|
||||
writel(0x37, SUNXI_DRAM_PHY0_BASE + 0x58);
|
||||
clrbits_le32(&mctl_com->unk_0x500, 0x200);
|
||||
|
@ -766,7 +914,15 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
writel(1, &mctl_ctl->swctl);
|
||||
mctl_await_completion(&mctl_ctl->swstat, 1, 1);
|
||||
|
||||
writel(0x1f14, &mctl_ctl->mrctrl1);
|
||||
if (para->tpr2 & 0x100) {
|
||||
mr0 = 0x1b50;
|
||||
mr2 = 0x10;
|
||||
} else {
|
||||
mr0 = 0x1f14;
|
||||
mr2 = 0x20;
|
||||
}
|
||||
|
||||
writel(mr0, &mctl_ctl->mrctrl1);
|
||||
writel(0x80000030, &mctl_ctl->mrctrl0);
|
||||
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
|
||||
|
||||
|
@ -774,7 +930,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
writel(0x80001030, &mctl_ctl->mrctrl0);
|
||||
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
|
||||
|
||||
writel(0x20, &mctl_ctl->mrctrl1);
|
||||
writel(mr2, &mctl_ctl->mrctrl1);
|
||||
writel(0x80002030, &mctl_ctl->mrctrl0);
|
||||
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
|
||||
|
||||
|
@ -788,7 +944,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
clrbits_le32(&mctl_ctl->rfshctl3, 1);
|
||||
writel(1, &mctl_ctl->swctl);
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING)) {
|
||||
if (para->tpr10 & TPR10_WRITE_LEVELING) {
|
||||
for (i = 0; i < 5; i++)
|
||||
if (mctl_phy_write_leveling(para))
|
||||
break;
|
||||
|
@ -798,7 +954,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION)) {
|
||||
if (para->tpr10 & TPR10_READ_CALIBRATION) {
|
||||
for (i = 0; i < 5; i++)
|
||||
if (mctl_phy_read_calibration(para))
|
||||
break;
|
||||
|
@ -808,7 +964,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_TRAINING)) {
|
||||
if (para->tpr10 & TPR10_READ_TRAINING) {
|
||||
for (i = 0; i < 5; i++)
|
||||
if (mctl_phy_read_training(para))
|
||||
break;
|
||||
|
@ -818,7 +974,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING)) {
|
||||
if (para->tpr10 & TPR10_WRITE_TRAINING) {
|
||||
for (i = 0; i < 5; i++)
|
||||
if (mctl_phy_write_training(para))
|
||||
break;
|
||||
|
@ -828,8 +984,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION))
|
||||
mctl_phy_bit_delay_compensation(para);
|
||||
mctl_phy_bit_delay_compensation(para);
|
||||
|
||||
clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 4);
|
||||
|
||||
|
@ -873,7 +1028,7 @@ static bool mctl_ctrl_init(struct dram_para *para)
|
|||
writel(0x06000400, &mctl_ctl->unk_0x3240);
|
||||
writel(0x06000400, &mctl_ctl->unk_0x4240);
|
||||
|
||||
setbits_le32(&mctl_com->cr, BIT(31));
|
||||
writel(BIT(31), &mctl_com->cr);
|
||||
|
||||
mctl_set_addrmap(para);
|
||||
|
||||
|
@ -1007,6 +1162,15 @@ unsigned long sunxi_dram_init(void)
|
|||
struct dram_para para = {
|
||||
.clk = CONFIG_DRAM_CLK,
|
||||
.type = SUNXI_DRAM_TYPE_DDR3,
|
||||
.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
|
||||
.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
|
||||
.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
|
||||
.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
|
||||
.tpr0 = CONFIG_DRAM_SUN50I_H616_TPR0,
|
||||
.tpr2 = CONFIG_DRAM_SUN50I_H616_TPR2,
|
||||
.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
|
||||
.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
|
||||
.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
|
||||
};
|
||||
unsigned long size;
|
||||
|
||||
|
|
|
@ -48,10 +48,22 @@ void mctl_set_timing_params(struct dram_para *para)
|
|||
u8 tcl = 7; /* JEDEC: CL / 2 => 6 */
|
||||
u8 tcwl = 5; /* JEDEC: 8 */
|
||||
u8 t_rdata_en = 9; /* ? */
|
||||
u8 t_wr_lat = 5; /* ? */
|
||||
|
||||
u8 twtp = 14; /* (WL + BL / 2 + tWR) / 2 */
|
||||
u8 twr2rd = trtp + 7; /* (WL + BL / 2 + tWTR) / 2 */
|
||||
u8 trd2wr = 5; /* (RL + BL / 2 + 2 - WL) / 2 */
|
||||
u8 twtp; /* (WL + BL / 2 + tWR) / 2 */
|
||||
u8 twr2rd; /* (WL + BL / 2 + tWTR) / 2 */
|
||||
u8 trd2wr; /* (RL + BL / 2 + 2 - WL) / 2 */
|
||||
|
||||
if (para->tpr2 & 0x100) {
|
||||
tcl = 5;
|
||||
tcwl = 4;
|
||||
t_rdata_en = 5;
|
||||
t_wr_lat = 3;
|
||||
}
|
||||
|
||||
twtp = tcl + 2 + tcwl;
|
||||
twr2rd = trtp + 2 + tcwl;
|
||||
trd2wr = tcl + 3 - tcwl;
|
||||
|
||||
/* set DRAM timing */
|
||||
writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
|
||||
|
@ -85,7 +97,7 @@ void mctl_set_timing_params(struct dram_para *para)
|
|||
clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
|
||||
|
||||
/* Configure DFI timing */
|
||||
writel((tcl - 2) | 0x2000000 | (t_rdata_en << 16) | 0x808000,
|
||||
writel(t_wr_lat | 0x2000000 | (t_rdata_en << 16) | 0x808000,
|
||||
&mctl_ctl->dfitmg0);
|
||||
writel(0x100202, &mctl_ctl->dfitmg1);
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-olinuxino-emmc"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-olinuxino"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SUN8I_EMAC=y
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-amarula-relic"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
# CONFIG_VIDEO_DE2 is not set
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-bananapi-m64"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-nanopi-a64"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SUN8I_EMAC=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-oceanic-5205-5inmfd"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_SUNXI_DRAM_LPDDR3_STOCK=y
|
||||
CONFIG_DRAM_CLK=552
|
||||
CONFIG_DRAM_ZQ=3881949
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-orangepi-win"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_MACPWR="PD14"
|
||||
CONFIG_SPL_SPI_SUNXI=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
|
|
|
@ -2,10 +2,10 @@ CONFIG_ARM=y
|
|||
CONFIG_ARCH_SUNXI=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-orangepi-zero2"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
|
||||
CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
|
||||
CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
|
||||
CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
|
||||
CONFIG_DRAM_SUN50I_H616_DX_ODT=0x08080808
|
||||
CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
|
||||
CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e
|
||||
CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
|
||||
CONFIG_MACH_SUN50I_H616=y
|
||||
CONFIG_R_I2C_ENABLE=y
|
||||
CONFIG_SPL_SPI_SUNXI=y
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-plus"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_PINE64_DT_SELECTION=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_OF_LIST="sun50i-a64-pine64 sun50i-a64-pine64-plus"
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-sopine-baseboard"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN50I=y
|
||||
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
|
||||
CONFIG_SUNXI_DRAM_LPDDR3_STOCK=y
|
||||
CONFIG_DRAM_CLK=552
|
||||
CONFIG_DRAM_ZQ=3881949
|
||||
|
|
|
@ -3,6 +3,13 @@ CONFIG_ARCH_SUNXI=y
|
|||
CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-x96-mate"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
|
||||
CONFIG_DRAM_SUN50I_H616_DX_ODT=0x03030303
|
||||
CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
|
||||
CONFIG_DRAM_SUN50I_H616_CA_DRI=0x1c12
|
||||
CONFIG_DRAM_SUN50I_H616_TPR0=0xc0000c05
|
||||
CONFIG_DRAM_SUN50I_H616_TPR10=0x2f0007
|
||||
CONFIG_DRAM_SUN50I_H616_TPR11=0xffffdddd
|
||||
CONFIG_DRAM_SUN50I_H616_TPR12=0xfedf7557
|
||||
CONFIG_MACH_SUN50I_H616=y
|
||||
CONFIG_R_I2C_ENABLE=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
|
|
|
@ -127,12 +127,10 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum emac_variant {
|
||||
A83T_EMAC = 1,
|
||||
H3_EMAC,
|
||||
A64_EMAC,
|
||||
R40_GMAC,
|
||||
H6_EMAC,
|
||||
struct emac_variant {
|
||||
uint syscon_offset;
|
||||
bool soc_has_internal_phy;
|
||||
bool support_rmii;
|
||||
};
|
||||
|
||||
struct emac_dma_desc {
|
||||
|
@ -160,9 +158,9 @@ struct emac_eth_dev {
|
|||
u32 tx_slot;
|
||||
bool use_internal_phy;
|
||||
|
||||
enum emac_variant variant;
|
||||
const struct emac_variant *variant;
|
||||
void *mac_reg;
|
||||
phys_addr_t sysctl_reg;
|
||||
void *sysctl_reg;
|
||||
struct phy_device *phydev;
|
||||
struct mii_dev *bus;
|
||||
struct clk tx_clk;
|
||||
|
@ -317,25 +315,12 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
|
|||
{
|
||||
u32 reg;
|
||||
|
||||
if (priv->variant == R40_GMAC) {
|
||||
/* Select RGMII for R40 */
|
||||
reg = readl(priv->sysctl_reg + 0x164);
|
||||
reg |= SC_ETCS_INT_GMII |
|
||||
SC_EPIT |
|
||||
(CONFIG_GMAC_TX_DELAY << SC_ETXDC_OFFSET);
|
||||
|
||||
writel(reg, priv->sysctl_reg + 0x164);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reg = readl(priv->sysctl_reg + 0x30);
|
||||
reg = readl(priv->sysctl_reg);
|
||||
|
||||
reg = sun8i_emac_set_syscon_ephy(priv, reg);
|
||||
|
||||
reg &= ~(SC_ETCS_MASK | SC_EPIT);
|
||||
if (priv->variant == H3_EMAC ||
|
||||
priv->variant == A64_EMAC ||
|
||||
priv->variant == H6_EMAC)
|
||||
if (priv->variant->support_rmii)
|
||||
reg &= ~SC_RMII_EN;
|
||||
|
||||
switch (priv->interface) {
|
||||
|
@ -349,13 +334,10 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
|
|||
reg |= SC_EPIT | SC_ETCS_INT_GMII;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
if (priv->variant == H3_EMAC ||
|
||||
priv->variant == A64_EMAC ||
|
||||
priv->variant == H6_EMAC) {
|
||||
if (priv->variant->support_rmii) {
|
||||
reg |= SC_RMII_EN | SC_ETCS_EXT_GMII;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
/* RMII not supported on A83T */
|
||||
default:
|
||||
debug("%s: Invalid PHY interface\n", __func__);
|
||||
return -EINVAL;
|
||||
|
@ -369,7 +351,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
|
|||
reg |= ((pdata->rx_delay_ps / 100) << SC_ERXDC_OFFSET)
|
||||
& SC_ERXDC_MASK;
|
||||
|
||||
writel(reg, priv->sysctl_reg + 0x30);
|
||||
writel(reg, priv->sysctl_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -792,6 +774,7 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
|
|||
struct sun8i_eth_pdata *sun8i_pdata = dev_get_plat(dev);
|
||||
struct eth_pdata *pdata = &sun8i_pdata->eth_pdata;
|
||||
struct emac_eth_dev *priv = dev_get_priv(dev);
|
||||
phys_addr_t syscon_base;
|
||||
const fdt32_t *reg;
|
||||
int node = dev_of_offset(dev);
|
||||
int offset = 0;
|
||||
|
@ -806,7 +789,7 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->variant = dev_get_driver_data(dev);
|
||||
priv->variant = (const void *)dev_get_driver_data(dev);
|
||||
|
||||
if (!priv->variant) {
|
||||
printf("%s: Missing variant\n", __func__);
|
||||
|
@ -837,13 +820,15 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
|
|||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob,
|
||||
offset, reg);
|
||||
if (priv->sysctl_reg == FDT_ADDR_T_NONE) {
|
||||
|
||||
syscon_base = fdt_translate_address((void *)gd->fdt_blob, offset, reg);
|
||||
if (syscon_base == FDT_ADDR_T_NONE) {
|
||||
debug("%s: Cannot find syscon base address\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->sysctl_reg = (void *)syscon_base + priv->variant->syscon_offset;
|
||||
|
||||
pdata->phy_interface = -1;
|
||||
priv->phyaddr = -1;
|
||||
priv->use_internal_phy = false;
|
||||
|
@ -860,7 +845,7 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
|
|||
if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
|
||||
return -EINVAL;
|
||||
|
||||
if (priv->variant == H3_EMAC) {
|
||||
if (priv->variant->soc_has_internal_phy) {
|
||||
ret = sun8i_handle_internal_phy(dev, priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -900,16 +885,41 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct emac_variant emac_variant_a83t = {
|
||||
.syscon_offset = 0x30,
|
||||
};
|
||||
|
||||
static const struct emac_variant emac_variant_h3 = {
|
||||
.syscon_offset = 0x30,
|
||||
.soc_has_internal_phy = true,
|
||||
.support_rmii = true,
|
||||
};
|
||||
|
||||
static const struct emac_variant emac_variant_r40 = {
|
||||
.syscon_offset = 0x164,
|
||||
};
|
||||
|
||||
static const struct emac_variant emac_variant_a64 = {
|
||||
.syscon_offset = 0x30,
|
||||
.support_rmii = true,
|
||||
};
|
||||
|
||||
static const struct emac_variant emac_variant_h6 = {
|
||||
.syscon_offset = 0x30,
|
||||
.support_rmii = true,
|
||||
};
|
||||
|
||||
static const struct udevice_id sun8i_emac_eth_ids[] = {
|
||||
{.compatible = "allwinner,sun8i-h3-emac", .data = (uintptr_t)H3_EMAC },
|
||||
{.compatible = "allwinner,sun50i-a64-emac",
|
||||
.data = (uintptr_t)A64_EMAC },
|
||||
{.compatible = "allwinner,sun8i-a83t-emac",
|
||||
.data = (uintptr_t)A83T_EMAC },
|
||||
{.compatible = "allwinner,sun8i-r40-gmac",
|
||||
.data = (uintptr_t)R40_GMAC },
|
||||
{.compatible = "allwinner,sun50i-h6-emac",
|
||||
.data = (uintptr_t)H6_EMAC },
|
||||
{ .compatible = "allwinner,sun8i-a83t-emac",
|
||||
.data = (ulong)&emac_variant_a83t },
|
||||
{ .compatible = "allwinner,sun8i-h3-emac",
|
||||
.data = (ulong)&emac_variant_h3 },
|
||||
{ .compatible = "allwinner,sun8i-r40-gmac",
|
||||
.data = (ulong)&emac_variant_r40 },
|
||||
{ .compatible = "allwinner,sun50i-a64-emac",
|
||||
.data = (ulong)&emac_variant_a64 },
|
||||
{ .compatible = "allwinner,sun50i-h6-emac",
|
||||
.data = (ulong)&emac_variant_h6 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -5,21 +5,27 @@
|
|||
* (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <display.h>
|
||||
#include <dm.h>
|
||||
#include <dw_hdmi.h>
|
||||
#include <edid.h>
|
||||
#include <log.h>
|
||||
#include <reset.h>
|
||||
#include <time.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/lcdc.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <power/regulator.h>
|
||||
|
||||
struct sunxi_dw_hdmi_priv {
|
||||
struct dw_hdmi hdmi;
|
||||
struct reset_ctl_bulk resets;
|
||||
struct clk_bulk clocks;
|
||||
struct udevice *hvcc;
|
||||
};
|
||||
|
||||
struct sunxi_hdmi_phy {
|
||||
|
@ -329,6 +335,9 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev)
|
|||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
int ret;
|
||||
|
||||
if (priv->hvcc)
|
||||
regulator_set_enable(priv->hvcc, true);
|
||||
|
||||
/* Set pll3 to 297 MHz */
|
||||
clock_set_pll3(297000000);
|
||||
|
||||
|
@ -336,14 +345,16 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev)
|
|||
clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK,
|
||||
CCM_HDMI_CTRL_PLL3);
|
||||
|
||||
/* Set ahb gating to pass */
|
||||
setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
|
||||
/* This reset is referenced from the PHY devicetree node. */
|
||||
setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI2);
|
||||
setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
|
||||
setbits_le32(&ccm->hdmi_slow_clk_cfg, CCM_HDMI_SLOW_CTRL_DDC_GATE);
|
||||
|
||||
/* Clock on */
|
||||
setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
|
||||
ret = reset_deassert_bulk(&priv->resets);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_enable_bulk(&priv->clocks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sunxi_dw_hdmi_phy_init(&priv->hdmi);
|
||||
|
||||
|
@ -362,6 +373,7 @@ static int sunxi_dw_hdmi_of_to_plat(struct udevice *dev)
|
|||
{
|
||||
struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev);
|
||||
struct dw_hdmi *hdmi = &priv->hdmi;
|
||||
int ret;
|
||||
|
||||
hdmi->ioaddr = (ulong)dev_read_addr(dev);
|
||||
hdmi->i2c_clk_high = 0xd8;
|
||||
|
@ -369,6 +381,18 @@ static int sunxi_dw_hdmi_of_to_plat(struct udevice *dev)
|
|||
hdmi->reg_io_width = 1;
|
||||
hdmi->phy_set = sunxi_dw_hdmi_phy_cfg;
|
||||
|
||||
ret = reset_get_bulk(dev, &priv->resets);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_bulk(dev, &priv->clocks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = device_get_supply_regulator(dev, "hvcc-supply", &priv->hvcc);
|
||||
if (ret)
|
||||
priv->hvcc = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue