diff options
author | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2017-09-01 18:48:53 +0200 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2017-09-01 18:51:13 +0200 |
commit | 07b6f3535f5abe3a7c00ca0838d1b8d674975228 (patch) | |
tree | 48d4396ec7b346767856a723d0733d0489f39c40 | |
parent | f098373c01a536a923aa9c8809d8d4d1d3b3bc59 (diff) |
[wip] rockchip: rk3399: implement FDT-based configuration
-rw-r--r-- | plat/rockchip/common/params_setup.c | 102 |
1 files changed, 102 insertions, 0 deletions
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 <bl_common.h> #include <console.h> #include <debug.h> +#include <libfdt.h> #include <gpio.h> #include <mmio.h> #include <platform.h> #include <plat_params.h> #include <plat_private.h> +#include <stdbool.h> +#include <stdint.h> #include <string.h> 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) { |