Exemple #1
0
static unsigned configure_dma_errata(void)
{
	unsigned errata = 0;

	/*
	 * Errata applicable for OMAP2430ES1.0 and all omap2420
	 *
	 * I.
	 * Erratum ID: Not Available
	 * Inter Frame DMA buffering issue DMA will wrongly
	 * buffer elements if packing and bursting is enabled. This might
	 * result in data gets stalled in FIFO at the end of the block.
	 * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
	 * guarantee no data will stay in the DMA FIFO in case inter frame
	 * buffering occurs
	 *
	 * II.
	 * Erratum ID: Not Available
	 * DMA may hang when several channels are used in parallel
	 * In the following configuration, DMA channel hanging can occur:
	 * a. Channel i, hardware synchronized, is enabled
	 * b. Another channel (Channel x), software synchronized, is enabled.
	 * c. Channel i is disabled before end of transfer
	 * d. Channel i is reenabled.
	 * e. Steps 1 to 4 are repeated a certain number of times.
	 * f. A third channel (Channel y), software synchronized, is enabled.
	 * Channel x and Channel y may hang immediately after step 'f'.
	 * Workaround:
	 * For any channel used - make sure NextLCH_ID is set to the value j.
	 */
	if (cpu_is_omap2420() || (cpu_is_omap2430() &&
				(omap_type() == OMAP2430_REV_ES1_0))) {

		SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
		SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
	}

	/*
	 * Erratum ID: i378: OMAP2+: sDMA Channel is not disabled
	 * after a transaction error.
	 * Workaround: SW should explicitely disable the channel.
	 */
	if (cpu_class_is_omap2())
		SET_DMA_ERRATA(DMA_ERRATA_i378);

	/*
	 * Erratum ID: i541: sDMA FIFO draining does not finish
	 * If sDMA channel is disabled on the fly, sDMA enters standby even
	 * through FIFO Drain is still in progress
	 * Workaround: Put sDMA in NoStandby more before a logical channel is
	 * disabled, then put it back to SmartStandby right after the channel
	 * finishes FIFO draining.
	 */
	if (cpu_is_omap34xx())
		SET_DMA_ERRATA(DMA_ERRATA_i541);

	/*
	 * Erratum ID: i88 : Special programming model needed to disable DMA
	 * before end of block.
	 * Workaround: software must ensure that the DMA is configured in No
	 * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
	 */
	if (omap_type() == OMAP3430_REV_ES1_0)
		SET_DMA_ERRATA(DMA_ERRATA_i88);

	/*
	 * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
	 * read before the DMA controller finished disabling the channel.
	 */
	SET_DMA_ERRATA(DMA_ERRATA_3_3);

	/*
	 * Erratum ID: Not Available
	 * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
	 * after secure sram context save and restore.
	 * Work around: Hence we need to manually clear those IRQs to avoid
	 * spurious interrupts. This affects only secure devices.
	 */
	if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
		SET_DMA_ERRATA(DMA_ROMCODE_BUG);

	return errata;
}
Exemple #2
0
/* Populate the scratchpad structure with restore structure */
void omap3_save_scratchpad_contents(void)
{
	void  __iomem *scratchpad_address;
	u32 arm_context_addr;
	struct omap3_scratchpad scratchpad_contents;
	struct omap3_scratchpad_prcm_block prcm_block_contents;
	struct omap3_scratchpad_sdrc_block sdrc_block_contents;

	/*
	 * Populate the Scratchpad contents
	 *
	 * The "get_*restore_pointer" functions are used to provide a
	 * physical restore address where the ROM code jumps while waking
	 * up from MPU OFF/OSWR state.
	 * The restore pointer is stored into the scratchpad.
	 */
	scratchpad_contents.boot_config_ptr = 0x0;
	if (cpu_is_omap3630())
		scratchpad_contents.public_restore_ptr =
			virt_to_phys(omap3_restore_3630);
	else if (omap_rev() != OMAP3430_REV_ES3_0 &&
					omap_rev() != OMAP3430_REV_ES3_1 &&
					omap_rev() != OMAP3430_REV_ES3_1_2)
		scratchpad_contents.public_restore_ptr =
			virt_to_phys(omap3_restore);
	else
		scratchpad_contents.public_restore_ptr =
			virt_to_phys(omap3_restore_es3);

	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
		scratchpad_contents.secure_ram_restore_ptr = 0x0;
	else
		scratchpad_contents.secure_ram_restore_ptr =
			(u32) __pa(omap3_secure_ram_storage);
	scratchpad_contents.sdrc_module_semaphore = 0x0;
	scratchpad_contents.prcm_block_offset = 0x2C;
	scratchpad_contents.sdrc_block_offset = 0x64;

	/* Populate the PRCM block contents */
	prcm_block_contents.prm_clksrc_ctrl =
		omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
				       OMAP3_PRM_CLKSRC_CTRL_OFFSET);
	prcm_block_contents.prm_clksel =
		omap2_prm_read_mod_reg(OMAP3430_CCR_MOD,
				       OMAP3_PRM_CLKSEL_OFFSET);
	prcm_block_contents.cm_clksel_core =
			omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
	prcm_block_contents.cm_clksel_wkup =
			omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
	prcm_block_contents.cm_clken_pll =
			omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
	/*
	 * As per erratum i671, ROM code does not respect the PER DPLL
	 * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
	 * Then,  in anycase, clear these bits to avoid extra latencies.
	 */
	prcm_block_contents.cm_autoidle_pll =
			omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
			~OMAP3430_AUTO_PERIPH_DPLL_MASK;
	prcm_block_contents.cm_clksel1_pll =
			omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
	prcm_block_contents.cm_clksel2_pll =
			omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
	prcm_block_contents.cm_clksel3_pll =
			omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
	prcm_block_contents.cm_clken_pll_mpu =
			omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
	prcm_block_contents.cm_autoidle_pll_mpu =
			omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
	prcm_block_contents.cm_clksel1_pll_mpu =
			omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
	prcm_block_contents.cm_clksel2_pll_mpu =
			omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
	prcm_block_contents.prcm_block_size = 0x0;

	/* Populate the SDRC block contents */
	sdrc_block_contents.sysconfig =
			(sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF);
	sdrc_block_contents.cs_cfg =
			(sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF);
	sdrc_block_contents.sharing =
			(sdrc_read_reg(SDRC_SHARING) & 0xFFFF);
	sdrc_block_contents.err_type =
			(sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF);
	sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL);
	sdrc_block_contents.dll_b_ctrl = 0x0;
	/*
	 * Due to a OMAP3 errata (1.142), on EMU/HS devices SRDC should
	 * be programed to issue automatic self refresh on timeout
	 * of AUTO_CNT = 1 prior to any transition to OFF mode.
	 */
	if ((omap_type() != OMAP2_DEVICE_TYPE_GP)
			&& (omap_rev() >= OMAP3430_REV_ES3_0))
		sdrc_block_contents.power = (sdrc_read_reg(SDRC_POWER) &
				~(SDRC_POWER_AUTOCOUNT_MASK|
				SDRC_POWER_CLKCTRL_MASK)) |
				(1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
				SDRC_SELF_REFRESH_ON_AUTOCOUNT;
	else
		sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);

	sdrc_block_contents.cs_0 = 0x0;
	sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0);
	sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF);
	sdrc_block_contents.emr_1_0 = 0x0;
	sdrc_block_contents.emr_2_0 = 0x0;
	sdrc_block_contents.emr_3_0 = 0x0;
	sdrc_block_contents.actim_ctrla_0 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_A_0);
	sdrc_block_contents.actim_ctrlb_0 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_B_0);
	sdrc_block_contents.rfr_ctrl_0 =
			sdrc_read_reg(SDRC_RFR_CTRL_0);
	sdrc_block_contents.cs_1 = 0x0;
	sdrc_block_contents.mcfg_1 = sdrc_read_reg(SDRC_MCFG_1);
	sdrc_block_contents.mr_1 = sdrc_read_reg(SDRC_MR_1) & 0xFFFF;
	sdrc_block_contents.emr_1_1 = 0x0;
	sdrc_block_contents.emr_2_1 = 0x0;
	sdrc_block_contents.emr_3_1 = 0x0;
	sdrc_block_contents.actim_ctrla_1 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_A_1);
	sdrc_block_contents.actim_ctrlb_1 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_B_1);
	sdrc_block_contents.rfr_ctrl_1 =
			sdrc_read_reg(SDRC_RFR_CTRL_1);
	sdrc_block_contents.dcdl_1_ctrl = 0x0;
	sdrc_block_contents.dcdl_2_ctrl = 0x0;
	sdrc_block_contents.flags = 0x0;
	sdrc_block_contents.block_size = 0x0;

	arm_context_addr = virt_to_phys(omap3_arm_context);

	/* Copy all the contents to the scratchpad location */
	scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
	memcpy_toio(scratchpad_address, &scratchpad_contents,
		 sizeof(scratchpad_contents));
	/* Scratchpad contents being 32 bits, a divide by 4 done here */
	memcpy_toio(scratchpad_address +
		scratchpad_contents.prcm_block_offset,
		&prcm_block_contents, sizeof(prcm_block_contents));
	memcpy_toio(scratchpad_address +
		scratchpad_contents.sdrc_block_offset,
		&sdrc_block_contents, sizeof(sdrc_block_contents));
	/*
	 * Copies the address of the location in SDRAM where ARM
	 * registers get saved during a MPU OFF transition.
	 */
	memcpy_toio(scratchpad_address +
		scratchpad_contents.sdrc_block_offset +
		sizeof(sdrc_block_contents), &arm_context_addr, 4);
}
/*
 * Distributor is enabled by the master CPU
 * Also clear the SAR backup status register
 */
