Unverified Commit fbf35335 authored by Antonio Niño Díaz's avatar Antonio Niño Díaz Committed by GitHub
Browse files

Merge pull request #1767 from Yann-lms/updates_stm32mp1

Updates for STM32MP1
parents f0bfe15b 7747356d
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <libfdt.h>
......@@ -17,135 +18,13 @@
#include <drivers/st/stm32mp1_ddr.h>
#include <drivers/st/stm32mp1_ram.h>
#include <stm32mp1_dt.h>
#define DT_GPIO_BANK_SHIFT 12
#define DT_GPIO_BANK_MASK 0x1F000U
#define DT_GPIO_PIN_SHIFT 8
#define DT_GPIO_PIN_MASK 0xF00U
#define DT_GPIO_MODE_MASK 0xFFU
static int fdt_checked;
static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
/*******************************************************************************
* This function gets the pin settings from DT information.
* When analyze and parsing is done, set the GPIO registers.
* Return 0 on success, else return a negative FDT_ERR_xxx error code.
******************************************************************************/
static int dt_set_gpio_config(int node)
{
const fdt32_t *cuint, *slewrate;
int len, pinctrl_node, pinctrl_subnode;
uint32_t i;
uint32_t speed = GPIO_SPEED_LOW;
uint32_t pull = GPIO_NO_PULL;
cuint = fdt_getprop(fdt, node, "pinmux", &len);
if (cuint == NULL) {
return -FDT_ERR_NOTFOUND;
}
pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
if (pinctrl_node < 0) {
return -FDT_ERR_NOTFOUND;
}
slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
if (slewrate != NULL) {
speed = fdt32_to_cpu(*slewrate);
}
if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
pull = GPIO_PULL_UP;
} else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
pull = GPIO_PULL_DOWN;
} else {
VERBOSE("No bias configured in node %d\n", node);
}
for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
uint32_t pincfg;
uint32_t bank;
uint32_t pin;
uint32_t mode;
uint32_t alternate = GPIO_ALTERNATE_0;
pincfg = fdt32_to_cpu(*cuint);
cuint++;
bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
mode = pincfg & DT_GPIO_MODE_MASK;
switch (mode) {
case 0:
mode = GPIO_MODE_INPUT;
break;
case 1 ... 16:
alternate = mode - 1U;
mode = GPIO_MODE_ALTERNATE;
break;
case 17:
mode = GPIO_MODE_ANALOG;
break;
default:
mode = GPIO_MODE_OUTPUT;
break;
}
if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
mode |= GPIO_OPEN_DRAIN;
}
fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
uint32_t bank_offset;
const fdt32_t *cuint2;
if (fdt_getprop(fdt, pinctrl_subnode,
"gpio-controller", NULL) == NULL) {
continue;
}
cuint2 = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
if (cuint2 == NULL) {
continue;
}
if (bank == GPIO_BANK_Z) {
bank_offset = 0;
} else {
bank_offset = bank * STM32_GPIO_BANK_OFFSET;
}
if (fdt32_to_cpu(*cuint2) == bank_offset) {
int clk_id = fdt_get_clock_id(pinctrl_subnode);
if (clk_id < 0) {
return -FDT_ERR_NOTFOUND;
}
if (stm32mp1_clk_enable((unsigned long)clk_id) <
0) {
return -FDT_ERR_BADVALUE;
}
break;
}
}
set_gpio(bank, pin, mode, speed, pull, alternate);
}
return 0;
}
/*******************************************************************************
* This function checks device tree file with its header.
* Returns 0 if success, and a negative value else.
* Returns 0 on success and a negative FDT error code on failure.
******************************************************************************/
int dt_open_and_check(void)
{
......@@ -174,7 +53,7 @@ int fdt_get_address(void **fdt_addr)
/*******************************************************************************
* This function check the presence of a node (generic use of fdt library).
* Returns true if present, false else.
* Returns true if present, else return false.
******************************************************************************/
bool fdt_check_node(int node)
{
......@@ -187,37 +66,30 @@ bool fdt_check_node(int node)
}
/*******************************************************************************
* This function check the status of a node (generic use of fdt library).
* Returns true if "okay" or missing, false else.
* This function return global node status (generic use of fdt library).
******************************************************************************/
bool fdt_check_status(int node)
uint32_t fdt_get_status(int node)
{
uint32_t status = DT_DISABLED;
int len;
const char *cchar;
cchar = fdt_getprop(fdt, node, "status", &len);
if (cchar == NULL) {
return true;
if ((cchar == NULL) ||
(strncmp(cchar, "okay", (size_t)len) == 0)) {
status |= DT_NON_SECURE;
}
return strncmp(cchar, "okay", (size_t)len) == 0;
}
/*******************************************************************************
* This function check the secure-status of a node (generic use of fdt library).
* Returns true if "okay" or missing, false else.
******************************************************************************/
bool fdt_check_secure_status(int node)
{
int len;
const char *cchar;
cchar = fdt_getprop(fdt, node, "secure-status", &len);
if (cchar == NULL) {
return true;
if (status == DT_NON_SECURE) {
status |= DT_SECURE;
}
} else if (strncmp(cchar, "okay", (size_t)len) == 0) {
status |= DT_SECURE;
}
return strncmp(cchar, "okay", (size_t)len) == 0;
return status;
}
/*******************************************************************************
......@@ -245,7 +117,7 @@ uint32_t fdt_read_uint32_default(int node, const char *prop_name,
* (generic use of fdt library).
* It reads the values inside the device tree, from property name and node.
* The number of parameters is also indicated as entry parameter.
* Returns 0 if success, and a negative value else.
* Returns 0 on success and a negative FDT error code on failure.
* If success, values are stored at the third parameter address.
******************************************************************************/
int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
......@@ -273,53 +145,10 @@ int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
return 0;
}
/*******************************************************************************
* This function gets the pin settings from DT information.
* When analyze and parsing is done, set the GPIO registers.
* Returns 0 if success, and a negative value else.
******************************************************************************/
int dt_set_pinctrl_config(int node)
{
const fdt32_t *cuint;
int lenp = 0;
uint32_t i;
if (!fdt_check_status(node)) {
return -FDT_ERR_NOTFOUND;
}
cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
if (cuint == NULL) {
return -FDT_ERR_NOTFOUND;
}
for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
int phandle_node, phandle_subnode;
phandle_node =
fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
if (phandle_node < 0) {
return -FDT_ERR_NOTFOUND;
}
fdt_for_each_subnode(phandle_subnode, fdt, phandle_node) {
int ret = dt_set_gpio_config(phandle_subnode);
if (ret < 0) {
return ret;
}
}
cuint++;
}
return 0;
}
/*******************************************************************************
* This function gets the stdout pin configuration information from the DT.
* And then calls the sub-function to treat it and set GPIO registers.
* Returns 0 if success, and a negative value else.
* Returns 0 on success and a negative FDT error code on failure.
******************************************************************************/
int dt_set_stdout_pinctrl(void)
{
......@@ -363,13 +192,12 @@ void dt_fill_device_info(struct dt_node_info *info, int node)
info->reset = -1;
}
info->status = fdt_check_status(node);
info->sec_status = fdt_check_secure_status(node);
info->status = fdt_get_status(node);
}
/*******************************************************************************
* This function retrieve the generic information from DT.
* Returns node if success, and a negative value else.
* Returns node on success and a negative FDT error code on failure.
******************************************************************************/
int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
{
......@@ -387,7 +215,7 @@ int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
/*******************************************************************************
* This function gets the UART instance info of stdout from the DT.
* Returns node if success, and a negative value else.
* Returns node on success and a negative FDT error code on failure.
******************************************************************************/
int dt_get_stdout_uart_info(struct dt_node_info *info)
{
......@@ -448,7 +276,7 @@ int dt_get_stdout_node_offset(void)
/*******************************************************************************
* This function gets DDR size information from the DT.
* Returns value in bytes if success, and STM32MP1_DDR_SIZE_DFLT else.
* Returns value in bytes on success, and 0 on failure.
******************************************************************************/
uint32_t dt_get_ddr_size(void)
{
......@@ -457,11 +285,10 @@ uint32_t dt_get_ddr_size(void)
node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
if (node < 0) {
INFO("%s: Cannot read DDR node in DT\n", __func__);
return STM32MP1_DDR_SIZE_DFLT;
return 0;
}
return fdt_read_uint32_default(node, "st,mem-size",
STM32MP1_DDR_SIZE_DFLT);
return fdt_read_uint32_default(node, "st,mem-size", 0);
}
/*******************************************************************************
......
/*
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <libfdt.h>
#include <platform_def.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/arm/gicv2.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
#include <stm32mp1_dt.h>
#include <stm32mp1_private.h>
struct stm32_gic_instance {
uint32_t cells;
uint32_t phandle_node;
};
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
* interrupts.
......@@ -22,19 +32,55 @@ static const interrupt_prop_t stm32mp1_interrupt_props[] = {
PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
};
static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
/* Fix target_mask_array as secondary core is not able to initialize it */
static unsigned int target_mask_array[PLATFORM_CORE_COUNT] = {1, 2};
static const gicv2_driver_data_t platform_gic_data = {
.gicd_base = STM32MP1_GICD_BASE,
.gicc_base = STM32MP1_GICC_BASE,
static gicv2_driver_data_t platform_gic_data = {
.interrupt_props = stm32mp1_interrupt_props,
.interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
.target_masks = target_mask_array,
.target_masks_num = ARRAY_SIZE(target_mask_array),
};
static struct stm32_gic_instance stm32_gic;
void stm32mp1_gic_init(void)
{
int node;
void *fdt;
const fdt32_t *cuint;
struct dt_node_info dt_gic;
if (fdt_get_address(&fdt) == 0) {
panic();
}
node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
if (node < 0) {
panic();
}
platform_gic_data.gicd_base = dt_gic.base;
cuint = fdt_getprop(fdt, node, "reg", NULL);
if (cuint == NULL) {
panic();
}
platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
if (cuint == NULL) {
panic();
}
stm32_gic.cells = fdt32_to_cpu(*cuint);
stm32_gic.phandle_node = fdt_get_phandle(fdt, node);
if (stm32_gic.phandle_node == 0U) {
panic();
}
gicv2_driver_init(&platform_gic_data);
gicv2_distif_init();
......
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -12,11 +12,8 @@
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_rcc.h>
#define GPIO_BANK_G_ADDRESS 0x50008000
#define GPIO_TX_PORT 11
#define GPIO_TX_SHIFT (GPIO_TX_PORT << 1)
#define GPIO_TX_ALT_SHIFT ((GPIO_TX_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
#define STM32MP1_HSI_CLK 64000000
#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
#define GPIO_TX_ALT_SHIFT ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
.globl platform_mem_init
.globl plat_report_exception
......@@ -112,13 +109,13 @@ endfunc plat_my_core_pos
* ---------------------------------------------
*/
func plat_crash_console_init
/* Enable GPIOs for UART4 TX */
ldr r1, =(RCC_BASE + RCC_MP_AHB4ENSETR)
/* Enable GPIOs for UART TX */
ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
ldr r2, [r1]
/* Configure GPIO G11 */
orr r2, r2, #RCC_MP_AHB4ENSETR_GPIOGEN
/* Configure GPIO */
orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
str r2, [r1]
ldr r1, =GPIO_BANK_G_ADDRESS
ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
/* Set GPIO mode alternate */
ldr r2, [r1, #GPIO_MODE_OFFSET]
bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
......@@ -132,23 +129,22 @@ func plat_crash_console_init
ldr r2, [r1, #GPIO_PUPD_OFFSET]
bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
str r2, [r1, #GPIO_PUPD_OFFSET]
/* Set alternate AF6 */
/* Set alternate */
ldr r2, [r1, #GPIO_AFRH_OFFSET]
bic r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
orr r2, r2, #(GPIO_ALTERNATE_6 << GPIO_TX_ALT_SHIFT)
orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT)
str r2, [r1, #GPIO_AFRH_OFFSET]
/* Enable UART clock, with HSI source */
ldr r1, =(RCC_BASE + RCC_UART24CKSELR)
mov r2, #RCC_UART24CKSELR_HSI
/* Enable UART clock, with its source */
ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
mov r2, #DEBUG_UART_TX_CLKSRC
str r2, [r1]
ldr r1, =(RCC_BASE + RCC_MP_APB1ENSETR)
ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
ldr r2, [r1]
orr r2, r2, #RCC_MP_APB1ENSETR_UART4EN
orr r2, r2, #DEBUG_UART_TX_EN
str r2, [r1]
ldr r0, =STM32MP1_DEBUG_USART_BASE
ldr r1, =STM32MP1_HSI_CLK
ldr r1, =STM32MP1_DEBUG_USART_CLK_FRQ
ldr r2, =STM32MP1_UART_BAUDRATE
b console_stm32_core_init
endfunc plat_crash_console_init
......
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -23,11 +23,9 @@
#include <boot_api.h>
#include <stm32mp1_private.h>
static uint32_t stm32_sec_entrypoint;
static uintptr_t stm32_sec_entrypoint;
static uint32_t cntfrq_core0;
#define SEND_SECURE_IT_TO_CORE_1 0x20000U
/*******************************************************************************
* STM32MP1 handler called when a CPU is about to enter standby.
* call by core 1 to enter in wfi
......@@ -42,6 +40,7 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state)
* Enter standby state
* dsb is good practice before using wfi to enter low power states
*/
isb();
dsb();
while (interrupt == GIC_SPURIOUS_INTERRUPT) {
wfi();
......@@ -59,7 +58,7 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state)
/*******************************************************************************
* STM32MP1 handler called when a power domain is about to be turned on. The
* mpidr determines the CPU to be turned on.
* call by core 0 to activate core 1
* call by core 0 to activate core 1
******************************************************************************/
static int stm32_pwr_domain_on(u_register_t mpidr)
{
......@@ -102,8 +101,7 @@ static int stm32_pwr_domain_on(u_register_t mpidr)
}
/* Generate an IT to core 1 */
mmio_write_32(STM32MP1_GICD_BASE + GICD_SGIR,
SEND_SECURE_IT_TO_CORE_1 | ARM_IRQ_SEC_SGI_0);
gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP1_SECONDARY_CPU);
return PSCI_E_SUCCESS;
}
......
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -65,22 +65,6 @@ static void init_tzc400(void)
******************************************************************************/
static void early_init_tzc400(void)
{
uint32_t rstsr, rst_standby;
rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
/* No warning if return from (C)STANDBY */
rst_standby = rstsr &
(RCC_MP_RSTSCLRR_STDBYRSTF | RCC_MP_RSTSCLRR_CSTDBYRSTF);
if (stm32mp1_clk_is_enabled(TZC1) && (rst_standby == 0U)) {
WARN("TZC400 port 1 clock already enable\n");
}
if (stm32mp1_clk_is_enabled(TZC2) && (rst_standby == 0U)) {
WARN("TZC400 port 2 clock already enable\n");
}
if (stm32mp1_clk_enable(TZC1) != 0) {
ERROR("Cannot enable TZC1 clock\n");
panic();
......@@ -103,6 +87,7 @@ static void early_init_tzc400(void)
STM32MP1_DDR_BASE +
(STM32MP1_DDR_MAX_SIZE - 1U),
TZC_REGION_S_RDWR,
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));
/* Raise an exception if a NS device tries to access secure memory */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment