Merge pull request #1557 from sivadur/integration

Xilinx latest platform related changes
This commit is contained in:
Dimitris Papastamos 2018-09-05 12:18:01 +01:00 committed by GitHub
commit 8e7940d15b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 239 additions and 78 deletions

View File

@ -44,19 +44,10 @@ unsigned int zynqmp_get_uart_clk(void)
{
unsigned int ver = zynqmp_get_silicon_ver();
switch (ver) {
case ZYNQMP_CSU_VERSION_VELOCE:
return 48000;
case ZYNQMP_CSU_VERSION_EP108:
return 25000000;
case ZYNQMP_CSU_VERSION_QEMU:
if (ver == ZYNQMP_CSU_VERSION_QEMU)
return 133000000;
default:
/* Do nothing in default case */
break;
}
return 100000000;
else
return 100000000;
}
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
@ -298,12 +289,6 @@ static void zynqmp_print_platform_name(void)
char *label = "Unknown";
switch (ver) {
case ZYNQMP_CSU_VERSION_VELOCE:
label = "VELOCE";
break;
case ZYNQMP_CSU_VERSION_EP108:
label = "EP108";
break;
case ZYNQMP_CSU_VERSION_QEMU:
label = "QEMU";
break;
@ -346,17 +331,8 @@ unsigned int plat_get_syscnt_freq2(void)
{
unsigned int ver = zynqmp_get_silicon_ver();
switch (ver) {
case ZYNQMP_CSU_VERSION_VELOCE:
return 10000;
case ZYNQMP_CSU_VERSION_EP108:
return 4000000;
case ZYNQMP_CSU_VERSION_QEMU:
if (ver == ZYNQMP_CSU_VERSION_QEMU)
return 50000000;
default:
/* Do nothing in default case */
break;
}
return mmio_read_32(IOU_SCNTRS_BASEFREQ);
else
return mmio_read_32(IOU_SCNTRS_BASEFREQ);
}

View File

@ -17,6 +17,10 @@ ENABLE_SVE_FOR_NS := 0
WORKAROUND_CVE_2017_5715 := 0
ARM_XLAT_TABLES_LIB_V1 := 1
$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
ifdef ZYNQMP_ATF_MEM_BASE
$(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))

View File