static inline void enable_gic_distributor(void)
{
	writel(0x1, gic_dist_base_addr + GIC_DIST_CTRL);
	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
		writel(0x0, sar_bank3_base + SAR_BACKUP_STATUS_OFFSET);
}
/*
 * OMAP4 MPUSS Low Power Entry Function
 *
 * The purpose of this function is to manage low power programming
 * of OMAP4 MPUSS subsystem
 * Paramenters:
 *	cpu : CPU ID
 *	power_state: Targetted Low power state.
 *
 * MPUSS Low power states
 * The basic rule is that the MPUSS power domain must be at the higher or
 * equal power state (state that consume more power) than the higher of the
 * two CPUs. For example, it is illegal for system power to be OFF, while
 * the power of one or both of the CPU is DORMANT. When an illegal state is
 * entered, then the hardware behavior is unpredictable.
 *
 * MPUSS state for the context save
 * save_state =
 *	0 - Nothing lost and no need to save: MPUSS INACTIVE
 *	1 - CPUx L1 and logic lost: MPUSS CSWR
 *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
 *	3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
 */
void omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
{
	unsigned int save_state, wakeup_cpu, inst_clk_enab = 0;

	if (cpu > NR_CPUS)
		return;

	/*
	 * Low power state not supported on ES1.0 silicon
	 */
	if (omap_rev() == OMAP4430_REV_ES1_0) {
		wmb();
		do_wfi();
		return;
	}

	switch (power_state) {
	case PWRDM_POWER_ON:
	case PWRDM_POWER_INACTIVE:
		save_state = 0;
		break;
	case PWRDM_POWER_OFF:
		save_state = 1;
		setup_wakeup_routine(cpu);
		save_local_timers(cpu);
		break;
	case PWRDM_POWER_RET:
		/*
		 * CPUx CSWR is invalid hardware state. Additionally
		 * CPUx OSWR  doesn't give any gain vs CPUxOFF and
		 * hence not supported
		 */
	default:
		/* Invalid state */
		pr_debug("Invalid CPU low power state\n");
		return;
	}

	/*
	 * MPUSS book keeping should be executed by master
	 * CPU only which is the last CPU to go down
	 */
	if (cpu)
		goto cpu_prepare;
	/*
	 * Check MPUSS next state and save GIC if needed
	 * GIC lost during MPU OFF and OSWR
	 */
	pwrdm_clear_all_prev_pwrst(mpuss_pd);
	if (omap4_device_off_read_next_state() &&
			 (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
		/* FIXME: Check if this can be optimised */

		/* l3_main inst clock must be enabled for
		 * a save ram operation
		 */
		if (!l3_main_3_ick->usecount) {
			inst_clk_enab = 1;
			clk_enable(l3_main_3_ick);
		}

		save_secure_all();
		save_gic_wakeupgen_secure();

		if (inst_clk_enab == 1)
			clk_disable(l3_main_3_ick);

		save_ivahd_tesla_regs();
		save_l3instr_regs();

		save_state = 3;
		goto cpu_prepare;
	}

	switch (pwrdm_read_next_pwrst(mpuss_pd)) {
	case PWRDM_POWER_ON:
	case PWRDM_POWER_INACTIVE:
		/* No need to save MPUSS context */
		break;
	case PWRDM_POWER_RET:
		/* MPUSS OSWR, logic lost */
		if (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF) {
			if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
				save_gic_wakeupgen_secure();
				save_l3instr_regs();
			} else {
				save_gic();
				omap4_wakeupgen_save();
			}
			save_state = 2;
		}
		break;
	case PWRDM_POWER_OFF:
		/* MPUSS OFF */
		if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
			/* l3_main inst clock must be enabled for
			 * a save ram operation
			 */
			if (!l3_main_3_ick->usecount) {
	                        inst_clk_enab = 1;
				clk_enable(l3_main_3_ick);
			}
			save_secure_ram();

			if (inst_clk_enab == 1)
				clk_disable(l3_main_3_ick);

			save_gic_wakeupgen_secure();
			save_ivahd_tesla_regs();
			save_l3instr_regs();
		} else {
			save_gic();
			omap4_wakeupgen_save();
		}
		save_state = 3;
		break;
	default:
		/* Fall through */
		;
	}

	/*
	 * Program the CPU targeted state
	 */
