blob: 85c1caf86b4ff439b1e0181bc12ac2703089985d [file] [log] [blame]
/*
* Copyright 2017 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <debug.h>
#include <stdlib.h>
#include <stdint.h>
#include <platform_def.h>
#include <utils_def.h>
#include <mmio.h>
#include <imx_csu.h>
#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},
#if defined (CSU_RDC_TEST)
{CSU_CSLn_GPIO5, CSU_SSRW, 0},
#else
{CSU_CSLn_GPIO5, CSU_RW, 0},
#endif
{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},
{CSU_CSLn_RDC, CSU_RW, 0},
{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