/* * Push the minimal suspend-resume code to SRAM */ int am33xx_push_sram_idle(void) { am33xx_do_wfi_sram = (void *)fncpy((void *)ocmcram_location, pm_sram->do_wfi, *pm_sram->do_wfi_sz); return 0; }
int init_mmdc_lpddr2_settings(struct platform_device *busfreq_pdev) { unsigned long ddr_code_size; busfreq_dev = &busfreq_pdev->dev; ddr_code_size = (&imx6_lpddr2_freq_change_end -&imx6_lpddr2_freq_change_start) *4; if (cpu_is_imx6sl()) mx6_change_lpddr2_freq = (void *)fncpy( (void *)ddr_freq_change_iram_base, &mx6_lpddr2_freq_change, ddr_code_size); else if (cpu_is_imx6sx() || cpu_is_imx6ul()) mx6_change_lpddr2_freq = (void *)fncpy( (void *)ddr_freq_change_iram_base, &imx6_up_lpddr2_freq_change, ddr_code_size); curr_ddr_rate = ddr_normal_rate; return 0; }
int main(int argc, char **argv) { FILE *fp; char filename[32] = {0}; u32 dir_off, dir_nmemb; unsigned int i; if(argc != 2 || strequ("-h", argv[1]) || strequ("--help", argv[1])) { fputs("dumps the objects in a gbfs file to separate files\n" "syntax: ungbfs FILE\n", stderr); return 1; } fp = fopen(argv[1], "rb"); if(!fp) { fputs("could not open ", stderr); perror(argv[1]); return 1; } /* read pertinent header fields */ fseek(fp, 20, SEEK_SET); dir_off = fgeti16(fp); dir_nmemb = fgeti16(fp); for(i = 0; i < dir_nmemb; i++) { unsigned long len, off; FILE *outfile; fseek(fp, dir_off + 32 * i, SEEK_SET); fread(filename, 24, 1, fp); len = fgeti32(fp); off = fgeti32(fp); printf("%10lu %s\n", (unsigned long)len, filename); outfile = fopen(filename, "wb"); if(!outfile) { fputs("could not open ", stderr); perror(filename); fclose(fp); return 1; } fseek(fp, off, SEEK_SET); fncpy(outfile, fp, len); fclose(outfile); } fclose(fp); return 0; }
void machine_kexec(struct kimage *image) { unsigned long page_list; unsigned long reboot_code_buffer_phys; unsigned long reboot_entry = (unsigned long)relocate_new_kernel; unsigned long reboot_entry_phys; void *reboot_code_buffer; if (num_online_cpus() > 1) { pr_err("kexec: error: multiple CPUs still online\n"); return; } page_list = image->head & PAGE_MASK; /* we need both effective and real address here */ reboot_code_buffer_phys = page_to_pfn(image->control_code_page) << PAGE_SHIFT; reboot_code_buffer = page_address(image->control_code_page); /* Prepare parameters for reboot_code_buffer*/ mem_text_write_kernel_word(&kexec_start_address, image->start); mem_text_write_kernel_word(&kexec_indirection_page, page_list); mem_text_write_kernel_word(&kexec_mach_type, machine_arch_type); if (!kexec_boot_atags) mem_text_write_kernel_word(&kexec_boot_atags, image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET); #ifdef CONFIG_KEXEC_HARDBOOT mem_text_write_kernel_word(&kexec_hardboot, image->hardboot); #endif /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, reboot_entry, relocate_new_kernel_size); reboot_entry_phys = (unsigned long)reboot_entry + (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); printk(KERN_INFO "Bye!\n"); if (kexec_reinit) kexec_reinit(); #ifdef CONFIG_KEXEC_HARDBOOT /* Run any final machine-specific shutdown code. */ if (image->hardboot && kexec_hardboot_hook) kexec_hardboot_hook(); #endif soft_restart(reboot_code_buffer_phys); }
void machine_kexec(struct kimage *image) { unsigned long page_list; unsigned long reboot_code_buffer_phys; unsigned long reboot_entry = (unsigned long)relocate_new_kernel; unsigned long reboot_entry_phys; void *reboot_code_buffer; /* * This can only happen if machine_shutdown() failed to disable some * CPU, and that can only happen if the checks in * machine_kexec_prepare() were not correct. If this fails, we can't * reliably kexec anyway, so BUG_ON is appropriate. */ BUG_ON(num_online_cpus() > 1); page_list = image->head & PAGE_MASK; /* we need both effective and real address here */ reboot_code_buffer_phys = page_to_pfn(image->control_code_page) << PAGE_SHIFT; reboot_code_buffer = page_address(image->control_code_page); /* Prepare parameters for reboot_code_buffer*/ set_kernel_text_rw(); kexec_start_address = image->start; kexec_indirection_page = page_list; kexec_mach_type = machine_arch_type; kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, reboot_entry, relocate_new_kernel_size); reboot_entry_phys = (unsigned long)reboot_entry + (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); pr_info("Bye!\n"); if (kexec_reinit) kexec_reinit(); soft_restart(reboot_entry_phys); }
void machine_kexec(struct kimage *image) { unsigned long page_list; unsigned long reboot_code_buffer_phys; unsigned long reboot_entry = (unsigned long)relocate_new_kernel; unsigned long reboot_entry_phys; void *reboot_code_buffer; if (num_online_cpus() > 1) { pr_err("kexec: error: multiple CPUs still online\n"); return; } page_list = image->head & PAGE_MASK; /* we need both effective and real address here */ reboot_code_buffer_phys = page_to_pfn(image->control_code_page) << PAGE_SHIFT; reboot_code_buffer = page_address(image->control_code_page); /* Prepare parameters for reboot_code_buffer*/ kexec_start_address = image->start; kexec_indirection_page = page_list; kexec_mach_type = machine_arch_type; if (!kexec_boot_atags) kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, reboot_entry, relocate_new_kernel_size); reboot_entry_phys = (unsigned long)reboot_entry + (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); printk(KERN_INFO "Bye!\n"); if (kexec_reinit) kexec_reinit(); soft_restart(reboot_entry_phys); }
static int ti_emif_push_sram(struct device *dev) { struct device_node *np = dev->of_node; sram_pool = of_gen_pool_get(np, "sram", 0); if (!sram_pool) { dev_err(dev, "Unable to get sram pool for ocmcram\n"); return -ENODEV; } ocmcram_location = gen_pool_alloc(sram_pool, ti_emif_sram_sz); if (!ocmcram_location) { dev_err(dev, "Unable to allocate memory from ocmcram\n"); return -EINVAL; } /* Save physical address to calculate resume offset during pm init */ ti_emif_sram_phys = gen_pool_virt_to_phys(sram_pool, ocmcram_location); ti_emif_sram_virt = fncpy((void *)ocmcram_location, &ti_emif_sram, ti_emif_sram_sz); /* * These functions are called during suspend path while MMU is * still on so add virtual base to offset for absolute address */ ti_emif_pm.save_context = sram_suspend_address(ti_emif_pm.save_context); ti_emif_pm.enter_sr = sram_suspend_address(ti_emif_pm.enter_sr); ti_emif_pm.abort_sr = sram_suspend_address(ti_emif_pm.abort_sr); /* * These are called during resume path when MMU is not enabled * so physical address is used instead */ ti_emif_pm.restore_context = sram_resume_address(ti_emif_pm.restore_context); ti_emif_pm.exit_sr = sram_resume_address(ti_emif_pm.exit_sr); return 0; }
int init_mmdc_lpddr2_settings(struct platform_device *busfreq_pdev) { struct platform_device *ocram_dev; unsigned int iram_paddr; struct device_node *node; struct gen_pool *iram_pool; busfreq_dev = &busfreq_pdev->dev; node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-mmdc"); if (!node) { printk(KERN_ERR "failed to find imx6sl-mmdc device tree data!\n"); return -EINVAL; } mmdc_base = of_iomap(node, 0); WARN(!mmdc_base, "unable to map mmdc registers\n"); node = NULL; node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-ccm"); if (!node) { printk(KERN_ERR "failed to find imx6sl-ccm device tree data!\n"); return -EINVAL; } ccm_base = of_iomap(node, 0); WARN(!ccm_base, "unable to map ccm registers\n"); node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache"); if (!node) { printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n"); return -EINVAL; } l2_base = of_iomap(node, 0); WARN(!l2_base, "unable to map PL310 registers\n"); node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); if (!node) { printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n"); return -EINVAL; } anatop_base = of_iomap(node, 0); WARN(!anatop_base, "unable to map anatop registers\n"); node = NULL; node = of_find_compatible_node(NULL, NULL, "mmio-sram"); if (!node) { dev_err(busfreq_dev, "%s: failed to find ocram node\n", __func__); return -EINVAL; } ocram_dev = of_find_device_by_node(node); if (!ocram_dev) { dev_err(busfreq_dev, "failed to find ocram device!\n"); return -EINVAL; } iram_pool = dev_get_gen_pool(&ocram_dev->dev); if (!iram_pool) { dev_err(busfreq_dev, "iram pool unavailable!\n"); return -EINVAL; } reg_addrs[0] = (unsigned long)anatop_base; reg_addrs[1] = (unsigned long)ccm_base; reg_addrs[2] = (unsigned long)mmdc_base; reg_addrs[3] = (unsigned long)l2_base; ddr_freq_change_iram_base = (void *)gen_pool_alloc(iram_pool, LPDDR2_FREQ_CHANGE_SIZE); if (!ddr_freq_change_iram_base) { dev_err(busfreq_dev, "Cannot alloc iram for ddr freq change code!\n"); return -ENOMEM; } iram_paddr = gen_pool_virt_to_phys(iram_pool, (unsigned long)ddr_freq_change_iram_base); /* * Need to remap the area here since we want * the memory region to be executable. */ ddr_freq_change_iram_base = __arm_ioremap(iram_paddr, LPDDR2_FREQ_CHANGE_SIZE, MT_MEMORY_NONCACHED); mx6_change_lpddr2_freq = (void *)fncpy(ddr_freq_change_iram_base, &mx6_lpddr2_freq_change, LPDDR2_FREQ_CHANGE_SIZE); curr_ddr_rate = ddr_normal_rate; return 0; }
int init_mmdc_settings(struct platform_device *busfreq_pdev) { struct device *dev = &busfreq_pdev->dev; struct platform_device *ocram_dev; unsigned int iram_paddr; int i, err; u32 cpu; struct device_node *node; struct gen_pool *iram_pool; node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-mmdc-combine"); if (!node) { printk(KERN_ERR "failed to find imx6q-mmdc device tree data!\n"); return -EINVAL; } mmdc_base = of_iomap(node, 0); WARN(!mmdc_base, "unable to map mmdc registers\n"); node = NULL; if (cpu_is_imx6q()) node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-iomuxc"); if (cpu_is_imx6dl()) node = of_find_compatible_node(NULL, NULL, "fsl,imx6dl-iomuxc"); if (!node) { printk(KERN_ERR "failed to find imx6q-iomux device tree data!\n"); return -EINVAL; } iomux_base = of_iomap(node, 0); WARN(!iomux_base, "unable to map iomux registers\n"); node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm"); if (!node) { printk(KERN_ERR "failed to find imx6q-ccm device tree data!\n"); return -EINVAL; } ccm_base = of_iomap(node, 0); WARN(!mmdc_base, "unable to map mmdc registers\n"); node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache"); if (!node) { printk(KERN_ERR "failed to find imx6q-pl310-cache device tree data!\n"); return -EINVAL; } l2_base = of_iomap(node, 0); WARN(!mmdc_base, "unable to map mmdc registers\n"); node = NULL; node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); if (!node) { printk(KERN_ERR "failed to find imx6q-a9-gic device tree data!\n"); return -EINVAL; } gic_dist_base = of_iomap(node, 0); WARN(!gic_dist_base, "unable to map gic dist registers\n"); if (cpu_is_imx6q()) ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6q) + ARRAY_SIZE(ddr3_calibration); if (cpu_is_imx6dl()) ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6dl) + ARRAY_SIZE(ddr3_calibration); normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL); if (cpu_is_imx6q()) { memcpy(normal_mmdc_settings, ddr3_dll_mx6q, sizeof(ddr3_dll_mx6q)); memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6q)), ddr3_calibration, sizeof(ddr3_calibration)); } if (cpu_is_imx6dl()) { memcpy(normal_mmdc_settings, ddr3_dll_mx6dl, sizeof(ddr3_dll_mx6dl)); memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6dl)), ddr3_calibration, sizeof(ddr3_calibration)); } /* store the original DDR settings at boot. */ for (i = 0; i < ddr_settings_size; i++) { /* * writes via command mode register cannot be read back. * hence hardcode them in the initial static array. * this may require modification on a per customer basis. */ if (normal_mmdc_settings[i][0] != 0x1C) normal_mmdc_settings[i][1] = readl_relaxed(mmdc_base + normal_mmdc_settings[i][0]); } irqs_used = devm_kzalloc(dev, sizeof(u32) * num_present_cpus(), GFP_KERNEL); for_each_present_cpu(cpu) { int irq; /* * set up a reserved interrupt to get all * the active cores into a WFE state * before changing the DDR frequency. */ irq = platform_get_irq(busfreq_pdev, cpu); err = request_irq(irq, wait_in_wfe_irq, IRQF_PERCPU, "mmdc_1", NULL); if (err) { dev_err(dev, "Busfreq:request_irq failed %d, err = %d\n", irq, err); return err; } err = irq_set_affinity(irq, cpumask_of(cpu)); if (err) { dev_err(dev, "Busfreq: Cannot set irq affinity irq=%d,\n", irq); return err; } irqs_used[cpu] = irq; } node = NULL; node = of_find_compatible_node(NULL, NULL, "mmio-sram"); if (!node) { dev_err(dev, "%s: failed to find ocram node\n", __func__); return -EINVAL; } ocram_dev = of_find_device_by_node(node); if (!ocram_dev) { dev_err(dev, "failed to find ocram device!\n"); return -EINVAL; } iram_pool = dev_get_gen_pool(&ocram_dev->dev); if (!iram_pool) { dev_err(dev, "iram pool unavailable!\n"); return -EINVAL; } iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q); iram_iomux_settings = gen_pool_alloc(iram_pool, (iomux_settings_size * 8) + 8); if (!iram_iomux_settings) { dev_err(dev, "unable to alloc iram for IOMUX settings!\n"); return -ENOMEM; } /* * Allocate extra space to store the number of entries in the * ddr_settings plus 4 extra regsiter information that needs * to be passed to the frequency change code. * sizeof(iram_ddr_settings) = sizeof(ddr_settings) + * entries in ddr_settings + 16. * The last 4 enties store the addresses of the registers: * CCM_BASE_ADDR * MMDC_BASE_ADDR * IOMUX_BASE_ADDR * L2X0_BASE_ADDR */ iram_ddr_settings = gen_pool_alloc(iram_pool, (ddr_settings_size * 8) + 8 + 32); if (!iram_ddr_settings) { dev_err(dev, "unable to alloc iram for ddr settings!\n"); return -ENOMEM; } i = ddr_settings_size + 1; iram_ddr_settings[i][0] = (unsigned long)mmdc_base; iram_ddr_settings[i+1][0] = (unsigned long)ccm_base; iram_ddr_settings[i+2][0] = (unsigned long)iomux_base; iram_ddr_settings[i+3][0] = (unsigned long)l2_base; if (cpu_is_imx6q()) { /* store the IOMUX settings at boot. */ for (i = 0; i < iomux_settings_size; i++) { iomux_offsets_mx6q[i][1] = readl_relaxed(iomux_base + iomux_offsets_mx6q[i][0]); iram_iomux_settings[i+1][0] = iomux_offsets_mx6q[i][0]; iram_iomux_settings[i+1][1] = iomux_offsets_mx6q[i][1]; } } if (cpu_is_imx6dl()) { for (i = 0; i < iomux_settings_size; i++) { iomux_offsets_mx6dl[i][1] = readl_relaxed(iomux_base + iomux_offsets_mx6dl[i][0]); iram_iomux_settings[i+1][0] = iomux_offsets_mx6dl[i][0]; iram_iomux_settings[i+1][1] = iomux_offsets_mx6dl[i][1]; } } ddr_freq_change_iram_base = gen_pool_alloc(iram_pool, DDR_FREQ_CHANGE_SIZE); if (!ddr_freq_change_iram_base) { dev_err(dev, "Cannot alloc iram for ddr freq change code!\n"); return -ENOMEM; } iram_paddr = gen_pool_virt_to_phys(iram_pool, (unsigned long)ddr_freq_change_iram_base); /* * need to remap the area here since we want * the memory region to be executable. */ ddr_freq_change_iram_base = __arm_ioremap(iram_paddr, DDR_FREQ_CHANGE_SIZE, MT_MEMORY_RWX_NONCACHED); mx6_change_ddr_freq = (void *)fncpy(ddr_freq_change_iram_base, &mx6_ddr3_freq_change, DDR_FREQ_CHANGE_SIZE); curr_ddr_rate = ddr_normal_rate; return 0; }