cpu_prepare:
	clear_cpu_prev_pwrst(cpu);
	if (cpu)
		pwrdm_set_next_pwrst(cpu1_pwrdm, power_state);
	else
		pwrdm_set_next_pwrst(cpu0_pwrdm, power_state);
	scu_pwrst_prepare(cpu, power_state);

	if (regset_save_on_suspend && !cpu)
		pm_dbg_regset_save(1);

	/*
	 * Call low level routine to enter to
	 * targeted power state
	 */
	__omap4_cpu_suspend(cpu, save_state);
	wakeup_cpu = hard_smp_processor_id();

	if (regset_save_on_suspend && !wakeup_cpu)
		pm_dbg_regset_save(2);

	/*
	 * Restore the CPUx and mpuss power state to ON otherwise
	 * CPUx power domain can transitions to programmed low power
	 * state while doing WFI outside the low powe code. On HS devices,
	 * CPUx can do WFI outside idle thread  which can result in
	 * power domain domain transition if the previous state was
	 * programmed to OFF/RET.
	 */
	if (wakeup_cpu) {
		pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
	} else {
		pwrdm_set_next_pwrst(cpu0_pwrdm, PWRDM_POWER_ON);
		pwrdm_set_next_pwrst(mpuss_pd, PWRDM_POWER_ON);
		omap4_secure_dispatcher(0x21, 4, 0, 0, 0, 0, 0);
	}

	/*
	 * Check the CPUx previous power state
	 */
	if (read_cpu_prev_pwrst(wakeup_cpu) == PWRDM_POWER_OFF) {
		cpu_init();
		restore_mmu_table_entry();
		restore_local_timers(wakeup_cpu);
	}

	/*
	 * Check MPUSS previous power state and enable
	 * GIC if needed.
	 */
	switch (pwrdm_read_prev_pwrst(mpuss_pd)) {
	case PWRDM_POWER_ON:
	case PWRDM_POWER_INACTIVE:
		/* No need to restore */
		break;
	case PWRDM_POWER_RET:
		if (pwrdm_read_prev_logic_pwrst(mpuss_pd) != PWRDM_POWER_OFF)
			break;
		/* fall through if hit MPU OSWR */
	case PWRDM_POWER_OFF:
		/*
		 * Enable GIC distributor
		 */
		if (!wakeup_cpu) {
			if ((omap_type() == OMAP2_DEVICE_TYPE_GP)
					&& omap4_device_off_read_prev_state()) {
				restore_gic();
				omap4_wakeupgen_restore();
			}
			enable_gic_distributor();
			if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
				if (omap4_device_off_read_prev_state())
					restore_ivahd_tesla_regs();
				restore_l3instr_regs();
			}
		}
		/*
		 * Enable GIC cpu inrterface
		 */
		enable_gic_cpu_interface();
		break;
	default:
		;
	}

}
Exemple #5
0
/*
 * Initialise OMAP4 MPUSS
 */
