1 1.41 thorpej /* $NetBSD: exynos_platform.c,v 1.41 2025/09/06 21:02:41 thorpej Exp $ */ 2 1.1 jmcneill 3 1.1 jmcneill /*- 4 1.1 jmcneill * Copyright (c) 2017 Jared D. McNeill <jmcneill (at) invisible.ca> 5 1.1 jmcneill * All rights reserved. 6 1.1 jmcneill * 7 1.1 jmcneill * Redistribution and use in source and binary forms, with or without 8 1.1 jmcneill * modification, are permitted provided that the following conditions 9 1.1 jmcneill * are met: 10 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright 11 1.1 jmcneill * notice, this list of conditions and the following disclaimer. 12 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the 14 1.1 jmcneill * documentation and/or other materials provided with the distribution. 15 1.1 jmcneill * 16 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 jmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 jmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 jmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 jmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 1.1 jmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 1.1 jmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 1.1 jmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 1.1 jmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 jmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 jmcneill * SUCH DAMAGE. 27 1.1 jmcneill */ 28 1.1 jmcneill 29 1.11 skrll #include "opt_arm_debug.h" 30 1.17 skrll #include "opt_console.h" 31 1.1 jmcneill #include "opt_exynos.h" 32 1.1 jmcneill #include "opt_multiprocessor.h" 33 1.17 skrll #include "opt_console.h" 34 1.1 jmcneill 35 1.1 jmcneill #include "ukbd.h" 36 1.1 jmcneill 37 1.1 jmcneill #include <sys/cdefs.h> 38 1.41 thorpej __KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.41 2025/09/06 21:02:41 thorpej Exp $"); 39 1.28 skrll 40 1.39 jmcneill #define EXYNOS_CORE_VBASE KERNEL_IO_VBASE 41 1.28 skrll 42 1.28 skrll /* 43 1.28 skrll * Booting a CA7 core on Exynos5422 is currently broken, disable starting CA7 secondaries. 44 1.28 skrll */ 45 1.28 skrll #define EXYNOS5422_DISABLE_CA7_CLUSTER 46 1.28 skrll 47 1.1 jmcneill #include <sys/param.h> 48 1.1 jmcneill #include <sys/bus.h> 49 1.1 jmcneill #include <sys/cpu.h> 50 1.1 jmcneill #include <sys/device.h> 51 1.1 jmcneill #include <sys/termios.h> 52 1.1 jmcneill 53 1.1 jmcneill #include <dev/fdt/fdtvar.h> 54 1.41 thorpej #include <dev/fdt/fdt_platform.h> 55 1.1 jmcneill 56 1.1 jmcneill #include <uvm/uvm_extern.h> 57 1.1 jmcneill 58 1.1 jmcneill #include <machine/bootconfig.h> 59 1.1 jmcneill #include <arm/cpufunc.h> 60 1.1 jmcneill 61 1.1 jmcneill #include <arm/samsung/exynos_reg.h> 62 1.1 jmcneill #include <arm/samsung/exynos_var.h> 63 1.10 jmcneill #include <arm/samsung/mct_var.h> 64 1.13 skrll #include <arm/samsung/sscom_reg.h> 65 1.1 jmcneill 66 1.39 jmcneill #include <evbarm/fdt/platform.h> 67 1.19 skrll #include <evbarm/fdt/machdep.h> 68 1.2 jmcneill 69 1.1 jmcneill #include <arm/fdt/arm_fdtvar.h> 70 1.1 jmcneill 71 1.22 jmcneill #include <libfdt.h> 72 1.22 jmcneill 73 1.13 skrll void exynos_platform_early_putchar(char); 74 1.13 skrll 75 1.15 jmcneill #define EXYNOS5800_PMU_BASE 0x10040000 76 1.15 jmcneill #define EXYNOS5800_PMU_SIZE 0x20000 77 1.21 jmcneill #define EXYNOS5800_PMU_SWRESET 0x0400 78 1.21 jmcneill #define EXYNOS5800_PMU_KFC_ETM_RESET(n) __BIT(20 + (n)) 79 1.21 jmcneill #define EXYNOS5800_PMU_KFC_CORE_RESET(n) __BIT(8 + (n)) 80 1.21 jmcneill #define EXYNOS5800_PMU_SPARE2 0x0908 81 1.21 jmcneill #define EXYNOS5800_PMU_SPARE3 0x090c 82 1.21 jmcneill #define EXYNOS5800_PMU_SWRESET_KFC_SEL 0x3 83 1.21 jmcneill #define EXYNOS5800_PMU_CORE_CONFIG(n) (0x2000 + 0x80 * (n)) 84 1.21 jmcneill #define EXYNOS5800_PMU_CORE_STATUS(n) (0x2004 + 0x80 * (n)) 85 1.21 jmcneill #define EXYNOS5800_PMU_CORE_POWER_EN 0x3 86 1.21 jmcneill #define EXYNOS5800_PMU_COMMON_CONFIG(n) (0x2500 + 0x80 * (n)) 87 1.21 jmcneill #define EXYNOS5800_PMU_COMMON_POWER_EN 0x3 88 1.21 jmcneill #define EXYNOS5800_PMU_COMMON_OPTION(n) (0x2508 + 0x80 * (n)) 89 1.21 jmcneill #define EXYNOS5800_PMU_USE_L2_COMMON_UP_STATE __BIT(30) 90 1.21 jmcneill #define EXYNOS5800_PMU_USE_ARM_CORE_DOWN_STATE __BIT(29) 91 1.21 jmcneill #define EXYNOS5800_PMU_AUTO_CORE_DOWN __BIT(9) 92 1.21 jmcneill 93 1.21 jmcneill #define EXYNOS5800_SYSRAM_BASE 0x02073000 94 1.21 jmcneill #define EXYNOS5800_SYSRAM_SIZE 0x1000 95 1.21 jmcneill #define EXYNOS5800_SYSRAM_HOTPLUG 0x001c 96 1.19 skrll 97 1.25 skrll static int 98 1.19 skrll exynos5800_mpstart(void) 99 1.19 skrll { 100 1.25 skrll int ret = 0; 101 1.19 skrll #if defined(MULTIPROCESSOR) 102 1.15 jmcneill bus_space_tag_t bst = &armv7_generic_bs_tag; 103 1.15 jmcneill bus_space_handle_t pmu_bsh, sysram_bsh; 104 1.21 jmcneill uint64_t mpidr, bp_mpidr; 105 1.15 jmcneill uint32_t val, started = 0; 106 1.21 jmcneill u_int cpuindex, n; 107 1.21 jmcneill int child; 108 1.15 jmcneill 109 1.15 jmcneill bus_space_map(bst, EXYNOS5800_PMU_BASE, EXYNOS5800_PMU_SIZE, 0, &pmu_bsh); 110 1.15 jmcneill bus_space_map(bst, EXYNOS5800_SYSRAM_BASE, EXYNOS5800_SYSRAM_SIZE, 0, &sysram_bsh); 111 1.15 jmcneill 112 1.21 jmcneill const int cpus = OF_finddevice("/cpus"); 113 1.21 jmcneill if (cpus == -1) { 114 1.21 jmcneill aprint_error("%s: no /cpus node found\n", __func__); 115 1.25 skrll return ret; 116 1.21 jmcneill } 117 1.21 jmcneill 118 1.21 jmcneill /* MPIDR affinity levels of boot processor. */ 119 1.21 jmcneill bp_mpidr = cpu_mpidr_aff_read(); 120 1.21 jmcneill 121 1.21 jmcneill /* Setup KFC reset */ 122 1.21 jmcneill bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_SPARE3, EXYNOS5800_PMU_SWRESET_KFC_SEL); 123 1.15 jmcneill 124 1.21 jmcneill const uint32_t option = EXYNOS5800_PMU_USE_L2_COMMON_UP_STATE | 125 1.21 jmcneill EXYNOS5800_PMU_USE_ARM_CORE_DOWN_STATE | 126 1.21 jmcneill EXYNOS5800_PMU_AUTO_CORE_DOWN; 127 1.21 jmcneill val = bus_space_read_4(bst, pmu_bsh, EXYNOS5800_PMU_COMMON_OPTION(0)); 128 1.21 jmcneill bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_COMMON_OPTION(0), val | option); 129 1.21 jmcneill val = bus_space_read_4(bst, pmu_bsh, EXYNOS5800_PMU_COMMON_OPTION(1)); 130 1.21 jmcneill bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_COMMON_OPTION(1), val | option); 131 1.21 jmcneill 132 1.21 jmcneill bus_space_write_4(bst, sysram_bsh, EXYNOS5800_SYSRAM_HOTPLUG, KERN_VTOPHYS((vaddr_t)cpu_mpstart)); 133 1.31 skrll dsb(sy); 134 1.21 jmcneill 135 1.21 jmcneill /* Power on clusters */ 136 1.21 jmcneill bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_COMMON_CONFIG(0), 137 1.21 jmcneill EXYNOS5800_PMU_COMMON_POWER_EN); 138 1.21 jmcneill bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_COMMON_CONFIG(1), 139 1.21 jmcneill EXYNOS5800_PMU_COMMON_POWER_EN); 140 1.21 jmcneill 141 1.21 jmcneill /* Boot APs */ 142 1.21 jmcneill cpuindex = 1; 143 1.21 jmcneill for (child = OF_child(cpus); child; child = OF_peer(child)) { 144 1.21 jmcneill if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0) 145 1.21 jmcneill continue; 146 1.21 jmcneill 147 1.21 jmcneill if (mpidr == bp_mpidr) 148 1.21 jmcneill continue; /* BP already started */ 149 1.21 jmcneill 150 1.21 jmcneill const u_int cluster = __SHIFTOUT(mpidr, MPIDR_AFF1); 151 1.21 jmcneill const u_int aff0 = __SHIFTOUT(mpidr, MPIDR_AFF0); 152 1.21 jmcneill const u_int cpu = cluster * 4 + aff0; 153 1.21 jmcneill 154 1.28 skrll #if defined(EXYNOS5422_DISABLE_CA7_CLUSTER) 155 1.28 skrll if (cluster == 1) 156 1.28 skrll continue; 157 1.28 skrll #endif 158 1.28 skrll 159 1.21 jmcneill val = bus_space_read_4(bst, pmu_bsh, EXYNOS5800_PMU_CORE_STATUS(cpu)); 160 1.21 jmcneill bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_CORE_CONFIG(cpu), 161 1.15 jmcneill EXYNOS5800_PMU_CORE_POWER_EN); 162 1.21 jmcneill 163 1.21 jmcneill for (n = 0x100000; n > 0; n--) { 164 1.21 jmcneill val = bus_space_read_4(bst, pmu_bsh, EXYNOS5800_PMU_CORE_STATUS(cpu)); 165 1.15 jmcneill if ((val & EXYNOS5800_PMU_CORE_POWER_EN) == EXYNOS5800_PMU_CORE_POWER_EN) { 166 1.21 jmcneill started |= __BIT(cpuindex); 167 1.15 jmcneill break; 168 1.15 jmcneill } 169 1.15 jmcneill } 170 1.21 jmcneill if (n == 0) 171 1.21 jmcneill aprint_error("cpu%d: WARNING: AP failed to power on\n", cpuindex); 172 1.21 jmcneill 173 1.21 jmcneill if (cluster == 1 && __SHIFTOUT(bp_mpidr, MPIDR_AFF1) == 1) { 174 1.21 jmcneill while (bus_space_read_4(bst, pmu_bsh, EXYNOS5800_PMU_SPARE2) == 0) 175 1.21 jmcneill ; 176 1.21 jmcneill bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_SWRESET, 177 1.21 jmcneill EXYNOS5800_PMU_KFC_CORE_RESET(aff0) | 178 1.21 jmcneill EXYNOS5800_PMU_KFC_ETM_RESET(aff0)); 179 1.21 jmcneill } 180 1.21 jmcneill 181 1.21 jmcneill /* Wait for AP to start */ 182 1.21 jmcneill for (n = 0x100000; n > 0; n--) { 183 1.27 skrll if (cpu_hatched_p(cpuindex)) 184 1.21 jmcneill break; 185 1.21 jmcneill } 186 1.25 skrll if (n == 0) { 187 1.25 skrll ret++; 188 1.21 jmcneill aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex); 189 1.25 skrll } 190 1.15 jmcneill 191 1.21 jmcneill cpuindex++; 192 1.15 jmcneill } 193 1.15 jmcneill 194 1.15 jmcneill bus_space_unmap(bst, sysram_bsh, EXYNOS5800_SYSRAM_SIZE); 195 1.15 jmcneill bus_space_unmap(bst, pmu_bsh, EXYNOS5800_PMU_SIZE); 196 1.15 jmcneill #endif 197 1.25 skrll return ret; 198 1.15 jmcneill } 199 1.15 jmcneill 200 1.33 thorpej static struct device_compatible_entry mp_compat_data[] = { 201 1.33 thorpej { .compat = "samsung,exynos5800", .data = exynos5800_mpstart }, 202 1.35 thorpej DEVICE_COMPAT_EOL 203 1.15 jmcneill }; 204 1.15 jmcneill 205 1.25 skrll static int 206 1.19 skrll exynos_platform_mpstart(void) 207 1.1 jmcneill { 208 1.13 skrll 209 1.25 skrll int (*mp_start)(void) = NULL; 210 1.19 skrll 211 1.33 thorpej const struct device_compatible_entry *cd = 212 1.36 thorpej of_compatible_lookup(OF_finddevice("/"), mp_compat_data); 213 1.15 jmcneill if (cd) 214 1.33 thorpej mp_start = cd->data; 215 1.15 jmcneill 216 1.19 skrll if (mp_start) 217 1.25 skrll return mp_start(); 218 1.25 skrll 219 1.25 skrll return 0; 220 1.1 jmcneill } 221 1.1 jmcneill 222 1.1 jmcneill static void 223 1.1 jmcneill exynos_platform_init_attach_args(struct fdt_attach_args *faa) 224 1.1 jmcneill { 225 1.1 jmcneill extern struct bus_space armv7_generic_bs_tag; 226 1.9 ryo extern struct arm32_bus_dma_tag arm_generic_dma_tag; 227 1.1 jmcneill 228 1.1 jmcneill faa->faa_bst = &armv7_generic_bs_tag; 229 1.9 ryo faa->faa_dmat = &arm_generic_dma_tag; 230 1.1 jmcneill } 231 1.1 jmcneill 232 1.29 skrll void __noasan 233 1.1 jmcneill exynos_platform_early_putchar(char c) 234 1.1 jmcneill { 235 1.13 skrll #ifdef CONSADDR 236 1.13 skrll #define CONSADDR_VA (CONSADDR - EXYNOS_CORE_PBASE + EXYNOS_CORE_VBASE) 237 1.2 jmcneill 238 1.13 skrll volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 239 1.13 skrll (volatile uint32_t *)CONSADDR_VA : 240 1.13 skrll (volatile uint32_t *)CONSADDR; 241 1.14 skrll 242 1.13 skrll while ((uartaddr[SSCOM_UFSTAT / 4] & UFSTAT_TXFULL) != 0) 243 1.13 skrll ; 244 1.13 skrll 245 1.13 skrll uartaddr[SSCOM_UTXH / 4] = c; 246 1.4 jmcneill #endif 247 1.1 jmcneill } 248 1.1 jmcneill 249 1.1 jmcneill static void 250 1.1 jmcneill exynos_platform_device_register(device_t self, void *aux) 251 1.1 jmcneill { 252 1.1 jmcneill exynos_device_register(self, aux); 253 1.1 jmcneill } 254 1.1 jmcneill 255 1.1 jmcneill static void 256 1.6 jmcneill exynos5_platform_reset(void) 257 1.1 jmcneill { 258 1.6 jmcneill bus_space_tag_t bst = &armv7_generic_bs_tag; 259 1.6 jmcneill bus_space_handle_t bsh; 260 1.6 jmcneill 261 1.21 jmcneill bus_space_map(bst, EXYNOS5800_PMU_BASE + EXYNOS5800_PMU_SWRESET, 4, 0, &bsh); 262 1.6 jmcneill bus_space_write_4(bst, bsh, 0, 1); 263 1.1 jmcneill } 264 1.1 jmcneill 265 1.1 jmcneill static u_int 266 1.1 jmcneill exynos_platform_uart_freq(void) 267 1.1 jmcneill { 268 1.1 jmcneill return EXYNOS_UART_FREQ; 269 1.1 jmcneill } 270 1.1 jmcneill 271 1.13 skrll 272 1.13 skrll #if defined(SOC_EXYNOS4) 273 1.13 skrll static const struct pmap_devmap * 274 1.13 skrll exynos4_platform_devmap(void) 275 1.13 skrll { 276 1.13 skrll static const struct pmap_devmap devmap[] = { 277 1.13 skrll DEVMAP_ENTRY(EXYNOS_CORE_VBASE, 278 1.13 skrll EXYNOS_CORE_PBASE, 279 1.13 skrll EXYNOS4_CORE_SIZE), 280 1.13 skrll DEVMAP_ENTRY(EXYNOS4_AUDIOCORE_VBASE, 281 1.13 skrll EXYNOS4_AUDIOCORE_PBASE, 282 1.13 skrll EXYNOS4_AUDIOCORE_SIZE), 283 1.13 skrll DEVMAP_ENTRY_END 284 1.13 skrll }; 285 1.13 skrll 286 1.13 skrll return devmap; 287 1.13 skrll } 288 1.13 skrll 289 1.18 skrll static void 290 1.18 skrll exynos4_platform_bootstrap(void) 291 1.18 skrll { 292 1.18 skrll 293 1.18 skrll exynos_bootstrap(4); 294 1.18 skrll 295 1.21 jmcneill #if defined(MULTIPROCESSOR) 296 1.21 jmcneill arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU); 297 1.21 jmcneill #endif 298 1.18 skrll } 299 1.18 skrll 300 1.40 skrll static const struct fdt_platform exynos4_platform = { 301 1.40 skrll .fp_devmap = exynos4_platform_devmap, 302 1.40 skrll // .fp_mpstart = exynos4_mpstart, 303 1.40 skrll .fp_bootstrap = exynos4_platform_bootstrap, 304 1.40 skrll .fp_init_attach_args = exynos_platform_init_attach_args, 305 1.40 skrll .fp_device_register = exynos_platform_device_register, 306 1.40 skrll .fp_reset = exynos5_platform_reset, 307 1.40 skrll .fp_delay = mct_delay, 308 1.40 skrll .fp_uart_freq = exynos_platform_uart_freq, 309 1.13 skrll }; 310 1.13 skrll 311 1.40 skrll FDT_PLATFORM(exynos4, "samsung,exynos4", &exynos4_platform); 312 1.13 skrll #endif 313 1.13 skrll 314 1.13 skrll 315 1.13 skrll #if defined(SOC_EXYNOS5) 316 1.13 skrll static const struct pmap_devmap * 317 1.13 skrll exynos5_platform_devmap(void) 318 1.13 skrll { 319 1.13 skrll static const struct pmap_devmap devmap[] = { 320 1.13 skrll DEVMAP_ENTRY(EXYNOS_CORE_VBASE, 321 1.13 skrll EXYNOS_CORE_PBASE, 322 1.13 skrll EXYNOS5_CORE_SIZE), 323 1.13 skrll DEVMAP_ENTRY(EXYNOS5_AUDIOCORE_VBASE, 324 1.13 skrll EXYNOS5_AUDIOCORE_PBASE, 325 1.13 skrll EXYNOS5_AUDIOCORE_SIZE), 326 1.15 jmcneill DEVMAP_ENTRY(EXYNOS5_SYSRAM_VBASE, 327 1.15 jmcneill EXYNOS5_SYSRAM_PBASE, 328 1.15 jmcneill EXYNOS5_SYSRAM_SIZE), 329 1.13 skrll DEVMAP_ENTRY_END 330 1.13 skrll }; 331 1.13 skrll 332 1.13 skrll return devmap; 333 1.13 skrll } 334 1.13 skrll 335 1.18 skrll static void 336 1.18 skrll exynos5_platform_bootstrap(void) 337 1.18 skrll { 338 1.18 skrll 339 1.18 skrll exynos_bootstrap(5); 340 1.18 skrll 341 1.28 skrll #if defined(MULTIPROCESSOR) && defined(EXYNOS5422_DISABLE_CA7_CLUSTER) 342 1.33 thorpej const struct device_compatible_entry *cd = 343 1.36 thorpej of_compatible_lookup(OF_finddevice("/"), mp_compat_data); 344 1.33 thorpej if (cd && cd->data == exynos5800_mpstart) { 345 1.28 skrll void *fdt_data = __UNCONST(fdtbus_get_data()); 346 1.28 skrll int cpu_off, cpus_off, len; 347 1.28 skrll 348 1.28 skrll cpus_off = fdt_path_offset(fdt_data, "/cpus"); 349 1.28 skrll if (cpus_off < 0) 350 1.28 skrll return; 351 1.28 skrll 352 1.28 skrll fdt_for_each_subnode(cpu_off, fdt_data, cpus_off) { 353 1.28 skrll const void *prop = fdt_getprop(fdt_data, cpu_off, "reg", &len); 354 1.28 skrll if (len != 4) 355 1.28 skrll continue; 356 1.28 skrll const uint32_t mpidr = be32dec(prop); 357 1.28 skrll if (mpidr != cpu_mpidr_aff_read() && __SHIFTOUT(mpidr, MPIDR_AFF1) == 1) 358 1.28 skrll fdt_setprop_string(fdt_data, cpu_off, "status", "fail"); 359 1.28 skrll } 360 1.28 skrll } 361 1.28 skrll #endif 362 1.28 skrll 363 1.21 jmcneill arm_fdt_cpu_bootstrap(); 364 1.18 skrll } 365 1.18 skrll 366 1.40 skrll static const struct fdt_platform exynos5_platform = { 367 1.40 skrll .fp_devmap = exynos5_platform_devmap, 368 1.40 skrll .fp_bootstrap = exynos5_platform_bootstrap, 369 1.40 skrll .fp_mpstart = exynos_platform_mpstart, 370 1.40 skrll .fp_init_attach_args = exynos_platform_init_attach_args, 371 1.40 skrll .fp_device_register = exynos_platform_device_register, 372 1.40 skrll .fp_reset = exynos5_platform_reset, 373 1.40 skrll .fp_delay = mct_delay, 374 1.40 skrll .fp_uart_freq = exynos_platform_uart_freq, 375 1.1 jmcneill }; 376 1.1 jmcneill 377 1.40 skrll FDT_PLATFORM(exynos5, "samsung,exynos5", &exynos5_platform); 378 1.13 skrll #endif 379