예제 #1
0
/*
 * The amount of SRAM depends on the core type.
 * Note that we cannot try to test for SRAM here because writes
 * to secure SRAM will hang the system. Also the SRAM is not
 * yet mapped at this point.
 */
static void __init omap_detect_sram(void)
{
	omap_sram_skip = SRAM_BOOTLOADER_SZ;
	if (is_sram_locked()) {
		if (cpu_is_omap34xx()) {
			omap_sram_start = OMAP3_SRAM_PUB_PA;
			if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||
			    (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {
				omap_sram_size = 0x7000; /* 28K */
				omap_sram_skip += SZ_16K;
			} else {
				omap_sram_size = 0x8000; /* 32K */
			}
		} else if (cpu_is_omap44xx()) {
			omap_sram_start = OMAP4_SRAM_PUB_PA;
			omap_sram_size = 0xa000; /* 40K */
		} else if (soc_is_omap54xx()) {
			omap_sram_start = OMAP5_SRAM_PA;
			omap_sram_size = SZ_128K; /* 128KB */
		} else {
			omap_sram_start = OMAP2_SRAM_PUB_PA;
			omap_sram_size = 0x800; /* 2K */
		}
	} else {
		if (soc_is_am33xx()) {
			omap_sram_start = AM33XX_SRAM_PA;
			omap_sram_size = 0x10000; /* 64K */
		} else if (soc_is_am43xx()) {
			omap_sram_start = AM33XX_SRAM_PA;
			omap_sram_size = SZ_64K;
		} else if (cpu_is_omap34xx()) {
			omap_sram_start = OMAP3_SRAM_PA;
			omap_sram_size = 0x10000; /* 64K */
		} else if (cpu_is_omap44xx()) {
			omap_sram_start = OMAP4_SRAM_PA;
			omap_sram_size = 0xe000; /* 56K */
		} else if (soc_is_omap54xx()) {
			omap_sram_start = OMAP5_SRAM_PA;
			omap_sram_size = SZ_128K; /* 128KB */
		} else {
			omap_sram_start = OMAP2_SRAM_PA;
			if (cpu_is_omap242x())
				omap_sram_size = 0xa0000; /* 640K */
			else if (cpu_is_omap243x())
				omap_sram_size = 0x10000; /* 64K */
		}
	}
}
예제 #2
0
static int __init omap4_l3_init(void)
{
    int i;
    struct omap_hwmod *oh[3];
    struct platform_device *pdev;
    char oh_name[L3_MODULES_MAX_LEN];

    /* If dtb is there, the devices will be created dynamically */
    if (of_have_populated_dt())
        return -ENODEV;

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

    for (i = 0; i < L3_MODULES; i++) {
        snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main_%d", i+1);

        oh[i] = omap_hwmod_lookup(oh_name);
        if (!(oh[i]))
            pr_err("could not look up %s\n", oh_name);
    }

    pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 0);

    WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);

    return PTR_RET(pdev);
}
예제 #3
0
파일: omap-smp.c 프로젝트: 020gzh/linux
static void omap4_secondary_init(unsigned int cpu)
{
	/*
	 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
	 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
	 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
	 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
	 * OMAP443X GP devices- SMP bit isn't accessible.
	 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
	 */
	if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
		omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
							4, 0, 0, 0, 0, 0);

	/*
	 * Configure the CNTFRQ register for the secondary cpu's which
	 * indicates the frequency of the cpu local timers.
	 */
	if (soc_is_omap54xx() || soc_is_dra7xx())
		set_cntfreq();

	/*
	 * Synchronise with the boot thread.
	 */
	spin_lock(&boot_lock);
	spin_unlock(&boot_lock);
}
예제 #4
0
void omap4_prminst_global_warm_sw_reset(void)
{
    u32 v;
    s16 dev_inst;

    if (cpu_is_omap44xx())
        dev_inst = OMAP4430_PRM_DEVICE_INST;
    else if (soc_is_omap54xx())
        dev_inst = OMAP54XX_PRM_DEVICE_INST;
    else if (soc_is_dra7xx())
        dev_inst = DRA7XX_PRM_DEVICE_INST;
    else if (soc_is_am43xx())
        dev_inst = AM43XX_PRM_DEVICE_INST;
    else
        return;

    v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst,
                                    OMAP4_PRM_RSTCTRL_OFFSET);
    v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
    omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
                                 dev_inst,
                                 OMAP4_PRM_RSTCTRL_OFFSET);

    /* OCP barrier */
    v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
                                    dev_inst,
                                    OMAP4_PRM_RSTCTRL_OFFSET);
}
예제 #5
0
static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
{
	/* platforms which support all ECC schemes */
	if (soc_is_am33xx() || soc_is_am43xx() || cpu_is_omap44xx() ||
		 soc_is_omap54xx() || soc_is_dra7xx())
		return 1;

	if (ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW ||
		 ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) {
		if (cpu_is_omap24xx())
			return 0;
		else if (cpu_is_omap3630() && (GET_OMAP_REVISION() == 0))
			return 0;
		else
			return 1;
	}

	/* OMAP3xxx do not have ELM engine, so cannot support ECC schemes
	 * which require H/W based ECC error detection */
	if ((cpu_is_omap34xx() || cpu_is_omap3630()) &&
	    ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
		 (ecc_opt == OMAP_ECC_BCH8_CODE_HW)))
		return 0;

	/* legacy platforms support only HAM1 (1-bit Hamming) ECC scheme */
	if (ecc_opt == OMAP_ECC_HAM1_CODE_HW ||
	    ecc_opt == OMAP_ECC_HAM1_CODE_SW)
		return 1;
	else
		return 0;
}
예제 #6
0
/*
 * Save WakeupGen interrupt context in SAR BANK3. Restore is done by
 * ROM code. WakeupGen IP is integrated along with GIC to manage the
 * interrupt wakeups from CPU low power states. It manages
 * masking/unmasking of Shared peripheral interrupts(SPI). So the
 * interrupt enable/disable control should be in sync and consistent
 * at WakeupGen and GIC so that interrupts are not lost.
 */