int __init omap4_mpuss_init(void)
{
	struct omap4_cpu_pm_info *pm_info;

	if (omap_rev() == OMAP4430_REV_ES1_0) {
		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
		return -ENODEV;
	}

	sar_base = omap4_get_sar_ram_base();

	/* Initilaise per CPU PM information */
	pm_info = &per_cpu(omap4_pm_info, 0x0);
	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
	if (!pm_info->pwrdm) {
		pr_err("Lookup failed for CPU0 pwrdm\n");
		return -ENODEV;
	}

	/* Clear CPU previous power domain state */
	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
	cpu_clear_prev_logic_pwrst(0);

	/* Initialise CPU0 power domain state to ON */
	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);

	pm_info = &per_cpu(omap4_pm_info, 0x1);
	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
	if (!pm_info->pwrdm) {
		pr_err("Lookup failed for CPU1 pwrdm\n");
		return -ENODEV;
	}

	/* Clear CPU previous power domain state */
	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
	cpu_clear_prev_logic_pwrst(1);

	/* Initialise CPU1 power domain state to ON */
	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);

	mpuss_pd = pwrdm_lookup("mpu_pwrdm");
	if (!mpuss_pd) {
		pr_err("Failed to lookup MPUSS power domain\n");
		return -ENODEV;
	}
	pwrdm_clear_all_prev_pwrst(mpuss_pd);
	mpuss_clear_prev_logic_pwrst();

	/* Save device type on scratchpad for low level code to use */
	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
		__raw_writel(1, sar_base + OMAP_TYPE_OFFSET);
	else
		__raw_writel(0, sar_base + OMAP_TYPE_OFFSET);

	save_l2x0_context();

	return 0;
}
Exemple #6
0
/*
 * Interrupt Handler for L3 error detection
 *	1) Identify the clock domain to which the error belongs to
 *	2) Identify the slave where the error information is logged
 *	3) Print the logged information
 */
static irqreturn_t l3_interrupt_handler(int irq, void *dev_id)
{
	int inttype, i, j;
	int err_source = 0;
	u32 stderrlog_main, stderrlog_main_reg_val, error_source_reg;
	u32 ctrl_sec_err_status, ctrl_sec_err_status_regval, slave_addr;
	char *source_name;

	/*
	 * Get the Type of interrupt
	 * 0- Application
	 * 1 - Debug
	 */
	if (irq == OMAP44XX_IRQ_L3_APP)
		inttype = 0;
	else
		inttype = 1;

	for (i = 0; i < 3; i++) {
		/*
		 * Read the regerr register of the clock domain
		 * to determine the source
		 */
		error_source_reg =  readl((l3_base[i] + l3_flagmux_regerr[i]
							+ (inttype << 3)));
		/* Get the corresponding error and analyse */
		if (error_source_reg) {
			/* Identify the source from control status register */
			for (j = 0; !err_source; j++)
				err_source = error_source_reg & (1<<j);
			/* Since array offset is from Zero */
			err_source = j-1;
			/* Read the stderrlog_main_source from clk domain */
			stderrlog_main = (u32)l3_base[i] +
				(*(l3_targ_stderrlog_main[i] + err_source));
			stderrlog_main_reg_val =  readl(stderrlog_main);

			switch ((stderrlog_main_reg_val & CUSTOM_ERROR)) {
			case STANDARD_ERROR:
				/* check if this is a firewall violation */
				ctrl_sec_err_status = (u32)ctrl_base +
						ctrl_sec_err_stat[inttype];
				ctrl_sec_err_status_regval =
						readl(ctrl_sec_err_status);
				source_name =
				(char *)(*(l3_targ_stderrlog_main_sourcename[i]
					+ err_source));
				slave_addr = stderrlog_main +

						L3_SLAVE_ADDRESS_OFFSET;
				if (!ctrl_sec_err_status_regval) {
					/*
					 * get the details about the inband
					 * error as command etc and print
					 * details
					 */
					pr_crit("L3 standard error: SOURCE:%s"
						"at address 0x%x\n",
						source_name, readl(slave_addr));
					dump_stack();
				} else {
					/* Then this is a Fire Wall Error */
					if (omap_type() == OMAP2_DEVICE_TYPE_GP)
						omap_fw_error_handler(
								ctrl_sec_err_status,
								ctrl_sec_err_status_regval);
				}
				/* clear the stderr log */
				writel((stderrlog_main_reg_val |
					CLEAR_STDERR_LOG), stderrlog_main);
				break;
			case CUSTOM_ERROR:
				pr_crit("CUSTOM SRESP error with SOURCE:%s\n",
				(char *)(*(l3_targ_stderrlog_main_sourcename[i]
						+ err_source)));
				/* clear the std error log*/
				writel((stderrlog_main_reg_val |
					CLEAR_STDERR_LOG), stderrlog_main);
				dump_stack();
				break;
			default:
				/* Nothing to be handled here as of now */
				break;
			}
		/* Error found so break the for loop */
		break;
		}
	}
	return IRQ_HANDLED;
}
static ssize_t omap4_soc_type_show(struct kobject *kobj,
                                   struct kobj_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", omap_types[omap_type()]);
}
Exemple #8
0
/* Populate the scratchpad structure with restore structure */
void omap3_save_scratchpad_contents(void)
{
	void  __iomem *scratchpad_address;
	u32 arm_context_addr;
	struct omap3_scratchpad scratchpad_contents;
	struct omap3_scratchpad_prcm_block prcm_block_contents;
	struct omap3_scratchpad_sdrc_block sdrc_block_contents;

	/* Populate the Scratchpad contents */
	scratchpad_contents.boot_config_ptr = 0x0;
	if (omap_rev() != OMAP3430_REV_ES3_0 &&
					omap_rev() != OMAP3430_REV_ES3_1)
		scratchpad_contents.public_restore_ptr =
			virt_to_phys(get_restore_pointer());
	else
		scratchpad_contents.public_restore_ptr =
			virt_to_phys(get_es3_restore_pointer());
	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
		scratchpad_contents.secure_ram_restore_ptr = 0x0;
	else
		scratchpad_contents.secure_ram_restore_ptr =
			(u32) __pa(omap3_secure_ram_storage);
	scratchpad_contents.sdrc_module_semaphore = 0x0;
	scratchpad_contents.prcm_block_offset = 0x2C;
	scratchpad_contents.sdrc_block_offset = 0x64;

	/* Populate the PRCM block contents */
	prcm_block_contents.prm_clksrc_ctrl = prm_read_mod_reg(OMAP3430_GR_MOD,
			OMAP3_PRM_CLKSRC_CTRL_OFFSET);
	prcm_block_contents.prm_clksel = prm_read_mod_reg(OMAP3430_CCR_MOD,
			OMAP3_PRM_CLKSEL_OFFSET);
	prcm_block_contents.cm_clksel_core =
			cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
	prcm_block_contents.cm_clksel_wkup =
			cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
	prcm_block_contents.cm_clken_pll =
			cm_read_mod_reg(PLL_MOD, CM_CLKEN);
	prcm_block_contents.cm_autoidle_pll =
			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL);
	prcm_block_contents.cm_clksel1_pll =
			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
	prcm_block_contents.cm_clksel2_pll =
			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
	prcm_block_contents.cm_clksel3_pll =
			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
	prcm_block_contents.cm_clken_pll_mpu =
			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
	prcm_block_contents.cm_autoidle_pll_mpu =
			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
	prcm_block_contents.cm_clksel1_pll_mpu =
			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
	prcm_block_contents.cm_clksel2_pll_mpu =
			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
	prcm_block_contents.prcm_block_size = 0x0;

	/* Populate the SDRC block contents */
	sdrc_block_contents.sysconfig =
			(sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF);
	sdrc_block_contents.cs_cfg =
			(sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF);
	sdrc_block_contents.sharing =
			(sdrc_read_reg(SDRC_SHARING) & 0xFFFF);
	sdrc_block_contents.err_type =
			(sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF);
	sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL);
	sdrc_block_contents.dll_b_ctrl = 0x0;
	/*
	 * Due to a OMAP3 errata (1.142), on EMU/HS devices SRDC should
	 * be programed to issue automatic self refresh on timeout
	 * of AUTO_CNT = 1 prior to any transition to OFF mode.
	 */
	if ((omap_type() != OMAP2_DEVICE_TYPE_GP)
			&& (omap_rev() >= OMAP3430_REV_ES3_0))
		sdrc_block_contents.power = (sdrc_read_reg(SDRC_POWER) &
				~(SDRC_POWER_AUTOCOUNT_MASK|
				SDRC_POWER_CLKCTRL_MASK)) |
				(1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
				SDRC_SELF_REFRESH_ON_AUTOCOUNT;
	else
		sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);

	sdrc_block_contents.cs_0 = 0x0;
	sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0);
	sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF);
	sdrc_block_contents.emr_1_0 = 0x0;
	sdrc_block_contents.emr_2_0 = 0x0;
	sdrc_block_contents.emr_3_0 = 0x0;
	sdrc_block_contents.actim_ctrla_0 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_A_0);
	sdrc_block_contents.actim_ctrlb_0 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_B_0);
	sdrc_block_contents.rfr_ctrl_0 =
			sdrc_read_reg(SDRC_RFR_CTRL_0);
	sdrc_block_contents.cs_1 = 0x0;
	sdrc_block_contents.mcfg_1 = sdrc_read_reg(SDRC_MCFG_1);
	sdrc_block_contents.mr_1 = sdrc_read_reg(SDRC_MR_1) & 0xFFFF;
	sdrc_block_contents.emr_1_1 = 0x0;
	sdrc_block_contents.emr_2_1 = 0x0;
	sdrc_block_contents.emr_3_1 = 0x0;
	sdrc_block_contents.actim_ctrla_1 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_A_1);
	sdrc_block_contents.actim_ctrlb_1 =
			sdrc_read_reg(SDRC_ACTIM_CTRL_B_1);
	sdrc_block_contents.rfr_ctrl_1 =
			sdrc_read_reg(SDRC_RFR_CTRL_1);
	sdrc_block_contents.dcdl_1_ctrl = 0x0;
	sdrc_block_contents.dcdl_2_ctrl = 0x0;
