1 /* 2 * Copyright (c) 2016, 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 <common/bl_common.h> 12 #include <common/debug.h> 13 #include <drivers/console.h> 14 #include <drivers/gpio.h> 15 #include <libfdt.h> 16 #include <lib/coreboot.h> 17 #include <lib/mmio.h> 18 #include <plat/common/platform.h> 19 20 #include <plat_params.h> 21 #include <plat_private.h> 22 23 static struct gpio_info param_reset; 24 static struct gpio_info param_poweroff; 25 static struct bl31_apio_param param_apio; 26 static struct gpio_info *rst_gpio; 27 static struct gpio_info *poweroff_gpio; 28 static struct gpio_info suspend_gpio[10]; 29 uint32_t suspend_gpio_cnt; 30 static struct apio_info *suspend_apio; 31 static uint32_t rk_uart_base = PLAT_RK_UART_BASE; 32 33 uint32_t rockchip_get_uart_base(void) 34 { 35 return rk_uart_base; 36 } 37 38 #if COREBOOT 39 static int dt_process_fdt(void *blob) 40 { 41 return -ENODEV; 42 } 43 #else 44 static uint8_t fdt_buffer[0x10000]; 45 46 void *plat_get_fdt(void) 47 { 48 return &fdt_buffer[0]; 49 } 50 51 static void plat_rockchip_dt_process_fdt_uart(void *fdt) 52 { 53 const char *path_name = "/chosen"; 54 const char *prop_name = "stdout-path"; 55 int node_offset; 56 int stdout_path_len; 57 const char *stdout_path; 58 char serial_char; 59 int serial_no; 60 uint32_t uart_base; 61 62 node_offset = fdt_path_offset(fdt, path_name); 63 if (node_offset < 0) 64 return; 65 66 stdout_path = fdt_getprop(fdt, node_offset, prop_name, 67 &stdout_path_len); 68 if (stdout_path == NULL) 69 return; 70 71 /* 72 * We expect something like: 73 * "serial0:..."" 74 */ 75 if (strncmp("serial", stdout_path, 6) != 0) 76 return; 77 78 serial_char = stdout_path[6]; 79 serial_no = serial_char - '0'; 80 81 switch (serial_no) { 82 case 0: 83 uart_base = UART0_BASE; 84 break; 85 case 1: 86 uart_base = UART1_BASE; 87 break; 88 case 2: 89 uart_base = UART2_BASE; 90 break; 91 #ifdef UART3_BASE 92 case 3: 93 uart_base = UART3_BASE; 94 break; 95 #endif 96 #ifdef UART4_BASE 97 case 4: 98 uart_base = UART4_BASE; 99 break; 100 #endif 101 default: 102 return; 103 } 104 105 rk_uart_base = uart_base; 106 } 107 108 static int dt_process_fdt(void *blob) 109 { 110 void *fdt = plat_get_fdt(); 111 int ret; 112 113 ret = fdt_open_into(blob, fdt, 0x10000); 114 if (ret < 0) 115 return ret; 116 117 plat_rockchip_dt_process_fdt_uart(fdt); 118 119 return 0; 120 } 121 #endif 122 123 struct gpio_info *plat_get_rockchip_gpio_reset(void) 124 { 125 return rst_gpio; 126 } 127 128 struct gpio_info *plat_get_rockchip_gpio_poweroff(void) 129 { 130 return poweroff_gpio; 131 } 132 133 struct gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count) 134 { 135 *count = suspend_gpio_cnt; 136 137 return &suspend_gpio[0]; 138 } 139 140 struct apio_info *plat_get_rockchip_suspend_apio(void) 141 { 142 return suspend_apio; 143 } 144 145 void params_early_setup(void *plat_param_from_bl2) 146 { 147 struct bl31_plat_param *bl2_param; 148 struct bl31_gpio_param *gpio_param; 149 150 /* 151 * Test if this is a FDT passed as a platform-specific parameter 152 * block. 153 */ 154 if (!dt_process_fdt(plat_param_from_bl2)) 155 return; 156 157 /* keep plat parameters for later processing if need */ 158 bl2_param = (struct bl31_plat_param *)plat_param_from_bl2; 159 while (bl2_param) { 160 switch (bl2_param->type) { 161 case PARAM_RESET: 162 gpio_param = (struct bl31_gpio_param *)bl2_param; 163 memcpy(¶m_reset, &gpio_param->gpio, 164 sizeof(struct gpio_info)); 165 rst_gpio = ¶m_reset; 166 break; 167 case PARAM_POWEROFF: 168 gpio_param = (struct bl31_gpio_param *)bl2_param; 169 memcpy(¶m_poweroff, &gpio_param->gpio, 170 sizeof(struct gpio_info)); 171 poweroff_gpio = ¶m_poweroff; 172 break; 173 case PARAM_SUSPEND_GPIO: 174 if (suspend_gpio_cnt >= ARRAY_SIZE(suspend_gpio)) { 175 ERROR("exceed support suspend gpio number\n"); 176 break; 177 } 178 gpio_param = (struct bl31_gpio_param *)bl2_param; 179 memcpy(&suspend_gpio[suspend_gpio_cnt], 180 &gpio_param->gpio, 181 sizeof(struct gpio_info)); 182 suspend_gpio_cnt++; 183 break; 184 case PARAM_SUSPEND_APIO: 185 memcpy(¶m_apio, bl2_param, 186 sizeof(struct bl31_apio_param)); 187 suspend_apio = ¶m_apio.apio; 188 break; 189 #if COREBOOT 190 case PARAM_COREBOOT_TABLE: 191 coreboot_table_setup((void *) 192 ((struct bl31_u64_param *)bl2_param)->value); 193 break; 194 #endif 195 default: 196 ERROR("not expected type found %lld\n", 197 bl2_param->type); 198 break; 199 } 200 bl2_param = bl2_param->next; 201 } 202 } 203