static void irq_save_context(void)
{
	if (!sar_base)
		sar_base = omap4_get_sar_ram_base();

	if (soc_is_omap54xx())
		omap5_irq_save_context();
	else
		omap4_irq_save_context();
}
예제 #7
0
/*
 * Clear WakeupGen SAR backup status.
 */
static void irq_sar_clear(void)
{
	u32 val;
	u32 offset = SAR_BACKUP_STATUS_OFFSET;

	if (soc_is_omap54xx())
		offset = OMAP5_SAR_BACKUP_STATUS_OFFSET;

	val = __raw_readl(sar_base + offset);
	val &= ~SAR_BACKUP_STATUS_WAKEUPGEN;
	__raw_writel(val, sar_base + offset);
}
예제 #8
0
/**
 * omap_ctrl_write_dsp_boot_addr - set boot address for a remote processor
 * @bootaddr: physical address of the boot loader
 *
 * Set boot address for the boot loader of a supported processor
 * when a power ON sequence occurs.
 */
void omap_ctrl_write_dsp_boot_addr(u32 bootaddr)
{
	u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTADDR :
		     cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTADDR :
		     cpu_is_omap44xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
		     soc_is_omap54xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
		     0;

	if (!offset) {
		pr_err("%s: unsupported omap type\n", __func__);
		return;
	}

	omap_ctrl_writel(bootaddr, offset);
}
예제 #9
0
파일: clock.c 프로젝트: 383530895/linux
/**
 * ti_clk_init_features - init clock features struct for the SoC
 *
 * Initializes the clock features struct based on the SoC type.
 */