#ifdef CONFIG_SAMSUNG_KERNEL_DEBUG
	sdrc_block_contents.flags = 0x4D524F4E; // reset flag (p:0x480029C4 v:F00029C4)
#else
	sdrc_block_contents.flags = 0x0;
#endif /* CONFIG_SAMSUNG_KERNEL_DEBUG */
	sdrc_block_contents.block_size = 0x0;

	arm_context_addr = virt_to_phys(omap3_arm_context);

	/* Copy all the contents to the scratchpad location */
	scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
	memcpy_toio(scratchpad_address, &scratchpad_contents,
		 sizeof(scratchpad_contents));
	/* Scratchpad contents being 32 bits, a divide by 4 done here */
	memcpy_toio(scratchpad_address +
		scratchpad_contents.prcm_block_offset,
		&prcm_block_contents, sizeof(prcm_block_contents));
	memcpy_toio(scratchpad_address +
		scratchpad_contents.sdrc_block_offset,
		&sdrc_block_contents, sizeof(sdrc_block_contents));
	/*
	 * Copies the address of the location in SDRAM where ARM
	 * registers get saved during a MPU OFF transition.
	 */
	memcpy_toio(scratchpad_address +
		scratchpad_contents.sdrc_block_offset +
		sizeof(sdrc_block_contents), &arm_context_addr, 4);
}
/*
 * Initialise the wakeupgen module.
 */
