1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 4 #include "pvr_device.h" 5 #include "pvr_fw.h" 6 #include "pvr_fw_mips.h" 7 #include "pvr_gem.h" 8 #include "pvr_rogue_mips.h" 9 #include "pvr_vm_mips.h" 10 11 #include <linux/elf.h> 12 #include <linux/err.h> 13 #include <linux/types.h> 14 15 #define ROGUE_FW_HEAP_MIPS_BASE 0xC0000000 16 #define ROGUE_FW_HEAP_MIPS_SHIFT 24 /* 16 MB */ 17 #define ROGUE_FW_HEAP_MIPS_RESERVED_SIZE SZ_1M 18 19 /** 20 * process_elf_command_stream() - Process ELF firmware image and populate 21 * firmware sections 22 * @pvr_dev: Device pointer. 23 * @fw: Pointer to firmware image. 24 * @fw_code_ptr: Pointer to FW code section. 25 * @fw_data_ptr: Pointer to FW data section. 26 * @fw_core_code_ptr: Pointer to FW coremem code section. 27 * @fw_core_data_ptr: Pointer to FW coremem data section. 28 * 29 * Returns : 30 * * 0 on success, or 31 * * -EINVAL on any error in ELF command stream. 32 */ 33 static int 34 process_elf_command_stream(struct pvr_device *pvr_dev, const u8 *fw, u8 *fw_code_ptr, 35 u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr) 36 { 37 struct elf32_hdr *header = (struct elf32_hdr *)fw; 38 struct elf32_phdr *program_header = (struct elf32_phdr *)(fw + header->e_phoff); 39 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 40 u32 entry; 41 int err; 42 43 for (entry = 0; entry < header->e_phnum; entry++, program_header++) { 44 void *write_addr; 45 46 /* Only consider loadable entries in the ELF segment table */ 47 if (program_header->p_type != PT_LOAD) 48 continue; 49 50 err = pvr_fw_find_mmu_segment(pvr_dev, program_header->p_vaddr, 51 program_header->p_memsz, fw_code_ptr, fw_data_ptr, 52 fw_core_code_ptr, fw_core_data_ptr, &write_addr); 53 if (err) { 54 drm_err(drm_dev, 55 "Addr 0x%x (size: %d) not found in any firmware segment", 56 program_header->p_vaddr, program_header->p_memsz); 57 return err; 58 } 59 60 /* Write to FW allocation only if available */ 61 if (write_addr) { 62 memcpy(write_addr, fw + program_header->p_offset, 63 program_header->p_filesz); 64 65 memset((u8 *)write_addr + program_header->p_filesz, 0, 66 program_header->p_memsz - program_header->p_filesz); 67 } 68 } 69 70 return 0; 71 } 72 73 static int 74 pvr_mips_init(struct pvr_device *pvr_dev) 75 { 76 pvr_fw_heap_info_init(pvr_dev, ROGUE_FW_HEAP_MIPS_SHIFT, ROGUE_FW_HEAP_MIPS_RESERVED_SIZE); 77 78 return pvr_vm_mips_init(pvr_dev); 79 } 80 81 static void 82 pvr_mips_fini(struct pvr_device *pvr_dev) 83 { 84 pvr_vm_mips_fini(pvr_dev); 85 } 86 87 static int 88 pvr_mips_fw_process(struct pvr_device *pvr_dev, const u8 *fw, 89 u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr, 90 u32 core_code_alloc_size) 91 { 92 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 93 struct pvr_fw_mips_data *mips_data = fw_dev->processor_data.mips_data; 94 const struct pvr_fw_layout_entry *boot_code_entry; 95 const struct pvr_fw_layout_entry *boot_data_entry; 96 const struct pvr_fw_layout_entry *exception_code_entry; 97 const struct pvr_fw_layout_entry *stack_entry; 98 struct rogue_mipsfw_boot_data *boot_data; 99 dma_addr_t dma_addr; 100 u32 page_nr; 101 int err; 102 103 err = process_elf_command_stream(pvr_dev, fw, fw_code_ptr, fw_data_ptr, fw_core_code_ptr, 104 fw_core_data_ptr); 105 if (err) 106 return err; 107 108 boot_code_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_BOOT_CODE); 109 boot_data_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_BOOT_DATA); 110 exception_code_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_EXCEPTIONS_CODE); 111 if (!boot_code_entry || !boot_data_entry || !exception_code_entry) 112 return -EINVAL; 113 114 WARN_ON(pvr_gem_get_dma_addr(fw_dev->mem.code_obj->gem, boot_code_entry->alloc_offset, 115 &mips_data->boot_code_dma_addr)); 116 WARN_ON(pvr_gem_get_dma_addr(fw_dev->mem.data_obj->gem, boot_data_entry->alloc_offset, 117 &mips_data->boot_data_dma_addr)); 118 WARN_ON(pvr_gem_get_dma_addr(fw_dev->mem.code_obj->gem, 119 exception_code_entry->alloc_offset, 120 &mips_data->exception_code_dma_addr)); 121 122 stack_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_STACK); 123 if (!stack_entry) 124 return -EINVAL; 125 126 boot_data = (struct rogue_mipsfw_boot_data *)(fw_data_ptr + boot_data_entry->alloc_offset + 127 ROGUE_MIPSFW_BOOTLDR_CONF_OFFSET); 128 129 WARN_ON(pvr_fw_object_get_dma_addr(fw_dev->mem.data_obj, stack_entry->alloc_offset, 130 &dma_addr)); 131 boot_data->stack_phys_addr = dma_addr; 132 133 boot_data->reg_base = pvr_dev->regs_resource->start; 134 135 for (page_nr = 0; page_nr < ARRAY_SIZE(boot_data->pt_phys_addr); page_nr++) { 136 /* Firmware expects 4k pages, but host page size might be different. */ 137 u32 src_page_nr = (page_nr * ROGUE_MIPSFW_PAGE_SIZE_4K) >> PAGE_SHIFT; 138 u32 page_offset = (page_nr * ROGUE_MIPSFW_PAGE_SIZE_4K) & ~PAGE_MASK; 139 140 boot_data->pt_phys_addr[page_nr] = mips_data->pt_dma_addr[src_page_nr] + 141 page_offset; 142 } 143 144 boot_data->pt_log2_page_size = ROGUE_MIPSFW_LOG2_PAGE_SIZE_4K; 145 boot_data->pt_num_pages = ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES; 146 boot_data->reserved1 = 0; 147 boot_data->reserved2 = 0; 148 149 return 0; 150 } 151 152 static int 153 pvr_mips_wrapper_init(struct pvr_device *pvr_dev) 154 { 155 struct pvr_fw_mips_data *mips_data = pvr_dev->fw_dev.processor_data.mips_data; 156 const u64 remap_settings = ROGUE_MIPSFW_BOOT_REMAP_LOG2_SEGMENT_SIZE; 157 u32 phys_bus_width; 158 159 int err = PVR_FEATURE_VALUE(pvr_dev, phys_bus_width, &phys_bus_width); 160 161 if (WARN_ON(err)) 162 return err; 163 164 /* Currently MIPS FW only supported with physical bus width > 32 bits. */ 165 if (WARN_ON(phys_bus_width <= 32)) 166 return -EINVAL; 167 168 pvr_cr_write32(pvr_dev, ROGUE_CR_MIPS_WRAPPER_CONFIG, 169 (ROGUE_MIPSFW_REGISTERS_VIRTUAL_BASE >> 170 ROGUE_MIPSFW_WRAPPER_CONFIG_REGBANK_ADDR_ALIGN) | 171 ROGUE_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MICROMIPS); 172 173 /* Configure remap for boot code, boot data and exceptions code areas. */ 174 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP1_CONFIG1, 175 ROGUE_MIPSFW_BOOT_REMAP_PHYS_ADDR_IN | 176 ROGUE_CR_MIPS_ADDR_REMAP1_CONFIG1_MODE_ENABLE_EN); 177 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP1_CONFIG2, 178 (mips_data->boot_code_dma_addr & 179 ~ROGUE_CR_MIPS_ADDR_REMAP1_CONFIG2_ADDR_OUT_CLRMSK) | remap_settings); 180 181 if (PVR_HAS_QUIRK(pvr_dev, 63553)) { 182 /* 183 * WA always required on 36 bit cores, to avoid continuous unmapped memory accesses 184 * to address 0x0. 185 */ 186 WARN_ON(phys_bus_width != 36); 187 188 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP5_CONFIG1, 189 ROGUE_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_EN); 190 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP5_CONFIG2, 191 (mips_data->boot_code_dma_addr & 192 ~ROGUE_CR_MIPS_ADDR_REMAP5_CONFIG2_ADDR_OUT_CLRMSK) | 193 remap_settings); 194 } 195 196 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP2_CONFIG1, 197 ROGUE_MIPSFW_DATA_REMAP_PHYS_ADDR_IN | 198 ROGUE_CR_MIPS_ADDR_REMAP2_CONFIG1_MODE_ENABLE_EN); 199 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP2_CONFIG2, 200 (mips_data->boot_data_dma_addr & 201 ~ROGUE_CR_MIPS_ADDR_REMAP2_CONFIG2_ADDR_OUT_CLRMSK) | remap_settings); 202 203 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP3_CONFIG1, 204 ROGUE_MIPSFW_CODE_REMAP_PHYS_ADDR_IN | 205 ROGUE_CR_MIPS_ADDR_REMAP3_CONFIG1_MODE_ENABLE_EN); 206 pvr_cr_write64(pvr_dev, ROGUE_CR_MIPS_ADDR_REMAP3_CONFIG2, 207 (mips_data->exception_code_dma_addr & 208 ~ROGUE_CR_MIPS_ADDR_REMAP3_CONFIG2_ADDR_OUT_CLRMSK) | remap_settings); 209 210 /* Garten IDLE bit controlled by MIPS. */ 211 pvr_cr_write64(pvr_dev, ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG, 212 ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META); 213 214 /* Turn on the EJTAG probe. */ 215 pvr_cr_write32(pvr_dev, ROGUE_CR_MIPS_DEBUG_CONFIG, 0); 216 217 return 0; 218 } 219 220 static u32 221 pvr_mips_get_fw_addr_with_offset(struct pvr_fw_object *fw_obj, u32 offset) 222 { 223 struct pvr_device *pvr_dev = to_pvr_device(gem_from_pvr_gem(fw_obj->gem)->dev); 224 225 /* MIPS cacheability is determined by page table. */ 226 return ((fw_obj->fw_addr_offset + offset) & pvr_dev->fw_dev.fw_heap_info.offset_mask) | 227 ROGUE_FW_HEAP_MIPS_BASE; 228 } 229 230 static bool 231 pvr_mips_has_fixed_data_addr(void) 232 { 233 return true; 234 } 235 236 const struct pvr_fw_defs pvr_fw_defs_mips = { 237 .init = pvr_mips_init, 238 .fini = pvr_mips_fini, 239 .fw_process = pvr_mips_fw_process, 240 .vm_map = pvr_vm_mips_map, 241 .vm_unmap = pvr_vm_mips_unmap, 242 .get_fw_addr_with_offset = pvr_mips_get_fw_addr_with_offset, 243 .wrapper_init = pvr_mips_wrapper_init, 244 .has_fixed_data_addr = pvr_mips_has_fixed_data_addr, 245 .irq = { 246 .enable_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_ENABLE, 247 .status_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS, 248 .clear_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR, 249 .event_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN, 250 .clear_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_EN, 251 }, 252 }; 253