/* * Copyright (c) 2021 Rockchip Electronics Co., Ltd * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; #define FIREWALL_DDR_BASE 0xfe030000 #define FW_DDR_MST5_REG 0x54 #define FW_DDR_MST13_REG 0x74 #define FW_DDR_MST19_REG 0x8c #define FW_DDR_MST21_REG 0x94 #define FW_DDR_MST26_REG 0xa8 #define FW_DDR_MST27_REG 0xac #define FIREWALL_SYSMEM_BASE 0xfe038000 #define FW_SYSM_MST5_REG 0x54 #define FW_SYSM_MST13_REG 0x74 #define FW_SYSM_MST19_REG 0x8c #define FW_SYSM_MST21_REG 0x94 #define FW_SYSM_MST26_REG 0xa8 #define FW_SYSM_MST27_REG 0xac #define PMU1_SGRF_BASE 0xfd582000 #define PMU1_SGRF_SOC_CON0 0x0 #define PMU1_SGRF_SOC_CON6 0x18 #define PMU1_SGRF_SOC_CON7 0x1c #define PMU1_SGRF_SOC_CON8 0x20 #define PMU1_SGRF_SOC_CON9 0x24 #define PMU1_SGRF_SOC_CON10 0x28 #define PMU1_SGRF_SOC_CON13 0x34 #define SYS_GRF_BASE 0xfd58c000 #define SYS_GRF_SOC_CON6 0x0318 #define USBGRF_BASE 0xfd5ac000 #define USB_GRF_USB3OTG0_CON1 0x001c #define BUS_SGRF_BASE 0xfd586000 #define BUS_SGRF_SOC_CON2 0x08 #define BUS_SGRF_FIREWALL_CON18 0x288 #define PMU_BASE 0xfd8d0000 #define PMU_PWR_GATE_SFTCON1 0x8150 #define USB2PHY1_GRF_BASE 0xfd5d4000 #define USB2PHY2_GRF_BASE 0xfd5d8000 #define USB2PHY3_GRF_BASE 0xfd5dc000 #define USB2PHY_GRF_CON2 0x0008 #define PMU1_IOC_BASE 0xfd5f0000 #define PMU2_IOC_BASE 0xfd5f4000 #define BUS_IOC_BASE 0xfd5f8000 #define BUS_IOC_GPIO2A_IOMUX_SEL_L 0x40 #define BUS_IOC_GPIO2A_IOMUX_SEL_H 0x44 #define BUS_IOC_GPIO2B_IOMUX_SEL_L 0x48 #define BUS_IOC_GPIO2B_IOMUX_SEL_H 0x4c #define BUS_IOC_GPIO2D_IOMUX_SEL_L 0x58 #define BUS_IOC_GPIO2D_IOMUX_SEL_H 0x5c #define BUS_IOC_GPIO3A_IOMUX_SEL_L 0x60 #define BUS_IOC_GPIO3A_IOMUX_SEL_H 0x64 #define BUS_IOC_GPIO3C_IOMUX_SEL_H 0x74 #define VCCIO3_5_IOC_BASE 0xfd5fa000 #define IOC_VCCIO3_5_GPIO2A_DS_H 0x44 #define IOC_VCCIO3_5_GPIO2B_DS_L 0x48 #define IOC_VCCIO3_5_GPIO2B_DS_H 0x4c #define IOC_VCCIO3_5_GPIO3A_DS_L 0x60 #define IOC_VCCIO3_5_GPIO3A_DS_H 0x64 #define IOC_VCCIO3_5_GPIO3C_DS_H 0x74 #define EMMC_IOC_BASE 0xfd5fd000 #define EMMC_IOC_GPIO2A_DS_L 0x40 #define EMMC_IOC_GPIO2D_DS_L 0x58 #define EMMC_IOC_GPIO2D_DS_H 0x5c #define CRU_BASE 0xfd7c0000 #define CRU_GPLL_CON1 0x01c4 #define CRU_SOFTRST_CON77 0x0b34 #define CRU_GLB_RST_CON 0x0c10 #define PMU1CRU_BASE 0xfd7f0000 #define PMU1CRU_SOFTRST_CON00 0x0a00 #define PMU1CRU_SOFTRST_CON03 0x0a0c #define PMU1CRU_SOFTRST_CON04 0x0a10 #define HDMIRX_NODE_FDT_PATH "/hdmirx-controller@fdee0000" #define RK3588_PHY_CONFIG 0xfdee00c0 #define VOP_M0_PRIORITY_REG 0xfdf82008 #define VOP_M1_PRIORITY_REG 0xfdf82208 #define QOS_PRIORITY_LEVEL(h, l) ((((h) & 7) << 8) | ((l) & 7)) #ifdef CONFIG_ARM64 #include static struct mm_region rk3588_mem_map[] = { { .virt = 0x0UL, .phys = 0x0UL, .size = 0xf0000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { .virt = 0xf0000000UL, .phys = 0xf0000000UL, .size = 0x10000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { .virt = 0x100000000UL, .phys = 0x100000000UL, .size = 0x700000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { .virt = 0x900000000, .phys = 0x900000000, .size = 0x150000000, .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 = rk3588_mem_map; #endif /* GPIO0B_IOMUX_SEL_L */ enum { GPIO0B0_SHIFT = 0, GPIO0B0_MASK = GENMASK(3, 0), GPIO0B0_UART0_RX_M1 = 4, GPIO0B1_SHIFT = 4, GPIO0B1_MASK = GENMASK(7, 4), GPIO0B1_UART0_TX_M1 = 4, }; /* GPIO0C_IOMUX_SEL_H */ enum { GPIO0C4_SHIFT = 0, GPIO0C4_MASK = GENMASK(3, 0), GPIO0C4_UART0_RX_M0 = 4, GPIO0C5_SHIFT = 4, GPIO0C5_MASK = GENMASK(7, 4), GPIO0C5_UART0_TX_M0 = 4, }; /* GPIO0B_IOMUX_SEL_H */ enum { GPIO0B5_SHIFT = 4, GPIO0B5_MASK = GENMASK(7, 4), GPIO0B5_REFER = 8, GPIO0B5_UART2_TX_M0 = 10, GPIO0B6_SHIFT = 8, GPIO0B6_MASK = GENMASK(11, 8), GPIO0B6_REFER = 8, GPIO0B6_UART2_RX_M0 = 10, }; /* GPIO0D_IOMUX_SEL_L */ enum { GPIO0D1_SHIFT = 4, GPIO0D1_MASK = GENMASK(7, 4), GPIO0D1_REFER = 8, GPIO0D1_UART1_TX_M2 = 10, GPIO0D2_SHIFT = 8, GPIO0D2_MASK = GENMASK(11, 8), GPIO0D2_REFER = 8, GPIO0D2_UART1_RX_M2 = 10, }; /* GPIO1A_IOMUX_SEL_L */ enum { GPIO1A0_SHIFT = 0, GPIO1A0_MASK = GENMASK(3, 0), GPIO1A0_UART6_RX_M1 = 10, GPIO1A1_SHIFT = 4, GPIO1A1_MASK = GENMASK(7, 4), GPIO1A1_UART6_TX_M1 = 10, }; /* GPIO1B_IOMUX_SEL_L */ enum { GPIO1B2_SHIFT = 8, GPIO1B2_MASK = GENMASK(11, 8), GPIO1B2_UART4_RX_M2 = 10, GPIO1B3_SHIFT = 12, GPIO1B3_MASK = GENMASK(15, 12), GPIO1B3_UART4_TX_M2 = 10, }; /* GPIO1B_IOMUX_SEL_H */ enum { GPIO1B4_SHIFT = 0, GPIO1B4_MASK = GENMASK(3, 0), GPIO1B4_UART7_RX_M2 = 10, GPIO1B5_SHIFT = 4, GPIO1B5_MASK = GENMASK(7, 4), GPIO1B5_UART7_TX_M2 = 10, GPIO1B6_SHIFT = 8, GPIO1B6_MASK = GENMASK(11, 8), GPIO1B6_UART1_TX_M1 = 10, GPIO1B7_SHIFT = 12, GPIO1B7_MASK = GENMASK(15, 12), GPIO1B7_UART1_RX_M1 = 10, }; /* GPIO1C_IOMUX_SEL_L */ enum { GPIO1C0_SHIFT = 0, GPIO1C0_MASK = GENMASK(3, 0), GPIO1C0_UART3_RX_M0 = 10, GPIO1C1_SHIFT = 4, GPIO1C1_MASK = GENMASK(7, 4), GPIO1C1_UART3_TX_M0 = 10, }; /* GPIO1D_IOMUX_SEL_L */ enum { GPIO1D0_SHIFT = 0, GPIO1D0_MASK = GENMASK(3, 0), GPIO1D0_UART6_TX_M2 = 10, GPIO1D1_SHIFT = 4, GPIO1D1_MASK = GENMASK(7, 4), GPIO1D1_UART6_RX_M2 = 10, GPIO1D2_SHIFT = 8, GPIO1D2_MASK = GENMASK(11, 8), GPIO1D2_UART4_TX_M0 = 10, GPIO1D3_SHIFT = 12, GPIO1D3_MASK = GENMASK(15, 12), GPIO1D3_UART4_RX_M0 = 10, }; /* GPIO2A_IOMUX_SEL_H */ enum { GPIO2A6_SHIFT = 8, GPIO2A6_MASK = GENMASK(11, 8), GPIO2A6_UART6_RX_M0 = 10, GPIO2A7_SHIFT = 12, GPIO2A7_MASK = GENMASK(15, 12), GPIO2A7_UART6_TX_M0 = 10, }; /* GPIO2B_IOMUX_SEL_H */ enum { GPIO2B4_SHIFT = 0, GPIO2B4_MASK = GENMASK(3, 0), GPIO2B4_UART7_RX_M0 = 10, GPIO2B5_SHIFT = 4, GPIO2B5_MASK = GENMASK(7, 4), GPIO2B5_UART7_TX_M0 = 10, GPIO2B6_SHIFT = 8, GPIO2B6_MASK = GENMASK(11, 8), GPIO2B6_UART1_RX_M0 = 10, GPIO2B7_SHIFT = 12, GPIO2B7_MASK = GENMASK(15, 12), GPIO2B7_UART1_TX_M0 = 10, }; /* GPIO2C_IOMUX_SEL_L */ enum { GPIO2C2_SHIFT = 8, GPIO2C2_MASK = GENMASK(11, 8), GPIO2C2_UART9_TX_M0 = 10, }; /* GPIO2C_IOMUX_SEL_H */ enum { GPIO2C4_SHIFT = 0, GPIO2C4_MASK = GENMASK(3, 0), GPIO2C4_UART9_RX_M0 = 10, }; /* GPIO2D_IOMUX_SEL_H */ enum { GPIO2D4_SHIFT = 0, GPIO2D4_MASK = GENMASK(3, 0), GPIO2D4_UART5_RX_M2 = 10, GPIO2D5_SHIFT = 4, GPIO2D5_MASK = GENMASK(7, 4), GPIO2D5_UART5_TX_M2 = 10, }; /* GPIO3A_IOMUX_SEL_H */ enum { GPIO3A2_SHIFT = 8, GPIO3A2_MASK = GENMASK(11, 8), GPIO3A2_UART8_TX_M1 = 10, GPIO3A3_SHIFT = 12, GPIO3A3_MASK = GENMASK(15, 12), GPIO3A3_UART8_RX_M1 = 10, }; /* GPIO3B_IOMUX_SEL_L */ enum { GPIO3B1_SHIFT = 4, GPIO3B1_MASK = GENMASK(7, 4), GPIO3B1_UART2_TX_M2 = 10, GPIO3B2_SHIFT = 8, GPIO3B2_MASK = GENMASK(11, 8), GPIO3B2_UART2_RX_M2 = 10, }; /* GPIO3B_IOMUX_SEL_H */ enum { GPIO3B5_SHIFT = 4, GPIO3B5_MASK = GENMASK(7, 4), GPIO3B5_UART3_TX_M1 = 10, GPIO3B6_SHIFT = 8, GPIO3B6_MASK = GENMASK(11, 8), GPIO3B6_UART3_RX_M1 = 10, }; /* GPIO3C_IOMUX_SEL_L */ enum { GPIO3C0_SHIFT = 0, GPIO3C0_MASK = GENMASK(3, 0), GPIO3C0_UART7_TX_M1 = 10, GPIO3C1_SHIFT = 4, GPIO3C1_MASK = GENMASK(7, 4), GPIO3C1_UART7_RX_M1 = 10, }; /* GPIO3C_IOMUX_SEL_H */ enum { GPIO3C4_SHIFT = 0, GPIO3C4_MASK = GENMASK(3, 0), GPIO3C4_UART5_TX_M1 = 10, GPIO3C5_SHIFT = 4, GPIO3C5_MASK = GENMASK(7, 4), GPIO3C5_UART5_RX_M1 = 10, }; /* GPIO3D_IOMUX_SEL_L */ enum { GPIO3D0_SHIFT = 0, GPIO3D0_MASK = GENMASK(3, 0), GPIO3D0_UART4_RX_M1 = 10, GPIO3D1_SHIFT = 4, GPIO3D1_MASK = GENMASK(7, 4), GPIO3D1_UART4_TX_M1 = 10, }; /* GPIO3D_IOMUX_SEL_H */ enum { GPIO3D4_SHIFT = 0, GPIO3D4_MASK = GENMASK(3, 0), GPIO3D4_UART9_RX_M2 = 10, GPIO3D5_SHIFT = 4, GPIO3D5_MASK = GENMASK(7, 4), GPIO3D5_UART9_TX_M2 = 10, }; /* GPIO4A_IOMUX_SEL_L */ enum { GPIO4A3_SHIFT = 12, GPIO4A3_MASK = GENMASK(15, 12), GPIO4A3_UART0_TX_M2 = 10, }; /* GPIO4A_IOMUX_SEL_H */ enum { GPIO4A4_SHIFT = 0, GPIO4A4_MASK = GENMASK(3, 0), GPIO4A4_UART0_RX_M2 = 10, GPIO4A5_SHIFT = 4, GPIO4A5_MASK = GENMASK(7, 4), GPIO4A5_UART3_TX_M2 = 10, GPIO4A6_SHIFT = 8, GPIO4A6_MASK = GENMASK(11, 8), GPIO4A6_UART3_RX_M2 = 10, }; /* GPIO4B_IOMUX_SEL_L */ enum { GPIO4B0_SHIFT = 0, GPIO4B0_MASK = GENMASK(3, 0), GPIO4B0_UART8_TX_M0 = 10, GPIO4B1_SHIFT = 4, GPIO4B1_MASK = GENMASK(7, 4), GPIO4B1_UART8_RX_M0 = 10, }; /* GPIO4B_IOMUX_SEL_H */ enum { GPIO4B4_SHIFT = 0, GPIO4B4_MASK = GENMASK(3, 0), GPIO4B4_UART9_TX_M1 = 10, GPIO4B5_SHIFT = 4, GPIO4B5_MASK = GENMASK(7, 4), GPIO4B5_UART9_RX_M1 = 10, }; /* GPIO4D_IOMUX_SEL_L */ enum { GPIO4D0_SHIFT = 0, GPIO4D0_MASK = GENMASK(3, 0), GPIO4D0_GPIO = 0, GPIO4D0_SDMMC_D0 = 1, GPIO4D0_PDM1_SDI3_M0 = 2, GPIO4D0_JTAG_TCK_M1 = 5, GPIO4D0_I2C3_SCL_M4 = 9, GPIO4D0_UART2_TX_M1 = 10, GPIO4D0_PWM8_M1 = 12, GPIO4D1_SHIFT = 4, GPIO4D1_MASK = GENMASK(7, 4), GPIO4D1_GPIO = 0, GPIO4D1_SDMMC_D1 = 1, GPIO4D1_PDM1_SDI2_M0 = 2, GPIO4D1_JTAG_TMS_M1 = 5, GPIO4D1_I2C3_SDA_M4 = 9, GPIO4D1_UART2_RX_M1 = 10, GPIO4D1_PWM9_M1 = 12, }; /* GPIO4D_IOMUX_SEL_H */ enum { GPIO4D4_SHIFT = 0, GPIO4D4_MASK = GENMASK(3, 0), GPIO4D4_UART5_RX_M0 = 10, GPIO4D5_SHIFT = 4, GPIO4D5_MASK = GENMASK(7, 4), GPIO4D5_UART5_TX_M0 = 10, }; void board_debug_uart_init(void) { __maybe_unused static struct rk3588_bus_ioc * const bus_ioc = (void *)BUS_IOC_BASE; /* UART 0 */ #if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfd890000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) static struct rk3588_pmu2_ioc * const pmu2_ioc = (void *)PMU2_IOC_BASE; /* UART0_M0 Switch iomux */ rk_clrsetreg(&pmu2_ioc->gpio0c_iomux_sel_h, GPIO0C4_MASK | GPIO0C5_MASK, GPIO0C4_UART0_RX_M0 << GPIO0C4_SHIFT | GPIO0C5_UART0_TX_M0 << GPIO0C5_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) static struct rk3588_pmu1_ioc * const pmu1_ioc = (void *)PMU1_IOC_BASE; /* UART0_M1 Switch iomux */ rk_clrsetreg(&pmu1_ioc->gpio0b_iomux_sel_l, GPIO0B0_MASK | GPIO0B1_MASK, GPIO0B0_UART0_RX_M1 << GPIO0B0_SHIFT | GPIO0B1_UART0_TX_M1 << GPIO0B1_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART0_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio4a_iomux_sel_h, GPIO4A4_MASK, GPIO4A4_UART0_RX_M2 << GPIO4A4_SHIFT); rk_clrsetreg(&bus_ioc->gpio4a_iomux_sel_l, GPIO4A3_MASK, GPIO4A3_UART0_TX_M2 << GPIO4A3_SHIFT); #endif /* UART 1 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfeb40000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART1_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio2b_iomux_sel_h, GPIO2B6_MASK | GPIO2B7_MASK, GPIO2B6_UART1_RX_M0 << GPIO2B6_SHIFT | GPIO2B7_UART1_TX_M0 << GPIO2B7_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART1_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio1b_iomux_sel_h, GPIO1B7_MASK | GPIO1B6_MASK, GPIO1B7_UART1_RX_M1 << GPIO1B7_SHIFT | GPIO1B6_UART1_TX_M1 << GPIO1B6_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) static struct rk3588_pmu2_ioc * const pmu2_ioc = (void *)PMU2_IOC_BASE; /* Refer to BUS_IOC */ rk_clrsetreg(&pmu2_ioc->gpio0d_iomux_sel_l, GPIO0D2_MASK | GPIO0D1_MASK, GPIO0D2_REFER << GPIO0D2_SHIFT | GPIO0D1_REFER << GPIO0D1_SHIFT); /* UART1_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio0d_iomux_sel_l, GPIO0D2_MASK | GPIO0D1_MASK, GPIO0D2_UART1_RX_M2 << GPIO0D2_SHIFT | GPIO0D1_UART1_TX_M2 << GPIO0D1_SHIFT); #endif /* UART 2 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfeb50000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) static struct rk3588_pmu2_ioc * const pmu2_ioc = (void *)PMU2_IOC_BASE; /* Refer to BUS_IOC */ rk_clrsetreg(&pmu2_ioc->gpio0b_iomux_sel_h, GPIO0B6_MASK | GPIO0B5_MASK, GPIO0B6_REFER << GPIO0B6_SHIFT | GPIO0B5_REFER << GPIO0B5_SHIFT); /* UART2_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio0b_iomux_sel_h, GPIO0B6_MASK | GPIO0B5_MASK, GPIO0B6_UART2_RX_M0 << GPIO0B6_SHIFT | GPIO0B5_UART2_TX_M0 << GPIO0B5_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART2_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio4d_iomux_sel_l, GPIO4D1_MASK | GPIO4D0_MASK, GPIO4D1_UART2_RX_M1 << GPIO4D1_SHIFT | GPIO4D0_UART2_TX_M1 << GPIO4D0_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART2_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio3b_iomux_sel_l, GPIO3B2_MASK | GPIO3B1_MASK, GPIO3B2_UART2_RX_M2 << GPIO3B2_SHIFT | GPIO3B1_UART2_TX_M2 << GPIO3B1_SHIFT); #endif /* UART 3 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfeb60000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART3_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio1c_iomux_sel_l, GPIO1C0_MASK | GPIO1C1_MASK, GPIO1C0_UART3_RX_M0 << GPIO1C0_SHIFT | GPIO1C1_UART3_TX_M0 << GPIO1C1_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART3_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio3b_iomux_sel_h, GPIO3B6_MASK | GPIO3B5_MASK, GPIO3B6_UART3_RX_M1 << GPIO3B6_SHIFT | GPIO3B5_UART3_TX_M1 << GPIO3B5_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART3_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio4a_iomux_sel_h, GPIO4A6_MASK | GPIO4A5_MASK, GPIO4A6_UART3_RX_M2 << GPIO4A6_SHIFT | GPIO4A5_UART3_TX_M2 << GPIO4A5_SHIFT); #endif /* UART 4 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfeb70000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART4_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio1d_iomux_sel_l, GPIO1D3_MASK | GPIO1D2_MASK, GPIO1D3_UART4_RX_M0 << GPIO1D3_SHIFT | GPIO1D2_UART4_TX_M0 << GPIO1D2_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART4_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio3d_iomux_sel_l, GPIO3D0_MASK | GPIO3D1_MASK, GPIO3D0_UART4_RX_M1 << GPIO3D0_SHIFT | GPIO3D1_UART4_TX_M1 << GPIO3D1_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART4_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio1b_iomux_sel_l, GPIO1B2_MASK | GPIO1B3_MASK, GPIO1B2_UART4_RX_M2 << GPIO1B2_SHIFT | GPIO1B3_UART4_TX_M2 << GPIO1B3_SHIFT); #endif /* UART 5 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfeb80000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART5_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio4d_iomux_sel_h, GPIO4D4_MASK | GPIO4D5_MASK, GPIO4D4_UART5_RX_M0 << GPIO4D4_SHIFT | GPIO4D5_UART5_TX_M0 << GPIO4D5_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART5_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio3c_iomux_sel_h, GPIO3C5_MASK | GPIO3C4_MASK, GPIO3C5_UART5_RX_M1 << GPIO3C5_SHIFT | GPIO3C4_UART5_TX_M1 << GPIO3C4_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART5_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio2d_iomux_sel_h, GPIO2D4_MASK | GPIO2D5_MASK, GPIO2D4_UART5_RX_M2 << GPIO2D4_SHIFT | GPIO2D5_UART5_TX_M2 << GPIO2D5_SHIFT); #endif /* UART 6 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfeb90000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART6_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio2a_iomux_sel_h, GPIO2A6_MASK | GPIO2A7_MASK, GPIO2A6_UART6_RX_M0 << GPIO2A6_SHIFT | GPIO2A7_UART6_TX_M0 << GPIO2A7_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART6_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio1a_iomux_sel_l, GPIO1A0_MASK | GPIO1A1_MASK, GPIO1A0_UART6_RX_M1 << GPIO1A0_SHIFT | GPIO1A1_UART6_TX_M1 << GPIO1A1_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART6_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio1d_iomux_sel_l, GPIO1D1_MASK | GPIO1D0_MASK, GPIO1D1_UART6_RX_M2 << GPIO1D1_SHIFT | GPIO1D0_UART6_TX_M2 << GPIO1D0_SHIFT); #endif /* UART 7 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfeba0000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART7_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio2b_iomux_sel_h, GPIO2B4_MASK | GPIO2B5_MASK, GPIO2B4_UART7_RX_M0 << GPIO2B4_SHIFT | GPIO2B5_UART7_TX_M0 << GPIO2B5_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART7_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio3c_iomux_sel_l, GPIO3C1_MASK | GPIO3C0_MASK, GPIO3C1_UART7_RX_M1 << GPIO3C1_SHIFT | GPIO3C0_UART7_TX_M1 << GPIO3C0_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART7_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio1b_iomux_sel_h, GPIO1B4_MASK | GPIO1B5_MASK, GPIO1B4_UART7_RX_M2 << GPIO1B4_SHIFT | GPIO1B5_UART7_TX_M2 << GPIO1B5_SHIFT); #endif /* UART 8 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfebb0000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART8_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio4b_iomux_sel_l, GPIO4B1_MASK | GPIO4B0_MASK, GPIO4B1_UART8_RX_M0 << GPIO4B1_SHIFT | GPIO4B0_UART8_TX_M0 << GPIO4B0_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART8_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio3a_iomux_sel_l, GPIO3A3_MASK | GPIO3A2_MASK, GPIO3A3_UART8_RX_M1 << GPIO3A3_SHIFT | GPIO3A2_UART8_TX_M1 << GPIO3A2_SHIFT); #endif /* UART 9 */ #elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xfebc0000) #if defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) /* UART9_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio2c_iomux_sel_h, GPIO2C4_MASK, GPIO2C4_UART9_RX_M0 << GPIO2C4_SHIFT); /* UART9_M0 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio2c_iomux_sel_l, GPIO2C2_MASK, GPIO2C2_UART9_TX_M0 << GPIO2C2_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* UART9_M1 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio4b_iomux_sel_h, GPIO4B5_MASK | GPIO4B4_MASK, GPIO4B5_UART9_RX_M1 << GPIO4B5_SHIFT | GPIO4B4_UART9_TX_M1 << GPIO4B4_SHIFT); #elif defined(CONFIG_ROCKCHIP_UART_MUX_SEL_M) && \ (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 2) /* UART9_M2 Switch iomux */ rk_clrsetreg(&bus_ioc->gpio3d_iomux_sel_h, GPIO3D4_MASK | GPIO3D5_MASK, GPIO3D4_UART9_RX_M2 << GPIO3D4_SHIFT | GPIO3D5_UART9_TX_M2 << GPIO3D5_SHIFT); #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); writel(0x1, CONFIG_ROCKCHIP_STIMER_BASE + 0x4); } static u32 gpio4d_iomux_sel_l = 0xffffffff; static u32 gpio4d_iomux_sel_h; static u32 gpio0a_iomux_sel_h; void spl_board_sd_iomux_save(void) { struct rk3588_bus_ioc * const bus_ioc = (void *)BUS_IOC_BASE; struct rk3588_pmu1_ioc * const pmu1_ioc = (void *)PMU1_IOC_BASE; gpio4d_iomux_sel_l = readl(&bus_ioc->gpio4d_iomux_sel_l); gpio4d_iomux_sel_h = readl(&bus_ioc->gpio4d_iomux_sel_h); gpio0a_iomux_sel_h = readl(&pmu1_ioc->gpio0a_iomux_sel_h); } void spl_board_storages_fixup(struct spl_image_loader *loader) { int ret = 0; if (!loader) return; if (loader->boot_device == BOOT_DEVICE_MMC2 && gpio4d_iomux_sel_l != 0xffffffff) { struct rk3588_bus_ioc * const bus_ioc = (void *)BUS_IOC_BASE; struct rk3588_pmu1_ioc * const pmu1_ioc = (void *)PMU1_IOC_BASE; struct mmc *mmc = NULL; bool no_card; ret = spl_mmc_find_device(&mmc, BOOT_DEVICE_MMC2); if (ret) return; no_card = mmc_getcd(mmc) == 0; if (no_card) { writel(0xffffuL << 16 | gpio4d_iomux_sel_l, &bus_ioc->gpio4d_iomux_sel_l); writel(0xffffuL << 16 | gpio4d_iomux_sel_h, &bus_ioc->gpio4d_iomux_sel_h); writel(0xffffuL << 16 | gpio0a_iomux_sel_h, &pmu1_ioc->gpio0a_iomux_sel_h); } } } #endif void board_set_iomux(enum if_type if_type, int devnum, int routing) { switch (if_type) { case IF_TYPE_MMC: /* * set the emmc io drive strength: * data and cmd: 50ohm * clock: 25ohm */ writel(0x00770052, EMMC_IOC_BASE + EMMC_IOC_GPIO2A_DS_L); writel(0x77772222, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_L); writel(0x77772222, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_H); /* set emmc iomux */ writel(0xffff1111, BUS_IOC_BASE + BUS_IOC_GPIO2A_IOMUX_SEL_L); writel(0xffff1111, BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_L); writel(0xffff1111, BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_H); break; case IF_TYPE_MTD: if (routing == 0) { writel(0x000f0002, BUS_IOC_BASE + BUS_IOC_GPIO2A_IOMUX_SEL_L); writel(0xffff2222, BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_L); writel(0x00f00020, BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_H); /* Set the fspi m0 io ds level to 55ohm */ writel(0x00070002, EMMC_IOC_BASE + EMMC_IOC_GPIO2A_DS_L); writel(0x77772222, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_L); writel(0x07000200, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_H); } else if (routing == 1) { writel(0xff003300, BUS_IOC_BASE + BUS_IOC_GPIO2A_IOMUX_SEL_H); writel(0xf0ff3033, BUS_IOC_BASE + BUS_IOC_GPIO2B_IOMUX_SEL_L); writel(0x000f0003, BUS_IOC_BASE + BUS_IOC_GPIO2B_IOMUX_SEL_H); /* Set the fspi m1 io ds level to 55ohm */ writel(0x33002200, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO2A_DS_H); writel(0x30332022, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO2B_DS_L); writel(0x00030002, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO2B_DS_H); } else if (routing == 2) { writel(0xffff5555, BUS_IOC_BASE + BUS_IOC_GPIO3A_IOMUX_SEL_L); writel(0x00f00050, BUS_IOC_BASE + BUS_IOC_GPIO3A_IOMUX_SEL_H); writel(0x00ff0022, BUS_IOC_BASE + BUS_IOC_GPIO3C_IOMUX_SEL_H); /* Set the fspi m2 io ds level to 55ohm */ writel(0x77772222, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO3A_DS_L); writel(0x00700020, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO3A_DS_H); writel(0x00070002, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO3C_DS_H); } break; default: break; } } #ifndef CONFIG_TPL_BUILD int arch_cpu_init(void) { #ifdef CONFIG_SPL_BUILD int secure_reg; /* Set the SDMMC eMMC crypto_ns FSPI access secure area */ secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST5_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST5_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST13_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST13_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST21_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST21_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST26_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST26_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST27_REG); secure_reg &= 0xffff0000; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST27_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST5_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST5_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST13_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST13_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST21_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST21_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST26_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST26_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST27_REG); secure_reg &= 0xffff0000; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST27_REG); /* * Select clk_tx source as default for i2s2/i2s3 * Set I2Sx_MCLK as input default * * It's safe to set mclk as input default to avoid high freq glitch * which may make devices work unexpected. And then enabled by * kernel stage or any state where user use it. */ writel(0x03c703c7, SYS_GRF_BASE + SYS_GRF_SOC_CON6); if (readl(BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_L) == 0x2222) { /* Set the fspi m0 io ds level to 55ohm */ writel(0x00070002, EMMC_IOC_BASE + EMMC_IOC_GPIO2A_DS_L); writel(0x77772222, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_L); writel(0x07000200, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_H); } else if (readl(BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_L) == 0x1111) { /* * set the emmc io drive strength: * data and cmd: 50ohm * clock: 25ohm */ writel(0x00770052, EMMC_IOC_BASE + EMMC_IOC_GPIO2A_DS_L); writel(0x77772222, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_L); writel(0x77772222, EMMC_IOC_BASE + EMMC_IOC_GPIO2D_DS_H); } else if ((readl(BUS_IOC_BASE + BUS_IOC_GPIO2B_IOMUX_SEL_L) & 0xf0ff) == 0x3033) { /* Set the fspi m1 io ds level to 55ohm */ writel(0x33002200, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO2A_DS_H); writel(0x30332022, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO2B_DS_L); writel(0x00030002, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO2B_DS_H); } else if (readl(BUS_IOC_BASE + BUS_IOC_GPIO3A_IOMUX_SEL_L) == 0x5555) { /* Set the fspi m2 io ds level to 55ohm */ writel(0x77772222, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO3A_DS_L); writel(0x00700020, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO3A_DS_H); writel(0x00070002, VCCIO3_5_IOC_BASE + IOC_VCCIO3_5_GPIO3C_DS_H); } /* * Assert reset the pipephy0, pipephy1 and pipephy2, * and de-assert reset them in Kernel combphy driver. */ writel(0x01c001c0, CRU_BASE + CRU_SOFTRST_CON77); /* * Assert SIDDQ for USB 2.0 PHY1, PHY2 and PHY3 to * power down all analog block to save power. And * PHY0 for OTG0 interface still in normal mode. */ writel(0x20002000, USB2PHY1_GRF_BASE + USB2PHY_GRF_CON2); writel(0x20002000, USB2PHY2_GRF_BASE + USB2PHY_GRF_CON2); writel(0x20002000, USB2PHY3_GRF_BASE + USB2PHY_GRF_CON2); /* Assert hdptxphy init,cmn,lane reset */ writel(0xb800b800, PMU1CRU_BASE + PMU1CRU_SOFTRST_CON03); writel(0x00030003, PMU1CRU_BASE + PMU1CRU_SOFTRST_CON04); spl_board_sd_iomux_save(); #elif defined(CONFIG_SUPPORT_USBPLUG) int secure_reg; /* Set the SDMMC eMMC crypto_ns FSPI access secure area */ secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST5_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST5_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST13_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST13_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST21_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST21_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST26_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST26_REG); secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST27_REG); secure_reg &= 0xffff0000; writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST27_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST5_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST5_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST13_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST13_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST21_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST21_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST26_REG); secure_reg &= 0xffff; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST26_REG); secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST27_REG); secure_reg &= 0xffff0000; writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST27_REG); #else /* U-Boot */ /* uboot: config iomux */ #ifdef CONFIG_ROCKCHIP_EMMC_IOMUX /* Set emmc iomux for good extention if the emmc is not the boot device */ writel(0xffff1111, BUS_IOC_BASE + BUS_IOC_GPIO2A_IOMUX_SEL_L); writel(0xffff1111, BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_L); writel(0xffff1111, BUS_IOC_BASE + BUS_IOC_GPIO2D_IOMUX_SEL_H); #endif /* * set VOP M0 and VOP M1 to priority 0x303,then * Peri > VOP/MCU > ISP/VICAP > other * Note: VOP priority can only be modified during the u-boot stage, * as VOP default power down, and power up after trust. */ writel(QOS_PRIORITY_LEVEL(3, 3), VOP_M0_PRIORITY_REG); writel(QOS_PRIORITY_LEVEL(3, 3), VOP_M1_PRIORITY_REG); #endif /* Select usb otg0 phy status to 0 that make rockusb can work at high-speed */ writel(0x00080008, USBGRF_BASE + USB_GRF_USB3OTG0_CON1); return 0; } #endif #define BAD_CPU(mask, n) ((mask) & (1 << (n))) #define BAD_RKVENC(mask, n) ((mask) & (1 << (n))) #define BAD_RKVDEC(mask, n) ((mask) & (1 << (n))) static void fdt_rm_path(void *blob, const char *path) { fdt_del_node(blob, fdt_path_offset(blob, path)); } static void fdt_rename_path(void *blob, const char *path, const char *name) { int noffset; noffset = fdt_path_offset(blob, path); if (noffset < 0) return; fdt_set_name(blob, noffset, name); } static void fdt_rm_cooling_map(const void *blob, u8 cpu_mask) { int map1, map2; int cpub1_phd; int cpub3_phd; int node; u32 *pp; node = fdt_path_offset(blob, "/cpus/cpu@500"); cpub1_phd = fdtdec_get_uint(blob, node, "phandle", -1); node = fdt_path_offset(blob, "/cpus/cpu@700"); cpub3_phd = fdtdec_get_uint(blob, node, "phandle", -1); if (BAD_CPU(cpu_mask, 4)) { map1 = fdt_path_offset(blob, "/thermal-zones/soc-thermal/cooling-maps/map1"); if (map1 > 0) { if (BAD_CPU(cpu_mask, 5)) { debug("rm: cooling-device map1\n"); fdt_del_node((void *)blob, map1); } else { pp = (u32 *)fdt_getprop(blob, map1, "cooling-device", NULL); if (pp) { pp[0] = cpu_to_fdt32(cpub1_phd); debug("fix: cooling-device cpub0->cpub1\n"); } } } } if (BAD_CPU(cpu_mask, 6)) { map2 = fdt_path_offset(blob, "/thermal-zones/soc-thermal/cooling-maps/map2"); if (map2 > 0) { if (BAD_CPU(cpu_mask, 7)) { debug("rm: cooling-device map2\n"); fdt_del_node((void *)blob, map2); } else { pp = (u32 *)fdt_getprop(blob, map2, "cooling-device", NULL); if (pp) { pp[0] = cpu_to_fdt32(cpub3_phd); debug("fix: cooling-device cpub2->cpub3\n"); } } } } } static void fdt_rm_cpu_affinity(const void *blob, u8 cpu_mask) { int i, remain, arm_pmu; u32 new_aff[8]; u32 *aff; arm_pmu = fdt_path_offset(blob, "/arm-pmu"); if (arm_pmu > 0) { aff = (u32 *)fdt_getprop(blob, arm_pmu, "interrupt-affinity", NULL); if (!aff) return; for (i = 0, remain = 0; i < 8; i++) { if (!BAD_CPU(cpu_mask, i)) { new_aff[remain++] = aff[i]; debug("new_aff: 0x%08x\n", (u32)aff[i]); } } fdt_setprop((void *)blob, arm_pmu, "interrupt-affinity", new_aff, remain * 4); } } static void fdt_rm_cpu(const void *blob, u8 cpu_mask) { const char *cpu_node_name[] = { "cpu@0", "cpu@100", "cpu@200", "cpu@300", "cpu@400", "cpu@500", "cpu@600", "cpu@700", }; const char *cluster_core_name[] = { "core0", "core1", "core2", "core3", "core0", "core1", "core0", "core1", }; const char *cluster_core, *cpu_node; int root_cpus, cpu; int cluster; int i; root_cpus = fdt_path_offset(blob, "/cpus"); if (root_cpus < 0) return; for (i = 0; i < 8; i++) { if (!BAD_CPU(cpu_mask, i)) continue; if (i < 4) cluster = fdt_path_offset(blob, "/cpus/cpu-map/cluster0"); else if (i < 6) cluster = fdt_path_offset(blob, "/cpus/cpu-map/cluster1"); else cluster = fdt_path_offset(blob, "/cpus/cpu-map/cluster2"); if (cluster < 0) return; cpu_node = cpu_node_name[i]; cluster_core = cluster_core_name[i]; debug("rm: %s, %s\n", cpu_node, cluster_core); cpu = fdt_subnode_offset(blob, cluster, cluster_core); if (cpu > 0) fdt_del_node((void *)blob, cpu); cpu = fdt_subnode_offset(blob, root_cpus, cpu_node); if (cpu > 0) fdt_del_node((void *)blob, cpu); } cluster = fdt_path_offset(blob, "/cpus/cpu-map/cluster1"); if (BAD_CPU(cpu_mask, 4) && BAD_CPU(cpu_mask, 5)) { debug("rm: cpu cluster1\n"); fdt_del_node((void *)blob, cluster); } cluster = fdt_path_offset(blob, "/cpus/cpu-map/cluster2"); if (BAD_CPU(cpu_mask, 6) && BAD_CPU(cpu_mask, 7)) { debug("rm: cpu cluster2\n"); fdt_del_node((void *)blob, cluster); } else { /* rename, otherwise linux only handles cluster0 */ if (fdt_path_offset(blob, "/cpus/cpu-map/cluster1") < 0) fdt_set_name((void *)blob, cluster, "cluster1"); } } static void rk3582_fdt_rm_cpus(const void *blob, u8 cpu_mask) { /* * policy: * * 1. both of cores within the same cluster should be normal, otherwise * remove both of them. * 2. if core4~7 are all normal, remove core6 and core7 anyway. */ if (BAD_CPU(cpu_mask, 4) || BAD_CPU(cpu_mask, 5)) cpu_mask |= BIT(4) | BIT(5); if (BAD_CPU(cpu_mask, 6) || BAD_CPU(cpu_mask, 7)) cpu_mask |= BIT(6) | BIT(7); if (!BAD_CPU(cpu_mask, 4) & !BAD_CPU(cpu_mask, 5) && !BAD_CPU(cpu_mask, 6) & !BAD_CPU(cpu_mask, 7)) cpu_mask |= BIT(6) | BIT(7); fdt_rm_cooling_map(blob, cpu_mask); fdt_rm_cpu_affinity(blob, cpu_mask); fdt_rm_cpu(blob, cpu_mask); } static void rk3582_fdt_rm_gpu(void *blob) { /* * policy: * * Remove GPU by default. */ fdt_rm_path(blob, "/gpu@fb000000"); fdt_rm_path(blob, "/thermal-zones/soc-thermal/cooling-maps/map3"); debug("rm: gpu\n"); } static void rk3582_fdt_rm_rkvdec01(void *blob) { /* * policy: * * Remove rkvdec0 and rkvdec1 by default. */ fdt_rm_path(blob, "/rkvdec-core@fdc38000"); fdt_rm_path(blob, "/iommu@fdc38700"); fdt_rm_path(blob, "/rkvdec-core@fdc48000"); fdt_rm_path(blob, "/iommu@fdc48700"); debug("rm: rkvdec0, rkvdec1\n"); } static void rk3582_fdt_rm_rkvenc01(void *blob, u8 mask) { /* * policy: * * 1. remove bad. * 2. if both of rkvenc0 and rkvenc1 are normal, remove rkvenc1 by default. * 3. disable '*-ccu' node * 4. rename '*-core@' node */ if (!BAD_RKVENC(mask, 0) && !BAD_RKVENC(mask, 1)) { /* rkvenc1 */ fdt_rm_path(blob, "/rkvenc-core@fdbe0000"); fdt_rm_path(blob, "/iommu@fdbef000"); debug("rm: rkvenv1\n"); } else { if (BAD_RKVENC(mask, 0)) { fdt_rm_path(blob, "/rkvenc-core@fdbd0000"); fdt_rm_path(blob, "/iommu@fdbdf000"); debug("rm: rkvenv0\n"); } if (BAD_RKVENC(mask, 1)) { fdt_rm_path(blob, "/rkvenc-core@fdbe0000"); fdt_rm_path(blob, "/iommu@fdbef000"); debug("rm: rkvenv1\n"); } } do_fixup_by_path((void *)blob, "/rkvenc-ccu", "status", "disabled", sizeof("disabled"), 0); /* rename node name if the node exist, actually only one exist */ fdt_rename_path(blob, "/rkvenc-core@fdbd0000", "rkvenc@fdbd0000"); fdt_rename_path(blob, "/rkvenc-core@fdbe0000", "rkvenc@fdbe0000"); } static void rk3583_fdt_rm_rkvdec01(void *blob, u8 mask) { /* * policy: * * 1. remove bad. * 2. if both of rkvdec0 and rkvdec1 are normal, remove rkvdec1 by default. * 3. disable '*-ccu' node * 4. rename '*-core@' node */ if (!BAD_RKVDEC(mask, 0) && !BAD_RKVDEC(mask, 1)) { /* rkvdec1 */ fdt_rm_path(blob, "/rkvdec-core@fdc48000"); fdt_rm_path(blob, "/iommu@fdc48700"); debug("rm: rkvdec1\n"); } else { if (BAD_RKVDEC(mask, 0)) { fdt_rm_path(blob, "/rkvdec-core@fdc38000"); fdt_rm_path(blob, "/iommu@fdc38700"); debug("rm: rkvdec0\n"); } if (BAD_RKVDEC(mask, 1)) { fdt_rm_path(blob, "/rkvdec-core@fdc48000"); fdt_rm_path(blob, "/iommu@fdc48700"); debug("rm: rkvdec1\n"); } } do_fixup_by_path((void *)blob, "/rkvdec-ccu@fdc30000", "status", "disabled", sizeof("disabled"), 0); /* rename node name if the node exist, actually only one exist */ fdt_rename_path(blob, "/rkvdec-core@fdc38000", "rkvdec@fdc38000"); fdt_rename_path(blob, "/rkvdec-core@fdc48000", "rkvdec@fdc48000"); } #define CHIP_ID_OFF 2 #define IP_STATE_OFF 29 static int fdt_fixup_modules(void *blob) { struct udevice *dev; u8 ip_state[3]; u8 chip_id[2]; u8 rkvenc_mask; u8 rkvdec_mask; u8 cpu_mask; int ret; ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(rockchip_otp), &dev); if (ret) { printf("can't get otp device, ret=%d\n", ret); return ret; } ret = misc_read(dev, CHIP_ID_OFF, &chip_id, sizeof(chip_id)); if (ret) { printf("can't read chip id, ret=%d\n", ret); return ret; } debug("# chip: rk%02x%02x\n", chip_id[0], chip_id[1]); /* only rk3582/rk3583 goes further */ if (!(chip_id[0] == 0x35 && chip_id[1] == 0x82) && !(chip_id[0] == 0x35 && chip_id[1] == 0x83)) return 0; ret = misc_read(dev, IP_STATE_OFF, &ip_state, sizeof(ip_state)); if (ret) { printf("can't read ip state, ret=%d\n", ret); return ret; } /* ip_state[0]: bit0~7 */ cpu_mask = ip_state[0]; /* ip_state[2]: bit0,2 */ rkvenc_mask = (ip_state[2] & 0x1) | ((ip_state[2] & 0x4) >> 1); /* ip_state[1]: bit6,7 */ rkvdec_mask = (ip_state[1] & 0xc0) >> 6; #if 0 /* ip_state[1]: bit1~4 */ gpu_mask = (ip_state[1] & 0x1e) >> 1; #endif debug("hw-mask: 0x%02x, 0x%02x, 0x%02x\n", ip_state[0], ip_state[1], ip_state[2]); debug("sw-mask: 0x%02x, 0x%02x, 0x%02x\n", cpu_mask, rkvenc_mask, rkvdec_mask); /* * FIXUP WARNING! * * The node delete changes the fdt structure, a node offset you already * got before maybe not right by now. Make sure always reading the node * offset exactly before you are going to use. */ if (chip_id[0] == 0x35 && chip_id[1] == 0x82) { /* * RK3582 Policy: gpu/rkvdec are removed by default, the same for other * IP under some condition. * * So don't use pattern like "if (rkvenc_mask) then rk3582_fdt_rm_rkvenc01()", * just go through all of them as this chip is rk3582. */ rk3582_fdt_rm_gpu(blob); rk3582_fdt_rm_rkvdec01(blob); rk3582_fdt_rm_rkvenc01(blob, rkvenc_mask); rk3582_fdt_rm_cpus(blob, cpu_mask); } else if (chip_id[0] == 0x35 && chip_id[1] == 0x83) { /* * RK3583 Policy: some rules are the same as rk3582. */ rk3583_fdt_rm_rkvdec01(blob, rkvdec_mask); rk3582_fdt_rm_rkvenc01(blob, rkvenc_mask); rk3582_fdt_rm_cpus(blob, cpu_mask); } return 0; } int rk_board_dm_fdt_fixup(const void *blob) { return fdt_fixup_modules((void *)blob); } int rk_board_fdt_fixup(const void *blob) { int node; /* set hdmirx to low power mode */ node = fdt_path_offset(blob, HDMIRX_NODE_FDT_PATH); if (node >= 0) { if (fdtdec_get_int(blob, node, "low-power-mode", 0)) { printf("hdmirx low power mode\n"); writel(0x00000100, RK3588_PHY_CONFIG); } } return 0; } #ifdef CONFIG_SPL_BUILD int spl_fit_standalone_release(char *id, uintptr_t entry_point) { u32 val; /* pmu m0 configuration: */ /* set gpll */ writel(0x00f00042, CRU_BASE + CRU_GPLL_CON1); /* set pmu mcu to access ddr memory */ val = readl(FIREWALL_DDR_BASE + FW_DDR_MST19_REG); writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST19_REG); /* set pmu mcu to access system memory */ val = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST19_REG); writel(val & 0x000000ff, FIREWALL_SYSMEM_BASE + FW_SYSM_MST19_REG); /* set pmu mcu to secure */ writel(0x00080000, PMU1_SGRF_BASE + PMU1_SGRF_SOC_CON0); /* set start addr, pmu_mcu_code_addr_start */ writel(0xFFFF0000 | (entry_point >> 16), PMU1_SGRF_BASE + PMU1_SGRF_SOC_CON9); /* set pmu_mcu_sram_addr_start */ writel(0xFFFF2000, PMU1_SGRF_BASE + PMU1_SGRF_SOC_CON10); /* set pmu_mcu_tcm_addr_start */ writel(0xFFFF2000, PMU1_SGRF_BASE + PMU1_SGRF_SOC_CON13); /* set cache cache_peripheral_addr */ /* 0xf0000000 ~ 0xfee00000 */ writel(0xffff0000, PMU1_SGRF_BASE + PMU1_SGRF_SOC_CON6); writel(0xffffee00, PMU1_SGRF_BASE + PMU1_SGRF_SOC_CON7); writel(0x00ff00ff, PMU1_SGRF_BASE + PMU1_SGRF_SOC_CON8); /* enable PMU WDT reset system */ writel(0x02000200, BUS_SGRF_BASE + BUS_SGRF_SOC_CON2); /* select WDT trigger global reset. */ writel(0x08400840, CRU_BASE + CRU_GLB_RST_CON); /* release pmu mcu */ /* writel(0x20000000, PMU1CRU_BASE + PMU1CRU_SOFTRST_CON00); */ return 0; } #endif