int __init omap_wakeupgen_init(void)
{
	int i;
	unsigned int boot_cpu = smp_processor_id();
	unsigned int max_spi_reg;

	/* Not supported on OMAP4 ES1.0 silicon */
	if (omap_rev() == OMAP4430_REV_ES1_0) {
		WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n");
		return -EPERM;
	}

	/* Static mapping, never released */
	wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K);
	if (WARN_ON(!wakeupgen_base))
		return -ENOMEM;

	if (cpu_is_omap44xx()) {
		irq_banks = OMAP4_NR_BANKS;
		max_irqs = OMAP4_NR_IRQS;
		secure_api_index = OMAP4_HAL_SAVEGIC_INDEX;
		secure_hw_api_index = OMAP4_HAL_SAVEHW_INDEX;
		secure_hal_save_all_api_index = OMAP4_HAL_SAVEALL_INDEX;
		secure_ram_api_index  = OMAP4_HAL_SAVESECURERAM_INDEX;
	} else if (cpu_is_omap54xx()) {
		secure_api_index = OMAP5_HAL_SAVEGIC_INDEX;
		secure_hw_api_index = OMAP5_HAL_SAVEHW_INDEX;
		secure_hal_save_all_api_index = OMAP5_HAL_SAVEALL_INDEX;
		secure_ram_api_index  = OMAP5_HAL_SAVESECURERAM_INDEX;
	}

	/* Clear all IRQ bitmasks at wakeupGen level */
	for (i = 0; i < irq_banks; i++) {
		wakeupgen_writel(0, i, CPU0_ID);
		wakeupgen_writel(0, i, CPU1_ID);
	}

	/*
	 * Override GIC architecture specific functions to add
	 * OMAP WakeupGen interrupt controller along with GIC
	 */
	gic_arch_extn.irq_mask = wakeupgen_mask;
	gic_arch_extn.irq_unmask = wakeupgen_unmask;
	gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE;

	/*
	 * FIXME: Add support to set_smp_affinity() once the core
	 * GIC code has necessary hooks in place.
	 */

	/* Associate all the IRQs to boot CPU like GIC init does. */
	for (i = 0; i < max_irqs; i++)
		irq_target_cpu[i] = boot_cpu;

	/*
	 * Find out how many interrupts are supported.
	 * OMAP4 supports max of 128 SPIs where as GIC can support
	 * up to 1020 interrupt sources. On OMAP4, maximum SPIs are
	 * fused in DIST_CTR bit-fields as 128. Hence the code is safe
	 * from reserved register writes since its well within 1020.
	 */
	max_spi_reg = gic_readl(GIC_DIST_CTR, 0) & 0x1f;

	spi_irq_banks = min(max_spi_reg, irq_banks);

	/*
	 * Set CPU0 GIC backup flag permanently for omap4460 GP,
	 * this is needed because of the ROM code bug that breaks
	 * GIC during wakeup from device off. This errata fix also
	 * clears the GIC save area during init to prevent restoring
	 * garbage to the GIC.
	 */
	if (cpu_is_omap446x() && omap_type() == OMAP2_DEVICE_TYPE_GP)
		pm44xx_errata |= PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx;

	if (cpu_is_omap44xx() && (omap_type() == OMAP2_DEVICE_TYPE_GP)) {
		sar_base = omap4_get_sar_ram_base();

		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx))
			for (i = SAR_BACKUP_STATUS_OFFSET;
			     i < WAKEUPGENENB_OFFSET_CPU0; i += 4)
				sar_writel(0, i, 0);

		sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU0_OFFSET, 0);
		sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU1_OFFSET, 0);
		for (i = 0; i < max_spi_reg; i++)
			sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_SPI_OFFSET,
				   i);

		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx))
			__raw_writel(SAR_BACKUP_STATUS_GIC_CPU0,
				     sar_base + SAR_BACKUP_STATUS_OFFSET);

	} else {
		l3_main_3_oh = omap_hwmod_lookup("l3_main_3");
		if (!l3_main_3_oh)
			pr_err("%s: failed to get l3_main_3_oh\n", __func__);
	}

	irq_hotplug_init();
	irq_pm_init();

	return 0;
}
Exemple #10
0
/*
 * Initialise OMAP4 MPUSS
 */
