Esempio n. 1
0
/*
 * 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;
}
Esempio n. 3
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;
}
Esempio n. 4
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);
}
Esempio n. 5
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;

	/*
	 * 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);
}
Esempio n. 6
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*/
	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);
}
Esempio n. 7
0
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}