/* * Copyright 2017 NXP * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include #include #include #define CSU_HP0_OFFSET (0x200) #define CSU_HP1_OFFSET (0x204) #define CSU_SA_OFFSET (0x218) #define CSU_HPC0_OFFSET (0x358) #define CSU_HPC1_OFFSET (0x35C) /* Default CSU slaves CSLn settings */ static struct csu_slave_conf csu_def_csl_conf[] = { {CSU_CSLn_GPIO1, CSU_RW, 0}, {CSU_CSLn_GPIO2, CSU_RW, 0}, {CSU_CSLn_GPIO3, CSU_RW, 0}, {CSU_CSLn_GPIO4, CSU_RW, 0}, {CSU_CSLn_GPIO5, CSU_RW, 0}, {CSU_CSLn_Reserved1, CSU_RW, 0}, {CSU_CSLn_ANA_TSENSOR, CSU_RW, 0}, {CSU_CSLn_ANA_OSC, CSU_RW, 0}, {CSU_CSLn_WDOG1, CSU_RW, 0}, {CSU_CSLn_WDOG2, CSU_RW, 0}, {CSU_CSLn_WDOG3, CSU_RW, 0}, {CSU_CSLn_SDMA2, CSU_RW, 0}, {CSU_CSLn_GPT1, CSU_RW, 0}, {CSU_CSLn_GPT2, CSU_RW, 0}, {CSU_CSLn_GPT3, CSU_RW, 0}, {CSU_CSLn_ROMCP, CSU_RW, 0}, {CSU_CSLn_LCDIF, CSU_RW, 0}, {CSU_CSLn_IOMUXC, CSU_RW, 0}, {CSU_CSLn_IOMUXC_GPR, CSU_RW, 0}, {CSU_CSLn_OCOTP_CTRL, CSU_RW, 0}, {CSU_CSLn_ANATOP_PLL, CSU_RW, 0}, {CSU_CSLn_SNVS_HP, CSU_RW, 0}, {CSU_CSLn_CCM, CSU_RW, 0}, {CSU_CSLn_SRC, CSU_RW, 0}, {CSU_CSLn_GPC, CSU_RW, 0}, {CSU_CSLn_SEMAPHORE1, CSU_RW, 0}, {CSU_CSLn_SEMAPHORE2, CSU_RW, 0}, #if defined(CSU_RDC_TEST) {CSU_CSLn_RDC, CSU_SSRW, 0}, #else {CSU_CSLn_RDC, CSU_RW, 0}, #endif {CSU_CSLn_CSU, CSU_RW, 0}, {CSU_CSLn_MST0, CSU_RW, 0}, {CSU_CSLn_MST1, CSU_RW, 0}, {CSU_CSLn_MST2, CSU_RW, 0}, {CSU_CSLn_MST3, CSU_RW, 0}, {CSU_CSLn_HDMI_SEC, CSU_RW, 0}, {CSU_CSLn_PWM1, CSU_RW, 0}, {CSU_CSLn_PWM2, CSU_RW, 0}, {CSU_CSLn_PWM3, CSU_RW, 0}, {CSU_CSLn_PWM4, CSU_RW, 0}, {CSU_CSLn_SysCounter_RD, CSU_RW, 0}, {CSU_CSLn_SysCounter_CMP, CSU_RW, 0}, {CSU_CSLn_SysCounter_CTRL, CSU_RW, 0}, {CSU_CSLn_HDMI_CTRL, CSU_RW, 0}, {CSU_CSLn_GPT6, CSU_RW, 0}, {CSU_CSLn_GPT5, CSU_RW, 0}, {CSU_CSLn_GPT4, CSU_RW, 0}, {CSU_CSLn_TZASC, CSU_RW, 0}, {CSU_CSLn_MTR, CSU_RW, 0}, {CSU_CSLn_PERFMON1, CSU_RW, 0}, {CSU_CSLn_PERFMON2, CSU_RW, 0}, {CSU_CSLn_PLATFORM_CTRL, CSU_RW, 0}, {CSU_CSLn_QoSC, CSU_RW, 0}, {CSU_CSLn_MIPI_PHY, CSU_RW, 0}, {CSU_CSLn_MIPI_DSI, CSU_RW, 0}, {CSU_CSLn_I2C1, CSU_RW, 0}, {CSU_CSLn_I2C2, CSU_RW, 0}, {CSU_CSLn_I2C3, CSU_RW, 0}, {CSU_CSLn_I2C4, CSU_RW, 0}, {CSU_CSLn_UART4, CSU_RW, 0}, {CSU_CSLn_MIPI_CSI1, CSU_RW, 0}, {CSU_CSLn_MIPI_CSI_PHY1, CSU_RW, 0}, {CSU_CSLn_CSI1, CSU_RW, 0}, {CSU_CSLn_MU_A, CSU_RW, 0}, {CSU_CSLn_MU_B, CSU_RW, 0}, {CSU_CSLn_SEMAPHORE_HS, CSU_RW, 0}, {CSU_CSLn_SAI1, CSU_RW, 0}, {CSU_CSLn_SAI6, CSU_RW, 0}, {CSU_CSLn_SAI5, CSU_RW, 0}, {CSU_CSLn_SAI4, CSU_RW, 0}, {CSU_CSLn_USDHC1, CSU_RW, 0}, {CSU_CSLn_USDHC2, CSU_RW, 0}, {CSU_CSLn_MIPI_CSI2, CSU_RW, 0}, {CSU_CSLn_MIPI_CSI_PHY2, CSU_RW, 0}, {CSU_CSLn_CSI2, CSU_RW, 0}, {CSU_CSLn_QSPI, CSU_RW, 0}, {CSU_CSLn_SDMA1, CSU_RW, 0}, {CSU_CSLn_ENET1, CSU_RW, 0}, {CSU_CSLn_SPDIF1, CSU_RW, 0}, {CSU_CSLn_ECSPI1, CSU_RW, 0}, {CSU_CSLn_ECSPI2, CSU_RW, 0}, {CSU_CSLn_ECSPI3, CSU_RW, 0}, {CSU_CSLn_UART1, CSU_RW, 0}, {CSU_CSLn_UART3, CSU_RW, 0}, {CSU_CSLn_UART2, CSU_RW, 0}, {CSU_CSLn_SPDIF2, CSU_RW, 0}, {CSU_CSLn_SAI2, CSU_RW, 0}, {CSU_CSLn_SAI3, CSU_RW, 0}, {CSU_CSLn_SPBA1, CSU_RW, 0}, {CSU_CSLn_MOD_EN3, CSU_RW, 0}, {CSU_CSLn_MOD_EN0, CSU_RW, 0}, {CSU_CSLn_CAAM, CSU_RW, 0}, {CSU_CSLn_DDRC_SEC, CSU_RW, 0}, {CSU_CSLn_GIC_EXSC, CSU_RW, 0}, {CSU_CSLn_USB_EXSC, CSU_RW, 0}, {CSU_CSLn_OCRAM_TZ, CSU_RW, 0}, {CSU_CSLn_OCRAM_S_TZ, CSU_RW, 0}, {CSU_CSLn_VPU_SEC, CSU_RW, 0}, {CSU_CSLn_DAP_EXSC, CSU_RW, 0}, {CSU_CSLn_ROMCP_SEC, CSU_RW, 0}, {CSU_CSLn_APBHDMA_SEC, CSU_RW, 0}, {CSU_CSLn_M4_SEC, CSU_RW, 0}, {CSU_CSLn_QSPI_SEC, CSU_RW, 0}, {CSU_CSLn_GPU_EXSC, CSU_RW, 0}, {CSU_CSLn_Internal1, CSU_RW, 0}, {CSU_CSLn_Internal2, CSU_RW, 0}, {CSU_CSLn_Internal3, CSU_RW, 0}, {CSU_CSLn_Internal4, CSU_RW, 0}, {CSU_CSLn_Internal5, CSU_RW, 0}, {CSU_CSLn_Internal6, CSU_RW, 0}, }; /* Default Secure Access configuration */ static struct csu_sa_conf sa_def_configs[] = { {CSU_SA_VPU, 1, 1}, {CSU_SA_GPU, 1, 1}, {CSU_SA_DCSS, 1, 1}, }; void csu_set_slave_index_mode(enum csu_csln_idx index, uint16_t mode, uint8_t lock) { uintptr_t reg; uint32_t tmp; uint16_t read_mode; uint8_t read_lock = 0; /* Check if CSLn is locked or the value is same as written */ csu_get_slave_index_mode(index, &read_mode, &read_lock); if (read_lock) { NOTICE("CSU CSLn(%d) already locked with mode:0x%x\n", index, read_mode); return; } if (read_mode == mode) { NOTICE("CSU CSLn(%d) mode 0x%x already written\n", index, read_mode); return; } reg = (uintptr_t)(IMX_CSU_BASE + (index / 2) * 4); tmp = mmio_read_32(reg); if (lock) mode |= 1 << 8; if (index % 2) { tmp &= 0x0000ffff; tmp |= mode << 16; } else { tmp &= 0xffff0000; tmp |= mode; } mmio_write_32(reg, tmp); } void csu_get_slave_index_mode(enum csu_csln_idx index, uint16_t *mode, uint8_t *lock) { uintptr_t reg; uint32_t tmp; reg = (uintptr_t)(IMX_CSU_BASE + (index / 2) * 4); tmp = mmio_read_32(reg); if (index % 2) tmp = tmp >> 16; tmp &= 0x1ff; *mode = tmp & 0xff; *lock = tmp >> 8; } void csu_set_slaves_modes(struct csu_slave_conf *csu_config, uint32_t count) { int i; for (i = 0; i < count; i++) { csu_set_slave_index_mode(csu_config[i].index, csu_config[i].mode, csu_config[i].lock); } } void csu_set_default_slaves_modes(void) { NOTICE("csu_set_default_slaves_modes: count = %d \n", (int)ARRAY_SIZE(csu_def_csl_conf)); csu_set_slaves_modes(csu_def_csl_conf, (uint32_t)ARRAY_SIZE(csu_def_csl_conf)); } void csu_set_hp_index_config(enum csu_hp_idx index, uint8_t enable, uint8_t set_control, uint8_t lock) { uint32_t tmp, value; uintptr_t reg; if (index < 16){ reg = (uintptr_t)(IMX_CSU_BASE + CSU_HP0_OFFSET); tmp = mmio_read_32(reg); value = 0x3 << (index * 2); tmp &= ~value; value = (lock * 2 | enable) << (index * 2); tmp |= value; mmio_write_32(reg, tmp); if (set_control) { reg = (uintptr_t)(IMX_CSU_BASE + CSU_HPC0_OFFSET); tmp = mmio_read_32(reg); value = (lock * 2 | set_control) << (index * 2); tmp &= ~value; tmp |= value; mmio_write_32(reg, tmp); } } else { reg = (uintptr_t)(IMX_CSU_BASE + CSU_HP1_OFFSET); mmio_write_32(reg,lock * 2 | enable); if (set_control) { reg = (uintptr_t)(IMX_CSU_BASE + CSU_HPC1_OFFSET); mmio_write_32(reg,lock * 2 | set_control); } } } void csu_set_sa_index_config(enum csu_sa_idx index, uint8_t enable, uint8_t lock) { uint32_t tmp, value; uintptr_t reg; reg = (uintptr_t)(IMX_CSU_BASE + CSU_SA_OFFSET); tmp = mmio_read_32((uintptr_t)reg); value = 0x3 << (index * 2); tmp &= ~value; value = (lock * 2 | enable) << (index * 2); tmp |= value; mmio_write_32(reg, tmp); } void csu_get_sa_index_config(enum csu_sa_idx index, uint8_t *enable, uint8_t *lock) { uint32_t tmp; uintptr_t reg; reg = (uintptr_t)(IMX_CSU_BASE + CSU_SA_OFFSET); tmp = mmio_read_32((uintptr_t)reg); *enable = (tmp >> (index * 2)) & 1; *lock = (tmp >> (index * 2 + 1)) & 1; } void csu_set_sa_configs(struct csu_sa_conf *sa_conf, uint32_t count) { int i; for (i = 0; i < count; i++) csu_set_sa_index_config(sa_conf[i].index, sa_conf[i].enable, sa_conf[i].lock); } void csu_set_default_secure_configs(void) { csu_set_sa_configs(sa_def_configs, (uint32_t)ARRAY_SIZE(sa_def_configs)); } #if defined (CSU_RDC_TEST) void csu_test(void) { csu_set_default_slaves_modes(); } #endif