int __init omap4_mpuss_init(void)
{
	struct omap4_cpu_pm_info *pm_info;

	if (omap_rev() == OMAP4430_REV_ES1_0) {
		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
		return -ENODEV;
	}

	if (cpu_is_omap44xx())
		sar_base = omap4_get_sar_ram_base();

	/* Initilaise per CPU PM information */
	pm_info = &per_cpu(omap4_pm_info, 0x0);
	if (sar_base) {
		pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
		pm_info->wkup_sar_addr = sar_base +
					CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
		pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
	}
	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
	if (!pm_info->pwrdm) {
		pr_err("Lookup failed for CPU0 pwrdm\n");
		return -ENODEV;
	}

	/* Clear CPU previous power domain state */
	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
	cpu_clear_prev_logic_pwrst(0);

	/* Initialise CPU0 power domain state to ON */
	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);

	pm_info = &per_cpu(omap4_pm_info, 0x1);
	if (sar_base) {
		pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
		pm_info->wkup_sar_addr = sar_base +
					CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
		pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
	}

	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
	if (!pm_info->pwrdm) {
		pr_err("Lookup failed for CPU1 pwrdm\n");
		return -ENODEV;
	}

	/* Clear CPU previous power domain state */
	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
	cpu_clear_prev_logic_pwrst(1);

	/* Initialise CPU1 power domain state to ON */
	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);

	mpuss_pd = pwrdm_lookup("mpu_pwrdm");
	if (!mpuss_pd) {
		pr_err("Failed to lookup MPUSS power domain\n");
		return -ENODEV;
	}
	pwrdm_clear_all_prev_pwrst(mpuss_pd);
	mpuss_clear_prev_logic_pwrst();

	if (sar_base) {
		/* Save device type on scratchpad for low level code to use */
		writel_relaxed((omap_type() != OMAP2_DEVICE_TYPE_GP) ? 1 : 0,
			       sar_base + OMAP_TYPE_OFFSET);
		save_l2x0_context();
	}

	if (cpu_is_omap44xx()) {
		omap_pm_ops.finish_suspend = omap4_finish_suspend;
		omap_pm_ops.resume = omap4_cpu_resume;
		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
		omap_pm_ops.hotplug_restart = omap4_secondary_startup;
		cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
	} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
		enable_mercury_retention_mode();
	}

	if (cpu_is_omap446x())
		omap_pm_ops.hotplug_restart = omap4460_secondary_startup;

	return 0;
}
static int __init omap_l2_cache_init(void)
{
	u32 aux_ctrl = 0;
	u32 por_ctrl = 0;
	u32 lockdown = 0;
	bool mpu_prefetch_disable_errata = false;

	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	/*
	 * To avoid code running on other OMAPs in
	 * multi-omap builds
	 */
	if (!cpu_is_omap44xx())
		return -ENODEV;
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

#ifdef CONFIG_OMAP_ALLOW_OSWR
	if (omap_rev() == OMAP4460_REV_ES1_0)
		mpu_prefetch_disable_errata = true;
#endif
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	/* Static mapping, never released */
	l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);
	if (WARN_ON(!l2cache_base))
		return -ENODEV;
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);
	/*
	 * 16-way associativity, parity disabled
	 * Way size - 32KB (es1.0)
	 * Way size - 64KB (es2.0 +)
	 */
	aux_ctrl = readl_relaxed(l2cache_base + L2X0_AUX_CTRL);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	if (omap_rev() == OMAP4430_REV_ES1_0) {
		aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
		goto skip_aux_por_api;
	}
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	/*
	 * Drop instruction prefetch hint since it degrades the
	 * the performance.
	 */
	aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
		(1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
		(1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	if (!mpu_prefetch_disable_errata)
		aux_ctrl |= (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	omap_smc1(0x109, aux_ctrl);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	/* Setup POR Control register */
	por_ctrl = readl_relaxed(l2cache_base + L2X0_PREFETCH_CTRL);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	/*
	 * Double linefill is available only on OMAP4460 L2X0.
	 * It may cause single cache line memory corruption, leave it disabled
	 * on all devices
	 */
	por_ctrl &= ~(1 << L2X0_PREFETCH_DOUBLE_LINEFILL_SHIFT);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);
	if (!mpu_prefetch_disable_errata) {
		por_ctrl &= ~L2X0_POR_OFFSET_MASK;
		por_ctrl |= L2X0_POR_OFFSET_VALUE;
	}
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	/* Set POR through PPA service only in EMU/HS devices */
	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
		omap4_secure_dispatcher(PPA_SERVICE_PL310_POR, 0x7, 1,
				por_ctrl, 0, 0, 0);
	else if (omap_rev() >= OMAP4430_REV_ES2_2)
		omap_smc1(0x113, por_ctrl);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);


	/*
	 * FIXME: Temporary WA for OMAP4460 stability issue.
	 * Lock-down specific L2 cache ways which  makes effective
	 * L2 size as 512 KB instead of 1 MB
	 */
	if (omap_rev() == OMAP4460_REV_ES1_0) {
		lockdown = 0xa5a5;
		writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_D0);
		printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);
		writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_D1);
		printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);
		writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_I0);
		printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);
		writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_I1);
	}
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

skip_aux_por_api:
	/* Enable PL310 L2 Cache controller */
	omap_smc1(0x102, 0x1);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	/*
	 * Override default outer_cache.disable with a OMAP4
	 * specific one
	*/
	outer_cache.disable = omap4_l2x0_disable;
	outer_cache.set_debug = omap4_l2x0_set_debug;
	printk(KERN_INFO "===[%s(%d)]===\n", __func__, __LINE__);

	return 0;
}
Exemple #12
0
/*
 * SAR RAM used to save and restore the HW
 * context in low power modes
 */