@ -25,7 +25,6 @@
#define CLK_TOPOLOGY_NODE_OFFSET U(16)
#define CLK_TOPOLOGY_PAYLOAD_LEN U(12)
#define CLK_PARENTS_PAYLOAD_LEN U(12)
#define CLK_INIT_ENABLE_SHIFT U(1)
#define CLK_TYPE_SHIFT U(2)
#define CLK_CLKFLAGS_SHIFT U(8)
#define CLK_TYPEFLAGS_SHIFT U(24)
@ -337,7 +336,8 @@ static struct pm_clock_node acpu_nodes[] = {
.width = PERIPH_GATE_WIDTH,
.clkflags = CLK_SET_RATE_PARENT |
CLK_IGNORE_UNUSED |
CLK_IS_BASIC,
CLK_IS_BASIC |
CLK_IS_CRITICAL,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@ -496,7 +496,7 @@ static struct pm_clock_node ddr_nodes[] = {
.type = TYPE_DIV1,
.offset = 8,
.width = 6,
.clkflags = CLK_IS_BASIC,
.clkflags = CLK_IS_BASIC | CLK_IS_CRITICAL,
.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
.mult = NA_MULT,
.div = NA_DIV,
@ -2022,12 +2022,11 @@ static struct pm_clock clocks[] = {
},
[CLK_WDT] = {
.name = "wdt",
.control_reg = IOU_SLCR_WDT_CLK_SEL,
.control_reg = FPD_SLCR_WDT_CLK_SEL,
.status_reg = 0,
.parents = &((int32_t []) {
CLK_TOPSW_LSBUS,
EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT,
EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
CLK_NA_PARENT
}),
.nodes = &wdt_nodes,
@ -2243,12 +2242,6 @@ static struct pm_ext_clock ext_clocks[] = {
/* Array of clock which are invalid for this variant */
static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB};
/* Array of clocks which needs to be enabled at init */
static uint32_t pm_clk_init_enable_list[] = {
CLK_ACPU,
CLK_DDR_REF,
};
/**
* pm_clock_valid - Check if clock is valid or not
* @clock_id Id of the clock to be queried
@ -2272,26 +2265,6 @@ static bool pm_clock_valid(unsigned int clock_id)
return 1;
}
/**
* pm_clock_init_enable - Check if clock needs to be enabled at init
* @clock_id Id of the clock to be queried
*
* This function is used to check if given clock needs to be enabled
* at boot up or not. Some clocks needs to be enabled at init.
*
* Return: Returns 1 if clock needs to be enabled at boot up else 0.
*/
static unsigned int pm_clock_init_enable(unsigned int clock_id)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(pm_clk_init_enable_list); i++)
if (pm_clk_init_enable_list[i] == clock_id)
return 1;
return 0;
}
/**
* pm_clock_type - Get clock's type
* @clock_id Id of the clock to be queried
@ -2509,9 +2482,6 @@ enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
/* Clock valid bit */
*attr = pm_clock_valid(clock_id);
/* If clock needs to be enabled during init */
*attr |= (pm_clock_init_enable(clock_id) << CLK_INIT_ENABLE_SHIFT);
/* Clock type (Output/External) */
*attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
@ -2657,10 +2627,11 @@ enum pm_ret_status pm_api_clock_enable(unsigned int clock_id)
if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
return PM_RET_ERROR_NOTSUPPORTED;
if (ISPLL(clock_id))
ret = pm_api_pll_bypass_and_reset(clock_id,
CLK_PLL_RESET_PULSE);
else
/*
* PLL type clock should not enable explicitly.
* It is done by FSBL on boot-up and by PMUFW whenever required.
*/
if (!ISPLL(clock_id))
ret = pm_api_clk_enable_disable(clock_id, 1);
return ret;
@ -2686,10 +2657,11 @@ enum pm_ret_status pm_api_clock_disable(unsigned int clock_id)
if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
return PM_RET_ERROR_NOTSUPPORTED;
if (ISPLL(clock_id))
ret = pm_api_pll_bypass_and_reset(clock_id,
CLK_PLL_RESET_ASSERT);
else
/*
* PLL type clock should not be disabled explicitly.
* It is done by PMUFW if required.
*/
if (!ISPLL(clock_id))
ret = pm_api_clk_enable_disable(clock_id, 0);
return ret;
@ -2837,8 +2809,13 @@ static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id,
unsigned int divider)
{
unsigned int reg = clocks[clock_id].control_reg;
enum pm_ret_status ret;
return pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT);
pm_api_pll_bypass_and_reset(clock_id, CLK_PLL_RESET_ASSERT);
ret = pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT);
pm_api_pll_bypass_and_reset(clock_id, CLK_PLL_RESET_RELEASE);
return ret;
}
/**
@ -2988,7 +2965,7 @@ enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
/**
* pm_api_clock_setparent - Set the clock parent for given id
* @clock_id Id of the clock
* @parent_id parent id
* @parent_idx parent index
*
* This function is used by master to set parent for any clock.
*
@ -3039,7 +3016,7 @@ enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
/**
* pm_api_clock_getparent - Get the clock parent for given id
* @clock_id Id of the clock
* @parent_id parent id
* @parent_idx parent index
*
* This function is used by master to get parent index
* for any clock.

View File

@ -452,6 +452,48 @@ static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
0xFFFFFFFFU, value);
}
/**
* pm_ioctl_afi() - Ioctl function for writing afi values
*
* @index AFI register index
* @value Register value to be written
*
*
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_afi(unsigned int index,
unsigned int value)
{
unsigned int mask;
unsigned int regarr[] = {0xFD360000,
0xFD360014,
0xFD370000,
0xFD370014,
0xFD380000,
0xFD380014,
0xFD390000,
0xFD390014,
0xFD3a0000,
0xFD3a0014,
0xFD3b0000,
0xFD3b0014,
0xFF9b0000,
0xFF9b0014,
0xFD615000,
0xFF419000,
};
if (index >= ARRAY_SIZE(regarr))
return PM_RET_ERROR_ARGS;
if (index < AFIFM6_WRCTRL)
mask = FABRIC_WIDTH;
else
mask = 0xf00;
return pm_mmio_write(regarr[index], mask, value);
}
/**
* pm_ioctl_read_pggs() - Ioctl function for reading persistent
* global general storage (pggs)
@ -471,6 +513,54 @@ static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
}
/**
* pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
*
* This function peerforms the ULPI reset sequence for resetting
* the ULPI transceiver.
*
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_ulpi_reset(void)
{
enum pm_ret_status ret;
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_HIGH);
if (ret != PM_RET_SUCCESS)
return ret;
/* Drive ULPI assert for atleast 1ms */
mdelay(1);
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_LOW);
if (ret != PM_RET_SUCCESS)
return ret;
/* Drive ULPI de-assert for atleast 1ms */
mdelay(1);
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_HIGH);
return ret;
}
/**
* pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
*
* This function sets healthy bit value to indicate boot health status
* to firmware.
*
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
{
return pm_mmio_write(PM_BOOT_HEALTH_STATUS_REG,
PM_BOOT_HEALTH_STATUS_MASK, value);
}
/**
* pm_api_ioctl() - PM IOCTL API for device control and configs
* @node_id Node ID of the device
@ -540,6 +630,15 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
case IOCTL_READ_PGGS:
ret = pm_ioctl_read_pggs(arg1, value);
break;
case IOCTL_ULPI_RESET:
ret = pm_ioctl_ulpi_reset();
break;
case IOCTL_SET_BOOT_HEALTH_STATUS:
ret = pm_ioctl_set_boot_health_status(arg1);
break;
case IOCTL_AFI:
ret = pm_ioctl_afi(arg1, arg2);
break;
default:
ret = PM_RET_ERROR_NOTSUPPORTED;
break;

View File

@ -32,6 +32,11 @@ enum {
IOCTL_READ_GGS,
IOCTL_WRITE_PGGS,
IOCTL_READ_PGGS,
/* IOCTL for ULPI reset */
IOCTL_ULPI_RESET,
/* Set healthy bit value */
IOCTL_SET_BOOT_HEALTH_STATUS,
IOCTL_AFI,
};
//RPU operation mode