void __init ti_clk_init_features(void)
{
	/* Fint setup for DPLLs */
	if (cpu_is_omap3430()) {
		ti_clk_features.fint_min = OMAP3430_DPLL_FINT_BAND1_MIN;
		ti_clk_features.fint_max = OMAP3430_DPLL_FINT_BAND2_MAX;
		ti_clk_features.fint_band1_max = OMAP3430_DPLL_FINT_BAND1_MAX;
		ti_clk_features.fint_band2_min = OMAP3430_DPLL_FINT_BAND2_MIN;
	} else {
		ti_clk_features.fint_min = OMAP3PLUS_DPLL_FINT_MIN;
		ti_clk_features.fint_max = OMAP3PLUS_DPLL_FINT_MAX;
	}

	/* Bypass value setup for DPLLs */
	if (cpu_is_omap24xx()) {
		ti_clk_features.dpll_bypass_vals |=
			(1 << OMAP2XXX_EN_DPLL_LPBYPASS) |
			(1 << OMAP2XXX_EN_DPLL_FRBYPASS);
	} else if (cpu_is_omap34xx()) {
		ti_clk_features.dpll_bypass_vals |=
			(1 << OMAP3XXX_EN_DPLL_LPBYPASS) |
			(1 << OMAP3XXX_EN_DPLL_FRBYPASS);
	} else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx() ||
		   soc_is_omap54xx() || soc_is_dra7xx()) {
		ti_clk_features.dpll_bypass_vals |=
			(1 << OMAP4XXX_EN_DPLL_LPBYPASS) |
			(1 << OMAP4XXX_EN_DPLL_FRBYPASS) |
			(1 << OMAP4XXX_EN_DPLL_MNBYPASS);
	}

	/* Jitter correction only available on OMAP343X */
	if (cpu_is_omap343x())
		ti_clk_features.flags |= TI_CLK_DPLL_HAS_FREQSEL;

	/* Idlest value for interface clocks.
	 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
	 * 34xx reverses this, just to keep us on our toes
	 * AM35xx uses both, depending on the module.
	 */
	if (cpu_is_omap24xx())
		ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL;
	else if (cpu_is_omap34xx())
		ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL;

	/* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */
	if (omap_rev() == OMAP3430_REV_ES1_0)
		ti_clk_features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM;
}
예제 #10
0
파일: prcm.c 프로젝트: mozzwald/linux-2.6
void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
{
    if (omap2_globals->prm)
        prm_base = omap2_globals->prm;
    if (omap2_globals->cm)
        cm_base = omap2_globals->cm;
    if (omap2_globals->cm2)
        cm2_base = omap2_globals->cm2;
    if (omap2_globals->prcm_mpu)
        prcm_mpu_base = omap2_globals->prcm_mpu;

    if (cpu_is_omap44xx() || soc_is_omap54xx()) {
        omap_prm_base_init();
        omap_cm_base_init();
    }
}
예제 #11
0
파일: prminst44xx.c 프로젝트: 21cnbao/linux
s32 omap4_prmst_get_prm_dev_inst(void)
{
	if (prm_dev_inst != PRM_INSTANCE_UNKNOWN)
		return prm_dev_inst;

	/* This cannot be done way early at boot.. as things are not setup */
	if (cpu_is_omap44xx())
		prm_dev_inst = OMAP4430_PRM_DEVICE_INST;
	else if (soc_is_omap54xx())
		prm_dev_inst = OMAP54XX_PRM_DEVICE_INST;
	else if (soc_is_dra7xx())
		prm_dev_inst = DRA7XX_PRM_DEVICE_INST;
	else if (soc_is_am43xx())
		prm_dev_inst = AM43XX_PRM_DEVICE_INST;

	return prm_dev_inst;
}
예제 #12
0
파일: id.c 프로젝트: 01org/KVMGT-kernel
int omap_type(void)
{
	u32 val = 0;

	if (cpu_is_omap24xx()) {
		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
	} else if (soc_is_am33xx() || soc_is_am43xx()) {
		val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
	} else if (cpu_is_omap34xx()) {
		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
	} else if (cpu_is_omap44xx()) {
		val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
	} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
		val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS);
		val &= OMAP5_DEVICETYPE_MASK;
		val >>= 6;
		goto out;
	} else {
예제 #13
0
파일: id.c 프로젝트: 1059232202/linux
int omap_type(void)
{
	static u32 val = OMAP2_DEVICETYPE_MASK;

	if (val < OMAP2_DEVICETYPE_MASK)
		return val;

	if (soc_is_omap24xx()) {
		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
	} else if (soc_is_ti81xx()) {
		val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
	} else if (soc_is_am33xx() || soc_is_am43xx()) {
		val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
	} else if (soc_is_omap34xx()) {
		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
	} else if (soc_is_omap44xx()) {
		val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
	} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
		val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS);
		val &= OMAP5_DEVICETYPE_MASK;
		val >>= 6;
		goto out;
	} else {
예제 #14
0
static void __init irq_pm_init(void)
{
	/* FIXME: Remove this when MPU OSWR support is added */
	if (!soc_is_omap54xx())
		cpu_pm_register_notifier(&irq_notifier_block);
}
예제 #15
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;
}