1 /* 2 * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 #include <string.h> 10 11 #include <lib/bl_aux_params/bl_aux_params.h> 12 #include <common/bl_common.h> 13 #include <common/debug.h> 14 #include <drivers/console.h> 15 #include <drivers/gpio.h> 16 #include <libfdt.h> 17 #include <lib/coreboot.h> 18 #include <lib/mmio.h> 19 #include <plat/common/platform.h> 20 21 #include <plat_params.h> 22 #include <plat_private.h> 23 24 static struct bl_aux_gpio_info rst_gpio; 25 static struct bl_aux_gpio_info poweroff_gpio; 26 static struct bl_aux_gpio_info suspend_gpio[10]; 27 uint32_t suspend_gpio_cnt; 28 static struct bl_aux_rk_apio_info suspend_apio; 29 static uint32_t rk_uart_base = PLAT_RK_UART_BASE; 30 31 uint32_t rockchip_get_uart_base(void) 32 { 33 return rk_uart_base; 34 } 35 36 #if COREBOOT 37 static int dt_process_fdt(u_register_t param_from_bl2) 38 { 39 return -ENODEV; 40 } 41 #else 42 static uint8_t fdt_buffer[0x10000]; 43 44 void *plat_get_fdt(void) 45 { 46 return &fdt_buffer[0]; 47 } 48 49 static void plat_rockchip_dt_process_fdt_uart(void *fdt) 50 { 51 const char *path_name = "/chosen"; 52 const char *prop_name = "stdout-path"; 53 int node_offset; 54 int stdout_path_len; 55 const char *stdout_path; 56 char serial_char; 57 int serial_no; 58 uint32_t uart_base; 59 60 node_offset = fdt_path_offset(fdt, path_name); 61 if (node_offset < 0) 62 return; 63 64 stdout_path = fdt_getprop(fdt, node_offset, prop_name, 65 &stdout_path_len); 66 if (stdout_path == NULL) 67 return; 68 69 /* 70 * We expect something like: 71 * "serial0:..."" 72 */ 73 if (strncmp("serial", stdout_path, 6) != 0) 74 return; 75 76 serial_char = stdout_path[6]; 77 serial_no = serial_char - '0'; 78 79 switch (serial_no) { 80 case 0: 81 uart_base = UART0_BASE; 82 break; 83 case 1: 84 uart_base = UART1_BASE; 85 break; 86 case 2: 87 uart_base = UART2_BASE; 88 break; 89 #ifdef UART3_BASE 90 case 3: 91 uart_base = UART3_BASE; 92 break; 93 #endif 94 #ifdef UART4_BASE 95 case 4: 96 uart_base = UART4_BASE; 97 break; 98 #endif 99 default: 100 return; 101 } 102 103 rk_uart_base = uart_base; 104 } 105 106 static int dt_process_fdt(u_register_t param_from_bl2) 107 { 108 void *fdt = plat_get_fdt(); 109 int ret; 110 111 ret = fdt_open_into((void *)param_from_bl2, fdt, 0x10000); 112 if (ret < 0) 113 return ret; 114 115 plat_rockchip_dt_process_fdt_uart(fdt); 116 117 return 0; 118 } 119 #endif 120 121 struct bl_aux_gpio_info *plat_get_rockchip_gpio_reset(void) 122 { 123 return &rst_gpio; 124 } 125 126 struct bl_aux_gpio_info *plat_get_rockchip_gpio_poweroff(void) 127 { 128 return &poweroff_gpio; 129 } 130 131 struct bl_aux_gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count) 132 { 133 *count = suspend_gpio_cnt; 134 135 return &suspend_gpio[0]; 136 } 137 138 struct bl_aux_rk_apio_info *plat_get_rockchip_suspend_apio(void) 139 { 140 return &suspend_apio; 141 } 142 143 static bool rk_aux_param_handler(struct bl_aux_param_header *param) 144 { 145 /* Store platform parameters for later processing if needed. */ 146 switch (param->type) { 147 case BL_AUX_PARAM_RK_RESET_GPIO: 148 rst_gpio = ((struct bl_aux_param_gpio *)param)->gpio; 149 return true; 150 case BL_AUX_PARAM_RK_POWEROFF_GPIO: 151 poweroff_gpio = ((struct bl_aux_param_gpio *)param)->gpio; 152 return true; 153 case BL_AUX_PARAM_RK_SUSPEND_GPIO: 154 if (suspend_gpio_cnt >= ARRAY_SIZE(suspend_gpio)) { 155 ERROR("Exceeded the supported suspend GPIO number.\n"); 156 return true; 157 } 158 suspend_gpio[suspend_gpio_cnt++] = 159 ((struct bl_aux_param_gpio *)param)->gpio; 160 return true; 161 case BL_AUX_PARAM_RK_SUSPEND_APIO: 162 suspend_apio = ((struct bl_aux_param_rk_apio *)param)->apio; 163 return true; 164 } 165 166 return false; 167 } 168 169 void params_early_setup(u_register_t plat_param_from_bl2) 170 { 171 /* 172 * Test if this is a FDT passed as a platform-specific parameter 173 * block. 174 */ 175 if (!dt_process_fdt(plat_param_from_bl2)) 176 return; 177 178 bl_aux_params_parse(plat_param_from_bl2, rk_aux_param_handler); 179 } 180