View File

@ -601,6 +601,30 @@ enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}
/**
* pm_aes_engine() - Aes data blob encryption/decryption
* This function provides access to the xilsecure library to
* encrypt/decrypt data blobs.
*
* address_low: lower 32-bit address of the AesParams structure
*
* address_high: higher 32-bit address of the AesParams structure
*
* value: Returned output value
*
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_aes_engine(uint32_t address_high,
uint32_t address_low,
uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_SECURE_AES, address_high, address_low);
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
/**
* pm_pinctrl_request() - Request Pin from firmware
* @pin Pin number to request
@ -1183,3 +1207,33 @@ enum pm_ret_status pm_secure_image(uint32_t address_low,
key_hi, key_lo);
return pm_ipi_send_sync(primary_proc, payload, value, 2);
}
/**
* pm_fpga_read - Perform the fpga configuration readback
*
* @reg_numframes: Configuration register offset (or) Number of frames to read
* @address_low: lower 32-bit Linear memory space address
* @address_high: higher 32-bit Linear memory space address
* @readback_type: Type of fpga readback operation
* 0 -- Configuration Register readback
* 1 -- Configuration Data readback
* @value: Value to read
*
* This function provides access to the xilfpga library to read
* the PL configuration.
*
* Return: Returns status, either success or error+reason.
*/
enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
uint32_t address_low,
uint32_t address_high,
uint32_t readback_type,
uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
/* Send request to the PMU */
PM_PACK_PAYLOAD5(payload, PM_FPGA_READ, reg_numframes, address_low,
address_high, readback_type);
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

View File

@ -166,4 +166,14 @@ enum pm_ret_status pm_secure_image(uint32_t address_low,
uint32_t key_lo,
uint32_t key_hi,
uint32_t *value);
enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
uint32_t address_low,
uint32_t address_high,
uint32_t readback_type,
uint32_t *value);
enum pm_ret_status pm_aes_engine(uint32_t address_high,
uint32_t address_low,
uint32_t *value);
#endif /* _PM_API_SYS_H_ */

View File

