luckfox-pico-sdk/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/rk3528/rk3528.c
2023-08-08 20:36:47 +08:00

525 lines
14 KiB
C

/*
* Copyright (c) 2020 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/hardware.h>
#include <asm/arch/grf_rk3528.h>
#include <asm/arch/ioc_rk3528.h>
DECLARE_GLOBAL_DATA_PTR;
#define FIREWALL_DDR_BASE 0xff2e0000
#define FW_DDR_MST1_REG 0x44
#define FW_DDR_MST6_REG 0x58
#define FW_DDR_MST7_REG 0x5c
#define FW_DDR_MST11_REG 0x6c
#define FW_DDR_MST14_REG 0x78
#define FW_DDR_MST16_REG 0x80
#define FW_DDR_MST_REG 0xf0
#define PMU_SGRF_BASE 0xff440000
#define PMU_SGRF_SOC_CON4 0x10
#define PMU_SGRF_SOC_CON5 0x14
#define PMU_SGRF_SOC_CON6 0x18
#define PMU_SGRF_SOC_CON8 0x20
#define PMU_SGRF_SOC_CON11 0x2c
#define PMU_CRU_BASE 0xff4b0000
#define PMU_CRU_GATE_CON00 0x800
#define PMU_CRU_SOFTRST_CON00 0xa00
#define VPU_IOC_BASE 0xff560000
#define GPIO1C_IOMUX_SEL_1 0x034
#define GPIO1D_IOMUX_SEL_0 0x038
#define GPIO1D_IOMUX_SEL_1 0x03c
#define CPU_PRIORITY_REG 0xff210008
#define QOS_PRIORITY_LEVEL(h, l) ((((h) & 7) << 8) | ((l) & 7))
#ifdef CONFIG_ARM64
#include <asm/armv8/mmu.h>
static struct mm_region rk3528_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 0xfc000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0xfc000000UL,
.phys = 0xfc000000UL,
.size = 0x04000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* List terminator */
0,
}
};
struct mm_region *mem_map = rk3528_mem_map;
#endif
#define GPIO0_IOC_BASE 0xFF540000
#define GPIO1_IOC_BASE 0xFF560000
#define GPIO2_IOC_BASE 0xFF570000
#define GPIO3_IOC_BASE 0xFF560000
#define GPIO4_IOC_BASE 0xFF550000
#define GPIO1_IOC_GPIO1D_IOMUX_SEL_L (GPIO1_IOC_BASE + 0x38)
#define GPIO1_IOC_GPIO1C_DS_2 (GPIO1_IOC_BASE + 0x148)
#define GPIO1_IOC_GPIO1C_DS_3 (GPIO1_IOC_BASE + 0x14C)
#define GPIO1_IOC_GPIO1D_DS_0 (GPIO1_IOC_BASE + 0x150)
#define GPIO1_IOC_GPIO1D_DS_1 (GPIO1_IOC_BASE + 0x154)
#define GPIO1_IOC_GPIO1D_DS_2 (GPIO1_IOC_BASE + 0x158)
/* uart0 iomux */
/* gpio4c7 */
#define UART0_RX_M0 1
#define UART0_RX_M0_OFFSET 12
#define UART0_RX_M0_ADDR (GPIO4_IOC_BASE + 0x94)
/* gpio4d0 */
#define UART0_TX_M0 1
#define UART0_TX_M0_OFFSET 0
#define UART0_TX_M0_ADDR (GPIO4_IOC_BASE + 0x98)
/* gpio2a0 */
#define UART0_RX_M1 2
#define UART0_RX_M1_OFFSET 0
#define UART0_RX_M1_ADDR (GPIO2_IOC_BASE + 0x40)
/* gpio2a1 */
#define UART0_TX_M1 2
#define UART0_TX_M1_OFFSET 4
#define UART0_TX_M1_ADDR (GPIO2_IOC_BASE + 0x40)
/* uart1 iomux */
/* gpio4a7 */
#define UART1_RX_M0 2
#define UART1_RX_M0_OFFSET 12
#define UART1_RX_M0_ADDR (GPIO1_IOC_BASE + 0x84)
/* gpio4a6 */
#define UART1_TX_M0 2
#define UART1_TX_M0_OFFSET 8
#define UART1_TX_M0_ADDR (GPIO1_IOC_BASE + 0x84)
/* gpio4c6 */
#define UART1_RX_M1 2
#define UART1_RX_M1_OFFSET 8
#define UART1_RX_M1_ADDR (GPIO4_IOC_BASE + 0x94)
/* gpio4c5 */
#define UART1_TX_M1 2
#define UART1_TX_M1_OFFSET 4
#define UART1_TX_M1_ADDR (GPIO4_IOC_BASE + 0x94)
/* uart2 iomux */
/* gpio3a0 */
#define UART2_RX_M0 1
#define UART2_RX_M0_OFFSET 0
#define UART2_RX_M0_ADDR (GPIO3_IOC_BASE + 0x60)
/* gpio3a1 */
#define UART2_TX_M0 1
#define UART2_TX_M0_OFFSET 4
#define UART2_TX_M0_ADDR (GPIO3_IOC_BASE + 0x60)
/* gpio1b0 */
#define UART2_RX_M1 1
#define UART2_RX_M1_OFFSET 0
#define UART2_RX_M1_ADDR (GPIO1_IOC_BASE + 0x28)
/* gpio1b1 */
#define UART2_TX_M1 1
#define UART2_TX_M1_OFFSET 4
#define UART2_TX_M1_ADDR (GPIO1_IOC_BASE + 0x28)
/* uart3 iomux */
/* gpio4b0 */
#define UART3_RX_M0 2
#define UART3_RX_M0_OFFSET 0
#define UART3_RX_M0_ADDR (GPIO4_IOC_BASE + 0x88)
/* gpio4b1 */
#define UART3_TX_M0 2
#define UART3_TX_M0_OFFSET 4
#define UART3_TX_M0_ADDR (GPIO4_IOC_BASE + 0x88)
/* gpio4b7 */
#define UART3_RX_M1 3
#define UART3_RX_M1_OFFSET 12
#define UART3_RX_M1_ADDR (GPIO4_IOC_BASE + 0x8C)
/* gpio4c0 */
#define UART3_TX_M1 3
#define UART3_TX_M1_OFFSET 0
#define UART3_TX_M1_ADDR (GPIO4_IOC_BASE + 0x90)
/* uart4 iomux */
/* gpio2a2 */
#define UART4_RX_M0 3
#define UART4_RX_M0_OFFSET 8
#define UART4_RX_M0_ADDR (GPIO2_IOC_BASE + 0x40)
/* gpio2a3 */
#define UART4_TX_M0 3
#define UART4_TX_M0_OFFSET 12
#define UART4_TX_M0_ADDR (GPIO2_IOC_BASE + 0x40)
/* uart5 iomux */
/* gpio1a2 */
#define UART5_RX_M0 2
#define UART5_RX_M0_OFFSET 8
#define UART5_RX_M0_ADDR (GPIO1_IOC_BASE + 0x20)
/* gpio1a3 */
#define UART5_TX_M0 2
#define UART5_TX_M0_OFFSET 12
#define UART5_TX_M0_ADDR (GPIO1_IOC_BASE + 0x20)
/* gpio1d4 */
#define UART5_RX_M1 2
#define UART5_RX_M1_OFFSET 0
#define UART5_RX_M1_ADDR (GPIO1_IOC_BASE + 0x3c)
/* gpio1d7 */
#define UART5_TX_M1 2
#define UART5_TX_M1_OFFSET 12
#define UART5_TX_M1_ADDR (GPIO1_IOC_BASE + 0x3c)
/* uart6 iomux */
/* gpio3a7 */
#define UART6_RX_M0 4
#define UART6_RX_M0_OFFSET 12
#define UART6_RX_M0_ADDR (GPIO3_IOC_BASE + 0x64)
/* gpio3a6 */
#define UART6_TX_M0 4
#define UART6_TX_M0_OFFSET 8
#define UART6_TX_M0_ADDR (GPIO3_IOC_BASE + 0x64)
/* gpio3c3 */
#define UART6_RX_M1 4
#define UART6_RX_M1_OFFSET 12
#define UART6_RX_M1_ADDR (GPIO3_IOC_BASE + 0x70)
/* gpio3c1 */
#define UART6_TX_M1 4
#define UART6_TX_M1_OFFSET 4
#define UART6_TX_M1_ADDR (GPIO3_IOC_BASE + 0x70)
/* uart7 iomux */
/* gpio3b3 */
#define UART7_RX_M0 4
#define UART7_RX_M0_OFFSET 12
#define UART7_RX_M0_ADDR (GPIO3_IOC_BASE + 0x68)
/* gpio3b2 */
#define UART7_TX_M0 4
#define UART7_TX_M0_OFFSET 8
#define UART7_TX_M0_ADDR (GPIO3_IOC_BASE + 0x68)
/* gpio1b3 */
#define UART7_RX_M1 4
#define UART7_RX_M1_OFFSET 12
#define UART7_RX_M1_ADDR (GPIO1_IOC_BASE + 0x28)
/* gpio1b2 */
#define UART7_TX_M1 4
#define UART7_TX_M1_OFFSET 8
#define UART7_TX_M1_ADDR (GPIO1_IOC_BASE + 0x28)
#define set_uart_iomux(bits_offset, bits_val, addr) \
writel(GENMASK(bits_offset + 19, bits_offset + 16) | (bits_val << bits_offset) , addr)
#define set_uart_iomux_rx(ID, MODE) \
set_uart_iomux(UART##ID##_RX_M##MODE##_OFFSET, UART##ID##_RX_M##MODE, UART##ID##_RX_M##MODE##_ADDR);
#define set_uart_iomux_tx(ID, MODE) \
set_uart_iomux(UART##ID##_TX_M##MODE##_OFFSET, UART##ID##_TX_M##MODE, UART##ID##_TX_M##MODE##_ADDR);
void board_debug_uart_init(void)
{
/* UART 0 */
#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff9f0000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART0_M0 Switch iomux */
set_uart_iomux_rx(0, 0);
set_uart_iomux_tx(0, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART0_M1 Switch iomux */
set_uart_iomux_rx(0, 1);
set_uart_iomux_tx(0, 1);
#endif
/* UART 1 */
#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff9f8000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART1_M0 Switch iomux */
set_uart_iomux_rx(1, 0);
set_uart_iomux_tx(1, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART1_M1 Switch iomux */
set_uart_iomux_rx(1, 1);
set_uart_iomux_tx(1, 1);
#endif
/* UART 2 */
#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xffa00000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART2_M0 Switch iomux */
set_uart_iomux_rx(2, 0);
set_uart_iomux_tx(2, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART2_M1 Switch iomux */
set_uart_iomux_rx(2, 1);
set_uart_iomux_tx(2, 1);
#endif
/* UART 3 */
#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xffa08000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART3_M0 Switch iomux */
set_uart_iomux_rx(3, 0);
set_uart_iomux_tx(3, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART3_M1 Switch iomux */
set_uart_iomux_rx(3, 1);
set_uart_iomux_tx(3, 1);
#endif
/* UART 4 */
#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xffa10000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART4_M0 Switch iomux */
set_uart_iomux_rx(4, 0);
set_uart_iomux_tx(4, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART4_M1 Switch iomux */
set_uart_iomux_rx(4, 1);
set_uart_iomux_tx(4, 1);
#endif
/* UART 5 */
#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xffa18000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART5_M0 Switch iomux */
set_uart_iomux_rx(5, 0);
set_uart_iomux_tx(5, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART5_M1 Switch iomux */
set_uart_iomux_rx(5, 1);
set_uart_iomux_tx(5, 1);
#endif
/* UART 6 */
#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xffa20000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART6_M0 Switch iomux */
set_uart_iomux_rx(6, 0);
set_uart_iomux_tx(6, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART6_M1 Switch iomux */
set_uart_iomux_rx(6, 1);
set_uart_iomux_tx(6, 1);
#endif
/* UART 7 */
#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xffa28000)
#if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
/* UART7_M0 Switch iomux */
set_uart_iomux_rx(7, 0);
set_uart_iomux_tx(7, 0);
#elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \
(CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
/* UART7_M1 Switch iomux */
set_uart_iomux_rx(7, 1);
set_uart_iomux_tx(7, 1);
#endif
#endif
}
#ifdef CONFIG_SPL_BUILD
void rockchip_stimer_init(void)
{
/* If Timer already enabled, don't re-init it */
u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x4);
if (reg & 0x1)
return;
asm volatile("msr CNTFRQ_EL0, %0" : : "r" (COUNTER_FREQUENCY));
writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x14);
writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x18);
dsb();
writel(0x1, CONFIG_ROCKCHIP_STIMER_BASE + 0x4);
}
#endif
int arch_cpu_init(void)
{
#if defined(CONFIG_SPL_BUILD)
u32 val;
/* Set the emmc to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST6_REG);
writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST6_REG);
/* Set the sdmmc to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST14_REG);
writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST14_REG);
/* Set the crypto to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST1_REG);
writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST1_REG);
#if defined(CONFIG_ROCKCHIP_SFC)
/* Set the fspi to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST7_REG);
writel(val & 0xffff0000, FIREWALL_DDR_BASE + FW_DDR_MST7_REG);
#endif
#ifndef CONFIG_TPL_BUILD
/* Set cpu qos priority, then
* Peri > VOP > CPU = RKVDEC/RKVENC/VPU > GPU/RGA/Other
*/
writel(QOS_PRIORITY_LEVEL(2, 2), CPU_PRIORITY_REG);
#endif
if (readl(GPIO1_IOC_GPIO1D_IOMUX_SEL_L) == 0x1111) {
/*
* set the emmc io drive strength:
* data and cmd: level 3
* clock: level 5
*/
writel(0x3F3F0F0F, GPIO1_IOC_GPIO1C_DS_2);
writel(0x3F3F0F0F, GPIO1_IOC_GPIO1C_DS_3);
writel(0x3F3F0F0F, GPIO1_IOC_GPIO1D_DS_0);
writel(0x3F3F0F0F, GPIO1_IOC_GPIO1D_DS_1);
writel(0x3F3F3F0F, GPIO1_IOC_GPIO1D_DS_2);
}
#elif defined(CONFIG_SUPPORT_USBPLUG)
u32 val;
/* Set the usb to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST16_REG);
writel(val & 0xffff0000, FIREWALL_DDR_BASE + FW_DDR_MST16_REG);
/* Set the emmc to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST6_REG);
writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST6_REG);
/* Set emmc iomux */
writel(0xffff1111, VPU_IOC_BASE + GPIO1C_IOMUX_SEL_1);
writel(0xffff1111, VPU_IOC_BASE + GPIO1D_IOMUX_SEL_0);
writel(0xffff1111, VPU_IOC_BASE + GPIO1D_IOMUX_SEL_1);
#if defined(CONFIG_ROCKCHIP_SFC)
/* Set the fspi to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST7_REG);
writel(val & 0xFFFF0000uL, FIREWALL_DDR_BASE + FW_DDR_MST7_REG);
/* Set fspi iomux */
writel(0xffff2222, VPU_IOC_BASE + GPIO1C_IOMUX_SEL_1);
writel(0x000f0002, VPU_IOC_BASE + GPIO1D_IOMUX_SEL_0);
writel(0x00f00020, VPU_IOC_BASE + GPIO1D_IOMUX_SEL_1);
#endif
#endif
return 0;
}
#ifdef CONFIG_SPL_BUILD
int spl_fit_standalone_release(char *id, uintptr_t entry_point)
{
u32 val;
/* open clk_pmu_mcu_jtag / clk_mcu_32k_en / fclk_mcu_en */
writel(0x05800000, PMU_CRU_BASE + PMU_CRU_GATE_CON00);
/* set the mcu to access ddr memory */
val = readl(FIREWALL_DDR_BASE + FW_DDR_MST11_REG);
writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST11_REG);
/* writel(0x00000000, FIREWALL_DDR_BASE + FW_DDR_MST_REG); */
/* set the mcu to secure */
writel(0x00200000, PMU_SGRF_BASE + PMU_SGRF_SOC_CON4);
/* open mcu_debug_en / mcu_dclk_en / mcu_hclk_en / mcu_sclk_en */
writel(0x000f000f, PMU_SGRF_BASE + PMU_SGRF_SOC_CON5);
/* set start addr, mcu_code_addr_start */
writel(0xffff0000 | (entry_point >> 16), PMU_SGRF_BASE + PMU_SGRF_SOC_CON6);
/* mcu_tcm_addr_start, multiplex pmu sram address */
writel(0xffffff10, PMU_SGRF_BASE + PMU_SGRF_SOC_CON11);
/* jtag_mcu_m0 gpio2a4/gpio2a5 iomux */
/* writel(0x00ff0022, GPIO2_IOC_BASE + 0x44); */
/* release the mcu */
writel(0x00800000, PMU_CRU_BASE + PMU_CRU_SOFTRST_CON00);
return 0;
}
#endif
#if CONFIG_IS_ENABLED(CLK_SCMI)
#include <clk.h>
#include <asm/arch/clock.h>
#include <dt-bindings/clock/rk3528-cru.h>
int set_armclk_rate(void)
{
struct clk clk;
u32 *rate = NULL;
int size, count;
int ret;
ret = rockchip_get_scmi_clk(&clk.dev);
if (ret) {
printf("Failed to get scmi clk, ret=%d\n", ret);
return ret;
}
size = dev_read_size(clk.dev, "rockchip,clk-init");
if (size < 0)
return 0;
count = size / sizeof(u32);
rate = calloc(count, sizeof(u32));
if (!rate)
return -ENOMEM;
ret = dev_read_u32_array(clk.dev, "rockchip,clk-init", rate, count);
if (ret) {
printf("Failed to get 'rockchip,clk-init' prop\n");
goto out;
}
clk.id = SCMI_CLK_CPU;
ret = clk_set_rate(&clk, rate[0]);
if (ret < 0) {
printf("Failed to set cpu %dhz, ret=%d\n", rate[0], ret);
goto out;
}
out:
free(rate);
return 0;
}
#endif