Commit d0691357db6745c7a19304a99dda55265cedd644
Committed by
Ye Li
1 parent
fe897bdc89
Exists in
emb_lf_v2023.04
MLK-20373-4 imx8: update mem map table
Update mem map table for xen uboot. xen console and some magic pages needs to be mappe as normal memory. Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Flynn xu <flynn.xu@nxp.com> (cherry picked from commit c96a9844cd3342f6e31627ccc4f3e63544ffd78e) (cherry picked from commit 30b2d9f4a7c0cfc9b3f999f1c3a1a8c466d66a68) (cherry picked from commit 03db7649c0f8c7a292160e2d5d8981e6c3b84ee3) (cherry picked from commit 4ce0b30c0fb047ff2d0c58ae3ae6bd92737ea611) (cherry picked from commit 1483f13672f065c8ce80ed2750cd6019e5b16e0e)
Showing 1 changed file with 20 additions and 9 deletions Inline Diff
arch/arm/mach-imx/imx8/cpu.c
| 1 | // SPDX-License-Identifier: GPL-2.0+ | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* | 2 | /* |
| 3 | * Copyright 2017-2021 NXP | 3 | * Copyright 2017-2021 NXP |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <common.h> | 6 | #include <common.h> |
| 7 | #include <clk.h> | 7 | #include <clk.h> |
| 8 | #include <cpu.h> | 8 | #include <cpu.h> |
| 9 | #include <cpu_func.h> | 9 | #include <cpu_func.h> |
| 10 | #include <dm.h> | 10 | #include <dm.h> |
| 11 | #include <event.h> | 11 | #include <event.h> |
| 12 | #include <init.h> | 12 | #include <init.h> |
| 13 | #include <log.h> | 13 | #include <log.h> |
| 14 | #include <asm/cache.h> | 14 | #include <asm/cache.h> |
| 15 | #include <asm/global_data.h> | 15 | #include <asm/global_data.h> |
| 16 | #include <dm/device-internal.h> | 16 | #include <dm/device-internal.h> |
| 17 | #include <dm/uclass-internal.h> | 17 | #include <dm/uclass-internal.h> |
| 18 | #include <dm/lists.h> | 18 | #include <dm/lists.h> |
| 19 | #include <dm/uclass.h> | 19 | #include <dm/uclass.h> |
| 20 | #include <errno.h> | 20 | #include <errno.h> |
| 21 | #include <asm/arch/clock.h> | 21 | #include <asm/arch/clock.h> |
| 22 | #include <thermal.h> | 22 | #include <thermal.h> |
| 23 | #include <asm/arch/sci/sci.h> | 23 | #include <asm/arch/sci/sci.h> |
| 24 | #include <power-domain.h> | 24 | #include <power-domain.h> |
| 25 | #include <elf.h> | 25 | #include <elf.h> |
| 26 | #include <asm/arch/sys_proto.h> | 26 | #include <asm/arch/sys_proto.h> |
| 27 | #include <asm/arch-imx/cpu.h> | 27 | #include <asm/arch-imx/cpu.h> |
| 28 | #include <asm/armv8/cpu.h> | 28 | #include <asm/armv8/cpu.h> |
| 29 | #include <asm/armv8/mmu.h> | 29 | #include <asm/armv8/mmu.h> |
| 30 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
| 31 | #include <asm/mach-imx/boot_mode.h> | 31 | #include <asm/mach-imx/boot_mode.h> |
| 32 | #include <spl.h> | 32 | #include <spl.h> |
| 33 | #include <env.h> | 33 | #include <env.h> |
| 34 | #include <asm/mach-imx/imx_vservice.h> | 34 | #include <asm/mach-imx/imx_vservice.h> |
| 35 | #include <usb/ci_udc.h> | 35 | #include <usb/ci_udc.h> |
| 36 | 36 | ||
| 37 | DECLARE_GLOBAL_DATA_PTR; | 37 | DECLARE_GLOBAL_DATA_PTR; |
| 38 | 38 | ||
| 39 | #define BT_PASSOVER_TAG 0x504F | 39 | #define BT_PASSOVER_TAG 0x504F |
| 40 | struct pass_over_info_t *get_pass_over_info(void) | 40 | struct pass_over_info_t *get_pass_over_info(void) |
| 41 | { | 41 | { |
| 42 | struct pass_over_info_t *p = | 42 | struct pass_over_info_t *p = |
| 43 | (struct pass_over_info_t *)PASS_OVER_INFO_ADDR; | 43 | (struct pass_over_info_t *)PASS_OVER_INFO_ADDR; |
| 44 | 44 | ||
| 45 | if (p->barker != BT_PASSOVER_TAG || | 45 | if (p->barker != BT_PASSOVER_TAG || |
| 46 | p->len != sizeof(struct pass_over_info_t)) | 46 | p->len != sizeof(struct pass_over_info_t)) |
| 47 | return NULL; | 47 | return NULL; |
| 48 | 48 | ||
| 49 | return p; | 49 | return p; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | int arch_cpu_init(void) | 52 | int arch_cpu_init(void) |
| 53 | { | 53 | { |
| 54 | #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION) | 54 | #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION) |
| 55 | spl_save_restore_data(); | 55 | spl_save_restore_data(); |
| 56 | #endif | 56 | #endif |
| 57 | 57 | ||
| 58 | return 0; | 58 | return 0; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | static void power_off_all_usb(void); | 61 | static void power_off_all_usb(void); |
| 62 | 62 | ||
| 63 | static int imx8_init_mu(void *ctx, struct event *event) | 63 | static int imx8_init_mu(void *ctx, struct event *event) |
| 64 | { | 64 | { |
| 65 | struct udevice *devp; | 65 | struct udevice *devp; |
| 66 | int node, ret; | 66 | int node, ret; |
| 67 | 67 | ||
| 68 | node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8-mu"); | 68 | node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8-mu"); |
| 69 | 69 | ||
| 70 | ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp); | 70 | ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp); |
| 71 | if (ret) { | 71 | if (ret) { |
| 72 | printf("could not get scu %d\n", ret); | 72 | printf("could not get scu %d\n", ret); |
| 73 | return ret; | 73 | return ret; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | if (IS_ENABLED(CONFIG_XEN)) | 76 | if (IS_ENABLED(CONFIG_XEN)) |
| 77 | return 0; | 77 | return 0; |
| 78 | 78 | ||
| 79 | struct pass_over_info_t *pass_over; | 79 | struct pass_over_info_t *pass_over; |
| 80 | 80 | ||
| 81 | if ((is_imx8qm() || is_imx8qxp()) && is_soc_rev(CHIP_REV_A)) { | 81 | if ((is_imx8qm() || is_imx8qxp()) && is_soc_rev(CHIP_REV_A)) { |
| 82 | pass_over = get_pass_over_info(); | 82 | pass_over = get_pass_over_info(); |
| 83 | if (pass_over && pass_over->g_ap_mu == 0) { | 83 | if (pass_over && pass_over->g_ap_mu == 0) { |
| 84 | /* | 84 | /* |
| 85 | * When ap_mu is 0, means the U-Boot booted | 85 | * When ap_mu is 0, means the U-Boot booted |
| 86 | * from first container | 86 | * from first container |
| 87 | */ | 87 | */ |
| 88 | sc_misc_boot_status(-1, SC_MISC_BOOT_STATUS_SUCCESS); | 88 | sc_misc_boot_status(-1, SC_MISC_BOOT_STATUS_SUCCESS); |
| 89 | } | 89 | } |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | #if !defined(CONFIG_TARGET_IMX8QM_MEK_A72_ONLY) && !defined(CONFIG_TARGET_IMX8QM_MEK_A53_ONLY) | 92 | #if !defined(CONFIG_TARGET_IMX8QM_MEK_A72_ONLY) && !defined(CONFIG_TARGET_IMX8QM_MEK_A53_ONLY) |
| 93 | if (is_imx8qm()) { | 93 | if (is_imx8qm()) { |
| 94 | ret = sc_pm_set_resource_power_mode(-1, SC_R_SMMU, | 94 | ret = sc_pm_set_resource_power_mode(-1, SC_R_SMMU, |
| 95 | SC_PM_PW_MODE_ON); | 95 | SC_PM_PW_MODE_ON); |
| 96 | if (ret) | 96 | if (ret) |
| 97 | return ret; | 97 | return ret; |
| 98 | } | 98 | } |
| 99 | #endif | 99 | #endif |
| 100 | 100 | ||
| 101 | power_off_all_usb(); | 101 | power_off_all_usb(); |
| 102 | 102 | ||
| 103 | return 0; | 103 | return 0; |
| 104 | } | 104 | } |
| 105 | EVENT_SPY(EVT_DM_POST_INIT, imx8_init_mu); | 105 | EVENT_SPY(EVT_DM_POST_INIT, imx8_init_mu); |
| 106 | 106 | ||
| 107 | #if defined(CONFIG_ARCH_MISC_INIT) | 107 | #if defined(CONFIG_ARCH_MISC_INIT) |
| 108 | int arch_misc_init(void) | 108 | int arch_misc_init(void) |
| 109 | { | 109 | { |
| 110 | if (IS_ENABLED(CONFIG_FSL_CAAM)) { | 110 | if (IS_ENABLED(CONFIG_FSL_CAAM)) { |
| 111 | struct udevice *dev; | 111 | struct udevice *dev; |
| 112 | int ret; | 112 | int ret; |
| 113 | 113 | ||
| 114 | ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); | 114 | ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); |
| 115 | if (ret) | 115 | if (ret) |
| 116 | printf("Failed to initialize caam_jr: %d\n", ret); | 116 | printf("Failed to initialize caam_jr: %d\n", ret); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | return 0; | 119 | return 0; |
| 120 | } | 120 | } |
| 121 | #endif | 121 | #endif |
| 122 | 122 | ||
| 123 | #ifdef CONFIG_IMX_BOOTAUX | 123 | #ifdef CONFIG_IMX_BOOTAUX |
| 124 | 124 | ||
| 125 | #ifdef CONFIG_IMX8QM | 125 | #ifdef CONFIG_IMX8QM |
| 126 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) | 126 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) |
| 127 | { | 127 | { |
| 128 | sc_rsrc_t core_rsrc, mu_rsrc; | 128 | sc_rsrc_t core_rsrc, mu_rsrc; |
| 129 | sc_faddr_t tcml_addr; | 129 | sc_faddr_t tcml_addr; |
| 130 | u32 tcm_size = SZ_256K; /* TCML + TCMU */ | 130 | u32 tcm_size = SZ_256K; /* TCML + TCMU */ |
| 131 | ulong addr; | 131 | ulong addr; |
| 132 | 132 | ||
| 133 | 133 | ||
| 134 | switch (core_id) { | 134 | switch (core_id) { |
| 135 | case 0: | 135 | case 0: |
| 136 | core_rsrc = SC_R_M4_0_PID0; | 136 | core_rsrc = SC_R_M4_0_PID0; |
| 137 | tcml_addr = 0x34FE0000; | 137 | tcml_addr = 0x34FE0000; |
| 138 | mu_rsrc = SC_R_M4_0_MU_1A; | 138 | mu_rsrc = SC_R_M4_0_MU_1A; |
| 139 | break; | 139 | break; |
| 140 | case 1: | 140 | case 1: |
| 141 | core_rsrc = SC_R_M4_1_PID0; | 141 | core_rsrc = SC_R_M4_1_PID0; |
| 142 | tcml_addr = 0x38FE0000; | 142 | tcml_addr = 0x38FE0000; |
| 143 | mu_rsrc = SC_R_M4_1_MU_1A; | 143 | mu_rsrc = SC_R_M4_1_MU_1A; |
| 144 | break; | 144 | break; |
| 145 | default: | 145 | default: |
| 146 | printf("Not support this core boot up, ID:%u\n", core_id); | 146 | printf("Not support this core boot up, ID:%u\n", core_id); |
| 147 | return -EINVAL; | 147 | return -EINVAL; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | addr = (sc_faddr_t)boot_private_data; | 150 | addr = (sc_faddr_t)boot_private_data; |
| 151 | 151 | ||
| 152 | if (addr >= tcml_addr && addr <= tcml_addr + tcm_size) { | 152 | if (addr >= tcml_addr && addr <= tcml_addr + tcm_size) { |
| 153 | printf("Wrong image address 0x%lx, should not in TCML\n", | 153 | printf("Wrong image address 0x%lx, should not in TCML\n", |
| 154 | addr); | 154 | addr); |
| 155 | return -EINVAL; | 155 | return -EINVAL; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | printf("Power on M4 and MU\n"); | 158 | printf("Power on M4 and MU\n"); |
| 159 | 159 | ||
| 160 | if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 160 | if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
| 161 | return -EIO; | 161 | return -EIO; |
| 162 | 162 | ||
| 163 | if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 163 | if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
| 164 | return -EIO; | 164 | return -EIO; |
| 165 | 165 | ||
| 166 | printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr); | 166 | printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr); |
| 167 | 167 | ||
| 168 | if (addr != tcml_addr) | 168 | if (addr != tcml_addr) |
| 169 | memcpy((void *)tcml_addr, (void *)addr, tcm_size); | 169 | memcpy((void *)tcml_addr, (void *)addr, tcm_size); |
| 170 | 170 | ||
| 171 | printf("Start M4 %u\n", core_id); | 171 | printf("Start M4 %u\n", core_id); |
| 172 | if (sc_pm_cpu_start(-1, core_rsrc, true, tcml_addr) != SC_ERR_NONE) | 172 | if (sc_pm_cpu_start(-1, core_rsrc, true, tcml_addr) != SC_ERR_NONE) |
| 173 | return -EIO; | 173 | return -EIO; |
| 174 | 174 | ||
| 175 | printf("bootaux complete\n"); | 175 | printf("bootaux complete\n"); |
| 176 | return 0; | 176 | return 0; |
| 177 | } | 177 | } |
| 178 | #endif | 178 | #endif |
| 179 | 179 | ||
| 180 | #if defined(CONFIG_IMX8QXP) || defined(CONFIG_IMX8DXL) | 180 | #if defined(CONFIG_IMX8QXP) || defined(CONFIG_IMX8DXL) |
| 181 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) | 181 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) |
| 182 | { | 182 | { |
| 183 | sc_rsrc_t core_rsrc, mu_rsrc = SC_R_NONE; | 183 | sc_rsrc_t core_rsrc, mu_rsrc = SC_R_NONE; |
| 184 | sc_faddr_t aux_core_ram; | 184 | sc_faddr_t aux_core_ram; |
| 185 | u32 size; | 185 | u32 size; |
| 186 | ulong addr; | 186 | ulong addr; |
| 187 | 187 | ||
| 188 | switch (core_id) { | 188 | switch (core_id) { |
| 189 | case 0: | 189 | case 0: |
| 190 | core_rsrc = SC_R_M4_0_PID0; | 190 | core_rsrc = SC_R_M4_0_PID0; |
| 191 | aux_core_ram = 0x34FE0000; | 191 | aux_core_ram = 0x34FE0000; |
| 192 | mu_rsrc = SC_R_M4_0_MU_1A; | 192 | mu_rsrc = SC_R_M4_0_MU_1A; |
| 193 | size = SZ_256K; | 193 | size = SZ_256K; |
| 194 | break; | 194 | break; |
| 195 | case 1: | 195 | case 1: |
| 196 | core_rsrc = SC_R_DSP; | 196 | core_rsrc = SC_R_DSP; |
| 197 | aux_core_ram = 0x596f8000; | 197 | aux_core_ram = 0x596f8000; |
| 198 | size = SZ_2K; | 198 | size = SZ_2K; |
| 199 | break; | 199 | break; |
| 200 | default: | 200 | default: |
| 201 | printf("Not support this core boot up, ID:%u\n", core_id); | 201 | printf("Not support this core boot up, ID:%u\n", core_id); |
| 202 | return -EINVAL; | 202 | return -EINVAL; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | addr = (sc_faddr_t)boot_private_data; | 205 | addr = (sc_faddr_t)boot_private_data; |
| 206 | 206 | ||
| 207 | if (addr >= aux_core_ram && addr <= aux_core_ram + size) { | 207 | if (addr >= aux_core_ram && addr <= aux_core_ram + size) { |
| 208 | printf("Wrong image address 0x%lx, should not in aux core ram\n", | 208 | printf("Wrong image address 0x%lx, should not in aux core ram\n", |
| 209 | addr); | 209 | addr); |
| 210 | return -EINVAL; | 210 | return -EINVAL; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | printf("Power on aux core %d\n", core_id); | 213 | printf("Power on aux core %d\n", core_id); |
| 214 | 214 | ||
| 215 | if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 215 | if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
| 216 | return -EIO; | 216 | return -EIO; |
| 217 | 217 | ||
| 218 | if (mu_rsrc != SC_R_NONE) { | 218 | if (mu_rsrc != SC_R_NONE) { |
| 219 | if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 219 | if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
| 220 | return -EIO; | 220 | return -EIO; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | if (core_id == 1) { | 223 | if (core_id == 1) { |
| 224 | struct power_domain pd; | 224 | struct power_domain pd; |
| 225 | 225 | ||
| 226 | if (sc_pm_clock_enable(-1, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) { | 226 | if (sc_pm_clock_enable(-1, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) { |
| 227 | printf("Error enable clock\n"); | 227 | printf("Error enable clock\n"); |
| 228 | return -EIO; | 228 | return -EIO; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | if (!power_domain_lookup_name("audio_sai0", &pd)) { | 231 | if (!power_domain_lookup_name("audio_sai0", &pd)) { |
| 232 | if (power_domain_on(&pd)) { | 232 | if (power_domain_on(&pd)) { |
| 233 | printf("Error power on SAI0\n"); | 233 | printf("Error power on SAI0\n"); |
| 234 | return -EIO; | 234 | return -EIO; |
| 235 | } | 235 | } |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | if (!power_domain_lookup_name("audio_ocram", &pd)) { | 238 | if (!power_domain_lookup_name("audio_ocram", &pd)) { |
| 239 | if (power_domain_on(&pd)) { | 239 | if (power_domain_on(&pd)) { |
| 240 | printf("Error power on HIFI RAM\n"); | 240 | printf("Error power on HIFI RAM\n"); |
| 241 | return -EIO; | 241 | return -EIO; |
| 242 | } | 242 | } |
| 243 | } | 243 | } |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram); | 246 | printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram); |
| 247 | if (core_id == 0) { | 247 | if (core_id == 0) { |
| 248 | /* M4 use bin file */ | 248 | /* M4 use bin file */ |
| 249 | memcpy((void *)aux_core_ram, (void *)addr, size); | 249 | memcpy((void *)aux_core_ram, (void *)addr, size); |
| 250 | } else { | 250 | } else { |
| 251 | /* HIFI use elf file */ | 251 | /* HIFI use elf file */ |
| 252 | if (!valid_elf_image(addr)) | 252 | if (!valid_elf_image(addr)) |
| 253 | return -1; | 253 | return -1; |
| 254 | addr = load_elf_image_shdr(addr); | 254 | addr = load_elf_image_shdr(addr); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | printf("Start %s\n", core_id == 0 ? "M4" : "HIFI"); | 257 | printf("Start %s\n", core_id == 0 ? "M4" : "HIFI"); |
| 258 | 258 | ||
| 259 | if (sc_pm_cpu_start(-1, core_rsrc, true, aux_core_ram) != SC_ERR_NONE) | 259 | if (sc_pm_cpu_start(-1, core_rsrc, true, aux_core_ram) != SC_ERR_NONE) |
| 260 | return -EIO; | 260 | return -EIO; |
| 261 | 261 | ||
| 262 | printf("bootaux complete\n"); | 262 | printf("bootaux complete\n"); |
| 263 | return 0; | 263 | return 0; |
| 264 | } | 264 | } |
| 265 | #endif | 265 | #endif |
| 266 | 266 | ||
| 267 | int arch_auxiliary_core_check_up(u32 core_id) | 267 | int arch_auxiliary_core_check_up(u32 core_id) |
| 268 | { | 268 | { |
| 269 | sc_rsrc_t core_rsrc; | 269 | sc_rsrc_t core_rsrc; |
| 270 | sc_pm_power_mode_t power_mode; | 270 | sc_pm_power_mode_t power_mode; |
| 271 | 271 | ||
| 272 | switch (core_id) { | 272 | switch (core_id) { |
| 273 | case 0: | 273 | case 0: |
| 274 | core_rsrc = SC_R_M4_0_PID0; | 274 | core_rsrc = SC_R_M4_0_PID0; |
| 275 | break; | 275 | break; |
| 276 | #ifdef CONFIG_IMX8QM | 276 | #ifdef CONFIG_IMX8QM |
| 277 | case 1: | 277 | case 1: |
| 278 | core_rsrc = SC_R_M4_1_PID0; | 278 | core_rsrc = SC_R_M4_1_PID0; |
| 279 | break; | 279 | break; |
| 280 | #endif | 280 | #endif |
| 281 | default: | 281 | default: |
| 282 | printf("Not support this core, ID:%u\n", core_id); | 282 | printf("Not support this core, ID:%u\n", core_id); |
| 283 | return 0; | 283 | return 0; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | if (sc_pm_get_resource_power_mode(-1, core_rsrc, &power_mode) != SC_ERR_NONE) | 286 | if (sc_pm_get_resource_power_mode(-1, core_rsrc, &power_mode) != SC_ERR_NONE) |
| 287 | return 0; | 287 | return 0; |
| 288 | 288 | ||
| 289 | if (power_mode != SC_PM_PW_MODE_OFF) | 289 | if (power_mode != SC_PM_PW_MODE_OFF) |
| 290 | return 1; | 290 | return 1; |
| 291 | 291 | ||
| 292 | return 0; | 292 | return 0; |
| 293 | } | 293 | } |
| 294 | #endif | 294 | #endif |
| 295 | 295 | ||
| 296 | int print_bootinfo(void) | 296 | int print_bootinfo(void) |
| 297 | { | 297 | { |
| 298 | enum boot_device bt_dev = get_boot_device(); | 298 | enum boot_device bt_dev = get_boot_device(); |
| 299 | 299 | ||
| 300 | puts("Boot: "); | 300 | puts("Boot: "); |
| 301 | switch (bt_dev) { | 301 | switch (bt_dev) { |
| 302 | case SD1_BOOT: | 302 | case SD1_BOOT: |
| 303 | puts("SD0\n"); | 303 | puts("SD0\n"); |
| 304 | break; | 304 | break; |
| 305 | case SD2_BOOT: | 305 | case SD2_BOOT: |
| 306 | puts("SD1\n"); | 306 | puts("SD1\n"); |
| 307 | break; | 307 | break; |
| 308 | case SD3_BOOT: | 308 | case SD3_BOOT: |
| 309 | puts("SD2\n"); | 309 | puts("SD2\n"); |
| 310 | break; | 310 | break; |
| 311 | case MMC1_BOOT: | 311 | case MMC1_BOOT: |
| 312 | puts("MMC0\n"); | 312 | puts("MMC0\n"); |
| 313 | break; | 313 | break; |
| 314 | case MMC2_BOOT: | 314 | case MMC2_BOOT: |
| 315 | puts("MMC1\n"); | 315 | puts("MMC1\n"); |
| 316 | break; | 316 | break; |
| 317 | case MMC3_BOOT: | 317 | case MMC3_BOOT: |
| 318 | puts("MMC2\n"); | 318 | puts("MMC2\n"); |
| 319 | break; | 319 | break; |
| 320 | case FLEXSPI_BOOT: | 320 | case FLEXSPI_BOOT: |
| 321 | puts("FLEXSPI\n"); | 321 | puts("FLEXSPI\n"); |
| 322 | break; | 322 | break; |
| 323 | case SATA_BOOT: | 323 | case SATA_BOOT: |
| 324 | puts("SATA\n"); | 324 | puts("SATA\n"); |
| 325 | break; | 325 | break; |
| 326 | case NAND_BOOT: | 326 | case NAND_BOOT: |
| 327 | puts("NAND\n"); | 327 | puts("NAND\n"); |
| 328 | break; | 328 | break; |
| 329 | case USB_BOOT: | 329 | case USB_BOOT: |
| 330 | puts("USB\n"); | 330 | puts("USB\n"); |
| 331 | break; | 331 | break; |
| 332 | default: | 332 | default: |
| 333 | printf("Unknown device %u\n", bt_dev); | 333 | printf("Unknown device %u\n", bt_dev); |
| 334 | break; | 334 | break; |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | return 0; | 337 | return 0; |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | enum boot_device get_boot_device(void) | 340 | enum boot_device get_boot_device(void) |
| 341 | { | 341 | { |
| 342 | enum boot_device boot_dev = SD1_BOOT; | 342 | enum boot_device boot_dev = SD1_BOOT; |
| 343 | 343 | ||
| 344 | sc_rsrc_t dev_rsrc; | 344 | sc_rsrc_t dev_rsrc; |
| 345 | 345 | ||
| 346 | #if defined(CONFIG_TARGET_IMX8QM_MEK_A72_ONLY) | 346 | #if defined(CONFIG_TARGET_IMX8QM_MEK_A72_ONLY) |
| 347 | return MMC1_BOOT; | 347 | return MMC1_BOOT; |
| 348 | #elif defined(CONFIG_TARGET_IMX8QM_MEK_A53_ONLY) | 348 | #elif defined(CONFIG_TARGET_IMX8QM_MEK_A53_ONLY) |
| 349 | return SD2_BOOT; | 349 | return SD2_BOOT; |
| 350 | #endif | 350 | #endif |
| 351 | /* Note we only support android in EMMC SDHC0 */ | 351 | /* Note we only support android in EMMC SDHC0 */ |
| 352 | if (IS_ENABLED(CONFIG_XEN)) | 352 | if (IS_ENABLED(CONFIG_XEN)) |
| 353 | return MMC1_BOOT; | 353 | return MMC1_BOOT; |
| 354 | 354 | ||
| 355 | sc_misc_get_boot_dev(-1, &dev_rsrc); | 355 | sc_misc_get_boot_dev(-1, &dev_rsrc); |
| 356 | 356 | ||
| 357 | switch (dev_rsrc) { | 357 | switch (dev_rsrc) { |
| 358 | case SC_R_SDHC_0: | 358 | case SC_R_SDHC_0: |
| 359 | boot_dev = MMC1_BOOT; | 359 | boot_dev = MMC1_BOOT; |
| 360 | break; | 360 | break; |
| 361 | case SC_R_SDHC_1: | 361 | case SC_R_SDHC_1: |
| 362 | boot_dev = SD2_BOOT; | 362 | boot_dev = SD2_BOOT; |
| 363 | break; | 363 | break; |
| 364 | case SC_R_SDHC_2: | 364 | case SC_R_SDHC_2: |
| 365 | boot_dev = SD3_BOOT; | 365 | boot_dev = SD3_BOOT; |
| 366 | break; | 366 | break; |
| 367 | case SC_R_NAND: | 367 | case SC_R_NAND: |
| 368 | boot_dev = NAND_BOOT; | 368 | boot_dev = NAND_BOOT; |
| 369 | break; | 369 | break; |
| 370 | case SC_R_FSPI_0: | 370 | case SC_R_FSPI_0: |
| 371 | boot_dev = FLEXSPI_BOOT; | 371 | boot_dev = FLEXSPI_BOOT; |
| 372 | break; | 372 | break; |
| 373 | case SC_R_SATA_0: | 373 | case SC_R_SATA_0: |
| 374 | boot_dev = SATA_BOOT; | 374 | boot_dev = SATA_BOOT; |
| 375 | break; | 375 | break; |
| 376 | case SC_R_USB_0: | 376 | case SC_R_USB_0: |
| 377 | case SC_R_USB_1: | 377 | case SC_R_USB_1: |
| 378 | case SC_R_USB_2: | 378 | case SC_R_USB_2: |
| 379 | boot_dev = USB_BOOT; | 379 | boot_dev = USB_BOOT; |
| 380 | break; | 380 | break; |
| 381 | default: | 381 | default: |
| 382 | break; | 382 | break; |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | return boot_dev; | 385 | return boot_dev; |
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | bool is_usb_boot(void) | 388 | bool is_usb_boot(void) |
| 389 | { | 389 | { |
| 390 | return get_boot_device() == USB_BOOT; | 390 | return get_boot_device() == USB_BOOT; |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | #if defined(CONFIG_SERIAL_TAG) || defined(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG) | 393 | #if defined(CONFIG_SERIAL_TAG) || defined(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG) |
| 394 | #define FUSE_UNIQUE_ID_WORD0 16 | 394 | #define FUSE_UNIQUE_ID_WORD0 16 |
| 395 | #define FUSE_UNIQUE_ID_WORD1 17 | 395 | #define FUSE_UNIQUE_ID_WORD1 17 |
| 396 | void get_board_serial(struct tag_serialnr *serialnr) | 396 | void get_board_serial(struct tag_serialnr *serialnr) |
| 397 | { | 397 | { |
| 398 | sc_err_t err; | 398 | sc_err_t err; |
| 399 | u32 val1 = 0, val2 = 0; | 399 | u32 val1 = 0, val2 = 0; |
| 400 | u32 word1, word2; | 400 | u32 word1, word2; |
| 401 | 401 | ||
| 402 | if (!serialnr) | 402 | if (!serialnr) |
| 403 | return; | 403 | return; |
| 404 | 404 | ||
| 405 | word1 = FUSE_UNIQUE_ID_WORD0; | 405 | word1 = FUSE_UNIQUE_ID_WORD0; |
| 406 | word2 = FUSE_UNIQUE_ID_WORD1; | 406 | word2 = FUSE_UNIQUE_ID_WORD1; |
| 407 | 407 | ||
| 408 | err = sc_misc_otp_fuse_read(-1, word1, &val1); | 408 | err = sc_misc_otp_fuse_read(-1, word1, &val1); |
| 409 | if (err != SC_ERR_NONE) { | 409 | if (err != SC_ERR_NONE) { |
| 410 | printf("%s fuse %d read error: %d\n", __func__, word1, err); | 410 | printf("%s fuse %d read error: %d\n", __func__, word1, err); |
| 411 | return; | 411 | return; |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | err = sc_misc_otp_fuse_read(-1, word2, &val2); | 414 | err = sc_misc_otp_fuse_read(-1, word2, &val2); |
| 415 | if (err != SC_ERR_NONE) { | 415 | if (err != SC_ERR_NONE) { |
| 416 | printf("%s fuse %d read error: %d\n", __func__, word2, err); | 416 | printf("%s fuse %d read error: %d\n", __func__, word2, err); |
| 417 | return; | 417 | return; |
| 418 | } | 418 | } |
| 419 | serialnr->low = val1; | 419 | serialnr->low = val1; |
| 420 | serialnr->high = val2; | 420 | serialnr->high = val2; |
| 421 | } | 421 | } |
| 422 | #endif /*CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG*/ | 422 | #endif /*CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG*/ |
| 423 | 423 | ||
| 424 | __weak int board_mmc_get_env_dev(int devno) | 424 | __weak int board_mmc_get_env_dev(int devno) |
| 425 | { | 425 | { |
| 426 | return devno; | 426 | return devno; |
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | int mmc_get_env_dev(void) | 429 | int mmc_get_env_dev(void) |
| 430 | { | 430 | { |
| 431 | sc_rsrc_t dev_rsrc; | 431 | sc_rsrc_t dev_rsrc; |
| 432 | int devno; | 432 | int devno; |
| 433 | 433 | ||
| 434 | #if defined(CONFIG_TARGET_IMX8QM_MEK_A72_ONLY) | 434 | #if defined(CONFIG_TARGET_IMX8QM_MEK_A72_ONLY) |
| 435 | dev_rsrc = SC_R_SDHC_0; | 435 | dev_rsrc = SC_R_SDHC_0; |
| 436 | #else | 436 | #else |
| 437 | sc_misc_get_boot_dev(-1, &dev_rsrc); | 437 | sc_misc_get_boot_dev(-1, &dev_rsrc); |
| 438 | #endif | 438 | #endif |
| 439 | 439 | ||
| 440 | switch (dev_rsrc) { | 440 | switch (dev_rsrc) { |
| 441 | case SC_R_SDHC_0: | 441 | case SC_R_SDHC_0: |
| 442 | devno = 0; | 442 | devno = 0; |
| 443 | break; | 443 | break; |
| 444 | case SC_R_SDHC_1: | 444 | case SC_R_SDHC_1: |
| 445 | devno = 1; | 445 | devno = 1; |
| 446 | break; | 446 | break; |
| 447 | case SC_R_SDHC_2: | 447 | case SC_R_SDHC_2: |
| 448 | devno = 2; | 448 | devno = 2; |
| 449 | break; | 449 | break; |
| 450 | default: | 450 | default: |
| 451 | /* If not boot from sd/mmc, use default value */ | 451 | /* If not boot from sd/mmc, use default value */ |
| 452 | return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV); | 452 | return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV); |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | return board_mmc_get_env_dev(devno); | 455 | return board_mmc_get_env_dev(devno); |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | #define MEMSTART_ALIGNMENT SZ_2M /* Align the memory start with 2MB */ | 458 | #define MEMSTART_ALIGNMENT SZ_2M /* Align the memory start with 2MB */ |
| 459 | 459 | ||
| 460 | static sc_faddr_t reserve_optee_shm(sc_faddr_t addr_start) | 460 | static sc_faddr_t reserve_optee_shm(sc_faddr_t addr_start) |
| 461 | { | 461 | { |
| 462 | /* OPTEE has a share memory at its top address, | 462 | /* OPTEE has a share memory at its top address, |
| 463 | * ATF assigns the share memory to non-secure os partition for share with kernel | 463 | * ATF assigns the share memory to non-secure os partition for share with kernel |
| 464 | * We should not add this share memory to DDR bank, as this memory is dedicated for | 464 | * We should not add this share memory to DDR bank, as this memory is dedicated for |
| 465 | * optee, optee driver will memremap it and can't be used by system malloc. | 465 | * optee, optee driver will memremap it and can't be used by system malloc. |
| 466 | */ | 466 | */ |
| 467 | 467 | ||
| 468 | sc_faddr_t optee_start = rom_pointer[0]; | 468 | sc_faddr_t optee_start = rom_pointer[0]; |
| 469 | sc_faddr_t optee_size = rom_pointer[1]; | 469 | sc_faddr_t optee_size = rom_pointer[1]; |
| 470 | 470 | ||
| 471 | if (optee_size && optee_start <= addr_start && | 471 | if (optee_size && optee_start <= addr_start && |
| 472 | addr_start < optee_start + optee_size) { | 472 | addr_start < optee_start + optee_size) { |
| 473 | debug("optee 0x%llx 0x%llx, addr_start 0x%llx\n", | 473 | debug("optee 0x%llx 0x%llx, addr_start 0x%llx\n", |
| 474 | optee_start, optee_size, addr_start); | 474 | optee_start, optee_size, addr_start); |
| 475 | return optee_start + optee_size; | 475 | return optee_start + optee_size; |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | return addr_start; | 478 | return addr_start; |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start, | 481 | static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start, |
| 482 | sc_faddr_t *addr_end) | 482 | sc_faddr_t *addr_end) |
| 483 | { | 483 | { |
| 484 | sc_faddr_t start, end; | 484 | sc_faddr_t start, end; |
| 485 | int ret; | 485 | int ret; |
| 486 | bool owned; | 486 | bool owned; |
| 487 | 487 | ||
| 488 | owned = sc_rm_is_memreg_owned(-1, mr); | 488 | owned = sc_rm_is_memreg_owned(-1, mr); |
| 489 | if (owned) { | 489 | if (owned) { |
| 490 | ret = sc_rm_get_memreg_info(-1, mr, &start, &end); | 490 | ret = sc_rm_get_memreg_info(-1, mr, &start, &end); |
| 491 | if (ret) { | 491 | if (ret) { |
| 492 | printf("Memreg get info failed, %d\n", ret); | 492 | printf("Memreg get info failed, %d\n", ret); |
| 493 | return -EINVAL; | 493 | return -EINVAL; |
| 494 | } | 494 | } |
| 495 | debug("0x%llx -- 0x%llx\n", start, end); | 495 | debug("0x%llx -- 0x%llx\n", start, end); |
| 496 | *addr_start = reserve_optee_shm(start); | 496 | *addr_start = reserve_optee_shm(start); |
| 497 | *addr_end = end; | 497 | *addr_end = end; |
| 498 | 498 | ||
| 499 | return 0; | 499 | return 0; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | return -EINVAL; | 502 | return -EINVAL; |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | __weak void board_mem_get_layout(u64 *phys_sdram_1_start, | 505 | __weak void board_mem_get_layout(u64 *phys_sdram_1_start, |
| 506 | u64 *phys_sdram_1_size, | 506 | u64 *phys_sdram_1_size, |
| 507 | u64 *phys_sdram_2_start, | 507 | u64 *phys_sdram_2_start, |
| 508 | u64 *phys_sdram_2_size) | 508 | u64 *phys_sdram_2_size) |
| 509 | { | 509 | { |
| 510 | *phys_sdram_1_start = PHYS_SDRAM_1; | 510 | *phys_sdram_1_start = PHYS_SDRAM_1; |
| 511 | *phys_sdram_1_size = PHYS_SDRAM_1_SIZE; | 511 | *phys_sdram_1_size = PHYS_SDRAM_1_SIZE; |
| 512 | *phys_sdram_2_start = PHYS_SDRAM_2; | 512 | *phys_sdram_2_start = PHYS_SDRAM_2; |
| 513 | *phys_sdram_2_size = PHYS_SDRAM_2_SIZE; | 513 | *phys_sdram_2_size = PHYS_SDRAM_2_SIZE; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | phys_size_t get_effective_memsize(void) | 516 | phys_size_t get_effective_memsize(void) |
| 517 | { | 517 | { |
| 518 | sc_rm_mr_t mr; | 518 | sc_rm_mr_t mr; |
| 519 | sc_faddr_t start, end, end1, start_aligned; | 519 | sc_faddr_t start, end, end1, start_aligned; |
| 520 | u64 phys_sdram_1_start, phys_sdram_1_size; | 520 | u64 phys_sdram_1_start, phys_sdram_1_size; |
| 521 | u64 phys_sdram_2_start, phys_sdram_2_size; | 521 | u64 phys_sdram_2_start, phys_sdram_2_size; |
| 522 | int err; | 522 | int err; |
| 523 | 523 | ||
| 524 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, | 524 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, |
| 525 | &phys_sdram_2_start, &phys_sdram_2_size); | 525 | &phys_sdram_2_start, &phys_sdram_2_size); |
| 526 | 526 | ||
| 527 | 527 | ||
| 528 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; | 528 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; |
| 529 | 529 | ||
| 530 | if (IS_ENABLED(CONFIG_XEN)) | 530 | if (IS_ENABLED(CONFIG_XEN)) |
| 531 | return PHYS_SDRAM_1_SIZE; | 531 | return PHYS_SDRAM_1_SIZE; |
| 532 | 532 | ||
| 533 | for (mr = 0; mr < 64; mr++) { | 533 | for (mr = 0; mr < 64; mr++) { |
| 534 | err = get_owned_memreg(mr, &start, &end); | 534 | err = get_owned_memreg(mr, &start, &end); |
| 535 | if (!err) { | 535 | if (!err) { |
| 536 | start_aligned = roundup(start, MEMSTART_ALIGNMENT); | 536 | start_aligned = roundup(start, MEMSTART_ALIGNMENT); |
| 537 | /* Too small memory region, not use it */ | 537 | /* Too small memory region, not use it */ |
| 538 | if (start_aligned > end) | 538 | if (start_aligned > end) |
| 539 | continue; | 539 | continue; |
| 540 | 540 | ||
| 541 | /* Find the memory region runs the U-Boot */ | 541 | /* Find the memory region runs the U-Boot */ |
| 542 | if (start >= phys_sdram_1_start && start <= end1 && | 542 | if (start >= phys_sdram_1_start && start <= end1 && |
| 543 | (start <= CONFIG_TEXT_BASE && | 543 | (start <= CONFIG_TEXT_BASE && |
| 544 | end >= CONFIG_TEXT_BASE)) { | 544 | end >= CONFIG_TEXT_BASE)) { |
| 545 | if ((end + 1) <= | 545 | if ((end + 1) <= |
| 546 | ((sc_faddr_t)phys_sdram_1_start + | 546 | ((sc_faddr_t)phys_sdram_1_start + |
| 547 | phys_sdram_1_size)) | 547 | phys_sdram_1_size)) |
| 548 | return (end - phys_sdram_1_start + 1); | 548 | return (end - phys_sdram_1_start + 1); |
| 549 | else | 549 | else |
| 550 | return phys_sdram_1_size; | 550 | return phys_sdram_1_size; |
| 551 | } | 551 | } |
| 552 | } | 552 | } |
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | return phys_sdram_1_size; | 555 | return phys_sdram_1_size; |
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | int dram_init(void) | 558 | int dram_init(void) |
| 559 | { | 559 | { |
| 560 | sc_rm_mr_t mr; | 560 | sc_rm_mr_t mr; |
| 561 | sc_faddr_t start, end, end1, end2; | 561 | sc_faddr_t start, end, end1, end2; |
| 562 | u64 phys_sdram_1_start, phys_sdram_1_size; | 562 | u64 phys_sdram_1_start, phys_sdram_1_size; |
| 563 | u64 phys_sdram_2_start, phys_sdram_2_size; | 563 | u64 phys_sdram_2_start, phys_sdram_2_size; |
| 564 | int err; | 564 | int err; |
| 565 | 565 | ||
| 566 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, | 566 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, |
| 567 | &phys_sdram_2_start, &phys_sdram_2_size); | 567 | &phys_sdram_2_start, &phys_sdram_2_size); |
| 568 | 568 | ||
| 569 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; | 569 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; |
| 570 | end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; | 570 | end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; |
| 571 | 571 | ||
| 572 | if (IS_ENABLED(CONFIG_XEN)) { | 572 | if (IS_ENABLED(CONFIG_XEN)) { |
| 573 | gd->ram_size = PHYS_SDRAM_1_SIZE; | 573 | gd->ram_size = PHYS_SDRAM_1_SIZE; |
| 574 | gd->ram_size += PHYS_SDRAM_2_SIZE; | 574 | gd->ram_size += PHYS_SDRAM_2_SIZE; |
| 575 | 575 | ||
| 576 | return 0; | 576 | return 0; |
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | for (mr = 0; mr < 64; mr++) { | 579 | for (mr = 0; mr < 64; mr++) { |
| 580 | err = get_owned_memreg(mr, &start, &end); | 580 | err = get_owned_memreg(mr, &start, &end); |
| 581 | if (!err) { | 581 | if (!err) { |
| 582 | start = roundup(start, MEMSTART_ALIGNMENT); | 582 | start = roundup(start, MEMSTART_ALIGNMENT); |
| 583 | /* Too small memory region, not use it */ | 583 | /* Too small memory region, not use it */ |
| 584 | if (start > end) | 584 | if (start > end) |
| 585 | continue; | 585 | continue; |
| 586 | 586 | ||
| 587 | if (start >= phys_sdram_1_start && start <= end1) { | 587 | if (start >= phys_sdram_1_start && start <= end1) { |
| 588 | if ((end + 1) <= end1) | 588 | if ((end + 1) <= end1) |
| 589 | gd->ram_size += end - start + 1; | 589 | gd->ram_size += end - start + 1; |
| 590 | else | 590 | else |
| 591 | gd->ram_size += end1 - start; | 591 | gd->ram_size += end1 - start; |
| 592 | } else if (start >= phys_sdram_2_start && | 592 | } else if (start >= phys_sdram_2_start && |
| 593 | start <= end2) { | 593 | start <= end2) { |
| 594 | if ((end + 1) <= end2) | 594 | if ((end + 1) <= end2) |
| 595 | gd->ram_size += end - start + 1; | 595 | gd->ram_size += end - start + 1; |
| 596 | else | 596 | else |
| 597 | gd->ram_size += end2 - start; | 597 | gd->ram_size += end2 - start; |
| 598 | } | 598 | } |
| 599 | } | 599 | } |
| 600 | } | 600 | } |
| 601 | 601 | ||
| 602 | /* If error, set to the default value */ | 602 | /* If error, set to the default value */ |
| 603 | if (!gd->ram_size) { | 603 | if (!gd->ram_size) { |
| 604 | gd->ram_size = phys_sdram_1_size; | 604 | gd->ram_size = phys_sdram_1_size; |
| 605 | gd->ram_size += phys_sdram_2_size; | 605 | gd->ram_size += phys_sdram_2_size; |
| 606 | } | 606 | } |
| 607 | return 0; | 607 | return 0; |
| 608 | } | 608 | } |
| 609 | 609 | ||
| 610 | static void dram_bank_sort(int current_bank) | 610 | static void dram_bank_sort(int current_bank) |
| 611 | { | 611 | { |
| 612 | phys_addr_t start; | 612 | phys_addr_t start; |
| 613 | phys_size_t size; | 613 | phys_size_t size; |
| 614 | 614 | ||
| 615 | while (current_bank > 0) { | 615 | while (current_bank > 0) { |
| 616 | if (gd->bd->bi_dram[current_bank - 1].start > | 616 | if (gd->bd->bi_dram[current_bank - 1].start > |
| 617 | gd->bd->bi_dram[current_bank].start) { | 617 | gd->bd->bi_dram[current_bank].start) { |
| 618 | start = gd->bd->bi_dram[current_bank - 1].start; | 618 | start = gd->bd->bi_dram[current_bank - 1].start; |
| 619 | size = gd->bd->bi_dram[current_bank - 1].size; | 619 | size = gd->bd->bi_dram[current_bank - 1].size; |
| 620 | 620 | ||
| 621 | gd->bd->bi_dram[current_bank - 1].start = | 621 | gd->bd->bi_dram[current_bank - 1].start = |
| 622 | gd->bd->bi_dram[current_bank].start; | 622 | gd->bd->bi_dram[current_bank].start; |
| 623 | gd->bd->bi_dram[current_bank - 1].size = | 623 | gd->bd->bi_dram[current_bank - 1].size = |
| 624 | gd->bd->bi_dram[current_bank].size; | 624 | gd->bd->bi_dram[current_bank].size; |
| 625 | 625 | ||
| 626 | gd->bd->bi_dram[current_bank].start = start; | 626 | gd->bd->bi_dram[current_bank].start = start; |
| 627 | gd->bd->bi_dram[current_bank].size = size; | 627 | gd->bd->bi_dram[current_bank].size = size; |
| 628 | } | 628 | } |
| 629 | current_bank--; | 629 | current_bank--; |
| 630 | } | 630 | } |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | int dram_init_banksize(void) | 633 | int dram_init_banksize(void) |
| 634 | { | 634 | { |
| 635 | sc_rm_mr_t mr; | 635 | sc_rm_mr_t mr; |
| 636 | sc_faddr_t start, end, end1, end2; | 636 | sc_faddr_t start, end, end1, end2; |
| 637 | int i = 0; | 637 | int i = 0; |
| 638 | u64 phys_sdram_1_start, phys_sdram_1_size; | 638 | u64 phys_sdram_1_start, phys_sdram_1_size; |
| 639 | u64 phys_sdram_2_start, phys_sdram_2_size; | 639 | u64 phys_sdram_2_start, phys_sdram_2_size; |
| 640 | int err; | 640 | int err; |
| 641 | 641 | ||
| 642 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, | 642 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, |
| 643 | &phys_sdram_2_start, &phys_sdram_2_size); | 643 | &phys_sdram_2_start, &phys_sdram_2_size); |
| 644 | 644 | ||
| 645 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; | 645 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; |
| 646 | end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; | 646 | end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; |
| 647 | 647 | ||
| 648 | if (IS_ENABLED(CONFIG_XEN)) { | 648 | if (IS_ENABLED(CONFIG_XEN)) { |
| 649 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | 649 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; |
| 650 | gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; | 650 | gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; |
| 651 | gd->bd->bi_dram[1].start = PHYS_SDRAM_2; | 651 | gd->bd->bi_dram[1].start = PHYS_SDRAM_2; |
| 652 | gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; | 652 | gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; |
| 653 | 653 | ||
| 654 | return 0; | 654 | return 0; |
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) { | 657 | for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) { |
| 658 | err = get_owned_memreg(mr, &start, &end); | 658 | err = get_owned_memreg(mr, &start, &end); |
| 659 | if (!err) { | 659 | if (!err) { |
| 660 | start = roundup(start, MEMSTART_ALIGNMENT); | 660 | start = roundup(start, MEMSTART_ALIGNMENT); |
| 661 | if (start > end) /* Small memory region, no use it */ | 661 | if (start > end) /* Small memory region, no use it */ |
| 662 | continue; | 662 | continue; |
| 663 | 663 | ||
| 664 | if (start >= phys_sdram_1_start && start <= end1) { | 664 | if (start >= phys_sdram_1_start && start <= end1) { |
| 665 | gd->bd->bi_dram[i].start = start; | 665 | gd->bd->bi_dram[i].start = start; |
| 666 | 666 | ||
| 667 | if ((end + 1) <= end1) | 667 | if ((end + 1) <= end1) |
| 668 | gd->bd->bi_dram[i].size = | 668 | gd->bd->bi_dram[i].size = |
| 669 | end - start + 1; | 669 | end - start + 1; |
| 670 | else | 670 | else |
| 671 | gd->bd->bi_dram[i].size = end1 - start; | 671 | gd->bd->bi_dram[i].size = end1 - start; |
| 672 | 672 | ||
| 673 | dram_bank_sort(i); | 673 | dram_bank_sort(i); |
| 674 | i++; | 674 | i++; |
| 675 | } else if (start >= phys_sdram_2_start && start <= end2) { | 675 | } else if (start >= phys_sdram_2_start && start <= end2) { |
| 676 | gd->bd->bi_dram[i].start = start; | 676 | gd->bd->bi_dram[i].start = start; |
| 677 | 677 | ||
| 678 | if ((end + 1) <= end2) | 678 | if ((end + 1) <= end2) |
| 679 | gd->bd->bi_dram[i].size = | 679 | gd->bd->bi_dram[i].size = |
| 680 | end - start + 1; | 680 | end - start + 1; |
| 681 | else | 681 | else |
| 682 | gd->bd->bi_dram[i].size = end2 - start; | 682 | gd->bd->bi_dram[i].size = end2 - start; |
| 683 | 683 | ||
| 684 | dram_bank_sort(i); | 684 | dram_bank_sort(i); |
| 685 | i++; | 685 | i++; |
| 686 | } | 686 | } |
| 687 | } | 687 | } |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | /* If error, set to the default value */ | 690 | /* If error, set to the default value */ |
| 691 | if (!i) { | 691 | if (!i) { |
| 692 | gd->bd->bi_dram[0].start = phys_sdram_1_start; | 692 | gd->bd->bi_dram[0].start = phys_sdram_1_start; |
| 693 | gd->bd->bi_dram[0].size = phys_sdram_1_size; | 693 | gd->bd->bi_dram[0].size = phys_sdram_1_size; |
| 694 | gd->bd->bi_dram[1].start = phys_sdram_2_start; | 694 | gd->bd->bi_dram[1].start = phys_sdram_2_start; |
| 695 | gd->bd->bi_dram[1].size = phys_sdram_2_size; | 695 | gd->bd->bi_dram[1].size = phys_sdram_2_size; |
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | return 0; | 698 | return 0; |
| 699 | } | 699 | } |
| 700 | 700 | ||
| 701 | static u64 get_block_attrs(sc_faddr_t addr_start) | 701 | static u64 get_block_attrs(sc_faddr_t addr_start) |
| 702 | { | 702 | { |
| 703 | u64 attr = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | | 703 | u64 attr = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | |
| 704 | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 704 | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
| 705 | u64 phys_sdram_1_start, phys_sdram_1_size; | 705 | u64 phys_sdram_1_start, phys_sdram_1_size; |
| 706 | u64 phys_sdram_2_start, phys_sdram_2_size; | 706 | u64 phys_sdram_2_start, phys_sdram_2_size; |
| 707 | 707 | ||
| 708 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, | 708 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, |
| 709 | &phys_sdram_2_start, &phys_sdram_2_size); | 709 | &phys_sdram_2_start, &phys_sdram_2_size); |
| 710 | 710 | ||
| 711 | if ((addr_start >= phys_sdram_1_start && | 711 | if ((addr_start >= phys_sdram_1_start && |
| 712 | addr_start <= ((sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size)) || | 712 | addr_start <= ((sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size)) || |
| 713 | (addr_start >= phys_sdram_2_start && | 713 | (addr_start >= phys_sdram_2_start && |
| 714 | addr_start <= ((sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size))) | 714 | addr_start <= ((sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size))) |
| 715 | #ifdef CONFIG_IMX_TRUSTY_OS | 715 | #ifdef CONFIG_IMX_TRUSTY_OS |
| 716 | return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); | 716 | return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); |
| 717 | #else | 717 | #else |
| 718 | return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE); | 718 | return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE); |
| 719 | #endif | 719 | #endif |
| 720 | 720 | ||
| 721 | return attr; | 721 | return attr; |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | static u64 get_block_size(sc_faddr_t addr_start, sc_faddr_t addr_end) | 724 | static u64 get_block_size(sc_faddr_t addr_start, sc_faddr_t addr_end) |
| 725 | { | 725 | { |
| 726 | sc_faddr_t end1, end2; | 726 | sc_faddr_t end1, end2; |
| 727 | u64 phys_sdram_1_start, phys_sdram_1_size; | 727 | u64 phys_sdram_1_start, phys_sdram_1_size; |
| 728 | u64 phys_sdram_2_start, phys_sdram_2_size; | 728 | u64 phys_sdram_2_start, phys_sdram_2_size; |
| 729 | 729 | ||
| 730 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, | 730 | board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, |
| 731 | &phys_sdram_2_start, &phys_sdram_2_size); | 731 | &phys_sdram_2_start, &phys_sdram_2_size); |
| 732 | 732 | ||
| 733 | 733 | ||
| 734 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; | 734 | end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; |
| 735 | end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; | 735 | end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; |
| 736 | 736 | ||
| 737 | if (addr_start >= phys_sdram_1_start && addr_start <= end1) { | 737 | if (addr_start >= phys_sdram_1_start && addr_start <= end1) { |
| 738 | if ((addr_end + 1) > end1) | 738 | if ((addr_end + 1) > end1) |
| 739 | return end1 - addr_start; | 739 | return end1 - addr_start; |
| 740 | } else if (addr_start >= phys_sdram_2_start && addr_start <= end2) { | 740 | } else if (addr_start >= phys_sdram_2_start && addr_start <= end2) { |
| 741 | if ((addr_end + 1) > end2) | 741 | if ((addr_end + 1) > end2) |
| 742 | return end2 - addr_start; | 742 | return end2 - addr_start; |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | return (addr_end - addr_start + 1); | 745 | return (addr_end - addr_start + 1); |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | #define MAX_PTE_ENTRIES 512 | 748 | #define MAX_PTE_ENTRIES 512 |
| 749 | #define MAX_MEM_MAP_REGIONS 16 | 749 | #define MAX_MEM_MAP_REGIONS 16 |
| 750 | 750 | ||
| 751 | static struct mm_region imx8_mem_map[MAX_MEM_MAP_REGIONS]; | 751 | static struct mm_region imx8_mem_map[MAX_MEM_MAP_REGIONS]; |
| 752 | struct mm_region *mem_map = imx8_mem_map; | 752 | struct mm_region *mem_map = imx8_mem_map; |
| 753 | 753 | ||
| 754 | void enable_caches(void) | 754 | void enable_caches(void) |
| 755 | { | 755 | { |
| 756 | sc_rm_mr_t mr; | 756 | sc_rm_mr_t mr; |
| 757 | sc_faddr_t start, end; | 757 | sc_faddr_t start, end; |
| 758 | int err, i; | 758 | int err, i; |
| 759 | 759 | ||
| 760 | if (IS_ENABLED(CONFIG_XEN)) { | 760 | if (IS_ENABLED(CONFIG_XEN)) { |
| 761 | imx8_mem_map[0].virt = 0x00000000UL; | 761 | imx8_mem_map[0].virt = 0x00000000UL; |
| 762 | imx8_mem_map[0].phys = 0x00000000UL; | 762 | imx8_mem_map[0].phys = 0x00000000UL; |
| 763 | imx8_mem_map[0].size = 0x80000000UL; | 763 | imx8_mem_map[0].size = 0x39000000UL; |
| 764 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 764 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
| 765 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 765 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
| 766 | imx8_mem_map[1].virt = 0x80000000UL; | 766 | imx8_mem_map[1].virt = 0x39000000UL; |
| 767 | imx8_mem_map[1].phys = 0x80000000UL; | 767 | imx8_mem_map[1].phys = 0x39000000UL; |
| 768 | imx8_mem_map[1].size = 0x80000000UL; | 768 | imx8_mem_map[1].size = 0x01000000UL; |
| 769 | imx8_mem_map[1].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE); | 769 | imx8_mem_map[1].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); |
| 770 | 770 | ||
| 771 | imx8_mem_map[2].virt = 0x100000000UL; | 771 | imx8_mem_map[2].virt = 0x40000000UL; |
| 772 | imx8_mem_map[2].phys = 0x100000000UL; | 772 | imx8_mem_map[2].phys = 0x40000000UL; |
| 773 | imx8_mem_map[2].size = 0x100000000UL; | 773 | imx8_mem_map[2].size = 0x40000000UL; |
| 774 | imx8_mem_map[2].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 774 | imx8_mem_map[2].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
| 775 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | ||
| 776 | |||
| 777 | imx8_mem_map[3].virt = 0x80000000UL; | ||
| 778 | imx8_mem_map[3].phys = 0x80000000UL; | ||
| 779 | imx8_mem_map[3].size = 0x80000000UL; | ||
| 780 | imx8_mem_map[3].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); | ||
| 781 | |||
| 782 | imx8_mem_map[4].virt = 0x100000000UL; | ||
| 783 | imx8_mem_map[4].phys = 0x100000000UL; | ||
| 784 | imx8_mem_map[4].size = 0x100000000UL; | ||
| 785 | imx8_mem_map[4].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | ||
| 775 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 786 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
| 776 | 787 | ||
| 777 | icache_enable(); | 788 | icache_enable(); |
| 778 | dcache_enable(); | 789 | dcache_enable(); |
| 779 | 790 | ||
| 780 | return; | 791 | return; |
| 781 | } | 792 | } |
| 782 | 793 | ||
| 783 | /* Create map for registers access from 0x1c000000 to 0x80000000*/ | 794 | /* Create map for registers access from 0x1c000000 to 0x80000000*/ |
| 784 | imx8_mem_map[0].virt = 0x1c000000UL; | 795 | imx8_mem_map[0].virt = 0x1c000000UL; |
| 785 | imx8_mem_map[0].phys = 0x1c000000UL; | 796 | imx8_mem_map[0].phys = 0x1c000000UL; |
| 786 | imx8_mem_map[0].size = 0x64000000UL; | 797 | imx8_mem_map[0].size = 0x64000000UL; |
| 787 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 798 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
| 788 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 799 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
| 789 | 800 | ||
| 790 | i = 1; | 801 | i = 1; |
| 791 | 802 | ||
| 792 | #ifdef CONFIG_IMX_VSERVICE_SHARED_BUFFER | 803 | #ifdef CONFIG_IMX_VSERVICE_SHARED_BUFFER |
| 793 | imx8_mem_map[i].virt = CONFIG_IMX_VSERVICE_SHARED_BUFFER; | 804 | imx8_mem_map[i].virt = CONFIG_IMX_VSERVICE_SHARED_BUFFER; |
| 794 | imx8_mem_map[i].phys = CONFIG_IMX_VSERVICE_SHARED_BUFFER; | 805 | imx8_mem_map[i].phys = CONFIG_IMX_VSERVICE_SHARED_BUFFER; |
| 795 | imx8_mem_map[i].size = CONFIG_IMX_VSERVICE_SHARED_BUFFER_SIZE; | 806 | imx8_mem_map[i].size = CONFIG_IMX_VSERVICE_SHARED_BUFFER_SIZE; |
| 796 | imx8_mem_map[i].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 807 | imx8_mem_map[i].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
| 797 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 808 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
| 798 | i++; | 809 | i++; |
| 799 | #endif | 810 | #endif |
| 800 | 811 | ||
| 801 | for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) { | 812 | for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) { |
| 802 | err = get_owned_memreg(mr, &start, &end); | 813 | err = get_owned_memreg(mr, &start, &end); |
| 803 | if (!err) { | 814 | if (!err) { |
| 804 | imx8_mem_map[i].virt = start; | 815 | imx8_mem_map[i].virt = start; |
| 805 | imx8_mem_map[i].phys = start; | 816 | imx8_mem_map[i].phys = start; |
| 806 | imx8_mem_map[i].size = get_block_size(start, end); | 817 | imx8_mem_map[i].size = get_block_size(start, end); |
| 807 | imx8_mem_map[i].attrs = get_block_attrs(start); | 818 | imx8_mem_map[i].attrs = get_block_attrs(start); |
| 808 | i++; | 819 | i++; |
| 809 | } | 820 | } |
| 810 | } | 821 | } |
| 811 | 822 | ||
| 812 | if (i < MAX_MEM_MAP_REGIONS) { | 823 | if (i < MAX_MEM_MAP_REGIONS) { |
| 813 | imx8_mem_map[i].size = 0; | 824 | imx8_mem_map[i].size = 0; |
| 814 | imx8_mem_map[i].attrs = 0; | 825 | imx8_mem_map[i].attrs = 0; |
| 815 | } else { | 826 | } else { |
| 816 | puts("Error, need more MEM MAP REGIONS reserved\n"); | 827 | puts("Error, need more MEM MAP REGIONS reserved\n"); |
| 817 | icache_enable(); | 828 | icache_enable(); |
| 818 | return; | 829 | return; |
| 819 | } | 830 | } |
| 820 | 831 | ||
| 821 | for (i = 0; i < MAX_MEM_MAP_REGIONS; i++) { | 832 | for (i = 0; i < MAX_MEM_MAP_REGIONS; i++) { |
| 822 | debug("[%d] vir = 0x%llx phys = 0x%llx size = 0x%llx attrs = 0x%llx\n", | 833 | debug("[%d] vir = 0x%llx phys = 0x%llx size = 0x%llx attrs = 0x%llx\n", |
| 823 | i, imx8_mem_map[i].virt, imx8_mem_map[i].phys, | 834 | i, imx8_mem_map[i].virt, imx8_mem_map[i].phys, |
| 824 | imx8_mem_map[i].size, imx8_mem_map[i].attrs); | 835 | imx8_mem_map[i].size, imx8_mem_map[i].attrs); |
| 825 | } | 836 | } |
| 826 | 837 | ||
| 827 | icache_enable(); | 838 | icache_enable(); |
| 828 | dcache_enable(); | 839 | dcache_enable(); |
| 829 | } | 840 | } |
| 830 | 841 | ||
| 831 | #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) | 842 | #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) |
| 832 | u64 get_page_table_size(void) | 843 | u64 get_page_table_size(void) |
| 833 | { | 844 | { |
| 834 | u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64); | 845 | u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64); |
| 835 | u64 size = 0; | 846 | u64 size = 0; |
| 836 | 847 | ||
| 837 | /* | 848 | /* |
| 838 | * For each memory region, the max table size: | 849 | * For each memory region, the max table size: |
| 839 | * 2 level 3 tables + 2 level 2 tables + 1 level 1 table | 850 | * 2 level 3 tables + 2 level 2 tables + 1 level 1 table |
| 840 | */ | 851 | */ |
| 841 | size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt; | 852 | size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt; |
| 842 | 853 | ||
| 843 | /* | 854 | /* |
| 844 | * We need to duplicate our page table once to have an emergency pt to | 855 | * We need to duplicate our page table once to have an emergency pt to |
| 845 | * resort to when splitting page tables later on | 856 | * resort to when splitting page tables later on |
| 846 | */ | 857 | */ |
| 847 | size *= 2; | 858 | size *= 2; |
| 848 | 859 | ||
| 849 | /* | 860 | /* |
| 850 | * We may need to split page tables later on if dcache settings change, | 861 | * We may need to split page tables later on if dcache settings change, |
| 851 | * so reserve up to 4 (random pick) page tables for that. | 862 | * so reserve up to 4 (random pick) page tables for that. |
| 852 | */ | 863 | */ |
| 853 | size += one_pt * 4; | 864 | size += one_pt * 4; |
| 854 | 865 | ||
| 855 | return size; | 866 | return size; |
| 856 | } | 867 | } |
| 857 | #endif | 868 | #endif |
| 858 | 869 | ||
| 859 | #if defined(CONFIG_IMX8QM) | 870 | #if defined(CONFIG_IMX8QM) |
| 860 | #define FUSE_MAC0_WORD0 452 | 871 | #define FUSE_MAC0_WORD0 452 |
| 861 | #define FUSE_MAC0_WORD1 453 | 872 | #define FUSE_MAC0_WORD1 453 |
| 862 | #define FUSE_MAC1_WORD0 454 | 873 | #define FUSE_MAC1_WORD0 454 |
| 863 | #define FUSE_MAC1_WORD1 455 | 874 | #define FUSE_MAC1_WORD1 455 |
| 864 | #elif defined(CONFIG_IMX8QXP) || defined (CONFIG_IMX8DXL) | 875 | #elif defined(CONFIG_IMX8QXP) || defined (CONFIG_IMX8DXL) |
| 865 | #define FUSE_MAC0_WORD0 708 | 876 | #define FUSE_MAC0_WORD0 708 |
| 866 | #define FUSE_MAC0_WORD1 709 | 877 | #define FUSE_MAC0_WORD1 709 |
| 867 | #define FUSE_MAC1_WORD0 710 | 878 | #define FUSE_MAC1_WORD0 710 |
| 868 | #define FUSE_MAC1_WORD1 711 | 879 | #define FUSE_MAC1_WORD1 711 |
| 869 | #endif | 880 | #endif |
| 870 | 881 | ||
| 871 | void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) | 882 | void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) |
| 872 | { | 883 | { |
| 873 | u32 word[2], val[2] = {}; | 884 | u32 word[2], val[2] = {}; |
| 874 | int i, ret; | 885 | int i, ret; |
| 875 | 886 | ||
| 876 | if (dev_id == 0) { | 887 | if (dev_id == 0) { |
| 877 | word[0] = FUSE_MAC0_WORD0; | 888 | word[0] = FUSE_MAC0_WORD0; |
| 878 | word[1] = FUSE_MAC0_WORD1; | 889 | word[1] = FUSE_MAC0_WORD1; |
| 879 | } else { | 890 | } else { |
| 880 | word[0] = FUSE_MAC1_WORD0; | 891 | word[0] = FUSE_MAC1_WORD0; |
| 881 | word[1] = FUSE_MAC1_WORD1; | 892 | word[1] = FUSE_MAC1_WORD1; |
| 882 | } | 893 | } |
| 883 | 894 | ||
| 884 | for (i = 0; i < 2; i++) { | 895 | for (i = 0; i < 2; i++) { |
| 885 | ret = sc_misc_otp_fuse_read(-1, word[i], &val[i]); | 896 | ret = sc_misc_otp_fuse_read(-1, word[i], &val[i]); |
| 886 | if (ret < 0) | 897 | if (ret < 0) |
| 887 | goto err; | 898 | goto err; |
| 888 | } | 899 | } |
| 889 | 900 | ||
| 890 | mac[0] = val[0]; | 901 | mac[0] = val[0]; |
| 891 | mac[1] = val[0] >> 8; | 902 | mac[1] = val[0] >> 8; |
| 892 | mac[2] = val[0] >> 16; | 903 | mac[2] = val[0] >> 16; |
| 893 | mac[3] = val[0] >> 24; | 904 | mac[3] = val[0] >> 24; |
| 894 | mac[4] = val[1]; | 905 | mac[4] = val[1]; |
| 895 | mac[5] = val[1] >> 8; | 906 | mac[5] = val[1] >> 8; |
| 896 | 907 | ||
| 897 | debug("%s: MAC%d: %02x.%02x.%02x.%02x.%02x.%02x\n", | 908 | debug("%s: MAC%d: %02x.%02x.%02x.%02x.%02x.%02x\n", |
| 898 | __func__, dev_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | 909 | __func__, dev_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
| 899 | return; | 910 | return; |
| 900 | err: | 911 | err: |
| 901 | printf("%s: fuse %d, err: %d\n", __func__, word[i], ret); | 912 | printf("%s: fuse %d, err: %d\n", __func__, word[i], ret); |
| 902 | } | 913 | } |
| 903 | 914 | ||
| 904 | u32 get_cpu_rev(void) | 915 | u32 get_cpu_rev(void) |
| 905 | { | 916 | { |
| 906 | u32 id = 0, rev = 0; | 917 | u32 id = 0, rev = 0; |
| 907 | int ret; | 918 | int ret; |
| 908 | 919 | ||
| 909 | ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id); | 920 | ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id); |
| 910 | if (ret) | 921 | if (ret) |
| 911 | return 0; | 922 | return 0; |
| 912 | 923 | ||
| 913 | rev = (id >> 5) & 0xf; | 924 | rev = (id >> 5) & 0xf; |
| 914 | id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */ | 925 | id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */ |
| 915 | 926 | ||
| 916 | /* 8DXL uses A1/A2, so generate dummy rev to differentiate with B/C */ | 927 | /* 8DXL uses A1/A2, so generate dummy rev to differentiate with B/C */ |
| 917 | if (id == MXC_CPU_IMX8DXL && rev != 0) | 928 | if (id == MXC_CPU_IMX8DXL && rev != 0) |
| 918 | rev = 0x10 + rev; | 929 | rev = 0x10 + rev; |
| 919 | 930 | ||
| 920 | return (id << 12) | rev; | 931 | return (id << 12) | rev; |
| 921 | } | 932 | } |
| 922 | 933 | ||
| 923 | void board_boot_order(u32 *spl_boot_list) | 934 | void board_boot_order(u32 *spl_boot_list) |
| 924 | { | 935 | { |
| 925 | spl_boot_list[0] = spl_boot_device(); | 936 | spl_boot_list[0] = spl_boot_device(); |
| 926 | 937 | ||
| 927 | if (spl_boot_list[0] == BOOT_DEVICE_SPI) { | 938 | if (spl_boot_list[0] == BOOT_DEVICE_SPI) { |
| 928 | /* Check whether we own the flexspi0, if not, use NOR boot */ | 939 | /* Check whether we own the flexspi0, if not, use NOR boot */ |
| 929 | if (!sc_rm_is_resource_owned(-1, SC_R_FSPI_0)) | 940 | if (!sc_rm_is_resource_owned(-1, SC_R_FSPI_0)) |
| 930 | spl_boot_list[0] = BOOT_DEVICE_NOR; | 941 | spl_boot_list[0] = BOOT_DEVICE_NOR; |
| 931 | } | 942 | } |
| 932 | } | 943 | } |
| 933 | 944 | ||
| 934 | bool m4_parts_booted(void) | 945 | bool m4_parts_booted(void) |
| 935 | { | 946 | { |
| 936 | sc_rm_pt_t m4_parts[2]; | 947 | sc_rm_pt_t m4_parts[2]; |
| 937 | int err; | 948 | int err; |
| 938 | 949 | ||
| 939 | err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]); | 950 | err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]); |
| 940 | if (err) { | 951 | if (err) { |
| 941 | printf("%s get resource [%d] owner error: %d\n", __func__, | 952 | printf("%s get resource [%d] owner error: %d\n", __func__, |
| 942 | SC_R_M4_0_PID0, err); | 953 | SC_R_M4_0_PID0, err); |
| 943 | return false; | 954 | return false; |
| 944 | } | 955 | } |
| 945 | 956 | ||
| 946 | if (sc_pm_is_partition_started(-1, m4_parts[0])) | 957 | if (sc_pm_is_partition_started(-1, m4_parts[0])) |
| 947 | return true; | 958 | return true; |
| 948 | 959 | ||
| 949 | if (is_imx8qm()) { | 960 | if (is_imx8qm()) { |
| 950 | err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]); | 961 | err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]); |
| 951 | if (err) { | 962 | if (err) { |
| 952 | printf("%s get resource [%d] owner error: %d\n", | 963 | printf("%s get resource [%d] owner error: %d\n", |
| 953 | __func__, SC_R_M4_1_PID0, err); | 964 | __func__, SC_R_M4_1_PID0, err); |
| 954 | return false; | 965 | return false; |
| 955 | } | 966 | } |
| 956 | 967 | ||
| 957 | if (sc_pm_is_partition_started(-1, m4_parts[1])) | 968 | if (sc_pm_is_partition_started(-1, m4_parts[1])) |
| 958 | return true; | 969 | return true; |
| 959 | } | 970 | } |
| 960 | 971 | ||
| 961 | return false; | 972 | return false; |
| 962 | } | 973 | } |
| 963 | 974 | ||
| 964 | void disconnect_from_pc(void) | 975 | void disconnect_from_pc(void) |
| 965 | { | 976 | { |
| 966 | int ret; | 977 | int ret; |
| 967 | struct power_domain pd; | 978 | struct power_domain pd; |
| 968 | 979 | ||
| 969 | if (!power_domain_lookup_name("conn_usb0", &pd)) { | 980 | if (!power_domain_lookup_name("conn_usb0", &pd)) { |
| 970 | ret = power_domain_on(&pd); | 981 | ret = power_domain_on(&pd); |
| 971 | if (ret) { | 982 | if (ret) { |
| 972 | printf("conn_usb0 Power up failed! (error = %d)\n", ret); | 983 | printf("conn_usb0 Power up failed! (error = %d)\n", ret); |
| 973 | return; | 984 | return; |
| 974 | } | 985 | } |
| 975 | 986 | ||
| 976 | writel(0x0, USB_BASE_ADDR + 0x140); | 987 | writel(0x0, USB_BASE_ADDR + 0x140); |
| 977 | 988 | ||
| 978 | ret = power_domain_off(&pd); | 989 | ret = power_domain_off(&pd); |
| 979 | if (ret) { | 990 | if (ret) { |
| 980 | printf("conn_usb0 Power off failed! (error = %d)\n", ret); | 991 | printf("conn_usb0 Power off failed! (error = %d)\n", ret); |
| 981 | return; | 992 | return; |
| 982 | } | 993 | } |
| 983 | } else { | 994 | } else { |
| 984 | printf("conn_usb0 finding failed!\n"); | 995 | printf("conn_usb0 finding failed!\n"); |
| 985 | return; | 996 | return; |
| 986 | } | 997 | } |
| 987 | } | 998 | } |
| 988 | 999 | ||
| 989 | bool check_owned_udevice(struct udevice *dev) | 1000 | bool check_owned_udevice(struct udevice *dev) |
| 990 | { | 1001 | { |
| 991 | int ret; | 1002 | int ret; |
| 992 | sc_rsrc_t resource_id; | 1003 | sc_rsrc_t resource_id; |
| 993 | struct ofnode_phandle_args args; | 1004 | struct ofnode_phandle_args args; |
| 994 | 1005 | ||
| 995 | /* Get the resource id from its power-domain */ | 1006 | /* Get the resource id from its power-domain */ |
| 996 | ret = dev_read_phandle_with_args(dev, "power-domains", | 1007 | ret = dev_read_phandle_with_args(dev, "power-domains", |
| 997 | "#power-domain-cells", 0, 0, &args); | 1008 | "#power-domain-cells", 0, 0, &args); |
| 998 | if (ret) { | 1009 | if (ret) { |
| 999 | printf("no power-domains found\n"); | 1010 | printf("no power-domains found\n"); |
| 1000 | return false; | 1011 | return false; |
| 1001 | } | 1012 | } |
| 1002 | 1013 | ||
| 1003 | /* Get the owner partition for resource*/ | 1014 | /* Get the owner partition for resource*/ |
| 1004 | resource_id = (sc_rsrc_t)ofnode_read_u32_default(args.node, "reg", SC_R_NONE); | 1015 | resource_id = (sc_rsrc_t)ofnode_read_u32_default(args.node, "reg", SC_R_NONE); |
| 1005 | if (resource_id == SC_R_NONE) { | 1016 | if (resource_id == SC_R_NONE) { |
| 1006 | printf("Can't find the resource id for udev %s\n", dev->name); | 1017 | printf("Can't find the resource id for udev %s\n", dev->name); |
| 1007 | return false; | 1018 | return false; |
| 1008 | } | 1019 | } |
| 1009 | 1020 | ||
| 1010 | debug("udev %s, resource id %d\n", dev->name, resource_id); | 1021 | debug("udev %s, resource id %d\n", dev->name, resource_id); |
| 1011 | 1022 | ||
| 1012 | return sc_rm_is_resource_owned(-1, resource_id); | 1023 | return sc_rm_is_resource_owned(-1, resource_id); |
| 1013 | } | 1024 | } |
| 1014 | 1025 | ||
| 1015 | #ifdef CONFIG_IMX_VSERVICE | 1026 | #ifdef CONFIG_IMX_VSERVICE |
| 1016 | struct udevice * board_imx_vservice_find_mu(struct udevice *dev) | 1027 | struct udevice * board_imx_vservice_find_mu(struct udevice *dev) |
| 1017 | { | 1028 | { |
| 1018 | int ret; | 1029 | int ret; |
| 1019 | const char *m4_mu_name[2] = { | 1030 | const char *m4_mu_name[2] = { |
| 1020 | "mu@5d230000", | 1031 | "mu@5d230000", |
| 1021 | "mu@5d240000" | 1032 | "mu@5d240000" |
| 1022 | }; | 1033 | }; |
| 1023 | struct udevice *m4_mu[2]; | 1034 | struct udevice *m4_mu[2]; |
| 1024 | sc_rm_pt_t m4_parts[2]; | 1035 | sc_rm_pt_t m4_parts[2]; |
| 1025 | int err; | 1036 | int err; |
| 1026 | struct ofnode_phandle_args args; | 1037 | struct ofnode_phandle_args args; |
| 1027 | sc_rsrc_t resource_id; | 1038 | sc_rsrc_t resource_id; |
| 1028 | sc_rm_pt_t resource_part; | 1039 | sc_rm_pt_t resource_part; |
| 1029 | 1040 | ||
| 1030 | /* Get the resource id from its power-domain */ | 1041 | /* Get the resource id from its power-domain */ |
| 1031 | ret = dev_read_phandle_with_args(dev, "power-domains", | 1042 | ret = dev_read_phandle_with_args(dev, "power-domains", |
| 1032 | "#power-domain-cells", 0, 0, &args); | 1043 | "#power-domain-cells", 0, 0, &args); |
| 1033 | if (ret) { | 1044 | if (ret) { |
| 1034 | printf("Can't find the power-domains property for udev %s\n", dev->name); | 1045 | printf("Can't find the power-domains property for udev %s\n", dev->name); |
| 1035 | return NULL; | 1046 | return NULL; |
| 1036 | } | 1047 | } |
| 1037 | 1048 | ||
| 1038 | /* Get the owner partition for resource*/ | 1049 | /* Get the owner partition for resource*/ |
| 1039 | resource_id = (sc_rsrc_t)ofnode_read_u32_default(args.node, "reg", SC_R_NONE); | 1050 | resource_id = (sc_rsrc_t)ofnode_read_u32_default(args.node, "reg", SC_R_NONE); |
| 1040 | if (resource_id == SC_R_NONE) { | 1051 | if (resource_id == SC_R_NONE) { |
| 1041 | printf("Can't find the resource id for udev %s\n", dev->name); | 1052 | printf("Can't find the resource id for udev %s\n", dev->name); |
| 1042 | return NULL; | 1053 | return NULL; |
| 1043 | } | 1054 | } |
| 1044 | 1055 | ||
| 1045 | err = sc_rm_get_resource_owner(-1, resource_id, &resource_part); | 1056 | err = sc_rm_get_resource_owner(-1, resource_id, &resource_part); |
| 1046 | if (err != SC_ERR_NONE) { | 1057 | if (err != SC_ERR_NONE) { |
| 1047 | printf("%s get resource [%d] owner error: %d\n", __func__, resource_id, err); | 1058 | printf("%s get resource [%d] owner error: %d\n", __func__, resource_id, err); |
| 1048 | return NULL; | 1059 | return NULL; |
| 1049 | } | 1060 | } |
| 1050 | 1061 | ||
| 1051 | debug("udev %s, resource id %d, resource part %d\n", dev->name, resource_id, resource_part); | 1062 | debug("udev %s, resource id %d, resource part %d\n", dev->name, resource_id, resource_part); |
| 1052 | 1063 | ||
| 1053 | /* MU8 for communication between M4_0 and u-boot, MU9 for M4_1 and u-boot */ | 1064 | /* MU8 for communication between M4_0 and u-boot, MU9 for M4_1 and u-boot */ |
| 1054 | err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]); | 1065 | err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]); |
| 1055 | if (err != SC_ERR_NONE) { | 1066 | if (err != SC_ERR_NONE) { |
| 1056 | printf("%s get resource [%d] owner error: %d\n", __func__, SC_R_M4_0_PID0, err); | 1067 | printf("%s get resource [%d] owner error: %d\n", __func__, SC_R_M4_0_PID0, err); |
| 1057 | return NULL; | 1068 | return NULL; |
| 1058 | } | 1069 | } |
| 1059 | 1070 | ||
| 1060 | ret = uclass_find_device_by_name(UCLASS_MISC, m4_mu_name[0], &m4_mu[0]); | 1071 | ret = uclass_find_device_by_name(UCLASS_MISC, m4_mu_name[0], &m4_mu[0]); |
| 1061 | if (!ret) { | 1072 | if (!ret) { |
| 1062 | /* If the i2c is in m4_0 partition, return the mu8 */ | 1073 | /* If the i2c is in m4_0 partition, return the mu8 */ |
| 1063 | if (resource_part == m4_parts[0]) | 1074 | if (resource_part == m4_parts[0]) |
| 1064 | return m4_mu[0]; | 1075 | return m4_mu[0]; |
| 1065 | } | 1076 | } |
| 1066 | 1077 | ||
| 1067 | if (is_imx8qm()) { | 1078 | if (is_imx8qm()) { |
| 1068 | err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]); | 1079 | err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]); |
| 1069 | if (err != SC_ERR_NONE) { | 1080 | if (err != SC_ERR_NONE) { |
| 1070 | printf("%s get resource [%d] owner error: %d\n", __func__, SC_R_M4_1_PID0, err); | 1081 | printf("%s get resource [%d] owner error: %d\n", __func__, SC_R_M4_1_PID0, err); |
| 1071 | return NULL; | 1082 | return NULL; |
| 1072 | } | 1083 | } |
| 1073 | 1084 | ||
| 1074 | ret = uclass_find_device_by_name(UCLASS_MISC, m4_mu_name[1], &m4_mu[1]); | 1085 | ret = uclass_find_device_by_name(UCLASS_MISC, m4_mu_name[1], &m4_mu[1]); |
| 1075 | if (!ret) { | 1086 | if (!ret) { |
| 1076 | /* If the i2c is in m4_1 partition, return the mu9 */ | 1087 | /* If the i2c is in m4_1 partition, return the mu9 */ |
| 1077 | if (resource_part == m4_parts[1]) | 1088 | if (resource_part == m4_parts[1]) |
| 1078 | return m4_mu[1]; | 1089 | return m4_mu[1]; |
| 1079 | } | 1090 | } |
| 1080 | } | 1091 | } |
| 1081 | 1092 | ||
| 1082 | return NULL; | 1093 | return NULL; |
| 1083 | } | 1094 | } |
| 1084 | 1095 | ||
| 1085 | void * board_imx_vservice_get_buffer(struct imx_vservice_channel *node, u32 size) | 1096 | void * board_imx_vservice_get_buffer(struct imx_vservice_channel *node, u32 size) |
| 1086 | { | 1097 | { |
| 1087 | const char *m4_mu_name[2] = { | 1098 | const char *m4_mu_name[2] = { |
| 1088 | "mu@5d230000", | 1099 | "mu@5d230000", |
| 1089 | "mu@5d240000" | 1100 | "mu@5d240000" |
| 1090 | }; | 1101 | }; |
| 1091 | 1102 | ||
| 1092 | /* Each MU ownes 1M buffer */ | 1103 | /* Each MU ownes 1M buffer */ |
| 1093 | if (size <= 0x100000) { | 1104 | if (size <= 0x100000) { |
| 1094 | if (!strcmp(node->mu_dev->name, m4_mu_name[0])) | 1105 | if (!strcmp(node->mu_dev->name, m4_mu_name[0])) |
| 1095 | return (void * )CONFIG_IMX_VSERVICE_SHARED_BUFFER; | 1106 | return (void * )CONFIG_IMX_VSERVICE_SHARED_BUFFER; |
| 1096 | else if (!strcmp(node->mu_dev->name, m4_mu_name[1])) | 1107 | else if (!strcmp(node->mu_dev->name, m4_mu_name[1])) |
| 1097 | return (void * )(CONFIG_IMX_VSERVICE_SHARED_BUFFER + 0x100000); | 1108 | return (void * )(CONFIG_IMX_VSERVICE_SHARED_BUFFER + 0x100000); |
| 1098 | else | 1109 | else |
| 1099 | return NULL; | 1110 | return NULL; |
| 1100 | } | 1111 | } |
| 1101 | 1112 | ||
| 1102 | return NULL; | 1113 | return NULL; |
| 1103 | } | 1114 | } |
| 1104 | #endif | 1115 | #endif |
| 1105 | 1116 | ||
| 1106 | /* imx8qxp i2c1 has lots of devices may used by both M4 and A core | 1117 | /* imx8qxp i2c1 has lots of devices may used by both M4 and A core |
| 1107 | * If A core partition does not own the resource, we will start | 1118 | * If A core partition does not own the resource, we will start |
| 1108 | * virtual i2c driver. Otherwise use local i2c driver. | 1119 | * virtual i2c driver. Otherwise use local i2c driver. |
| 1109 | */ | 1120 | */ |
| 1110 | int board_imx_virt_i2c_bind(struct udevice *dev) | 1121 | int board_imx_virt_i2c_bind(struct udevice *dev) |
| 1111 | { | 1122 | { |
| 1112 | if (check_owned_udevice(dev)) | 1123 | if (check_owned_udevice(dev)) |
| 1113 | return -ENODEV; | 1124 | return -ENODEV; |
| 1114 | 1125 | ||
| 1115 | return 0; | 1126 | return 0; |
| 1116 | } | 1127 | } |
| 1117 | 1128 | ||
| 1118 | int board_imx_lpi2c_bind(struct udevice *dev) | 1129 | int board_imx_lpi2c_bind(struct udevice *dev) |
| 1119 | { | 1130 | { |
| 1120 | if (check_owned_udevice(dev)) | 1131 | if (check_owned_udevice(dev)) |
| 1121 | return 0; | 1132 | return 0; |
| 1122 | 1133 | ||
| 1123 | return -ENODEV; | 1134 | return -ENODEV; |
| 1124 | } | 1135 | } |
| 1125 | 1136 | ||
| 1126 | #ifdef CONFIG_USB_PORT_AUTO | 1137 | #ifdef CONFIG_USB_PORT_AUTO |
| 1127 | static int usb_port_auto_check(void) | 1138 | static int usb_port_auto_check(void) |
| 1128 | { | 1139 | { |
| 1129 | int ret; | 1140 | int ret; |
| 1130 | u32 usb2_data; | 1141 | u32 usb2_data; |
| 1131 | struct power_domain pd; | 1142 | struct power_domain pd; |
| 1132 | struct power_domain phy_pd; | 1143 | struct power_domain phy_pd; |
| 1133 | struct ehci_mx6_phy_data phy_data; | 1144 | struct ehci_mx6_phy_data phy_data; |
| 1134 | 1145 | ||
| 1135 | if (!power_domain_lookup_name("conn_usb0", &pd)) { | 1146 | if (!power_domain_lookup_name("conn_usb0", &pd)) { |
| 1136 | ret = power_domain_on(&pd); | 1147 | ret = power_domain_on(&pd); |
| 1137 | if (ret) { | 1148 | if (ret) { |
| 1138 | printf("conn_usb0 Power up failed!\n"); | 1149 | printf("conn_usb0 Power up failed!\n"); |
| 1139 | return ret; | 1150 | return ret; |
| 1140 | } | 1151 | } |
| 1141 | 1152 | ||
| 1142 | if (!power_domain_lookup_name("conn_usb0_phy", &phy_pd)) { | 1153 | if (!power_domain_lookup_name("conn_usb0_phy", &phy_pd)) { |
| 1143 | ret = power_domain_on(&phy_pd); | 1154 | ret = power_domain_on(&phy_pd); |
| 1144 | if (ret) { | 1155 | if (ret) { |
| 1145 | printf("conn_usb0_phy Power up failed!\n"); | 1156 | printf("conn_usb0_phy Power up failed!\n"); |
| 1146 | return ret; | 1157 | return ret; |
| 1147 | } | 1158 | } |
| 1148 | } else { | 1159 | } else { |
| 1149 | return -1; | 1160 | return -1; |
| 1150 | } | 1161 | } |
| 1151 | 1162 | ||
| 1152 | phy_data.phy_addr = (void __iomem *)(ulong)USB_PHY0_BASE_ADDR; | 1163 | phy_data.phy_addr = (void __iomem *)(ulong)USB_PHY0_BASE_ADDR; |
| 1153 | phy_data.misc_addr = (void __iomem *)(ulong)(USB_BASE_ADDR + 0x200); | 1164 | phy_data.misc_addr = (void __iomem *)(ulong)(USB_BASE_ADDR + 0x200); |
| 1154 | phy_data.anatop_addr = NULL; | 1165 | phy_data.anatop_addr = NULL; |
| 1155 | 1166 | ||
| 1156 | enable_usboh3_clk(1); | 1167 | enable_usboh3_clk(1); |
| 1157 | usb2_data = ci_udc_check_bus_active(USB_BASE_ADDR, &phy_data, 0); | 1168 | usb2_data = ci_udc_check_bus_active(USB_BASE_ADDR, &phy_data, 0); |
| 1158 | 1169 | ||
| 1159 | ret = power_domain_off(&phy_pd); | 1170 | ret = power_domain_off(&phy_pd); |
| 1160 | if (ret) { | 1171 | if (ret) { |
| 1161 | printf("conn_usb0_phy Power off failed!\n"); | 1172 | printf("conn_usb0_phy Power off failed!\n"); |
| 1162 | return ret; | 1173 | return ret; |
| 1163 | } | 1174 | } |
| 1164 | ret = power_domain_off(&pd); | 1175 | ret = power_domain_off(&pd); |
| 1165 | if (ret) { | 1176 | if (ret) { |
| 1166 | printf("conn_usb0 Power off failed!\n"); | 1177 | printf("conn_usb0 Power off failed!\n"); |
| 1167 | return ret; | 1178 | return ret; |
| 1168 | } | 1179 | } |
| 1169 | 1180 | ||
| 1170 | if (!usb2_data) | 1181 | if (!usb2_data) |
| 1171 | return 1; | 1182 | return 1; |
| 1172 | else | 1183 | else |
| 1173 | return 0; | 1184 | return 0; |
| 1174 | } | 1185 | } |
| 1175 | return -1; | 1186 | return -1; |
| 1176 | } | 1187 | } |
| 1177 | 1188 | ||
| 1178 | int board_usb_gadget_port_auto(void) | 1189 | int board_usb_gadget_port_auto(void) |
| 1179 | { | 1190 | { |
| 1180 | int usb_boot_index; | 1191 | int usb_boot_index; |
| 1181 | usb_boot_index = usb_port_auto_check(); | 1192 | usb_boot_index = usb_port_auto_check(); |
| 1182 | 1193 | ||
| 1183 | if (usb_boot_index < 0) | 1194 | if (usb_boot_index < 0) |
| 1184 | usb_boot_index = 0; | 1195 | usb_boot_index = 0; |
| 1185 | 1196 | ||
| 1186 | printf("auto usb %d\n", usb_boot_index); | 1197 | printf("auto usb %d\n", usb_boot_index); |
| 1187 | 1198 | ||
| 1188 | return usb_boot_index; | 1199 | return usb_boot_index; |
| 1189 | } | 1200 | } |
| 1190 | #endif | 1201 | #endif |
| 1191 | 1202 | ||
| 1192 | static void power_off_all_usb(void) | 1203 | static void power_off_all_usb(void) |
| 1193 | { | 1204 | { |
| 1194 | if (is_usb_boot()) { | 1205 | if (is_usb_boot()) { |
| 1195 | /* Turn off all usb resource to let conn SS power down */ | 1206 | /* Turn off all usb resource to let conn SS power down */ |
| 1196 | sc_pm_set_resource_power_mode(-1, SC_R_USB_0_PHY, SC_PM_PW_MODE_OFF); | 1207 | sc_pm_set_resource_power_mode(-1, SC_R_USB_0_PHY, SC_PM_PW_MODE_OFF); |
| 1197 | sc_pm_set_resource_power_mode(-1, SC_R_USB_1_PHY, SC_PM_PW_MODE_OFF); | 1208 | sc_pm_set_resource_power_mode(-1, SC_R_USB_1_PHY, SC_PM_PW_MODE_OFF); |
| 1198 | sc_pm_set_resource_power_mode(-1, SC_R_USB_2_PHY, SC_PM_PW_MODE_OFF); | 1209 | sc_pm_set_resource_power_mode(-1, SC_R_USB_2_PHY, SC_PM_PW_MODE_OFF); |
| 1199 | 1210 | ||
| 1200 | sc_pm_set_resource_power_mode(-1, SC_R_USB_0, SC_PM_PW_MODE_OFF); | 1211 | sc_pm_set_resource_power_mode(-1, SC_R_USB_0, SC_PM_PW_MODE_OFF); |
| 1201 | sc_pm_set_resource_power_mode(-1, SC_R_USB_1, SC_PM_PW_MODE_OFF); | 1212 | sc_pm_set_resource_power_mode(-1, SC_R_USB_1, SC_PM_PW_MODE_OFF); |
| 1202 | sc_pm_set_resource_power_mode(-1, SC_R_USB_2, SC_PM_PW_MODE_OFF); | 1213 | sc_pm_set_resource_power_mode(-1, SC_R_USB_2, SC_PM_PW_MODE_OFF); |
| 1203 | } | 1214 | } |
| 1204 | } | 1215 | } |
| 1205 | 1216 |