@ -89,6 +89,9 @@ enum pm_api_id {
PM_CLOCK_SETPARENT,
PM_CLOCK_GETPARENT,
PM_SECURE_IMAGE,
/* FPGA PL Readback */
PM_FPGA_READ,
PM_SECURE_AES,
PM_API_MAX
};

View File

@ -546,6 +546,23 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
result[1]);
}
case PM_FPGA_READ:
{
uint32_t value;
ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
&value);
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
}
case PM_SECURE_AES:
{
uint32_t value;
ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
}
default:
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);

View File

@ -48,6 +48,7 @@
#define CRL_APB_BOOT_MODE_USER (CRL_APB_BASE + 0x200)
#define CRL_APB_RESET_CTRL (CRL_APB_BASE + 0x218)
#define CRL_APB_RST_LPD_TOP (CRL_APB_BASE + 0x23C)
#define CRL_APB_BOOT_PIN_CTRL (CRL_APB_BASE + U(0x250))
#define CRL_APB_CLK_BASE U(0xFF5E0020)
#define CRL_APB_RPU_AMBA_RESET (U(1) << 2)
@ -56,7 +57,15 @@
#define CRL_APB_RESET_CTRL_SOFT_RESET (U(1) << 4)
#define CRL_APB_BOOT_MODE_MASK (U(0xf) << 0)
#define CRL_APB_BOOT_PIN_MASK (U(0xf0f) << 0)
#define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT U(9)
#define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT U(1)
#define CRL_APB_BOOT_ENABLE_PIN_1 (U(0x1) << CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
#define CRL_APB_BOOT_DRIVE_PIN_1 (U(0x1) << CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
#define ZYNQMP_BOOTMODE_JTAG U(0)
#define ZYNQMP_ULPI_RESET_VAL_HIGH (CRL_APB_BOOT_ENABLE_PIN_1 | \
CRL_APB_BOOT_DRIVE_PIN_1)
#define ZYNQMP_ULPI_RESET_VAL_LOW CRL_APB_BOOT_ENABLE_PIN_1
/* system counter registers and bitfields */
#define IOU_SCNTRS_BASE 0xFF260000
@ -148,8 +157,6 @@
#define ZYNQMP_SILICON_VER_MASK 0xF000
#define ZYNQMP_SILICON_VER_SHIFT 12
#define ZYNQMP_CSU_VERSION_SILICON 0
#define ZYNQMP_CSU_VERSION_EP108 1
#define ZYNQMP_CSU_VERSION_VELOCE 2
#define ZYNQMP_CSU_VERSION_QEMU 3
#define ZYNQMP_RTL_VER_MASK 0xFF0
@ -192,6 +199,7 @@
#define ACTLR_EL3_L2ACTLR_BIT (1 << 6)
#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
#define FPD_SLCR_BASEADDR U(0xFD610000)
#define IOU_SLCR_BASEADDR U(0xFF180000)
#define ZYNQMP_RPU_GLBL_CNTL U(0xFF9A0000)
@ -316,7 +324,7 @@
#define CRL_APB_TIMESTAMP_REF_CTRL (CRL_APB_CLK_BASE + 0x108)
#define IOU_SLCR_GEM_CLK_CTRL (IOU_SLCR_BASEADDR + 0x308)
#define IOU_SLCR_CAN_MIO_CTRL (IOU_SLCR_BASEADDR + 0x304)
#define IOU_SLCR_WDT_CLK_SEL (IOU_SLCR_BASEADDR + 0x300)
#define FPD_SLCR_WDT_CLK_SEL (FPD_SLCR_BASEADDR + 0x100)
/* Global general storage register base address */
#define GGS_BASEADDR (0xFFD80030U)
@ -326,4 +334,12 @@
#define PGGS_BASEADDR (0xFFD80050U)
#define PGGS_NUM_REGS U(4)
/* Warm restart boot health status register and mask */
#define PM_BOOT_HEALTH_STATUS_REG (GGS_BASEADDR + U(0x10))
#define PM_BOOT_HEALTH_STATUS_MASK U(0x01)
/*AFI registers */
#define AFIFM6_WRCTRL U(13)
#define FABRIC_WIDTH U(3)
#endif /* __ZYNQMP_DEF_H__ */