diff --git a/patch/atf/atf-rockchip64/rk3328-efuse-init.patch b/patch/atf/atf-rockchip64/rk3328-efuse-init.patch new file mode 100644 index 000000000..8be7556ad --- /dev/null +++ b/patch/atf/atf-rockchip64/rk3328-efuse-init.patch @@ -0,0 +1,597 @@ +diff --git a/plat/rockchip/rk3328/drivers/efuse/efuse.c b/plat/rockchip/rk3328/drivers/efuse/efuse.c +new file mode 100644 +index 0000000..05bbcf4 +--- /dev/null ++++ b/plat/rockchip/rk3328/drivers/efuse/efuse.c +@@ -0,0 +1,397 @@ ++/* ++ * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define EFUSE_AUTO_MODE 1 // RK3328 wants auto mode on ++ ++#define read32(reg) mmio_read_32(reg) ++#define write32(v, reg) mmio_write_32(reg, v) ++#define efuse8_read(offset) mmio_read_32(EFUSE8_BASE + offset) ++#define efuse8_write(v, offset) mmio_write_32(EFUSE8_BASE + offset, v) ++#define efuse32_read(offset) mmio_read_32(EFUSE32_BASE + offset) ++#define efuse32_write(v, offset) mmio_write_32(EFUSE32_BASE + offset, v) ++ ++/* global buf to store efuse data */ ++static uint32_t efuse32_buf[32] = {0}; ++ ++enum clk_type { ++ CLK = 0, ++ PCLK, ++}; ++ ++int enable_efuse_clk() ++{ ++ ++ uint32_t reg = 0; ++ ++ reg = read32(CRU_BASE + CRU_CLKGATE_CON2); ++ /* enable efuse work clk */ ++ if (reg & EFUSE_SRC_CLK_EN) ++ write32(EFUSE_SRC_CLK_EN << CRU_WRITE_MASK, ++ CRU_BASE + CRU_CLKGATE_CON2); ++ ++ reg = read32(CRU_BASE + CRU_CLKGATE_CON15); ++ /* enable efuse APB clk */ ++ if (reg & EFUSE_1024_PCLK_EN) ++ write32(EFUSE_1024_PCLK_EN << CRU_WRITE_MASK, ++ CRU_BASE + CRU_CLKGATE_CON15); ++ ++ return reg; ++ ++} ++ ++/* ++static uint32_t enable_efuse_clk(int clk) ++{ ++ uint32_t reg = 0; ++ ++ switch (clk) { ++ case CLK: ++ reg = read32(CRU_BASE + CRU_CLKGATE_CON2); ++ // enable efuse work clk ++ if (reg & EFUSE_SRC_CLK_EN) ++ write32(EFUSE_SRC_CLK_EN << CRU_WRITE_MASK, ++ CRU_BASE + CRU_CLKGATE_CON2); ++ break; ++ case PCLK: ++ reg = read32(CRU_BASE + CRU_CLKGATE_CON15); ++ // enable efuse APB clk ++ if (reg & EFUSE_1024_PCLK_EN) ++ write32(EFUSE_1024_PCLK_EN << CRU_WRITE_MASK, ++ CRU_BASE + CRU_CLKGATE_CON15); ++ break; ++ default: ++ break; ++ } ++ ++ return reg; ++} ++*/ ++ ++static void restore_efuse_clk(int clk, uint32_t reg) ++{ ++ switch (clk) { ++ case CLK: ++ /* disable efuse work clk */ ++ if (reg & EFUSE_SRC_CLK_EN) ++ write32(reg | (EFUSE_SRC_CLK_EN << CRU_WRITE_MASK), ++ CRU_BASE + CRU_CLKGATE_CON2); ++ break; ++ case PCLK: ++ /* disable efuse APB clk */ ++ if (reg & EFUSE_1024_PCLK_EN) ++ write32(reg | (EFUSE_1024_PCLK_EN << CRU_WRITE_MASK), ++ CRU_BASE + CRU_CLKGATE_CON15); ++ break; ++ default: ++ return; ++ } ++} ++ ++/* user mode and auto mode */ ++int rk_efuse32_readregs(uint32_t addr, uint32_t length, uint32_t *buf) ++{ ++ uint32_t reg0 = 0; ++ uint32_t reg1 = 0; ++ ++ uint32_t efuse_base = 0; ++ ++ if (addr > 31) ++ return -1; ++ if (length < 1 || length > 32) ++ return -1; ++ if (!buf) ++ return -1; ++ ++ if (addr < 24) { ++ if (addr + length < 25) ++ efuse_base = EFUSE32_BASE; ++ else ++ return -1; ++ } ++ if (addr > 23) { ++ if (addr + length < 33) ++ efuse_base = EFUSE8_BASE; ++ else ++ return -1; ++ } ++ ++ //reg0 = enable_efuse_clk(CLK); ++ //reg1 = enable_efuse_clk(PCLK); ++ ++#if EFUSE_AUTO_MODE ++ do { ++ write32(EFUSE_AUTO_RD | EFUSE_AUTO_ENABLE | ++ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT), ++ efuse_base + REG_EFUSE_AUTO_CTRL); ++ udelay(2); ++ while (1) { ++ if (read32(efuse_base + REG_EFUSE_INT_STATUS) & 0x01) ++ break; ++ } ++ *buf = read32(efuse_base + REG_EFUSE_DOUT); ++ write32(read32(efuse_base + REG_EFUSE_AUTO_CTRL) & ++ (~EFUSE_AUTO_ENABLE), efuse_base + REG_EFUSE_AUTO_CTRL); ++ write32(0x07, efuse_base + REG_EFUSE_INT_STATUS); ++ buf++; ++ addr++; ++ ++ } while (--length); ++#else ++ /* enable read in user mode */ ++ write32((read32(efuse_base + REG_EFUSE_MOD) | EFUSE_RD_ENB_USER) & ++ (~EFUSE_PG_ENB_USER), efuse_base + REG_EFUSE_MOD); ++ write32(EFUSE_CSB, efuse_base + REG_EFUSE_CTRL); ++ write32(EFUSE_LOAD | EFUSE_PGENB, efuse_base + REG_EFUSE_CTRL); ++ udelay(2); ++ do { ++ write32(read32(efuse_base + REG_EFUSE_CTRL) & ++ (~(EFUSE_A_MASK << EFUSE_A_SHIFT)), ++ efuse_base + REG_EFUSE_CTRL); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) | ++ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT), ++ efuse_base + REG_EFUSE_CTRL); ++ ++ udelay(2); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) | ++ EFUSE_STROBE, efuse_base + REG_EFUSE_CTRL); ++ udelay(2); ++ *buf = read32(efuse_base + REG_EFUSE_DOUT); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) & ++ (~EFUSE_STROBE), efuse_base + REG_EFUSE_CTRL); ++ udelay(2); ++ buf++; ++ addr++; ++ } while (--length); ++ udelay(2); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) | EFUSE_CSB, ++ efuse_base + REG_EFUSE_CTRL); ++ udelay(1); ++#endif /* EFUSE_AUTO_MODE */ ++ ++ restore_efuse_clk(CLK, reg0); ++ restore_efuse_clk(PCLK, reg1); ++ ++ return 0; ++} ++ ++/*user mode and auto mode*/ ++int rk_efuse32_write(uint32_t addr, uint32_t val) ++{ ++ uint32_t reg0 = 0, reg1 = 0, efuse_base = 0; ++ ++ if (addr > 31) ++ return -1; ++ ++ if (addr < 24) ++ efuse_base = EFUSE32_BASE; ++ if (addr > 23 && addr < 32) ++ efuse_base = EFUSE8_BASE; ++ ++ //reg0 = enable_efuse_clk(CLK); ++ //reg1 = enable_efuse_clk(PCLK); ++ ++#if EFUSE_AUTO_MODE ++ while (val) { ++ if (val & 0x01) { ++ write32((EFUSE_AUTO_ENABLE | ++ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT)) ++ & (~EFUSE_AUTO_RD), ++ efuse_base + REG_EFUSE_AUTO_CTRL); ++ udelay(2); ++ while (1) { ++ if (read32(efuse_base + REG_EFUSE_INT_STATUS) & ++ 0x01) ++ break; ++ } ++ write32(read32(efuse_base + REG_EFUSE_AUTO_CTRL) & ++ (~EFUSE_AUTO_ENABLE), ++ efuse_base + REG_EFUSE_AUTO_CTRL); ++ write32(0x07, efuse_base + REG_EFUSE_INT_STATUS); ++ udelay(2); ++ } ++ addr += 32; ++ val = val >> 1; ++ udelay(2); ++ } ++#else ++ /* enable program in user mode */ ++ write32((read32(efuse_base + REG_EFUSE_MOD) | EFUSE_PG_ENB_USER) & ++ (~EFUSE_RD_ENB_USER), efuse_base + REG_EFUSE_MOD); ++ write32(EFUSE_CSB | EFUSE_LOAD | EFUSE_PGENB, ++ efuse_base + REG_EFUSE_CTRL); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) & (~EFUSE_CSB), ++ efuse_base + REG_EFUSE_CTRL); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) & (~EFUSE_PGENB) & ++ (~EFUSE_LOAD), efuse_base + REG_EFUSE_CTRL); ++ udelay(2); ++ ++ while (val) { ++ if (val & 0x01) { ++ write32(read32(efuse_base + REG_EFUSE_CTRL) & ++ (~(EFUSE_A_MASK << EFUSE_A_SHIFT)), ++ efuse_base + REG_EFUSE_CTRL); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) | ++ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT), ++ efuse_base + REG_EFUSE_CTRL); ++ udelay(2); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) | ++ EFUSE_STROBE, efuse_base + REG_EFUSE_CTRL); ++ udelay(10); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) & ++ (~EFUSE_STROBE), ++ efuse_base + REG_EFUSE_CTRL); ++ udelay(2); ++ } ++ addr += 32; ++ val = val >> 1; ++ } ++ ++ udelay(2); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) | EFUSE_LOAD | ++ EFUSE_PGENB, efuse_base + REG_EFUSE_CTRL); ++ write32(read32(efuse_base + REG_EFUSE_CTRL) | EFUSE_CSB, ++ efuse_base + REG_EFUSE_CTRL); ++ udelay(1); ++#endif /* EFUSE_AUTO_MODE */ ++ ++ restore_efuse_clk(CLK, reg0); ++ restore_efuse_clk(PCLK, reg1); ++ ++ return 0; ++} ++ ++int rk_efuse32_read(uint32_t addr, uint32_t length, uint32_t *buf) ++{ ++ if (!buf) ++ return -1; ++ ++ if (addr > 23) { ++ if (length < 1 || length + addr > 32) ++ return -1; ++ ++ memcpy(buf, efuse32_buf + addr, length * sizeof(uint32_t)); ++ } else if (addr < 24) { ++ if (length < 1 || length + addr > 24) ++ return -1; ++ ++ memcpy(buf, efuse32_buf + addr, length * sizeof(uint32_t)); ++ } ++ ++ return 0; ++} ++ ++void mode_init(int sec) ++{ ++ int reg; ++ uint32_t efuse_base = 0; ++ ++ if (sec == 1) ++ efuse_base = EFUSE32_BASE;/*secure efuse addr*/ ++ if (sec == 0) ++ efuse_base = EFUSE8_BASE;/*un_secure efsue addr*/ ++ ++#if EFUSE_AUTO_MODE ++ /* enable auto mode */ ++ reg = read32(efuse_base + REG_EFUSE_MOD); ++ write32(reg & (~EFUSE_USER_MODE), efuse_base + REG_EFUSE_MOD); ++ ++ /* enable finish & auto_s_access_ns_err & auto_ns_access_s_err int */ ++ write32(0x07, efuse_base + REG_EFUSE_INT_CON); ++ write32((T_CSB_P_S << 16) | T_CSB_P_L, ++ efuse_base + REG_EFUSE_T_CSB_P); ++ write32((T_PGENB_P_S << 16) | T_PGENB_P_L, ++ efuse_base + REG_EFUSE_T_PGENB_P); ++ write32((T_LOAD_P_S << 16) | T_LOAD_P_L, ++ efuse_base + REG_EFUSE_T_LOAD_P); ++ write32((T_ADDR_P_S << 16) | T_ADDR_P_L, ++ efuse_base + REG_EFUSE_T_ADDR_P); ++ write32((T_STROBE_P_S << 16) | T_STROBE_P_L, ++ efuse_base + REG_EFUSE_T_STROBE_P); ++ write32((T_CSB_R_S << 16) | T_CSB_R_L, ++ efuse_base + REG_EFUSE_T_CSB_R); ++ write32((T_PGENB_R_S << 16) | T_PGENB_R_L, ++ efuse_base + REG_EFUSE_T_PGENB_R); ++ write32((T_LOAD_R_S << 16) | T_LOAD_R_L, ++ efuse_base + REG_EFUSE_T_LOAD_R); ++ write32((T_ADDR_R_S << 16) | T_ADDR_R_L, ++ efuse_base + REG_EFUSE_T_ADDR_R); ++ write32((T_STROBE_R_S << 16) | T_STROBE_R_L, ++ efuse_base + REG_EFUSE_T_STROBE_R); ++#else ++ reg = read32(efuse_base + REG_EFUSE_MOD); ++ write32(reg | EFUSE_USER_MODE, efuse_base + REG_EFUSE_MOD); ++#endif /* EFUSE_AUTO_MODE */ ++} ++ ++void rk_efuse_prog_en(int n) ++{ ++ if (n == 1) { ++ write32(read32(GPIO2_BASE) & (~(0X1 << 3)), GPIO2_BASE); ++ write32((efuse_pwren | efuse_pwren << 16) | ++ ((0) << 7 | efuse_pwren << 16 << 1), ++ GRF_BASE + GRF_GPIO2A_IOMUX); ++ /*efuse program enable*/ ++ write32((1 << 7) | (1 << 7 << 16), SGRF_BASE + ++ EFUSE_SGRF_SOC_CON5); ++ } else { ++ write32((0 << 7) | (1 << 7 << 16), ++ SGRF_BASE + EFUSE_SGRF_SOC_CON5); ++ write32(0 << 6 | efuse_pwren << 16 | ++ ((0) << 7 | efuse_pwren << 16 << 1), ++ GRF_BASE + GRF_GPIO2A_IOMUX); ++ write32(read32(GPIO2_BASE) | (0X1 << 3), GPIO2_BASE); ++ } ++} ++ ++int rk_efuse_init(void) ++{ ++ mode_init(1); ++ mode_init(0); ++ ++ if (rk_efuse32_readregs(RK322XH_S_EFUSE_START, ++ RK322XH_S_EFUSE_WORDS, ++ efuse32_buf)) { ++ ERROR("read S-efuse failed!!!!\n"); ++ return -1; ++ } ++ ++ if (rk_efuse32_readregs(RK322XH_NS_EFUSE_START, ++ RK322XH_NS_EFUSE_WORDS, ++ efuse32_buf + RK322XH_NS_EFUSE_START)) { ++ ERROR("read NS-efuse failed!!!!\n"); ++ return -1; ++ } ++ ++ return 0; ++} +diff --git a/plat/rockchip/rk3328/drivers/efuse/efuse.h b/plat/rockchip/rk3328/drivers/efuse/efuse.h +new file mode 100644 +index 0000000..22275c2 +--- /dev/null ++++ b/plat/rockchip/rk3328/drivers/efuse/efuse.h +@@ -0,0 +1,142 @@ ++/* ++ * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef EFUSE_H ++#define EFUSE_H ++ ++#include ++ ++/* CRU controller register */ ++#define CRU_WRITE_MASK (16) ++ ++#define GRF_GPIO2A_IOMUX (0x0020) ++#define EFUSE_SGRF_SOC_CON5 (0X0014) ++ ++#define CRU_CLKGATE_CON2 (0x0208) ++#define CRU_CLKGATE_CON15 (0x023C) ++#define EFUSE_SRC_CLK_EN (1 << 13) ++#define EFUSE_1024_PCLK_EN (1 << 9) ++ ++#define RK322XH_S_EFUSE_START 0 ++#define RK322XH_S_EFUSE_WORDS 24 ++#define RK322XH_NS_EFUSE_START (RK322XH_S_EFUSE_START + RK322XH_S_EFUSE_WORDS) ++#define RK322XH_NS_EFUSE_WORDS 8 ++ ++/* SGRF controller register */ ++#define SGRF_WRITE_MASK (16) ++ ++/* eFuse controller register */ ++#define CRU_CLKSEL_CON5 (0x0114) ++#define REG_EFUSE_MOD (0x0000) ++#define efuse_pwren (1 << 6) ++#define EFUSE_RD_ENB_USER (1 << 6) ++#define EFUSE_PG_ENB_USER (1 << 5) ++#define EFUSE_STROBE_POL (1 << 4) ++#define EFUSE_LOAD_POL (1 << 3) ++#define EFUSE_PGENB_POL (1 << 2) ++#define EFUSE_CSB_POL (1 << 1) ++/* 0:auto mode; 1:user mode */ ++#define EFUSE_USER_MODE (1 << 0) ++ ++#define REG_EFUSE_RD_MASK_S (0x0004) ++#define REG_EFUSE_PG_MASK_S (0x0008) ++ ++#define REG_EFUSE_RD_MASK_NS (0x000C) ++#define REG_EFUSE_PG_MASK_NS (0x0010) ++ ++#define REG_EFUSE_INT_CON (0x0014) ++#define REG_EFUSE_INT_STATUS (0x0018) ++#define REG_EFUSE_USER_CTRL (0x001C) ++#define EFUSE_A_SHIFT (16) ++#define EFUSE_A_MASK (0x3FF) ++#define EFUSE_PGENB (1 << 3) /* active low */ ++#define EFUSE_LOAD (1 << 2) ++#define EFUSE_STROBE (1 << 1) ++#define EFUSE_CSB (1 << 0) /* active low */ ++#define REG_EFUSE_DOUT (0x0020) ++#define REG_EFUSE_AUTO_CTRL (0x0024) ++/* 0:programming mode; 1:read mode */ ++#define EFUSE_AUTO_RD (1 << 1) ++#define EFUSE_AUTO_ENABLE (1 << 0) ++ ++#define EFUSE_PG_ENB_MODE (0 << 1) ++ ++#define REG_EFUSE_T_CSB_P (0x0028) ++#define REG_EFUSE_T_PGENB_P (0x002C) ++#define REG_EFUSE_T_LOAD_P (0x0030) ++#define REG_EFUSE_T_ADDR_P (0x0034) ++#define REG_EFUSE_T_STROBE_P (0x0038) ++#define REG_EFUSE_T_CSB_R (0x003C) ++#define REG_EFUSE_T_PGENB_R (0x0040) ++#define REG_EFUSE_T_LOAD_R (0x0044) ++#define REG_EFUSE_T_ADDR_R (0x0048) ++#define REG_EFUSE_T_STROBE_R (0x004C) ++#define REG_EFUSE_REVISION (0x0050) ++#define REG_EFUSE_CTRL REG_EFUSE_USER_CTRL ++ ++#define T_CSB_P_S 1 ++#define T_PGENB_P_S 1 ++#define T_LOAD_P_S 1 ++#define T_ADDR_P_S 1 ++#define T_STROBE_P_S 2 ++#define T_CSB_P_L 241 ++#define T_PGENB_P_L 241 ++#define T_LOAD_P_L 241 ++#define T_ADDR_P_L 241 ++#define T_STROBE_P_L 240 ++#define T_CSB_R_S 1 ++#define T_PGENB_R_S 1 ++#define T_LOAD_R_S 1 ++#define T_ADDR_R_S 1 ++#define T_STROBE_R_S 2 ++#define T_CSB_R_L 4 ++#define T_PGENB_R_L 4 ++#define T_LOAD_R_L 4 ++#define T_ADDR_R_L 4 ++#define T_STROBE_R_L 3 ++ ++/* ++ * readregs function is real-time read, from the efuse hardware. ++ * read function is not real-time read, read the value stored in ++ * memory when machine starting up. ++ */ ++int rk_efuse8_readregs(uint32_t addr, uint32_t length, uint8_t *buf); ++int rk_efuse8_write(uint32_t addr, uint8_t val); ++ ++int rk_efuse32_readregs(uint32_t addr, uint32_t length, uint32_t *buf); ++int rk_efuse32_write(uint32_t addr, uint32_t val); ++int rk_efuse32_read(uint32_t addr, uint32_t length, uint32_t *buf); ++ ++int enable_efuse_clk(); ++ ++void mode_init(int sec); ++void rk_efuse_prog_en(int n); ++ ++int rk_efuse_init(void); ++ ++#endif /* RK_EFUSE_H */ ++ +diff --git a/plat/rockchip/rk3328/drivers/soc/soc.c b/plat/rockchip/rk3328/drivers/soc/soc.c +index 306308f..48a001c 100644 +--- a/plat/rockchip/rk3328/drivers/soc/soc.c ++++ b/plat/rockchip/rk3328/drivers/soc/soc.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + /* Table of regions to map using the MMU. */ + const mmap_region_t plat_rk_mmap[] = { +@@ -153,6 +154,11 @@ void plat_rockchip_soc_init(void) + secure_timer_init(); + sgrf_init(); + ++ mode_init(1); ++ mode_init(0); ++ ++ enable_efuse_clk(); ++ + NOTICE("BL31:Rockchip release version: v%d.%d\n", + MAJOR_VERSION, MINOR_VERSION); + } +diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk +index 0219422..8c570b2 100644 +--- a/plat/rockchip/rk3328/platform.mk ++++ b/plat/rockchip/rk3328/platform.mk +@@ -20,6 +20,7 @@ PLAT_INCLUDES := -Idrivers/arm/gic/common/ \ + -I${RK_PLAT_SOC}/ \ + -I${RK_PLAT_SOC}/drivers/pmu/ \ + -I${RK_PLAT_SOC}/drivers/soc/ \ ++ -I${RK_PLAT_SOC}/drivers/efuse/ \ + -I${RK_PLAT_SOC}/include/ + + RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ +@@ -50,7 +51,8 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ + ${RK_PLAT_COMMON}/plat_topology.c \ + ${RK_PLAT_COMMON}/aarch64/platform_common.c \ + ${RK_PLAT_SOC}/drivers/pmu/pmu.c \ +- ${RK_PLAT_SOC}/drivers/soc/soc.c ++ ${RK_PLAT_SOC}/drivers/soc/soc.c \ ++ ${RK_PLAT_SOC}/drivers/efuse/efuse.c + + ifdef PLAT_RK_SECURE_DDR_MINILOADER + BL31_SOURCES += ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c diff --git a/patch/kernel/rockchip-current/xt-q8l-v10-add-device-tree.patch b/patch/kernel/rockchip-current/xt-q8l-v10-add-device-tree.patch index 7a63ee325..31f1b786b 100644 --- a/patch/kernel/rockchip-current/xt-q8l-v10-add-device-tree.patch +++ b/patch/kernel/rockchip-current/xt-q8l-v10-add-device-tree.patch @@ -1,9 +1,9 @@ diff --git a/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts b/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts new file mode 100644 -index 000000000..784528f6d +index 000000000..90d0594af --- /dev/null +++ b/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts -@@ -0,0 +1,1075 @@ +@@ -0,0 +1,1077 @@ +/* + * Copyright (c) 2014, 2015 FUKAUMI Naoki + * 2018 Paolo Sabatino @@ -208,12 +208,15 @@ index 000000000..784528f6d + post-power-on-delay-ms = <100>; + }; + ++ /* ++ * Not really needed, and also break some eMMC configuraions + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + pinctrl-0 = <&emmc_reset>; + pinctrl-names = "default"; + reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + }; ++ */ + + /* + * Sound taken from tinkerboard device tree, adapted to q8. @@ -289,22 +292,22 @@ index 000000000..784528f6d + snps,reset-gpio = <&gpio4 8 GPIO_ACTIVE_LOW>; + tx_delay = <0x30>; + rx_delay = <0x10>; -+ status = "okay"; ++ status = "ok"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; -+ status = "okay"; ++ status = "ok"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; -+ status = "okay"; ++ status = "ok"; +}; + +&i2c0 { + clock-frequency = <400000>; -+ status = "okay"; ++ status = "ok"; + + vdd_cpu: syr827@40 { + compatible = "silergy,syr827"; @@ -587,11 +590,11 @@ index 000000000..784528f6d +}; + +&i2c1 { -+ status = "okay"; ++ status = "disabled"; +}; + +&i2c2 { -+ status = "okay"; ++ status = "disabled"; +}; + +&i2c4 { @@ -604,7 +607,7 @@ index 000000000..784528f6d + * Datasheet is available here: + * http://dl.radxa.com/rock/docs/hw/ds/RK1000-S%20DATASHEET%20V14.pdf + */ -+ status = "okay"; ++ status = "disabled"; + +}; + @@ -810,7 +813,6 @@ index 000000000..784528f6d + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_flash>; + -+ mmc-pwrseq = <&emmc_pwrseq>; + mmc-ddr-1_8v; + rockchip,default-sample-phase = <180>; + @@ -890,6 +892,7 @@ index 000000000..784528f6d +}; + +&tsadc { ++ rockchip,grf = <&grf>; + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; @@ -956,7 +959,6 @@ index 000000000..784528f6d +}; + +&usb_host0_ehci { -+ dr_mode = "host"; + reg = <0x0 0xff500000 0x0 0x20000>; + status = "disable"; +}; @@ -1074,7 +1076,7 @@ index 000000000..784528f6d + }; + +}; -+ ++ + +&gpiomem { + status = "okay"; diff --git a/patch/kernel/rockchip-dev/xt-q8l-v10-add-device-tree.patch b/patch/kernel/rockchip-dev/xt-q8l-v10-add-device-tree.patch index 7a63ee325..31f1b786b 100644 --- a/patch/kernel/rockchip-dev/xt-q8l-v10-add-device-tree.patch +++ b/patch/kernel/rockchip-dev/xt-q8l-v10-add-device-tree.patch @@ -1,9 +1,9 @@ diff --git a/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts b/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts new file mode 100644 -index 000000000..784528f6d +index 000000000..90d0594af --- /dev/null +++ b/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts -@@ -0,0 +1,1075 @@ +@@ -0,0 +1,1077 @@ +/* + * Copyright (c) 2014, 2015 FUKAUMI Naoki + * 2018 Paolo Sabatino @@ -208,12 +208,15 @@ index 000000000..784528f6d + post-power-on-delay-ms = <100>; + }; + ++ /* ++ * Not really needed, and also break some eMMC configuraions + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + pinctrl-0 = <&emmc_reset>; + pinctrl-names = "default"; + reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + }; ++ */ + + /* + * Sound taken from tinkerboard device tree, adapted to q8. @@ -289,22 +292,22 @@ index 000000000..784528f6d + snps,reset-gpio = <&gpio4 8 GPIO_ACTIVE_LOW>; + tx_delay = <0x30>; + rx_delay = <0x10>; -+ status = "okay"; ++ status = "ok"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; -+ status = "okay"; ++ status = "ok"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; -+ status = "okay"; ++ status = "ok"; +}; + +&i2c0 { + clock-frequency = <400000>; -+ status = "okay"; ++ status = "ok"; + + vdd_cpu: syr827@40 { + compatible = "silergy,syr827"; @@ -587,11 +590,11 @@ index 000000000..784528f6d +}; + +&i2c1 { -+ status = "okay"; ++ status = "disabled"; +}; + +&i2c2 { -+ status = "okay"; ++ status = "disabled"; +}; + +&i2c4 { @@ -604,7 +607,7 @@ index 000000000..784528f6d + * Datasheet is available here: + * http://dl.radxa.com/rock/docs/hw/ds/RK1000-S%20DATASHEET%20V14.pdf + */ -+ status = "okay"; ++ status = "disabled"; + +}; + @@ -810,7 +813,6 @@ index 000000000..784528f6d + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_flash>; + -+ mmc-pwrseq = <&emmc_pwrseq>; + mmc-ddr-1_8v; + rockchip,default-sample-phase = <180>; + @@ -890,6 +892,7 @@ index 000000000..784528f6d +}; + +&tsadc { ++ rockchip,grf = <&grf>; + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; @@ -956,7 +959,6 @@ index 000000000..784528f6d +}; + +&usb_host0_ehci { -+ dr_mode = "host"; + reg = <0x0 0xff500000 0x0 0x20000>; + status = "disable"; +}; @@ -1074,7 +1076,7 @@ index 000000000..784528f6d + }; + +}; -+ ++ + +&gpiomem { + status = "okay"; diff --git a/patch/kernel/rockchip-legacy/patch-4.4.199-200.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.199-200.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.199-200.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.199-200.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.200-201.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.200-201.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.200-201.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.200-201.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.201-202.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.201-202.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.201-202.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.201-202.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.202-203.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.202-203.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.202-203.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.202-203.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.203-204.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.203-204.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.203-204.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.203-204.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.204-205.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.204-205.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.204-205.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.204-205.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.205-206.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.205-206.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.205-206.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.205-206.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.206-207.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.206-207.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.206-207.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.206-207.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.207-208.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.207-208.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.207-208.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.207-208.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.208-209.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.208-209.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.208-209.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.208-209.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.209-210.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.209-210.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.209-210.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.209-210.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.210-211.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.210-211.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.210-211.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.210-211.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.211-212.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.211-212.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.211-212.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.211-212.patch diff --git a/patch/kernel/rockchip-legacy/patch-4.4.212-213.patch b/patch/kernel/rockchip-legacy/04-patch-4.4.212-213.patch similarity index 100% rename from patch/kernel/rockchip-legacy/patch-4.4.212-213.patch rename to patch/kernel/rockchip-legacy/04-patch-4.4.212-213.patch diff --git a/patch/kernel/rockchip-legacy/1-2-regulator-act8865-add-restart-handler-for-act8846.patch.disabled b/patch/kernel/rockchip-legacy/1-2-regulator-act8865-add-restart-handler-for-act8846.patch similarity index 64% rename from patch/kernel/rockchip-legacy/1-2-regulator-act8865-add-restart-handler-for-act8846.patch.disabled rename to patch/kernel/rockchip-legacy/1-2-regulator-act8865-add-restart-handler-for-act8846.patch index 6d4982176..1662ebdba 100644 --- a/patch/kernel/rockchip-legacy/1-2-regulator-act8865-add-restart-handler-for-act8846.patch.disabled +++ b/patch/kernel/rockchip-legacy/1-2-regulator-act8865-add-restart-handler-for-act8846.patch @@ -1,11 +1,5 @@ -Patches act8846 regulator providing the proper reset handle and exploit -the SIPC bit in GLB_POWER_OFF register. Mainly used to reset some rockchip -boards. - -Origin: - diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c -index 2ff73d7..836d10b 100644 +index 6e9592c2..0121a819 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -27,6 +27,7 @@ @@ -25,15 +19,14 @@ index 2ff73d7..836d10b 100644 struct act8865 { struct regmap *regmap; int off_reg; -@@ -402,6 +405,22 @@ static void act8865_power_off(void) +@@ -412,6 +415,21 @@ static void act8865_power_off(void) while (1); } +static int act8846_power_cycle(struct notifier_block *this, -+ unsigned long code, void *unused) ++ unsigned long code, void *unused) +{ + struct act8865 *act8846; -+ + act8846 = i2c_get_clientdata(act8865_i2c_client); + regmap_write(act8846->regmap, ACT8846_GLB_OFF_CTRL, ACT8846_SIPC_MASK); + @@ -48,18 +41,9 @@ index 2ff73d7..836d10b 100644 static int act8865_pmic_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { -@@ -484,6 +503,8 @@ static int act8865_pmic_probe(struct i2c_client *client, - } - - if (of_device_is_system_power_controller(dev->of_node)) { -+ int ret; -+ - if (!pm_power_off && (off_reg > 0)) { - act8865_i2c_client = client; - act8865->off_reg = off_reg; -@@ -492,6 +513,14 @@ static int act8865_pmic_probe(struct i2c_client *client, +@@ -512,6 +530,14 @@ static int act8865_pmic_probe(struct i2c_client *client, } else { - dev_err(dev, "Failed to set poweroff capability, already defined\n"); + dev_err(dev, "Failed to set poweroff capability\n"); } + + if (type == ACT8846) { diff --git a/patch/kernel/rockchip-legacy/xt-q8l-v10-add-device-tree.patch b/patch/kernel/rockchip-legacy/xt-q8l-v10-add-device-tree.patch index 70d41a6c6..ed113cf92 100644 --- a/patch/kernel/rockchip-legacy/xt-q8l-v10-add-device-tree.patch +++ b/patch/kernel/rockchip-legacy/xt-q8l-v10-add-device-tree.patch @@ -1,9 +1,12 @@ +diff --git a/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts b/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts +new file mode 100644 +index 00000000..42c18901 --- /dev/null -+++ b/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts 2018-09-23 13:07:34.000000000 +0000 -@@ -0,0 +1,1120 @@ ++++ b/arch/arm/boot/dts/rk3288-xt-q8l-v10.dts +@@ -0,0 +1,1125 @@ +/* + * Copyright (c) 2014, 2015 FUKAUMI Naoki -+ * 2018 Paolo Sabatino ++ * 2018 Paolo Sabatino + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual @@ -47,18 +50,17 @@ +/dts-v1/; + +#include "rk3288.dtsi" -+#include "rk3288-linux.dtsi" +#include + +/ { -+ ++ + model = "XT-Q8L-V10-RK3288"; + compatible = "generic,xt-q8l-v10-rk3288", "rockchip,rk3288"; + + memory { + reg = <0x0 0x0 0x0 0x80000000>; + }; -+ ++ + /* + * Peripheral from original q8 device tree, currently no references + * for drivers in linux kernel. @@ -89,7 +91,7 @@ + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; -+ ++ + pinctrl-names = "default"; + pinctrl-0 = <&pwr_key>; + @@ -101,7 +103,13 @@ + wakeup-source; + debounce-interval = <100>; + }; -+ ++ ++ }; ++ ++ rk3288-gpiomem { ++ compatible = "rockchip,rk3288-gpiomem"; ++ reg = <0x0 0xff750000 0x0 0x1000>; ++ status = "okay"; + }; + + leds { @@ -113,7 +121,7 @@ + so while there is mass storage access it turns red and + when it is idle is blue + */ -+ gpios = <&gpio7 2 GPIO_ACTIVE_LOW>; ++ gpios = <&gpio7 2 GPIO_ACTIVE_LOW>; + label = "power"; + linux,default-trigger = "mmc0"; + pinctrl-names = "default"; @@ -124,9 +132,11 @@ + + /* + * Legacy platform data for wireless-wlan. -+ * Is this still used or required? ++ * This is used in case rockchip_wlan is in use, ++ * but we prefer the native brcmfmac driver. + * Taken from original q8 firmware device tree + */ ++ /* + wireless-wlan { + compatible = "wlan-platdata"; + wifi_chip_type = "bcmwifi"; @@ -136,6 +146,7 @@ + WIFI,host_wake_irq = <&gpio4 30 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; ++ */ + + /* + * Legacy platform data for wireless-bluetooth. @@ -187,17 +198,6 @@ + vin-supply = <&vcc_io>; + }; + -+ vcc_5v: usb-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_5v"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-always-on; -+// regulator-boot-on; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ + vcc_host_5v: usb-host-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>; @@ -206,10 +206,9 @@ + regulator-name = "vcc_host_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; -+ regulator-always-on; -+ enable-active-high; -+// startup-delay-us = <1000>; -+ vin-supply = <&vcc_5v>; ++ regulator-always-on; ++ enable-active-high; ++ vin-supply = <&vcc_sys>; + }; + + @@ -222,9 +221,8 @@ + regulator-name = "vcc_otg_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; -+// startup-delay-us = <1000>; + regulator-always-on; -+ vin-supply = <&vcc_5v>; ++ vin-supply = <&vcc_sys>; + }; + + /* @@ -238,7 +236,7 @@ + reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>, <&gpio4 29 GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <100>; + }; -+ ++ + /* + * Sound taken from tinkerboard device tree, adapted to q8. + * Should be updated to include at least spdif controller, but the @@ -247,7 +245,7 @@ + soundcard-hdmi { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "rockchip,q8-codec"; ++ simple-audio-card,name = "DW-I2S-HDMI"; + simple-audio-card,mclk-fs = <512>; + + simple-audio-card,codec { @@ -258,20 +256,20 @@ + sound-dai = <&i2s>; + }; + }; -+ ++ + soundcard-spdif { + compatible = "simple-audio-card"; + simple-audio-card,name = "SPDIF"; + simple-audio-card,dai-link@1 { -+ -+ cpu { -+ sound-dai = <&spdif>; ++ ++ cpu { ++ sound-dai = <&spdif>; + }; -+ -+ codec { -+ sound-dai = <&spdif_out>; ++ ++ codec { ++ sound-dai = <&spdif_out>; + }; -+ ++ + }; + }; + @@ -279,7 +277,7 @@ + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; -+ ++ +}; + +/* q8 device tree specifies that pwm0 is enabled on the device and @@ -287,7 +285,7 @@ + * it here. + */ +&pwm0 { -+ ++ + compatible = "rockchip,remotectl-pwm"; + reg = <0x0 0xff680000 0x0 0x10>; + #pwm-cells = <0x3>; @@ -301,8 +299,8 @@ + + ir_key1 { + rockchip,usercode = <0x1dcc>; -+ rockchip,key_table = -+ <0xff KEY_POWER>, ++ rockchip,key_table = ++ <0xff KEY_POWER>, + <0xea KEY_PLAYPAUSE>, + <0xe9 KEY_STOP>, + <0xf9 KEY_PREVIOUSSONG>, @@ -336,7 +334,7 @@ + <0xf6 KEY_F3>, + <0xf2 KEY_F4>; + }; -+ ++ +}; + +&io_domains { @@ -344,7 +342,7 @@ + + audio-supply = <&vcca_33>; + bb-supply = <&vcc_io>; -+ //dvp-supply = <&dovdd_1v8>; ++ dvp-supply = <&vcc_18>; + flash0-supply = <&vcc_flash>; + flash1-supply = <&vcc_lan>; + gpio30-supply = <&vcc_io>; @@ -375,31 +373,43 @@ +}; + +&hdmi { -+ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <0>; + /* + * Delete pinctrl-names and pinctrl-* to avoid the configurations + * which clashes with i2c.ff170000 (i2c5) which houses also the HDMI -+ * ddc display configuration. They clash because hdmi_ddc uses FUNC2, -+ * hdmi_gpio (the "sleep" configuration, see rk3288.dtsi) uses FUNC1 ++ * ddc display configuration. They clash because hdmi_ddc uses FUNC2, ++ * hdmi_gpio (the "sleep" configuration, see rk3288.dtsi) uses FUNC1 + * and i2c5 xfer pin group uses FUNC_GPIO + */ + /delete-property/pinctrl-names; + /delete-property/pinctrl-0; + /delete-property/pinctrl-1; -+ ++ + ddc-i2c-bus = <&i2c5>; -+ #sound-dai-cells = <0>; ++ rockchip,phy-table = ++ <74250000 0x8009 0x0004 0x0272>, ++ <165000000 0x802b 0x0004 0x0209>, ++ <371250000 0x802d 0x0001 0x0149>, ++ <0 0x0000 0x0000 0x0000>; + status = "okay"; ++ /* Don't use vopl for HDMI */ ++ ports { ++ hdmi_in: port { ++ /delete-node/ endpoint@1; ++ }; ++ }; +}; + +&gpu { + mali-supply = <&vdd_gpu>; -+ status = "okay"; ++ status = "ok"; +}; + +&i2c0 { + clock-frequency = <400000>; -+ status = "okay"; ++ status = "ok"; + + vdd_cpu: syr827@40 { + compatible = "silergy,syr827"; @@ -442,7 +452,7 @@ + compatible = "active-semi,act8846"; + reg = <0x5a>; + pinctrl-names = "default"; -+ pinctrl-0 = <&pwr_hold>; ++ pinctrl-0 = <&pmic_vsel>; + system-power-controller; + + vp1-supply = <&vcc_sys>; @@ -454,7 +464,7 @@ + inl3-supply = <&vcc_20>; + + regulators { -+ ++ + /* + * Regulator controlling DDR memory - always on + */ @@ -507,7 +517,7 @@ + */ + vccio_sd: REG5 { + regulator-name = "vccio_sd"; -+ regulator-min-microvolt = <1800000>; ++ regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; @@ -593,8 +603,8 @@ +}; + +&i2c1 { -+ status = "okay"; -+ ++ status = "disabled"; ++ + /* + * Apparently the original q8 device tree described an RTC controller + * at this point. Probing the i2c bus at this point does not provide @@ -606,22 +616,23 @@ + reg = <0x51>; + }; + */ -+ ++ + /* + * Firefly board and EVB board have an accelerometer on this bus. + * I don't know if we got something on our tv box, but I guess not + */ -+ ++ +}; + +&i2c2 { -+ status = "okay"; ++ status = "disabled"; +}; + +&i2c4 { -+ -+ status = "okay"; + ++ status = "disabled"; ++ ++ /* + rk1000_ctl: rk1000-ctl@40 { + compatible = "rockchip,rk1000-ctl"; + reg = <0x40>; @@ -651,7 +662,8 @@ + rockchip,ctl = <&rk1000_ctl>; + status = "okay"; + }; -+ ++ */ ++ +}; + +&i2c5 { @@ -681,12 +693,12 @@ + bias-pull-up; + drive-strength = <8>; + }; -+ ++ + pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma { + bias-pull-up; + drive-strength = <8>; + }; -+ ++ + pcfg_pull_none_8ma: pcfg-pull-none-8ma { + bias-disable; + drive-strength = <8>; @@ -700,18 +712,18 @@ + pcfg_wl_int: pcfg-wl-int { + bias-pull-up; + }; -+ ++ + act8846 { -+ ++ + /* + * Original q8 device tree says: + * - gpio0 11 HIGH -> power hold -+ * - gpio7 1 LOW -> possiblt pmic-vsel, we don't care -+ */ -+ /*pmic_vsel: pmic-vsel { ++ * - gpio7 1 LOW -> possibly pmic-vsel, we don't care ++ */ ++ pmic_vsel: pmic-vsel { + rockchip,pins = <7 1 RK_FUNC_GPIO &pcfg_output_low>; -+ };*/ -+ ++ }; ++ + pwr_hold: pwr-hold { + rockchip,pins = <0 11 RK_FUNC_GPIO &pcfg_pull_up>; + }; @@ -739,7 +751,7 @@ + + keys { + pwr_key: pwr-key { -+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; ++ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + @@ -758,7 +770,7 @@ + */ + + sdmmc { -+ ++ + /* + * Copied from firefly board definition to give more drive to + * the sdmmc pins. The Q8 seems to be quite able to drive @@ -809,14 +821,22 @@ + }; + + }; -+ -+ ++ ++ + wireless-bluetooth { + uart0_gpios: uart0-gpios { + rockchip,pins = <4 19 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + ++ emmc { ++ ++ emmc_reset: emmc-reset { ++ rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ }; ++ +}; + +&saradc { @@ -825,29 +845,25 @@ +}; + +&emmc { -+ ++ + /* + * Coming from the original q8 device tree + */ + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; ++ + disable-wp; + non-removable; + pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; -+ -+ /* -+ * Apparently these are not supported on legacy kernel, we don't -+ * declare them here -+ sd-uhs-sdr12; -+ sd-uhs-sdr25; -+ sd-uhs-sdr50; -+ sd-uhs-sdr104; -+ sd-uhs-ddr50; -+ * */ ++ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>; ++ + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_flash>; ++ ++ mmc-ddr-1_8v; ++ rockchip,default-sample-phase = <180>; ++ + status = "okay"; +}; + @@ -857,68 +873,66 @@ + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; -+ card-detect-delay = <200>; ++ cd-gpios = <&gpio6 RK_PC6 GPIO_ACTIVE_LOW>; ++ cd-debounce-delay-ms = <500>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; -+ vmmc-supply = <&vcc_sd>; + -+ /* -+ * Apparently these are not supported in legacy kernel, we don't declare -+ * them here ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vccio_sd>; + + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + sd-uhs-ddr50; -+ */ ++ + status = "okay"; +}; + +&sdio0 { -+ ++ + #address-cells = <1>; + #size-cells = <0>; -+ ++ + bus-width = <4>; + mmc-pwrseq = <&sdio0_pwrseq>; -+ ++ + vmmc-supply = <&vcc_io>; -+ vqmmc-supply = <&vcc_18>; // This must be the same as in io_domains, ++ vqmmc-supply = <&vcc_18>; // This must be the same as in io_domains, + // otherwise the mmc1 device won't be detected properly -+ ++ +// clock-frequency = <50000000>; +// max-frequency = <50000000>; + + pinctrl-names = "default"; -+ pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>, <&sdio0_int>; -+ ++ pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>, <&sdio0_int>; ++ + cap-sdio-irq; + no-mmc; + no-sd; + cap-sd-highspeed; // required, otherwise does not work! -+ supports-sdio; ++ supports-sdio; + non-removable; -+ ++ + keep-power-in-suspend; + disable-wp; -+ -+ ++ + status = "okay"; -+ ++ + brcmf: bcrmf@1 { -+ ++ + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + interrupt-parent = <&gpio4>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host-wake"; + status = "okay"; -+ }; -+ ++ }; ++ + //sd-uhs-sdr104; // required to be disabled, otherwise the device get -+ // detected, but there is no communication ++ // detected, but there is no communication + +}; + @@ -939,10 +953,10 @@ + * These dmas described here for uarts are present in original q8 board + * dts, so I replicate them here because documentation says that serial + * ports can have dmas. -+ * note: ++ * note: + * - uart0 is the serial port connected to the bluetooth module -+ * - uart2 is the onboard serial port -+ * ++ * - uart2 is the onboard serial port ++ * + */ +&uart0 { + pinctrl-names = "default"; @@ -950,7 +964,7 @@ + dmas = <&dmac_peri 1 &dmac_peri 2>; + dma-names = "tx", "rx"; + status = "okay"; -+// uart-has-rtscts; ++// uart-has-rtscts; +}; + +&uart1 { @@ -990,38 +1004,35 @@ + * The reference patch which works in conjuction with the reset lines: + * https://patchwork.kernel.org/patch/9469811/ + */ -+ &usbphy { ++&usbphy { + status = "okay"; +}; -+ ++ +&usbphy0 { -+ vbus-drv = <&vcc_otg_5v>; -+ vbus_drv-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; ++ vbus-drv = <&vcc_otg_5v>; ++ vbus_drv-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; +}; + +&usbphy1 { -+ resets = <&cru SRST_USBHOST0_PHY>; -+ reset-names = "phy-reset"; ++ resets = <&cru SRST_USBHOST0_PHY>; ++ reset-names = "phy-reset"; +}; + +&usbphy2 { -+ vbus-drv = <&vcc_host_5v>; -+ vbus_drv-gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>; ++ vbus-drv = <&vcc_host_5v>; ++ vbus_drv-gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>; +}; + +&usb_host0_ehci { -+ dr_mode = "host"; -+ status = "okay"; ++ status = "disabled"; +}; + +/* + * Prevents the kernel moaning about the missing regulators + */ +&usb_host1 { -+ dr_mode = "host"; -+ vusb_d-supply = <&vcc_host_5v>; -+ vusb_a-supply = <&vcc_host_5v>; -+ ++ vusb_d-supply = <&vcc_host_5v>; ++ vusb_a-supply = <&vcc_host_5v>; + status = "okay"; +}; + @@ -1030,8 +1041,8 @@ + */ +&usb_otg { + dr_mode = "host"; -+ vusb_d-supply = <&vcc_otg_5v>; -+ vusb_a-supply = <&vcc_otg_5v>; ++ vusb_d-supply = <&vcc_otg_5v>; ++ vusb_a-supply = <&vcc_otg_5v>; + status = "okay"; +}; + @@ -1045,6 +1056,10 @@ + +&vopl { + status = "okay"; ++ /* Don't use vopl for HDMI */ ++ vopl_out: port { ++ /delete-node/ endpoint@0; ++ }; +}; + +&vopl_mmu { @@ -1092,6 +1107,7 @@ + * avoid kernel warning about fractional divisors (didn't investigate too + * much, but uart0 was complaining about) + */ ++/* +&cru { + assigned-clocks = <&cru PLL_GPLL>, <&cru PLL_CPLL>, + <&cru PLL_NPLL>, <&cru ACLK_CPU>, @@ -1104,20 +1120,12 @@ + <300000000>, <150000000>, + <75000000>; +}; ++*/ + -+/* -+ * For an unknown cause, in rk3288-linux.dtsi there is a string switching -+ * the ffb20000 dmac to ff600000. This causes a total wreakage, so we fix -+ * it here -+ */ -+ &dmac_bus_s { -+ /* Revert change in rk3288-linux.dtsi */ -+ reg = <0x0 0xffb20000 0x0 0x4000>; ++&gpu_opp_table { ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1250000>; ++ }; +}; + -+/* -+ * Fix typo (diasbled) in rk3288-linux.dtsi -+ */ -+&dmc { -+ status = "disabled"; -+}; diff --git a/patch/kernel/rockchip64-current/rk3328-fix-mali-node.patch b/patch/kernel/rockchip64-current/rk3328-fix-mali-node.patch new file mode 100644 index 000000000..beb707d17 --- /dev/null +++ b/patch/kernel/rockchip64-current/rk3328-fix-mali-node.patch @@ -0,0 +1,13 @@ +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index bbdb19a3e..f623d5fd9 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -603,7 +603,7 @@ + + gpu: gpu@ff300000 { + compatible = "rockchip,rk3328-mali", "arm,mali-450"; +- reg = <0x0 0xff300000 0x0 0x40000>; ++ reg = <0x0 0xff300000 0x0 0x30000>; + interrupts = , + , + , diff --git a/patch/kernel/rockchip64-dev/general-add-pll-hdmi-timings.patch b/patch/kernel/rockchip64-dev/general-add-pll-hdmi-timings.patch new file mode 100644 index 000000000..deb39113c --- /dev/null +++ b/patch/kernel/rockchip64-dev/general-add-pll-hdmi-timings.patch @@ -0,0 +1,82 @@ +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 9ca20c947..ca91a01f3 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -316,6 +316,77 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { + {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0}, + {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B}, + {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0}, ++ { 25175000, 25175000, 30, 1007, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 31500000, 31500000, 1, 21, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 33750000, 33750000, 1, 45, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 35500000, 35500000, 3, 71, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 36000000, 36000000, 1, 12, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 49500000, 49500000, 1, 33, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 50000000, 50000000, 3, 50, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 56250000, 56250000, 1, 75, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 65000000, 65000000, 3, 65, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 68250000, 68250000, 1, 91, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 71000000, 71000000, 3, 71, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 72000000, 72000000, 1, 24, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 73250000, 73250000, 3, 293, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 75000000, 75000000, 1, 25, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 78750000, 78750000, 1, 105, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 79500000, 79500000, 1, 53, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 83500000, 83500000, 3, 167, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 85500000, 85500000, 1, 57, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 88750000, 88750000, 3, 355, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 94500000, 94500000, 1, 63, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {101000000, 101000000, 3, 101, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {102250000, 102250000, 3, 409, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {106500000, 106500000, 1, 71, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {108000000, 108000000, 1, 36, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {115500000, 115500000, 1, 77, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {117500000, 117500000, 3, 235, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {119000000, 119000000, 3, 119, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {121750000, 121750000, 3, 487, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {122500000, 122500000, 3, 245, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {135000000, 135000000, 1, 45, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {136750000, 136750000, 3, 547, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {140250000, 140250000, 1, 187, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {146250000, 146250000, 1, 195, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {148250000, 148250000, 3, 593, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {154000000, 154000000, 3, 154, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {156000000, 156000000, 1, 52, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {156750000, 156750000, 1, 209, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {157000000, 157000000, 3, 157, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {157500000, 157500000, 1, 105, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {162000000, 162000000, 1, 54, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {175500000, 175500000, 1, 117, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {179500000, 179500000, 3, 359, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {182750000, 182750000, 3, 731, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {187000000, 187000000, 3, 187, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {187250000, 187250000, 3, 749, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {189000000, 189000000, 1, 63, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {193250000, 193250000, 3, 773, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {202500000, 202500000, 1, 135, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {204750000, 204750000, 1, 273, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {208000000, 208000000, 3, 208, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {214750000, 214750000, 3, 859, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {218250000, 218250000, 1, 291, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {229500000, 229500000, 1, 153, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {234000000, 234000000, 1, 78, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {241500000, 241500000, 1, 161, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {245250000, 245250000, 1, 327, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {245500000, 245500000, 3, 491, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {261000000, 261000000, 1, 87, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {268250000, 268250000, 3, 1073, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {268500000, 268500000, 1, 179, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {281250000, 281250000, 1, 375, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {288000000, 288000000, 1, 96, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {312250000, 312250000, 3, 1249, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {317000000, 317000000, 3, 317, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {333250000, 333250000, 3, 1333, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {348500000, 348500000, 3, 697, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {356500000, 356500000, 3, 713, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {380500000, 380500000, 3, 761, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {443250000, 443250000, 1, 591, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {505250000, 505250000, 3, 2021, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {552750000, 552750000, 1, 737, 1, 2, 2, 1, 2, 3, 4, 0, 0}, + { /* sentinel */ } + }; + diff --git a/patch/kernel/rockchip64-dev/rk3328-fix-mali-node.patch b/patch/kernel/rockchip64-dev/rk3328-fix-mali-node.patch new file mode 100644 index 000000000..beb707d17 --- /dev/null +++ b/patch/kernel/rockchip64-dev/rk3328-fix-mali-node.patch @@ -0,0 +1,13 @@ +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index bbdb19a3e..f623d5fd9 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -603,7 +603,7 @@ + + gpu: gpu@ff300000 { + compatible = "rockchip,rk3328-mali", "arm,mali-450"; +- reg = <0x0 0xff300000 0x0 0x40000>; ++ reg = <0x0 0xff300000 0x0 0x30000>; + interrupts = , + , + , diff --git a/patch/misc/general-packaging-5.10.y.patch b/patch/misc/general-packaging-5.10.y.patch index d3e0464b7..17115421b 100644 --- a/patch/misc/general-packaging-5.10.y.patch +++ b/patch/misc/general-packaging-5.10.y.patch @@ -183,7 +183,7 @@ index 1b11f8993..c21d931ea 100755 set -e -@@ -208,14 +272,72 @@ +@@ -208,14 +272,73 @@ chmod 755 "$tmpdir/DEBIAN/$script" done @@ -236,6 +236,8 @@ index 1b11f8993..c21d931ea 100755 +(cd $srctree; find security/*/include -type f) >> "$objtree/debian/hdrsrcfiles" +(cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles" +(cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles" ++ldstemp=$(mktemp);cp scripts/module.lds $ldstemp ++(cd $objtree; make M=scripts clean;) +if is_enabled CONFIG_STACK_VALIDATION; then + (cd $objtree; find tools/objtool -type f -executable) >> "$objtree/debian/hdrobjfiles" +fi @@ -249,13 +251,12 @@ index 1b11f8993..c21d931ea 100755 +(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) +(cd $objtree; tar -c -f - -T -) < "$objtree/debian/hdrobjfiles" | (cd $destdir; tar -xf -) +(cd $objtree; cp $KCONFIG_CONFIG $destdir/.config) # copy .config manually to be where it's expected to be ++mv ${ldstemp} $destdir/scripts/module.lds +ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build" +rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" - deploy_libc_headers debian/linux-libc-dev - create_package linux-libc-dev debian/linux-libc-dev -+(cd $destdir; make M=scripts clean) -+ +if [ "$ARCH" != "um" ]; then + create_package "$kernel_headers_packagename" "$kernel_headers_dir" "headers" + create_package "$dtb_packagename" "$dtb_dir" "dtb" diff --git a/patch/u-boot/u-boot-rockchip64-mainline/general-support-rmii-integrated-phy.patch b/patch/u-boot/u-boot-rockchip64-mainline/general-support-rmii-integrated-phy.patch new file mode 100644 index 000000000..6b43671ef --- /dev/null +++ b/patch/u-boot/u-boot-rockchip64-mainline/general-support-rmii-integrated-phy.patch @@ -0,0 +1,849 @@ +diff --git a/arch/arm/dts/rk3229-evb.dts b/arch/arm/dts/rk3229-evb.dts +index 632cdc9bc3..f868524ae1 100644 +--- a/arch/arm/dts/rk3229-evb.dts ++++ b/arch/arm/dts/rk3229-evb.dts +@@ -50,19 +50,25 @@ + }; + + &gmac { +- assigned-clocks = <&cru SCLK_MAC_EXTCLK>, <&cru SCLK_MAC>; +- assigned-clock-parents = <&ext_gmac>, <&cru SCLK_MAC_EXTCLK>; +- clock_in_out = "input"; +- phy-supply = <&vcc_phy>; +- phy-mode = "rgmii"; +- pinctrl-names = "default"; +- pinctrl-0 = <&rgmii_pins>; +- snps,reset-gpio = <&gpio2 RK_PD0 GPIO_ACTIVE_LOW>; +- snps,reset-active-low; +- snps,reset-delays-us = <0 10000 1000000>; +- tx_delay = <0x30>; +- rx_delay = <0x10>; +- status = "okay"; ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rmii"; ++ phy-handle = <&phy>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy: phy@0 { ++ compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ phy-is-integrated; ++ }; ++ }; + }; + + &emmc { +diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi +index 4a8be5dabb..3c2861f271 100644 +--- a/arch/arm/dts/rk322x.dtsi ++++ b/arch/arm/dts/rk322x.dtsi +@@ -448,13 +448,13 @@ + clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, + <&cru SCLK_MAC_TX>, <&cru SCLK_MAC_REF>, + <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, +- <&cru PCLK_GMAC>; ++ <&cru PCLK_GMAC>, <&cru SCLK_MAC_PHY>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "clk_mac_refout", "aclk_mac", +- "pclk_mac"; +- resets = <&cru SRST_GMAC>; +- reset-names = "stmmaceth"; ++ "pclk_mac", "clk_macphy"; ++ resets = <&cru SRST_GMAC>, <&cru SRST_MACPHY>; ++ reset-names = "stmmaceth", "mac-phy"; + rockchip,grf = <&grf>; + status = "disabled"; + }; +diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +index c87c830716..15039c87be 100644 +--- a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h ++++ b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +@@ -12,6 +12,7 @@ + + #define APLL_HZ (600 * MHz) + #define GPLL_HZ (594 * MHz) ++#define CPLL_HZ (500 * MHz) + + #define CORE_PERI_HZ 150000000 + #define CORE_ACLK_HZ 300000000 +diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig +index f8e648bbb4..5fd2bd3ba2 100644 +--- a/configs/evb-rk3229_defconfig ++++ b/configs/evb-rk3229_defconfig +@@ -58,6 +58,8 @@ CONFIG_GMAC_ROCKCHIP=y + CONFIG_PHY=y + CONFIG_PINCTRL=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_BAUDRATE=1500000 +diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig +index 5bbdc00214..19c09e4503 100644 +--- a/configs/evb-rk3328_defconfig ++++ b/configs/evb-rk3328_defconfig +@@ -71,6 +71,8 @@ CONFIG_DM_REGULATOR_FIXED=y + CONFIG_REGULATOR_RK8XX=y + CONFIG_PWM_ROCKCHIP=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_BAUDRATE=1500000 +diff --git a/doc/device-tree-bindings/net/phy.txt b/doc/device-tree-bindings/net/phy.txt +index 6599c667b5..ca1a4a8526 100644 +--- a/doc/device-tree-bindings/net/phy.txt ++++ b/doc/device-tree-bindings/net/phy.txt +@@ -8,6 +8,19 @@ Required properties: + + - reg : The ID number for the phy, usually a small integer + ++Optional Properties: ++ ++- compatible: Compatible list, may contain ++ "ethernet-phy-ieee802.3-c22" or "ethernet-phy-ieee802.3-c45" for ++ PHYs that implement IEEE802.3 clause 22 or IEEE802.3 clause 45 ++ specifications. If neither of these are specified, the default is to ++ assume clause 22. ++ ++- phy-is-integrated: If set, indicates that the PHY is integrated into the same ++ physical package as the Ethernet MAC. If needed, muxers should be configured ++ to ensure the integrated PHY is used. The absence of this property indicates ++ the muxers should be configured so that the external PHY is used. ++ + Example: + + ethernet-phy@0 { +diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c +index ef33adbf29..c427e0438b 100644 +--- a/drivers/clk/rockchip/clk_rk322x.c ++++ b/drivers/clk/rockchip/clk_rk322x.c +@@ -38,6 +38,7 @@ enum { + /* use integer mode*/ + static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1); + static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); ++static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 3, 1); + + static int rkclk_set_pll(struct rk322x_cru *cru, enum rk_clk_id clk_id, + const struct pll_div *div) +@@ -87,11 +88,13 @@ static void rkclk_init(struct rk322x_cru *cru) + rk_clrsetreg(&cru->cru_mode_con, + GPLL_MODE_MASK | APLL_MODE_MASK, + GPLL_MODE_SLOW << GPLL_MODE_SHIFT | +- APLL_MODE_SLOW << APLL_MODE_SHIFT); ++ APLL_MODE_SLOW << APLL_MODE_SHIFT | ++ CPLL_MODE_SLOW << CPLL_MODE_SHIFT); + + /* init pll */ + rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg); + rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); ++ rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); + + /* + * select apll as cpu/core clock pll source and +@@ -164,7 +167,8 @@ static void rkclk_init(struct rk322x_cru *cru) + rk_clrsetreg(&cru->cru_mode_con, + GPLL_MODE_MASK | APLL_MODE_MASK, + GPLL_MODE_NORM << GPLL_MODE_SHIFT | +- APLL_MODE_NORM << APLL_MODE_SHIFT); ++ APLL_MODE_NORM << APLL_MODE_SHIFT | ++ CPLL_MODE_NORM << CPLL_MODE_SHIFT); + } + + /* Get pll rate by id */ +@@ -254,11 +258,10 @@ static ulong rk322x_mac_set_clk(struct rk322x_cru *cru, uint freq) + ulong pll_rate; + u8 div; + +- if ((con >> MAC_PLL_SEL_SHIFT) & MAC_PLL_SEL_MASK) ++ if (con & MAC_PLL_SEL_MASK) + pll_rate = GPLL_HZ; + else +- /* CPLL is not set */ +- return -EPERM; ++ pll_rate = CPLL_HZ; + + div = DIV_ROUND_UP(pll_rate, freq) - 1; + if (div <= 0x1f) +@@ -387,6 +390,7 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) + case CLK_DDR: + new_rate = rk322x_ddr_set_clk(priv->cru, rate); + break; ++ case SCLK_MAC_SRC: + case SCLK_MAC: + new_rate = rk322x_mac_set_clk(priv->cru, rate); + break; +diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c +index 8e867c58df..ba2b34c626 100644 +--- a/drivers/clk/rockchip/clk_rk3328.c ++++ b/drivers/clk/rockchip/clk_rk3328.c +@@ -93,6 +93,14 @@ enum { + PCLK_DBG_DIV_SHIFT = 0, + PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT, + ++ /* CLKSEL_CON26 */ ++ GMAC2PHY_PLL_SEL_SHIFT = 7, ++ GMAC2PHY_PLL_SEL_MASK = 1 << GMAC2PHY_PLL_SEL_SHIFT, ++ GMAC2PHY_PLL_SEL_CPLL = 0, ++ GMAC2PHY_PLL_SEL_GPLL = 1, ++ GMAC2PHY_CLK_DIV_MASK = 0x1f, ++ GMAC2PHY_CLK_DIV_SHIFT = 0, ++ + /* CLKSEL_CON27 */ + GMAC2IO_PLL_SEL_SHIFT = 7, + GMAC2IO_PLL_SEL_MASK = 1 << GMAC2IO_PLL_SEL_SHIFT, +@@ -440,6 +448,39 @@ static ulong rk3328_gmac2io_set_clk(struct rk3328_cru *cru, ulong rate) + return ret; + } + ++static ulong rk3328_gmac2phy_src_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ u32 con = readl(&cru->clksel_con[26]); ++ ulong pll_rate; ++ u8 div; ++ ++ if ((con >> GMAC2PHY_PLL_SEL_SHIFT) & GMAC2PHY_PLL_SEL_GPLL) ++ pll_rate = GPLL_HZ; ++ else ++ pll_rate = CPLL_HZ; ++ ++ div = DIV_ROUND_UP(pll_rate, rate) - 1; ++ if (div <= 0x1f) ++ rk_clrsetreg(&cru->clksel_con[26], GMAC2PHY_CLK_DIV_MASK, ++ div << GMAC2PHY_CLK_DIV_SHIFT); ++ else ++ debug("Unsupported div for gmac:%d\n", div); ++ ++ return DIV_TO_RATE(pll_rate, div); ++} ++ ++static ulong rk3328_gmac2phy_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ struct rk3328_grf_regs *grf; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ if (readl(&grf->mac_con[2]) & BIT(10)) ++ /* An external clock will always generate the right rate... */ ++ return rate; ++ else ++ return rk3328_gmac2phy_src_set_clk(cru, rate); ++} ++ + static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id) + { + u32 div, con, con_id; +@@ -608,6 +649,12 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) + case SCLK_MAC2IO: + ret = rk3328_gmac2io_set_clk(priv->cru, rate); + break; ++ case SCLK_MAC2PHY: ++ ret = rk3328_gmac2phy_set_clk(priv->cru, rate); ++ break; ++ case SCLK_MAC2PHY_SRC: ++ ret = rk3328_gmac2phy_src_set_clk(priv->cru, rate); ++ break; + case SCLK_PWM: + ret = rk3328_pwm_set_clk(priv->cru, rate); + break; +@@ -728,6 +775,43 @@ static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) + return -EINVAL; + } + ++static int rk3328_gmac2phy_set_parent(struct clk *clk, struct clk *parent) ++{ ++ struct rk3328_grf_regs *grf; ++ const char *clock_output_name; ++ int ret; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ ++ /* ++ * If the requested parent is in the same clock-controller and the id ++ * is SCLK_MAC2PHY_SRC ("clk_mac2phy_src"), switch to the internal clock. ++ */ ++ if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2PHY_SRC)) { ++ debug("%s: switching MAC CLK to SCLK_MAC2IO_PHY\n", __func__); ++ rk_clrreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ /* ++ * Otherwise, we need to check the clock-output-names of the ++ * requested parent to see if the requested id is "phy_50m_out". ++ */ ++ ret = dev_read_string_index(parent->dev, "clock-output-names", ++ parent->id, &clock_output_name); ++ if (ret < 0) ++ return -ENODATA; ++ ++ /* If this is "phy_50m_out", switch to the external clock input */ ++ if (!strcmp(clock_output_name, "phy_50m_out")) { ++ debug("%s: switching MAC CLK to PHY_50M_OUT\n", __func__); ++ rk_setreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ + static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + { + switch (clk->id) { +@@ -735,6 +819,8 @@ static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + return rk3328_gmac2io_set_parent(clk, parent); + case SCLK_MAC2IO_EXT: + return rk3328_gmac2io_ext_set_parent(clk, parent); ++ case SCLK_MAC2PHY: ++ return rk3328_gmac2phy_set_parent(clk, parent); + case DCLK_LCDC: + case SCLK_PDM: + case SCLK_RTC32K: +diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c +index e152faf083..d3f6973043 100644 +--- a/drivers/net/gmac_rockchip.c ++++ b/drivers/net/gmac_rockchip.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,6 +24,8 @@ + #include + #include + #include ++#include ++#include + #include + #include "designware.h" + +@@ -39,21 +41,29 @@ DECLARE_GLOBAL_DATA_PTR; + struct gmac_rockchip_platdata { + struct dw_eth_pdata dw_eth_pdata; + bool clock_input; ++ bool integrated_phy; ++ struct reset_ctl phy_reset; + int tx_delay; + int rx_delay; + }; + + struct rk_gmac_ops { +- int (*fix_mac_speed)(struct dw_eth_dev *priv); ++ int (*fix_rmii_speed)(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv); ++ int (*fix_rgmii_speed)(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv); + void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); + void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); ++ void (*integrated_phy_powerup)(struct gmac_rockchip_platdata *pdata); + }; + + + static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) + { + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); ++ struct ofnode_phandle_args args; + const char *string; ++ int ret; + + string = dev_read_string(dev, "clock_in_out"); + if (!strcmp(string, "input")) +@@ -61,6 +71,25 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) + else + pdata->clock_input = false; + ++ /* If phy-handle property is passed from DT, use it as the PHY */ ++ ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, &args); ++ if (ret) { ++ debug("Cannot get phy phandle: ret=%d\n", ret); ++ pdata->integrated_phy = dev_read_bool(dev, "phy-is-integrated"); ++ } else { ++ debug("Found phy-handle subnode\n"); ++ pdata->integrated_phy = ofnode_read_bool(args.node, ++ "phy-is-integrated"); ++ } ++ ++ if (pdata->integrated_phy) { ++ ret = reset_get_by_name(dev, "mac-phy", &pdata->phy_reset); ++ if (ret) { ++ debug("No PHY reset control found: ret=%d\n", ret); ++ return ret; ++ } ++ } ++ + /* Check the new naming-style first... */ + pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); + pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); +@@ -74,7 +103,8 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) + return designware_eth_ofdata_to_platdata(dev); + } + +-static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int px30_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct px30_grf *grf; + struct clk clk_speed; +@@ -115,7 +145,43 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3228_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) ++{ ++ struct rk322x_grf *grf; ++ int clk; ++ enum { ++ RK3228_GMAC_RMII_CLK_MASK = BIT(7), ++ RK3228_GMAC_RMII_CLK_2_5M = 0, ++ RK3228_GMAC_RMII_CLK_25M = BIT(7), ++ ++ RK3228_GMAC_RMII_SPEED_MASK = BIT(2), ++ RK3228_GMAC_RMII_SPEED_10 = 0, ++ RK3228_GMAC_RMII_SPEED_100 = BIT(2), ++ }; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ clk = RK3228_GMAC_RMII_CLK_2_5M | RK3228_GMAC_RMII_SPEED_10; ++ break; ++ case 100: ++ clk = RK3228_GMAC_RMII_CLK_25M | RK3228_GMAC_RMII_SPEED_100; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GMAC_RMII_CLK_MASK | RK3228_GMAC_RMII_SPEED_MASK, ++ clk); ++ ++ return 0; ++} ++ ++static int rk3228_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk322x_grf *grf; + int clk; +@@ -148,7 +214,8 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3288_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3288_grf *grf; + int clk; +@@ -174,7 +241,8 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3308_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3308_grf *grf; + struct clk clk_speed; +@@ -215,7 +283,43 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3328_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) ++{ ++ struct rk3328_grf_regs *grf; ++ int clk; ++ enum { ++ RK3328_GMAC_RMII_CLK_MASK = BIT(7), ++ RK3328_GMAC_RMII_CLK_2_5M = 0, ++ RK3328_GMAC_RMII_CLK_25M = BIT(7), ++ ++ RK3328_GMAC_RMII_SPEED_MASK = BIT(2), ++ RK3328_GMAC_RMII_SPEED_10 = 0, ++ RK3328_GMAC_RMII_SPEED_100 = BIT(2), ++ }; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ clk = RK3328_GMAC_RMII_CLK_2_5M | RK3328_GMAC_RMII_SPEED_10; ++ break; ++ case 100: ++ clk = RK3328_GMAC_RMII_CLK_25M | RK3328_GMAC_RMII_SPEED_100; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_GMAC_RMII_CLK_MASK | RK3328_GMAC_RMII_SPEED_MASK, ++ clk); ++ ++ return 0; ++} ++ ++static int rk3328_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3328_grf_regs *grf; + int clk; +@@ -248,7 +352,8 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3368_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3368_grf *grf; + int clk; +@@ -280,7 +385,8 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3399_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3399_grf_regs *grf; + int clk; +@@ -306,7 +412,8 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rv1108_set_rmii_speed(struct dw_eth_dev *priv) ++static int rv1108_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rv1108_grf *grf; + int clk, speed; +@@ -357,6 +464,28 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) + PX30_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3228_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_RMII_MODE_MASK = BIT(11), ++ RK3228_GRF_CON_RMII_MODE_SEL = BIT(11), ++ RK3228_RMII_MODE_MASK = BIT(10), ++ RK3228_RMII_MODE_SEL = BIT(10), ++ RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3228_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GRF_CON_RMII_MODE_MASK | ++ RK3228_RMII_MODE_MASK | ++ RK3228_GMAC_PHY_INTF_SEL_MASK, ++ RK3228_GRF_CON_RMII_MODE_SEL | ++ RK3228_RMII_MODE_SEL | ++ RK3228_GMAC_PHY_INTF_SEL_RMII); ++} ++ + static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) + { + struct rk322x_grf *grf; +@@ -435,6 +564,25 @@ static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) + RK3308_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3328_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_RMII_MODE_MASK = BIT(9), ++ RK3328_RMII_MODE = BIT(9), ++ ++ RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3328_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_RMII_MODE_MASK | ++ RK3328_GMAC_PHY_INTF_SEL_MASK, ++ RK3328_GMAC_PHY_INTF_SEL_RMII | ++ RK3328_RMII_MODE); ++} ++ + static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) + { + struct rk3328_grf_regs *grf; +@@ -550,6 +698,126 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) + RV1108_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3228_gmac_integrated_phy_powerup(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY_MASK = BIT(15), ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY = BIT(15), ++ }; ++ enum { ++ RK3228_MACPHY_CFG_CLK_50M_MASK = BIT(14), ++ RK3228_MACPHY_CFG_CLK_50M = BIT(14), ++ ++ RK3228_MACPHY_RMII_MODE_MASK = GENMASK(7, 6), ++ RK3228_MACPHY_RMII_MODE = BIT(6), ++ ++ RK3228_MACPHY_ENABLE_MASK = BIT(0), ++ RK3228_MACPHY_DISENABLE = 0, ++ RK3228_MACPHY_ENABLE = BIT(0), ++ }; ++ enum { ++ RK3228_RK_GRF_CON2_MACPHY_ID_MASK = GENMASK(6, 0), ++ RK3228_RK_GRF_CON2_MACPHY_ID = 0x1234, ++ }; ++ enum { ++ RK3228_RK_GRF_CON3_MACPHY_ID_MASK = GENMASK(5, 0), ++ RK3228_RK_GRF_CON3_MACPHY_ID = 0x35, ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->con_iomux, ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY_MASK, ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); ++ ++ rk_clrsetreg(&grf->macphy_con[2], ++ RK3228_RK_GRF_CON2_MACPHY_ID_MASK, ++ RK3228_RK_GRF_CON2_MACPHY_ID); ++ ++ rk_clrsetreg(&grf->macphy_con[3], ++ RK3228_RK_GRF_CON3_MACPHY_ID_MASK, ++ RK3228_RK_GRF_CON3_MACPHY_ID); ++ ++ /* disabled before trying to reset it */ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3228_MACPHY_CFG_CLK_50M_MASK | ++ RK3228_MACPHY_RMII_MODE_MASK | ++ RK3228_MACPHY_ENABLE_MASK, ++ RK3228_MACPHY_CFG_CLK_50M | ++ RK3228_MACPHY_RMII_MODE | ++ RK3228_MACPHY_DISENABLE); ++ ++ reset_assert(&pdata->phy_reset); ++ udelay(10); ++ reset_deassert(&pdata->phy_reset); ++ udelay(10); ++ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3228_MACPHY_ENABLE_MASK, ++ RK3228_MACPHY_ENABLE); ++ udelay(30 * 1000); ++} ++ ++static void rk3328_gmac_integrated_phy_powerup(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_GRF_CON_RMII_MODE_MASK = BIT(9), ++ RK3328_GRF_CON_RMII_MODE = BIT(9), ++ }; ++ enum { ++ RK3328_MACPHY_CFG_CLK_50M_MASK = BIT(14), ++ RK3328_MACPHY_CFG_CLK_50M = BIT(14), ++ ++ RK3328_MACPHY_RMII_MODE_MASK = GENMASK(7, 6), ++ RK3328_MACPHY_RMII_MODE = BIT(6), ++ ++ RK3328_MACPHY_ENABLE_MASK = BIT(0), ++ RK3328_MACPHY_DISENABLE = 0, ++ RK3328_MACPHY_ENABLE = BIT(0), ++ }; ++ enum { ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK = GENMASK(6, 0), ++ RK3328_RK_GRF_CON2_MACPHY_ID = 0x1234, ++ }; ++ enum { ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK = GENMASK(5, 0), ++ RK3328_RK_GRF_CON3_MACPHY_ID = 0x35, ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->macphy_con[1], ++ RK3328_GRF_CON_RMII_MODE_MASK, ++ RK3328_GRF_CON_RMII_MODE); ++ ++ rk_clrsetreg(&grf->macphy_con[2], ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON2_MACPHY_ID); ++ ++ rk_clrsetreg(&grf->macphy_con[3], ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON3_MACPHY_ID); ++ ++ /* disabled before trying to reset it */ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_CFG_CLK_50M_MASK | ++ RK3328_MACPHY_RMII_MODE_MASK | ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_CFG_CLK_50M | ++ RK3328_MACPHY_RMII_MODE | ++ RK3328_MACPHY_DISENABLE); ++ ++ reset_assert(&pdata->phy_reset); ++ udelay(10); ++ reset_deassert(&pdata->phy_reset); ++ udelay(10); ++ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_ENABLE); ++ udelay(30 * 1000); ++} ++ + static int gmac_rockchip_probe(struct udevice *dev) + { + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); +@@ -569,6 +837,9 @@ static int gmac_rockchip_probe(struct udevice *dev) + if (ret) + return ret; + ++ if (pdata->integrated_phy && ops->integrated_phy_powerup) ++ ops->integrated_phy_powerup(pdata); ++ + switch (eth_pdata->phy_interface) { + case PHY_INTERFACE_MODE_RGMII: + /* Set to RGMII mode */ +@@ -652,7 +923,7 @@ static int gmac_rockchip_probe(struct udevice *dev) + break; + + default: +- debug("NO interface defined!\n"); ++ debug("%s: no interface defined!\n", __func__); + return -ENXIO; + } + +@@ -661,18 +932,33 @@ static int gmac_rockchip_probe(struct udevice *dev) + + static int gmac_rockchip_eth_start(struct udevice *dev) + { +- struct eth_pdata *pdata = dev_get_platdata(dev); ++ struct eth_pdata *eth_pdata = dev_get_platdata(dev); + struct dw_eth_dev *priv = dev_get_priv(dev); + struct rk_gmac_ops *ops = + (struct rk_gmac_ops *)dev_get_driver_data(dev); ++ struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + int ret; + +- ret = designware_eth_init(priv, pdata->enetaddr); +- if (ret) +- return ret; +- ret = ops->fix_mac_speed(priv); ++ ret = designware_eth_init(priv, eth_pdata->enetaddr); + if (ret) + return ret; ++ ++ switch (eth_pdata->phy_interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ ret = ops->fix_rgmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ ret = ops->fix_rmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ default: ++ debug("%s: no interface defined!\n", __func__); ++ return -ENXIO; ++ } ++ + ret = designware_eth_enable(priv); + if (ret) + return ret; +@@ -690,42 +976,48 @@ const struct eth_ops gmac_rockchip_eth_ops = { + }; + + const struct rk_gmac_ops px30_gmac_ops = { +- .fix_mac_speed = px30_gmac_fix_mac_speed, ++ .fix_rmii_speed = px30_gmac_fix_rmii_speed, + .set_to_rmii = px30_gmac_set_to_rmii, + }; + + const struct rk_gmac_ops rk3228_gmac_ops = { +- .fix_mac_speed = rk3228_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3228_gmac_fix_rmii_speed, ++ .fix_rgmii_speed = rk3228_gmac_fix_rgmii_speed, ++ .set_to_rmii = rk3228_gmac_set_to_rmii, + .set_to_rgmii = rk3228_gmac_set_to_rgmii, ++ .integrated_phy_powerup = rk3228_gmac_integrated_phy_powerup, + }; + + const struct rk_gmac_ops rk3288_gmac_ops = { +- .fix_mac_speed = rk3288_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3288_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3288_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3308_gmac_ops = { +- .fix_mac_speed = rk3308_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3308_gmac_fix_rmii_speed, + .set_to_rmii = rk3308_gmac_set_to_rmii, + }; + + const struct rk_gmac_ops rk3328_gmac_ops = { +- .fix_mac_speed = rk3328_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3328_gmac_fix_rmii_speed, ++ .fix_rgmii_speed = rk3328_gmac_fix_rgmii_speed, ++ .set_to_rmii = rk3328_gmac_set_to_rmii, + .set_to_rgmii = rk3328_gmac_set_to_rgmii, ++ .integrated_phy_powerup = rk3328_gmac_integrated_phy_powerup, + }; + + const struct rk_gmac_ops rk3368_gmac_ops = { +- .fix_mac_speed = rk3368_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3368_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3368_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3399_gmac_ops = { +- .fix_mac_speed = rk3399_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3399_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3399_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rv1108_gmac_ops = { +- .fix_mac_speed = rv1108_set_rmii_speed, ++ .fix_rmii_speed = rv1108_gmac_fix_rmii_speed, + .set_to_rmii = rv1108_gmac_set_to_rmii, + }; + +diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c +index ae9fe9da..92514af1 100644 +--- a/drivers/net/gmac_rockchip.c ++++ b/drivers/net/gmac_rockchip.c +@@ -891,7 +891,7 @@ static int gmac_rockchip_probe(struct udevice *dev) + + if (!pdata->clock_input) { + rate = clk_set_rate(&clk, 50000000); +- if (rate != 50000000) ++ if (rate != 50000000 && rate != 49500000) + return -EINVAL; + } + break;