From 07b6f3535f5abe3a7c00ca0838d1b8d674975228 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 1 Sep 2017 18:48:53 +0200 Subject: [wip] rockchip: rk3399: implement FDT-based configuration --- plat/rockchip/common/params_setup.c | 102 ++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c index ad4ef7f3..a75523e8 100644 --- a/plat/rockchip/common/params_setup.c +++ b/plat/rockchip/common/params_setup.c @@ -9,11 +9,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include static struct gpio_info param_reset; @@ -25,6 +28,8 @@ static struct gpio_info suspend_gpio[10]; uint32_t suspend_gpio_cnt; static struct apio_info *suspend_apio; +static uint8_t fdt_buffer[0x10000]; + struct gpio_info *plat_get_rockchip_gpio_reset(void) { return rst_gpio; @@ -47,11 +52,108 @@ struct apio_info *plat_get_rockchip_suspend_apio(void) return suspend_apio; } +void* plat_get_fdt(void) +{ + return &fdt_buffer[0]; +} + +void dt_get_reset_gpio(void) +{ + void *fdt = plat_get_fdt(); + int node = fdt_path_offset(fdt, "/config"); + const char *property = "arm-trusted-firmware,reset-gpio"; + const fdt32_t *gpio_cell; + uint32_t gpio_num; + int len; + + if (node < 0) + return; + + param_reset.pull_mode = BL31_GPIO_PULL_NONE; + param_reset.polarity = BL31_GPIO_LEVEL_LOW; + param_reset.direction = BL31_GPIO_DIR_OUT; + + gpio_cell = fdt_getprop(fdt, node, property, &len); + if (!gpio_cell) { + INFO("%s: could not find '%s' property\n", + __func__, property); + return; + } + + gpio_num = fdt32_to_cpu(*gpio_cell); + param_reset.index = gpio_num; + + INFO("%s: gpio# for reset is %d\n", __func__, gpio_num); +} + +void dt_relocate_pmu_firmware(void) +{ + /* TODO: ERROR HANDLING & 64bit FDT */ + + void *fdt = plat_get_fdt(); + int node = fdt_path_offset(fdt, "/fit-images/pmu"); + const fdt32_t *addr_cell, *size_cell; + int len; + uint32_t addr, size; + + if (node < 0) { + INFO("%s: could not find PMU firmware at /fit-images/pmu\n", + __func__); + return; + } + + addr_cell = fdt_getprop(fdt, node, "load-addr", &len); + // if (!addr_cell) + // handle error + size_cell = fdt_getprop(fdt, node, "size", &len); + addr = fdt32_to_cpu(*addr_cell); + size = fdt32_to_cpu(*size_cell); + INFO("%s: PMU firmware is %d bytes at %p\n", + __func__, size, (void*)(uintptr_t)addr); + + memcpy((void*)0xff8c0000UL /* M0_BINCODE_BASE */, + (void*)(uintptr_t)addr, size); + INFO("%s: relocated PMU firmware\n", __func__); +} + +bool dt_board_is_compatible(const char *board) +{ + void *fdt = plat_get_fdt(); + return fdt_node_check_compatible(fdt, 0, board) == 0; +} + +static int dt_process_fdt(void* blob) +{ + int ret; + void *fdt = plat_get_fdt(); + + ret = fdt_open_into(blob, fdt, 0x10000); + if (ret < 0) { + INFO("%s: not a FDT\n", __func__); + return ret; + } + + INFO("%s: opened FDT at %p\n", __func__, blob); + dt_relocate_pmu_firmware(); + dt_get_reset_gpio(); + + return 0; +} + void params_early_setup(void *plat_param_from_bl2) { struct bl31_plat_param *bl2_param; struct bl31_gpio_param *gpio_param; + INFO("plat_param_from_bl2: %p\n", plat_param_from_bl2); + + /* + * Test if this is a FDT passed as a platform-specific parameter + * block. + */ + if (!dt_process_fdt(plat_param_from_bl2)) + return; + /* keep plat parameters for later processing if need */ bl2_param = (struct bl31_plat_param *)plat_param_from_bl2; while (bl2_param) { -- cgit v1.2.3