static int __init omap4_sar_ram_init(void)
{
	/*
	 * To avoid code running on other OMAPs in
	 * multi-omap builds
	 */
	if (!cpu_is_omap44xx())
		return -ENODEV;

	/*
	 * Static mapping, never released Actual SAR area used is 8K it's
	 * spaced over 16K address with some part is reserved.
	 */
	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
	BUG_ON(!sar_ram_base);

	/*
	 * All these are static mappings so ioremap() will
	 * just return with mapped VA
	 */
	omap4_sar_modules[EMIF1_INDEX] = ioremap(OMAP44XX_EMIF1, SZ_1M);
	BUG_ON(!omap4_sar_modules[EMIF1_INDEX]);
	omap4_sar_modules[EMIF2_INDEX] = ioremap(OMAP44XX_EMIF2, SZ_1M);
	BUG_ON(!omap4_sar_modules[EMIF2_INDEX]);
	omap4_sar_modules[DMM_INDEX] = ioremap(OMAP44XX_DMM_BASE, SZ_1M);
	BUG_ON(!omap4_sar_modules[DMM_INDEX]);
	omap4_sar_modules[CM1_INDEX] = ioremap(OMAP4430_CM1_BASE, SZ_8K);
	BUG_ON(!omap4_sar_modules[CM1_INDEX]);
	omap4_sar_modules[CM2_INDEX] = ioremap(OMAP4430_CM2_BASE, SZ_8K);
	BUG_ON(!omap4_sar_modules[CM2_INDEX]);
	omap4_sar_modules[C2C_INDEX] = ioremap(OMAP44XX_C2C_BASE, SZ_1M);
	BUG_ON(!omap4_sar_modules[C2C_INDEX]);
	omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX] =
	    ioremap(OMAP443X_CTRL_BASE, SZ_4K);
	BUG_ON(!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX]);
	omap4_sar_modules[L3_CLK1_INDEX] = ioremap(L3_44XX_BASE_CLK1, SZ_1M);
	BUG_ON(!omap4_sar_modules[L3_CLK1_INDEX]);
	omap4_sar_modules[L3_CLK2_INDEX] = ioremap(L3_44XX_BASE_CLK2, SZ_1M);
	BUG_ON(!omap4_sar_modules[L3_CLK2_INDEX]);
	omap4_sar_modules[L3_CLK3_INDEX] = ioremap(L3_44XX_BASE_CLK3, SZ_1M);
	BUG_ON(!omap4_sar_modules[L3_CLK3_INDEX]);
	omap4_sar_modules[USBTLL_INDEX] = ioremap(OMAP44XX_USBTLL_BASE, SZ_1M);
	BUG_ON(!omap4_sar_modules[USBTLL_INDEX]);
	omap4_sar_modules[UHH_INDEX] = ioremap(OMAP44XX_UHH_CONFIG_BASE, SZ_1M);
	BUG_ON(!omap4_sar_modules[UHH_INDEX]);
	omap4_sar_modules[L4CORE_INDEX] = ioremap(L4_44XX_PHYS, SZ_4M);
	BUG_ON(!omap4_sar_modules[L4CORE_INDEX]);
	omap4_sar_modules[L4PER_INDEX] = ioremap(L4_PER_44XX_PHYS, SZ_4M);
	BUG_ON(!omap4_sar_modules[L4PER_INDEX]);

	/*
	 * SAR BANK3 contains all firewall settings and it's saved through
	 * secure API on HS device. On GP device these registers are
	 * meaningless but still needs to be saved. Otherwise Auto-restore
	 * phase DMA takes an abort. Hence save these conents only once
	 * in init to avoid the issue while waking up from device OFF
	 */
	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
		save_sar_bank3();
	/*
	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
	 * Mode Transition When CS1 Is Used On EMIF":
	 * Overwrite EMIF1/EMIF2
	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
	 */
	if (cpu_is_omap443x()) {
		void __iomem *secure_ctrl_mod;

		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
		BUG_ON(!secure_ctrl_mod);

		__raw_writel(0x10, secure_ctrl_mod +
				OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
		__raw_writel(0x10, secure_ctrl_mod +
				OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
		wmb();
		iounmap(secure_ctrl_mod);
	}

	/*
	 * L3INIT PD and clocks are needed for SAR save phase
	 */
	l3init_pwrdm = pwrdm_lookup("l3init_pwrdm");
	if (!l3init_pwrdm)
		pr_err("Failed to get l3init_pwrdm\n");

	l3init_clkdm = clkdm_lookup("l3_init_clkdm");
	if (!l3init_clkdm)
		pr_err("Failed to get l3_init_clkdm\n");

	usb_host_ck = clk_get(NULL, "usb_host_hs_fck");
	if (!usb_host_ck)
		pr_err("Could not get usb_host_ck\n");

	usb_tll_ck = clk_get(NULL, "usb_tll_hs_ick");
	if (!usb_tll_ck)
		pr_err("Could not get usb_tll_ck\n");

	return 0;
}
static int __init omap_l2_cache_init(void)
{
	u32 l2x0_auxctrl;
	u32 l2x0_por;
	u32 l2x0_lockdown;

	/*
	 * To avoid code running on other OMAPs in
	 * multi-omap builds
	 */
	if (!cpu_is_omap44xx())
		return -ENODEV;

	/* Static mapping, never released */
	l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
	BUG_ON(!l2cache_base);

	if (omap_rev() == OMAP4430_REV_ES1_0) {
		l2x0_auxctrl = OMAP443X_L2X0_AUXCTL_VALUE_ES1;
		goto skip_auxctlr;
	}

	if (cpu_is_omap446x()) {
		if (omap_rev() == OMAP4460_REV_ES1_0) {
			l2x0_auxctrl = OMAP446X_L2X0_AUXCTL_VALUE_ES1;
			l2x0_por = OMAP446X_PL310_POR_ES1;
			l2x0_lockdown = 0xa5a5;
		} else {
			l2x0_auxctrl = OMAP446X_L2X0_AUXCTL_VALUE;
			l2x0_por = OMAP446X_PL310_POR;
			l2x0_lockdown = 0;
		}
	} else {
		l2x0_auxctrl = OMAP443X_L2X0_AUXCTL_VALUE;
		l2x0_por = OMAP443X_PL310_POR;
		l2x0_lockdown = 0;
	}

	/* Set POR through PPA service only in EMU/HS devices */
	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
		omap4_secure_dispatcher(
				PPA_SERVICE_PL310_POR, 0x7, 1,
				l2x0_por, 0, 0, 0);
	} else if (omap_rev() > OMAP4430_REV_ES2_1)
			omap_smc1(0x113, l2x0_por);

	/*
	 * FIXME : Temporary WA for the OMAP4460 stability
	 * issue. For OMAP4460 the effective L2X0 Size  = 512 KB
	 * with this WA.
	 */
	writel_relaxed(l2x0_lockdown, l2cache_base + 0x900);
	writel_relaxed(l2x0_lockdown, l2cache_base + 0x908);
	writel_relaxed(l2x0_lockdown, l2cache_base + 0x904);
	writel_relaxed(l2x0_lockdown, l2cache_base + 0x90C);

	/*
	 * Doble Linefill, BRESP enabled, $I and $D prefetch ON,
	 * Share-override = 1, NS lockdown enabled
	 */
	omap_smc1(0x109, l2x0_auxctrl);

skip_auxctlr:
	/* Enable PL310 L2 Cache controller */
	omap_smc1(0x102, 0x1);

	/*
	 * 32KB way size, 16-way associativity,
	 * parity disabled
	 */
	l2x0_init(l2cache_base, l2x0_auxctrl, 0xd0000fff);

	return 0;
}