int am33xx_cpsw_init(enum am33xx_cpsw_mac_mode mode, unsigned char *phy_id0,
		     unsigned char *phy_id1)
{
	struct omap_hwmod *oh;
	struct platform_device *pdev;
	u32 mac_lo, mac_hi, gmii_sel;
	u32 i;

	mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_LO);
	mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_HI);
	am33xx_cpsw_slaves[0].mac_addr[0] = mac_hi & 0xFF;
	am33xx_cpsw_slaves[0].mac_addr[1] = (mac_hi & 0xFF00) >> 8;
	am33xx_cpsw_slaves[0].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
	am33xx_cpsw_slaves[0].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
	am33xx_cpsw_slaves[0].mac_addr[4] = mac_lo & 0xFF;
	am33xx_cpsw_slaves[0].mac_addr[5] = (mac_lo & 0xFF00) >> 8;

	/* Read MACID0 from eeprom if eFuse MACID is invalid */
	if (!is_valid_ether_addr(am33xx_cpsw_slaves[0].mac_addr)) {
		for (i = 0; i < ETH_ALEN; i++)
			am33xx_cpsw_slaves[0].mac_addr[i] = am33xx_macid0[i];
	}

	mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_LO);
	mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_HI);
	am33xx_cpsw_slaves[1].mac_addr[0] = mac_hi & 0xFF;
	am33xx_cpsw_slaves[1].mac_addr[1] = (mac_hi & 0xFF00) >> 8;
	am33xx_cpsw_slaves[1].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
	am33xx_cpsw_slaves[1].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
	am33xx_cpsw_slaves[1].mac_addr[4] = mac_lo & 0xFF;
	am33xx_cpsw_slaves[1].mac_addr[5] = (mac_lo & 0xFF00) >> 8;

	/* Read MACID1 from eeprom if eFuse MACID is invalid */
	if (!is_valid_ether_addr(am33xx_cpsw_slaves[1].mac_addr)) {
		for (i = 0; i < ETH_ALEN; i++)
			am33xx_cpsw_slaves[1].mac_addr[i] = am33xx_macid1[i];
	}

	switch (mode) {
	case AM33XX_CPSW_MODE_MII:
		gmii_sel = AM33XX_MII_MODE_EN;
		break;
	case AM33XX_CPSW_MODE_RMII:
		gmii_sel = AM33XX_RMII_MODE_EN;
		break;
	case AM33XX_CPSW_MODE_RGMII:
		gmii_sel = AM33XX_RGMII_MODE_EN;
		break;
	case CALIXTO_EVM_ETHERNET_INTERFACE:
		gmii_sel = CALIXTO_EVM_ETHERNET_MODE_EN;
		break;
	default:
		return -EINVAL;
	}

	writel(gmii_sel, AM33XX_CTRL_REGADDR(AM33XX_CONTROL_GMII_SEL_OFFSET));

	if (phy_id0 != NULL)
		am33xx_cpsw_slaves[0].phy_id = phy_id0;

	if (phy_id1 != NULL)
		am33xx_cpsw_slaves[1].phy_id = phy_id1;

	memcpy(am33xx_cpsw_pdata.mac_addr,
			am33xx_cpsw_slaves[0].mac_addr, ETH_ALEN);

	oh = omap_hwmod_lookup("mdio");
	if (!oh) {
		pr_err("could not find cpgmac0 hwmod data\n");
		return -ENODEV;
	}

	pdev = omap_device_build("davinci_mdio", 0, oh, &am33xx_cpsw_mdiopdata,
			sizeof(am33xx_cpsw_mdiopdata), NULL, 0, 0);
	if (IS_ERR(pdev))
		pr_err("could not build omap_device for cpsw\n");

	oh = omap_hwmod_lookup("cpgmac0");
	if (!oh) {
		pr_err("could not find cpgmac0 hwmod data\n");
		return -ENODEV;
	}

	pdev = omap_device_build("cpsw", -1, oh, &am33xx_cpsw_pdata,
			sizeof(am33xx_cpsw_pdata), NULL, 0, 0);
	if (IS_ERR(pdev))
		pr_err("could not build omap_device for cpsw\n");

	return 0;
}
/* Read EFUSE values from control registers for OMAP3430 */
static void __init sr_read_efuse(struct omap_sr_dev_data *dev_data,
				struct omap_sr_data *sr_data)
{
	int i;
	void __iomem *ctrl_base;

	if (!dev_data) {
		pr_warning(" Bad parameters! dev_data NULL!\n");
		return;
	}

	if (!dev_data->volts_supported || !dev_data->volt_data ||
			!dev_data->efuse_nvalues_offs) {
		pr_warning("%s: Bad parameters! dev_data = %x,"
			"dev_data->volts_supported = %x,"
			"dev_data->volt_data = %x,"
			"dev_data->efuse_nvalues_offs = %x\n", __func__,
			(unsigned int)dev_data, dev_data->volts_supported,
			(unsigned int)dev_data->volt_data,
			(unsigned int)dev_data->efuse_nvalues_offs);
		return;
	}

	/*
	 * From OMAP3630 onwards there are no efuse registers for senn_mod
	 * and senp_mod. They have to be 0x1 by default.
	 */
	if (!dev_data->efuse_sr_control) {
		sr_data->senn_mod = 0x1;
		sr_data->senp_mod = 0x1;
	} else {
		sr_data->senn_mod =
				((omap_ctrl_readl(dev_data->efuse_sr_control) &
				(0x3 << dev_data->sennenable_shift)) >>
				dev_data->sennenable_shift);
		sr_data->senp_mod =
				((omap_ctrl_readl(dev_data->efuse_sr_control) &
				(0x3 << dev_data->senpenable_shift)) >>
				dev_data->senpenable_shift);
	}

	if (cpu_is_omap44xx())
		ctrl_base =  ioremap(0x4A002000, SZ_1K);

	for (i = 0; i < dev_data->volts_supported; i++) {
		if (cpu_is_omap44xx()) {
			u16 offset = dev_data->efuse_nvalues_offs[i];

			dev_data->volt_data[i].sr_nvalue =
				__raw_readb(ctrl_base + offset) |
				__raw_readb(ctrl_base + offset + 1) << 8 |
				__raw_readb(ctrl_base + offset + 2) << 16;
		} else {
#ifdef CONFIG_SAMSUNG_LATONA_OPP5_ENABLED
			if (i == 4) {
				// The Latona board does not have an eFuse for OPP5.
				// We have to calculate a rough approximation of the nValue for this OPP.
				dev_data->volt_data[i].sr_nvalue = cal_opp5_nvalue(2025, 1750);
			} else {
				dev_data->volt_data[i].sr_nvalue = omap_ctrl_readl(
					dev_data->efuse_nvalues_offs[i]);
			}
#else
			dev_data->volt_data[i].sr_nvalue = omap_ctrl_readl(
				dev_data->efuse_nvalues_offs[i]);
#endif

#ifdef CONFIG_SAMSUNG_KERNEL_DEBUG_USER
			printk("%s: dom %s[%d]: using eFUSE ntarget 0x%08X\n",
					__func__,
					dev_data->vdd_name, i,
					dev_data->volt_data[i].sr_nvalue);
#endif
		}
	}
	if (cpu_is_omap44xx())
		iounmap(ctrl_base);
}
Example #3
0
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
			int controller_nr)
{
	if ((mmc_controller->slots[0].switch_pin > 0) && \
		(mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
		omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
					OMAP_PIN_INPUT_PULLUP);
	if ((mmc_controller->slots[0].gpio_wp > 0) && \
		(mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
		omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
					OMAP_PIN_INPUT_PULLUP);

	if (cpu_is_omap2420() && controller_nr == 0) {
		omap_cfg_reg(H18_24XX_MMC_CMD);
		omap_cfg_reg(H15_24XX_MMC_CLKI);
		omap_cfg_reg(G19_24XX_MMC_CLKO);
		omap_cfg_reg(F20_24XX_MMC_DAT0);
		omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
		omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
		if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
			omap_cfg_reg(H14_24XX_MMC_DAT1);
			omap_cfg_reg(E19_24XX_MMC_DAT2);
			omap_cfg_reg(D19_24XX_MMC_DAT3);
			omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
			omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
			omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
		}

		/*
		 * Use internal loop-back in MMC/SDIO Module Input Clock
		 * selection
		 */
		if (mmc_controller->slots[0].internal_clock) {
			u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
			v |= (1 << 24);
			omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
		}
	}

	if (cpu_is_omap34xx()) {
		if (controller_nr == 0) {
			omap_mux_init_signal("sdmmc1_clk",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc1_cmd",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc1_dat0",
				OMAP_PIN_INPUT_PULLUP);
			if (mmc_controller->slots[0].caps &
				(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
				omap_mux_init_signal("sdmmc1_dat1",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat2",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat3",
					OMAP_PIN_INPUT_PULLUP);
			}
			if (mmc_controller->slots[0].caps &
						MMC_CAP_8_BIT_DATA) {
				omap_mux_init_signal("sdmmc1_dat4",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat5",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat6",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat7",
					OMAP_PIN_INPUT_PULLUP);
			}
		}
		if (controller_nr == 1) {
			/* MMC2 */
			omap_mux_init_signal("sdmmc2_clk",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc2_cmd",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc2_dat0",
				OMAP_PIN_INPUT_PULLUP);

			/*
			 * For 8 wire configurations, lines DAT4, 5, 6 and 7
			 * need to be muxed in the board-*.c files
			 */
			if (mmc_controller->slots[0].caps &
				(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
				omap_mux_init_signal("sdmmc2_dat1",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat2",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat3",
					OMAP_PIN_INPUT_PULLUP);
			}
			if (mmc_controller->slots[0].caps &
							MMC_CAP_8_BIT_DATA) {
				omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7",
					OMAP_PIN_INPUT_PULLUP);
			}
		}

		/*
		 * For MMC3 the pins need to be muxed in the board-*.c files
		 */
	}
}
Example #4
0
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
			int controller_nr)
{
	if (cpu_is_omap2420() && controller_nr == 0) {
		omap_cfg_reg(H18_24XX_MMC_CMD);
		omap_cfg_reg(H15_24XX_MMC_CLKI);
		omap_cfg_reg(G19_24XX_MMC_CLKO);
		omap_cfg_reg(F20_24XX_MMC_DAT0);
		omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
		omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
		if (mmc_controller->slots[0].wires == 4) {
			omap_cfg_reg(H14_24XX_MMC_DAT1);
			omap_cfg_reg(E19_24XX_MMC_DAT2);
			omap_cfg_reg(D19_24XX_MMC_DAT3);
			omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
			omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
			omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
		}

		/*
		 * Use internal loop-back in MMC/SDIO Module Input Clock
		 * selection
		 */
		if (mmc_controller->slots[0].internal_clock) {
			u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
			v |= (1 << 24);
			omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
		}
	}

	if (cpu_is_omap3430()) {
		if (controller_nr == 0) {
			omap_cfg_reg(N28_3430_MMC1_CLK);
			omap_cfg_reg(M27_3430_MMC1_CMD);
			omap_cfg_reg(N27_3430_MMC1_DAT0);
			if (mmc_controller->slots[0].wires == 4 ||
				mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(N26_3430_MMC1_DAT1);
				omap_cfg_reg(N25_3430_MMC1_DAT2);
				omap_cfg_reg(P28_3430_MMC1_DAT3);
			}
			if (mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(P27_3430_MMC1_DAT4);
				omap_cfg_reg(P26_3430_MMC1_DAT5);
				omap_cfg_reg(R27_3430_MMC1_DAT6);
				omap_cfg_reg(R25_3430_MMC1_DAT7);
			}
		}
		if (controller_nr == 1) {
			/* MMC2 */
			omap_cfg_reg(AE2_3430_MMC2_CLK);
			omap_cfg_reg(AG5_3430_MMC2_CMD);
			omap_cfg_reg(AH5_3430_MMC2_DAT0);

			/*
			 * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
			 * in the board-*.c files
			 */
			if (mmc_controller->slots[0].wires == 4 ||
				mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(AH4_3430_MMC2_DAT1);
				omap_cfg_reg(AG4_3430_MMC2_DAT2);
				omap_cfg_reg(AF4_3430_MMC2_DAT3);
			}
		}

		/*
		 * For MMC3 the pins need to be muxed in the board-*.c files
		 */
	}
}
Example #5
0
/*
 * The realtime counter also called master counter, is a free-running
 * counter, which is related to real time. It produces the count used
 * by the CPU local timer peripherals in the MPU cluster. The timer counts
 * at a rate of 6.144 MHz. Because the device operates on different clocks
 * in different power modes, the master counter shifts operation between
 * clocks, adjusting the increment per clock in hardware accordingly to
 * maintain a constant count rate.
 */
static void __init realtime_counter_init(void)
{
	void __iomem *base;
	static struct clk *sys_clk;
	unsigned long rate;
	unsigned int reg;
	unsigned long long num, den;

	base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
	if (!base) {
		pr_err("%s: ioremap failed\n", __func__);
		return;
	}
	sys_clk = clk_get(NULL, "sys_clkin");
	if (IS_ERR(sys_clk)) {
		pr_err("%s: failed to get system clock handle\n", __func__);
		iounmap(base);
		return;
	}

	rate = clk_get_rate(sys_clk);

	if (soc_is_dra7xx()) {
		/*
		 * Errata i856 says the 32.768KHz crystal does not start at
		 * power on, so the CPU falls back to an emulated 32KHz clock
		 * based on sysclk / 610 instead. This causes the master counter
		 * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2
		 * (OR sysclk * 75 / 244)
		 *
		 * This affects at least the DRA7/AM572x 1.0, 1.1 revisions.
		 * Of course any board built without a populated 32.768KHz
		 * crystal would also need this fix even if the CPU is fixed
		 * later.
		 *
		 * Either case can be detected by using the two speedselect bits
		 * If they are not 0, then the 32.768KHz clock driving the
		 * coarse counter that corrects the fine counter every time it
		 * ticks is actually rate/610 rather than 32.768KHz and we
		 * should compensate to avoid the 570ppm (at 20MHz, much worse
		 * at other rates) too fast system time.
		 */
		reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP);
		if (reg & DRA7_SPEEDSELECT_MASK) {
			num = 75;
			den = 244;
			goto sysclk1_based;
		}
	}

	/* Numerator/denumerator values refer TRM Realtime Counter section */
	switch (rate) {
	case 12000000:
		num = 64;
		den = 125;
		break;
	case 13000000:
		num = 768;
		den = 1625;
		break;
	case 19200000:
		num = 8;
		den = 25;
		break;
	case 20000000:
		num = 192;
		den = 625;
		break;
	case 26000000:
		num = 384;
		den = 1625;
		break;
	case 27000000:
		num = 256;
		den = 1125;
		break;
	case 38400000:
	default:
		/* Program it for 38.4 MHz */
		num = 4;
		den = 25;
		break;
	}

sysclk1_based:
	/* Program numerator and denumerator registers */
	reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
			NUMERATOR_DENUMERATOR_MASK;
	reg |= num;
	__raw_writel(reg, base + INCREMENTER_NUMERATOR_OFFSET);

	reg = __raw_readl(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) &
			NUMERATOR_DENUMERATOR_MASK;
	reg |= den;
	__raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);

	arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den);
	set_cntfreq();

	iounmap(base);
}
Example #6
0
/**
 * omap_ldo_abb_init() - initialize the ABB LDO for associated for this domain
 * @voltdm:	voltdm for which we need to initialize the ABB LDO
 *
 * Programs up the the configurations that dont change in the domain
 *
 * Return 0 if all goes fine, else returns appropriate error value
 */
void __init omap_ldo_abb_init(struct voltagedomain *voltdm)
{
	u32 sys_clk_rate;
	u32 cycle_rate;
	u32 settling_time;
	u32 wait_count_val;
	u32 reg, trim, rbb;
	struct omap_ldo_abb_instance *abb;
	struct omap_volt_data *volt_data;

	if (IS_ERR_OR_NULL(voltdm)) {
		pr_err("%s: No voltdm?\n", __func__);
		return;
	}
	if (!voltdm->read || !voltdm->write || !voltdm->rmw) {
		pr_err("%s: No read/write/rmw API for accessing vdd_%s regs\n",
		       __func__, voltdm->name);
		return;
	}

	abb = voltdm->abb;
	if (IS_ERR_OR_NULL(abb))
		return;
	if (IS_ERR_OR_NULL(abb->ctrl_bits) || IS_ERR_OR_NULL(abb->setup_bits)) {
		pr_err("%s: Corrupted ABB configuration on vdd_%s regs\n",
		       __func__, voltdm->name);
		return;
	}

	/*
	 * SR2_WTCNT_VALUE must be programmed with the expected settling time
	 * for ABB ldo transition.  This value depends on the cycle rate for
	 * the ABB IP (varies per OMAP family), and the system clock frequency
	 * (varies per board).  The formula is:
	 *
	 * SR2_WTCNT_VALUE = SettlingTime / (CycleRate / SystemClkRate))
	 * where SettlingTime is in micro-seconds and SystemClkRate is in MHz.
	 *
	 * To avoid dividing by zero multiply both CycleRate and SettlingTime
	 * by 10 such that the final result is the one we want.
	 */

	/* Convert SYS_CLK rate to MHz & prevent divide by zero */
	sys_clk_rate = DIV_ROUND_CLOSEST(voltdm->sys_clk.rate, 1000000);
	cycle_rate = abb->cycle_rate * 10;
	settling_time = abb->settling_time * 10;

	/* Calculate cycle rate */
	cycle_rate = DIV_ROUND_CLOSEST(cycle_rate, sys_clk_rate);

	/* Calulate SR2_WTCNT_VALUE */
	wait_count_val = DIV_ROUND_CLOSEST(settling_time, cycle_rate);

	voltdm->rmw(abb->setup_bits->wait_count_mask,
		    wait_count_val << __ffs(abb->setup_bits->wait_count_mask),
		    abb->setup_reg);

	/*
	 * Determine MPU ABB state at OPP_TURBO on 4460
	 *
	 * On 4460 all OPPs have preset states for the MPU's ABB LDO, except
	 * for OPP_TURBO.  OPP_TURBO may require bypass, FBB or RBB depending
	 * on a combination of characterisation data blown into eFuse register
	 * CONTROL_STD_FUSE_OPP_DPLL_1.
	 *
	 * Bits 18 & 19 of that register signify DPLL_MPU trim (see
	 * arch/arm/mach-omap2/omap4-trim-quirks.c).  OPP_TURBO might put MPU's
	 * ABB LDO into bypass or FBB based on this value.
	 *
	 * Bit 20 siginifies if RBB should be enabled.  If set it will always
	 * override the values from bits 18 & 19.
	 *
	 * The table below captures the valid combinations:
	 *
	 * Bit 18|Bit 19|Bit 20|ABB type
	 * 0	  0	 0	bypass
	 * 0	  1	 0	bypass	(invalid combo)
	 * 1	  0	 0	FBB	(2.4GHz DPLL_MPU)
	 * 1	  1	 0	FBB	(3GHz DPLL_MPU)
	 * 0	  0	 1	RBB
	 * 0	  1	 1	RBB	(invalid combo)
	 * 1	  0	 1	RBB	(2.4GHz DPLL_MPU)
	 * 1	  1	 1	RBB	(3GHz DPLL_MPU)
	 */
	if (cpu_is_omap446x() && !strcmp("mpu", voltdm->name)) {
		/* read eFuse register here */
		reg = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_1);
		trim = reg & OMAP4460_MPU_OPP_DPLL_TRIM;
		rbb = reg & OMAP4460_MPU_OPP_DPLL_TURBO_RBB;

		volt_data = omap_voltage_get_voltdata(voltdm,
				OMAP4460_VDD_MPU_OPPTURBO_UV);

		/* OPP_TURBO is FAST_OPP (FBB) by default */
		if (rbb)
			volt_data->abb_type = OMAP_ABB_SLOW_OPP;
		else if (!trim)
			volt_data->abb_type = OMAP_ABB_NOMINAL_OPP;

	}
	/* Enable ABB */
	_abb_set_availability(voltdm, abb, true);

	/*
	 * Beware of the bootloader!
	 * Initialize current abb type based on what we read off the reg.
	 * we cant trust the initial state based off boot voltage's volt_data
	 * even. Not all bootloaders are nice :(
	 */
	abb->__cur_abb_type = (voltdm->read(abb->ctrl_reg) &
			       abb->ctrl_bits->opp_sel_mask) >>
				    __ffs(abb->ctrl_bits->opp_sel_mask);

	return;
}
static unsigned long omap_temp_sensor_readl(struct omap_temp_sensor
					    *temp_sensor, u32 reg)
{
	return omap_ctrl_readl(temp_sensor->phy_base + reg);
}
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
			int controller_nr)
{
	if ((mmc_controller->slots[0].switch_pin > 0) && \
		(mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
		omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
					OMAP_PIN_INPUT_PULLUP);
	if ((mmc_controller->slots[0].gpio_wp > 0) && \
		(mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
		omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
					OMAP_PIN_INPUT_PULLUP);

	if (cpu_is_omap2420() && controller_nr == 0) {
		omap_mux_init_signal("sdmmc_cmd", 0);
		omap_mux_init_signal("sdmmc_clki", 0);
		omap_mux_init_signal("sdmmc_clko", 0);
		omap_mux_init_signal("sdmmc_dat0", 0);
		omap_mux_init_signal("sdmmc_dat_dir0", 0);
		omap_mux_init_signal("sdmmc_cmd_dir", 0);
		if (mmc_controller->slots[0].wires == 4) {
			omap_mux_init_signal("sdmmc_dat1", 0);
			omap_mux_init_signal("sdmmc_dat2", 0);
			omap_mux_init_signal("sdmmc_dat3", 0);
			omap_mux_init_signal("sdmmc_dat_dir1", 0);
			omap_mux_init_signal("sdmmc_dat_dir2", 0);
			omap_mux_init_signal("sdmmc_dat_dir3", 0);
		}

		/*
		 * Use internal loop-back in MMC/SDIO Module Input Clock
		 * selection
		 */
		if (mmc_controller->slots[0].internal_clock) {
			u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
			v |= (1 << 24);
			omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
		}
	}

	if (cpu_is_omap34xx()) {
		if (controller_nr == 0) {
			omap_mux_init_signal("sdmmc1_clk",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc1_cmd",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc1_dat0",
				OMAP_PIN_INPUT_PULLUP);
			if (mmc_controller->slots[0].wires == 4 ||
				mmc_controller->slots[0].wires == 8) {
				omap_mux_init_signal("sdmmc1_dat1",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat2",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat3",
					OMAP_PIN_INPUT_PULLUP);
			}
			if (mmc_controller->slots[0].wires == 8) {
				omap_mux_init_signal("sdmmc1_dat4",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat5",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat6",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc1_dat7",
					OMAP_PIN_INPUT_PULLUP);
			}
		}
		if (controller_nr == 1) {
			/* MMC2 */
			omap_mux_init_signal("sdmmc2_clk",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc2_cmd",
				OMAP_PIN_INPUT_PULLUP);
			omap_mux_init_signal("sdmmc2_dat0",
				OMAP_PIN_INPUT_PULLUP);

			/*
			 * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
			 * in the board-*.c files
			 */
			if (mmc_controller->slots[0].wires == 4 ||
				mmc_controller->slots[0].wires == 8) {
				omap_mux_init_signal("sdmmc2_dat1",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat2",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat3",
					OMAP_PIN_INPUT_PULLUP);
			}
			if (mmc_controller->slots[0].wires == 8) {
				omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6",
					OMAP_PIN_INPUT_PULLUP);
				omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7",
					OMAP_PIN_INPUT_PULLUP);
			}
		}

		/*
		 * For MMC3 the pins need to be muxed in the board-*.c files
		 */
	}
}
static __init int omap4_ldo_trim_init(void)
{
	u32 bgap_trimmed = 0;

	/* Applicable only for OMAP4 */
	if (!cpu_is_omap44xx())
		return 0;

	/*
	 * Some ES2.2 efuse  values for BGAP and SLDO trim
	 * are not programmed. For these units
	 * 1. we can set overide mode for SLDO trim,
	 * and program the max multiplication factor, to ensure
	 * high enough voltage on SLDO output.
	 * 2. trim VDAC value for TV output as per recomendation
	 */
	if (omap_rev() >= CHIP_IS_OMAP4430ES2_2)
		bgap_trimmed = omap_ctrl_readl(
			OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP);

	bgap_trimmed &= OMAP4_STD_FUSE_OPP_BGAP_MASK_LSB;

	/* if not trimmed, we set force overide, insted of efuse. */
	if (!bgap_trimmed)
		bgap_trim_sw_overide = true;

	/* LGE_SJIT 2012-01-13 [[email protected]]
	 * wrong works on iFF rev_b, so temporarily blocked
	 */
#ifdef CONFIG_MACH_LGE_IFF
	/* If not already trimmed, use s/w override */
	if (system_rev > 2 && cpu_is_omap446x())
		omap4460_mpu_dpll_trim_override();
#else
	/* If not already trimmed, use s/w override */
	if (cpu_is_omap446x())
		omap4460_mpu_dpll_trim_override();
#endif

	/*
	 * Errata i684 (revision B)
	 * Impacts all OMAP4430ESx.y trimmed and untrimmed excluding units
	 * with with ProdID[51:50]=11
	 * OMAP4460/70 are not impacted.
	 *
	 * ProdID:
	 * 51 50
	 * 0  0  Incorrect trim, SW WA needed.
	 * 0  1  Fixed test program issue of overlapping of LPDDR & SmartIO
	 *	 efuse fields, SW WA needed for LPDDR.
	 * 1  1  New LPDDR trim formula to compensate for vertical vs horizontal
	 *	 cell layout.  No overwrite required.
	 */
	if (cpu_is_omap443x()) {
		u32 prod_id;

		prod_id = omap_ctrl_readl(
				OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1);
		prod_id &= OMAP4_PROD_ID_I684_MASK;
		if (prod_id != OMAP4_PROD_ID_I684_MASK)
			ddr_io_trim_override = true;
	}

	return omap4_ldo_trim_configure();
}
Example #10
0
static void sr_set_efuse_nvalues(struct omap_sr *sr)
{
	if (sr->srid == SR1) {
		if (cpu_is_omap3630()) {
			sr->senn_mod = sr->senp_mod = 0x1;

			sr->opp5_nvalue = sr1_opp[5] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP5_VDD1);
			if (sr->opp5_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP5 %x\n",
							sr->opp5_nvalue);
			} else {
				pr_info(KERN_INFO "SR: Nvalues not fused for"
							"1.2G, disabled\n");
			}

			sr->opp4_nvalue = sr1_opp[4] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP4_VDD1);
			if (sr->opp4_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP4 %x\n",
							sr->opp4_nvalue);
			} else {
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}

			sr->opp3_nvalue = sr1_opp[3] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP3_VDD1);
			if (sr->opp3_nvalue != 0) {
				pr_info("SR2:Fused Nvalues for VDD2OPP3 %d\n",
							sr->opp3_nvalue);
			} else {
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}
			sr->opp2_nvalue = sr1_opp[2] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP2_VDD1);
			if (sr->opp2_nvalue != 0) {
				pr_info("SR2:Fused Nvalues for VDD2OPP2 %d\n",
							sr->opp2_nvalue);
			} else {
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}
			sr->opp1_nvalue = sr1_opp[1] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP1_VDD1);
			if (sr->opp1_nvalue != 0) {
				pr_info("SR2:Fused Nvalues for VDD2OPP1 %d\n",
							sr->opp1_nvalue);
			} else {
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}

			if (sr_margin_steps || sr_margin_steps_1g)
				sr_add_margin_steps(sr);
		} else {
			sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
						OMAP343X_SR1_SENNENABLE_MASK) >>
						OMAP343X_SR1_SENNENABLE_SHIFT;
			sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
						OMAP343X_SR1_SENPENABLE_MASK) >>
						OMAP343X_SR1_SENPENABLE_SHIFT;

			sr->opp5_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP5_VDD1);
			if (sr->opp5_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP5 %x\n",
							sr->opp5_nvalue);
			} else {
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}
			sr->opp4_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP4_VDD1);
			sr->opp3_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP3_VDD1);
			sr->opp2_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP2_VDD1);
			sr->opp1_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP1_VDD1);
			if (sr->opp5_nvalue) {
				sr->opp6_nvalue = calculate_opp_nvalue(sr->opp5_nvalue,
				227, 379);
			}
		}
	} else if (sr->srid == SR2) {
Example #11
0
static void __init omap_init_mmc(void)
{
	const struct omap_mmc_config	*mmc_conf;
	const struct omap_mmc_conf	*mmc;

	/* NOTE:  assumes MMC was never (wrongly) enabled */
	mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
	if (!mmc_conf)
		return;

	/* block 1 is always available and has just one pinout option */
	mmc = &mmc_conf->mmc[0];

	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
		if (mmc->enabled)
			(void) platform_device_register(&mmc_omap_device1);

#if defined(CONFIG_ARCH_OMAP243X) || defined(CONFIG_ARCH_OMAP34XX)
		mmc = &mmc_conf->mmc[1];
		if (mmc->enabled)
			(void) platform_device_register(&mmc_omap_device2);
#endif

		return;
	}

	if (mmc->enabled) {
		if (cpu_is_omap24xx()) {
			omap_cfg_reg(H18_24XX_MMC_CMD);
			omap_cfg_reg(H15_24XX_MMC_CLKI);
			omap_cfg_reg(G19_24XX_MMC_CLKO);
			omap_cfg_reg(F20_24XX_MMC_DAT0);
			omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
			omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
		} else {
			omap_cfg_reg(MMC_CMD);
			omap_cfg_reg(MMC_CLK);
			omap_cfg_reg(MMC_DAT0);
			if (cpu_is_omap1710()) {
				omap_cfg_reg(M15_1710_MMC_CLKI);
				omap_cfg_reg(P19_1710_MMC_CMDDIR);
				omap_cfg_reg(P20_1710_MMC_DATDIR0);
			}
		}
		if (mmc->wire4) {
			if (cpu_is_omap24xx()) {
				omap_cfg_reg(H14_24XX_MMC_DAT1);
				omap_cfg_reg(E19_24XX_MMC_DAT2);
				omap_cfg_reg(D19_24XX_MMC_DAT3);
				omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
				omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
				omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
			} else {
				omap_cfg_reg(MMC_DAT1);
				/* NOTE:  DAT2 can be on W10 (here) or M15 */
				if (!mmc->nomux)
					omap_cfg_reg(MMC_DAT2);
				omap_cfg_reg(MMC_DAT3);
			}
		}
#if defined(CONFIG_ARCH_OMAP2420)
		if (mmc->internal_clock) {
			/*
			 * Use internal loop-back in MMC/SDIO
			 * Module Input Clock selection
			 */
#ifdef CONFIG_ARCH_OMAP24XX
			if (cpu_is_omap24xx()) {
				u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
				v |= (1 << 24); /* not used in 243x */
				omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
			}
#endif
		}
#endif
		mmc1_data.conf = *mmc;
		(void) platform_device_register(&mmc_omap_device1);
	}

#ifdef	CONFIG_ARCH_OMAP16XX
	/* block 2 is on newer chips, and has many pinout options */
	mmc = &mmc_conf->mmc[1];
	if (mmc->enabled) {
		if (!mmc->nomux) {
			omap_cfg_reg(Y8_1610_MMC2_CMD);
			omap_cfg_reg(Y10_1610_MMC2_CLK);
			omap_cfg_reg(R18_1610_MMC2_CLKIN);
			omap_cfg_reg(W8_1610_MMC2_DAT0);
			if (mmc->wire4) {
				omap_cfg_reg(V8_1610_MMC2_DAT1);
				omap_cfg_reg(W15_1610_MMC2_DAT2);
				omap_cfg_reg(R10_1610_MMC2_DAT3);
			}

			/* These are needed for the level shifter */
			omap_cfg_reg(V9_1610_MMC2_CMDDIR);
			omap_cfg_reg(V5_1610_MMC2_DATDIR0);
			omap_cfg_reg(W19_1610_MMC2_DATDIR1);
		}

		/* Feedback clock must be set on OMAP-1710 MMC2 */
		if (cpu_is_omap1710())
			omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
				     MOD_CONF_CTRL_1);
		mmc2_data.conf = *mmc;
		(void) platform_device_register(&mmc_omap_device2);
	}
#endif
	return;
}
static void sr_set_efuse_nvalues(struct omap_sr *sr)
{
	u32 senn_adj = 3.0*12.5;
	u32 senp_adj = 2.6*12.5;

	if (sr->srid == SR1) {
		if (cpu_is_omap3630()) {
			sr->senn_mod = sr->senp_mod = 0x1;

#if !(defined(CONFIG_MACH_OMAP3621_BOXER) ||\
	defined(CONFIG_MACH_OMAP3621_EVT1A) ||\
	defined(CONFIG_MACH_OMAP3621_EDP) ||\
	defined(CONFIG_MACH_OMAP3621_GOSSAMER))
			sr->opp5_nvalue = sr1_opp[5] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP5_VDD1);
			if (sr->opp5_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP5 %x\n",
							sr->opp5_nvalue);
			} else {
				pr_info(KERN_INFO "SR: Nvalues not fused for"
							"1.2G, disabled\n");
			}

			sr->opp4_nvalue = sr1_opp[4] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP4_VDD1);

			if (sr->opp4_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP4 %x\n",
							sr->opp4_nvalue);
			} else {
				pr_info(KERN_INFO "SR: using test nvalues\n");
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}
			sr->opp5_nvalue = sr->opp4_nvalue;
#endif

			sr->opp3_nvalue = sr1_opp[3] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP3_VDD1);
			if (sr->opp3_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP3 %x\n",
							sr->opp3_nvalue);
			} else {
				pr_info(KERN_INFO "SR: using test nvalues\n");
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}
			sr->opp2_nvalue = sr1_opp[2] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP2_VDD1);
			if (sr->opp2_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP2 %x\n",
							sr->opp2_nvalue);
			} else {
				pr_info(KERN_INFO "SR: using test nvalues\n");
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}

			sr->opp1_nvalue = sr1_opp[1] =
			   omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP1_VDD1);
			if (sr->opp1_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP1 %x\n",
							sr->opp1_nvalue);
			} else {
				pr_info(KERN_INFO "SR: using test nvalues\n");
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}

			if (sr_margin_steps || sr_margin_steps_1g)
				sr_add_margin_steps(sr);
		} else {
			sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
						OMAP343X_SR1_SENNENABLE_MASK) >>
						OMAP343X_SR1_SENNENABLE_SHIFT;
			sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
						OMAP343X_SR1_SENPENABLE_MASK) >>
						OMAP343X_SR1_SENPENABLE_SHIFT;

#if !(defined(CONFIG_MACH_OMAP3621_BOXER) ||\
	defined(CONFIG_MACH_OMAP3621_EVT1A) ||\
	defined(CONFIG_MACH_OMAP3621_EDP) ||\
	defined(CONFIG_MACH_OMAP3621_GOSSAMER))
			sr->opp5_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP5_VDD1);
			if (sr->opp5_nvalue != 0x0) {
				pr_info("SR1:Fused Nvalues for VDD1OPP5 %x\n",
							sr->opp5_nvalue);
			} else {
				/* use test nvalues */
				sr_set_testing_nvalues(sr);
				return;
			}
			sr->opp4_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP4_VDD1);
#endif

			sr->opp3_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP3_VDD1);
			sr->opp2_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP2_VDD1);
			sr->opp1_nvalue = omap_ctrl_readl(
						OMAP343X_CONTROL_FUSE_OPP1_VDD1);

#if !(defined(CONFIG_MACH_OMAP3621_BOXER) ||\
	defined(CONFIG_MACH_OMAP3621_EVT1A) ||\
	defined(CONFIG_MACH_OMAP3621_EDP) ||\
	defined(CONFIG_MACH_OMAP3621_GOSSAMER))
			if (sr->opp5_nvalue) {
				sr->opp6_nvalue = calculate_opp_nvalue(sr->opp5_nvalue,
				227, 379);
			}
#endif
		}
	} else if (sr->srid == SR2) {
static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd)
{
	int ret = 0;
	struct twl_mmc_controller *c = NULL;
	struct omap_mmc_platform_data *mmc = dev->platform_data;
	int i;

	for (i = 1; i < ARRAY_SIZE(hsmmc); i++) {
		if (mmc == hsmmc[i].mmc) {
			c = &hsmmc[i];
			break;
		}
	}

	if (c == NULL)
		return -ENODEV;

	/* If we don't see a Vcc regulator, assume it's a fixed
	 * voltage always-on regulator.
	 */
	if (!c->vcc)
		return 0;

	/*
	 * Assume Vcc regulator is used only to power the card ... OMAP
	 * VDDS is used to power the pins, optionally with a transceiver to
	 * support cards using voltages other than VDDS (1.8V nominal).  When a
	 * transceiver is used, DAT3..7 are muxed as transceiver control pins.
	 *
	 * In some cases this regulator won't support enable/disable;
	 * e.g. it's a fixed rail for a WLAN chip.
	 *
	 * In other cases vcc_aux switches interface power.  Example, for
	 * eMMC cards it represents VccQ.  Sometimes transceivers or SDIO
	 * chips/cards need an interface voltage rail too.
	 */
	if (power_on) {
		/* only MMC2 supports a CLKIN */
		if (mmc->slots[0].internal_clock) {
			u32 reg;

			reg = omap_ctrl_readl(control_devconf1_offset);
			reg |= OMAP2_MMCSDIO2ADPCLKISEL;
			omap_ctrl_writel(reg, control_devconf1_offset);
		}
		ret = mmc_regulator_set_ocr(c->vcc, vdd);
		/* enable interface voltage rail, if needed */
		if (ret == 0 && c->vcc_aux) {
			ret = regulator_enable(c->vcc_aux);
			if (ret < 0)
				ret = mmc_regulator_set_ocr(c->vcc, 0);
		}
	} else {
		if (c->vcc_aux && (ret = regulator_is_enabled(c->vcc_aux)) > 0)
			ret = regulator_disable(c->vcc_aux);
		if (ret == 0)
			ret = mmc_regulator_set_ocr(c->vcc, 0);
	}

	return ret;
}
static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
				int vdd)
{
	u32 reg, prog_io;
	int ret = 0;
	struct twl_mmc_controller *c = &hsmmc[0];
	struct omap_mmc_platform_data *mmc = dev->platform_data;

	/*
	 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
	 * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
	 * 1.8V and 3.0V modes, controlled by the PBIAS register.
	 *
	 * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
	 * is most naturally TWL VSIM; those pins also use PBIAS.
	 *
	 * FIXME handle VMMC1A as needed ...
	 */
	if (power_on) {
		if (cpu_is_omap2430()) {
			reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
			if ((1 << vdd) >= MMC_VDD_30_31)
				reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
			else
				reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
			omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
		}

		if (mmc->slots[0].internal_clock) {
			reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
			reg |= OMAP2_MMCSDIO1ADPCLKISEL;
			omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
		}

		reg = omap_ctrl_readl(control_pbias_offset);
		if (cpu_is_omap3630()) {
			/* Set MMC I/O to 52Mhz */
			prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
			prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
			omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
		} else {
			reg |= OMAP2_PBIASSPEEDCTRL0;
		}
		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
		omap_ctrl_writel(reg, control_pbias_offset);

		ret = mmc_regulator_set_ocr(c->vcc, vdd);

		/* 100ms delay required for PBIAS configuration */
		msleep(100);
		reg = omap_ctrl_readl(control_pbias_offset);
		reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
		if ((1 << vdd) <= MMC_VDD_165_195)
			reg &= ~OMAP2_PBIASLITEVMODE0;
		else
			reg |= OMAP2_PBIASLITEVMODE0;
		omap_ctrl_writel(reg, control_pbias_offset);
	} else {
		reg = omap_ctrl_readl(control_pbias_offset);
		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
		omap_ctrl_writel(reg, control_pbias_offset);

		ret = mmc_regulator_set_ocr(c->vcc, 0);

		/* 100ms delay required for PBIAS configuration */
		msleep(100);
		reg = omap_ctrl_readl(control_pbias_offset);
		reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
			OMAP2_PBIASLITEVMODE0);
		omap_ctrl_writel(reg, control_pbias_offset);
	}

	return ret;
}
Example #15
0
int omap_uart_cts_wakeup(int uart_no, int state)
{
	struct uart_omap_port *up = ui[uart_no];
	struct omap_uart_port_info *omap_up_info = up->pdev->dev.platform_data;
	u16 offset = 0; /* 32-bit align */
	u32 v;

	/* No CTS based Wake-ups are enabled. If enabled this would
	 * hold the CTS Pad Conf Register offset.
	 */
	if (!omap_up_info->cts_padconf) {
		dev_dbg(up->port.dev, "No CTS wake-up for UART %d\n", uart_no);
		return -EPERM;
	}

	if (state) {
		/*
		 * Enable the CTS for io pad wakeup
		 */
		dev_dbg(up->port.dev, "Enable CTS wakeup for UART %d", uart_no);

		offset = omap_up_info->cts_padconf & ~0x3; /* 32-bit align */

		if (cpu_is_omap44xx())
			v = omap4_ctrl_pad_readl(offset);
		else
			v = omap_ctrl_readl(offset);

		if (omap_up_info->cts_padconf & 0x2) {
			omap_up_info->cts_padvalue = 0xFFFF0000 & v;
			v |= (((OMAP_WAKEUP_EN | OMAP_OFF_PULL_EN |
				OMAP_OFF_PULL_UP | OMAP_OFFOUT_EN |
				OMAP_OFF_EN | OMAP_PULL_UP)) << 16);
		} else {
			omap_up_info->cts_padvalue = 0x0000FFFF & v;
			v |= ((OMAP_WAKEUP_EN | OMAP_OFF_PULL_EN |
				OMAP_OFF_PULL_UP | OMAP_OFFOUT_EN |
				OMAP_OFF_EN | OMAP_PULL_UP));
		}

		if (cpu_is_omap44xx())
			omap4_ctrl_pad_writel(v, offset);
		else
			omap_ctrl_writel(v, offset);

		/*
		 * Enable the CTS for module level wakeup
		 */
		serial_out(up, UART_OMAP_WER,
				serial_in(up, UART_OMAP_WER) | 0x1);
	} else {
		dev_dbg(up->port.dev, "Disable CTS wakeup for UART%d\n",
				uart_no);
		/*
		 * Disable the CTS capability for io pad wakeup
		 */
		offset = omap_up_info->cts_padconf & ~0x3; /* 32-bit align */
		if (cpu_is_omap44xx())
			v = omap4_ctrl_pad_readl(offset);
		else
			v = omap_ctrl_readl(offset);
		v = ((omap_up_info->cts_padconf & 0x2 ? 0x0000FFFF : 0xFFFF0000)
				& v) | omap_up_info->cts_padvalue;

		if (cpu_is_omap44xx())
			omap4_ctrl_pad_writel(v, offset);
		else
			omap_ctrl_writel(v, offset);
	}
	return 0;
}
Example #16
0
int tvout_read(void)
{
	u16 devconf1_offset = tvout_reg_offset();

	return omap_ctrl_readl(devconf1_offset);
}
Example #17
0
static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
					struct omap_mmc_platform_data *mmc)
{
	char *hc_name;
	u32 reg;

	hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL);
	if (!hc_name) {
		pr_err("Cannot allocate memory for controller slot name\n");
		kfree(hc_name);
		return -ENOMEM;
	}

	if (c->name)
		strncpy(hc_name, c->name, HSMMC_NAME_LEN);
	else
		snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i",
								c->mmc, 1);
	mmc->slots[0].name = hc_name;
	mmc->nr_slots = 1;
	mmc->slots[0].caps = c->caps;
	mmc->slots[0].internal_clock = !c->ext_clock;
	mmc->dma_mask = 0xffffffff;
	if (cpu_is_omap44xx())
		mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
	else
		mmc->reg_offset = 0;

	mmc->get_context_loss_count = hsmmc_get_context_loss;

	mmc->slots[0].switch_pin = c->gpio_cd;
	mmc->slots[0].gpio_wp = c->gpio_wp;

	if (c->caps2 & MMC_CAP2_CD_HIGH_ACTIVE)
		mmc->slots[0].features |= HSMMC_CD_HIGH_ACTIVE;

	mmc->slots[0].remux = c->remux;
	mmc->slots[0].init_card = c->init_card;

	if (c->cover_only)
		mmc->slots[0].cover = 1;

	if (c->nonremovable)
		mmc->slots[0].nonremovable = 1;

	if (c->power_saving)
		mmc->slots[0].power_saving = 1;

	if (c->no_off)
		mmc->slots[0].no_off = 1;

	if (c->no_off_init)
		mmc->slots[0].no_regulator_off_init = c->no_off_init;

	if (c->vcc_aux_disable_is_sleep)
		mmc->slots[0].vcc_aux_disable_is_sleep = 1;

	/*
	 * NOTE:  MMC slots should have a Vcc regulator set up.
	 * This may be from a TWL4030-family chip, another
	 * controllable regulator, or a fixed supply.
	 *
	 * temporary HACK: ocr_mask instead of fixed supply
	 */
	mmc->slots[0].ocr_mask = c->ocr_mask;

	if (cpu_is_omap3517() || cpu_is_omap3505())
		mmc->slots[0].set_power = nop_mmc_set_power;
	else
		mmc->slots[0].features |= HSMMC_HAS_PBIAS;

	if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
		mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;

	switch (c->mmc) {
	case 1:
		if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
			/* on-chip level shifting via PBIAS0/PBIAS1 */
			if (cpu_is_omap44xx()) {
				mmc->slots[0].before_set_reg =
						omap4_hsmmc1_before_set_reg;
				mmc->slots[0].after_set_reg =
						omap4_hsmmc1_after_set_reg;
			} else {
				mmc->slots[0].before_set_reg =
						omap_hsmmc1_before_set_reg;
				mmc->slots[0].after_set_reg =
						omap_hsmmc1_after_set_reg;
			}
		}

		/* OMAP3630 HSMMC1 supports only 4-bit */
		if (cpu_is_omap3630() &&
				(c->caps & MMC_CAP_8_BIT_DATA)) {
			c->caps &= ~MMC_CAP_8_BIT_DATA;
			c->caps |= MMC_CAP_4_BIT_DATA;
			mmc->slots[0].caps = c->caps;
		}
		break;
	case 2:
		if (c->ext_clock)
			c->transceiver = 1;
		if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
			c->caps &= ~MMC_CAP_8_BIT_DATA;
			c->caps |= MMC_CAP_4_BIT_DATA;
		}

		reg = omap_ctrl_readl(control_devconf1_offset);
		reg |= OMAP2_MMCSDIO2ADPCLKISEL;
		omap_ctrl_writel(reg, control_devconf1_offset);

		// FALLTHROUGH
	case 3:
		if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
			/* off-chip level shifting, or none */
			mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
			mmc->slots[0].after_set_reg = NULL;
		}
		break;
	case 4:
	case 5:
		mmc->slots[0].before_set_reg = NULL;
		mmc->slots[0].after_set_reg = NULL;
		break;
	default:
		pr_err("MMC%d configuration not supported!\n", c->mmc);
		kfree(hc_name);
		return -ENODEV;
	}
	return 0;
}
Example #18
0
void omap3_prcm_save_context(void)
{
	prcm_context.control_padconf_sys_nirq =
			 omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ);
	prcm_context.iva2_cm_clksel1 =
			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
	prcm_context.iva2_cm_clksel2 =
			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
	prcm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
	prcm_context.sgx_cm_clksel =
			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
	prcm_context.wkup_cm_clksel = cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
	prcm_context.dss_cm_clksel =
			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
	prcm_context.cam_cm_clksel =
			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
	prcm_context.per_cm_clksel =
			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
	prcm_context.emu_cm_clksel =
			 cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
	prcm_context.emu_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSTCTRL);
	prcm_context.pll_cm_autoidle2 =
			 cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
	prcm_context.pll_cm_clksel4 =
			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
	prcm_context.pll_cm_clksel5 =
			 cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
	prcm_context.pll_cm_clken =
			cm_read_mod_reg(PLL_MOD, CM_CLKEN);
	prcm_context.pll_cm_clken2 =
			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
	prcm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
	prcm_context.iva2_cm_fclken =
			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
	prcm_context.iva2_cm_clken_pll = cm_read_mod_reg(OMAP3430_IVA2_MOD,
			OMAP3430_CM_CLKEN_PLL);
	prcm_context.core_cm_fclken1 =
			 cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
	prcm_context.core_cm_fclken3 =
			 cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
	prcm_context.sgx_cm_fclken =
			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
	prcm_context.wkup_cm_fclken =
			 cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
	prcm_context.dss_cm_fclken =
			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
	prcm_context.cam_cm_fclken =
			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
	prcm_context.per_cm_fclken =
			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
	prcm_context.usbhost_cm_fclken =
			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
	prcm_context.core_cm_iclken1 =
			 cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
	prcm_context.core_cm_iclken2 =
			 cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
	prcm_context.core_cm_iclken3 =
			 cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
	prcm_context.sgx_cm_iclken =
			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
	prcm_context.wkup_cm_iclken =
			 cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
	prcm_context.dss_cm_iclken =
			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
	prcm_context.cam_cm_iclken =
			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
	prcm_context.per_cm_iclken =
			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
	prcm_context.usbhost_cm_iclken =
			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
	prcm_context.iva2_cm_autiidle2 =
			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
	prcm_context.mpu_cm_autoidle2 =
			 cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
	prcm_context.pll_cm_autoidle =
			 cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
	prcm_context.iva2_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL);
	prcm_context.mpu_cm_clkstctrl =
			 cm_read_mod_reg(MPU_MOD, CM_CLKSTCTRL);
	prcm_context.core_cm_clkstctrl =
			 cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL);
	prcm_context.sgx_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSTCTRL);
	prcm_context.dss_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSTCTRL);
	prcm_context.cam_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSTCTRL);
	prcm_context.per_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSTCTRL);
	prcm_context.neon_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430_NEON_MOD, CM_CLKSTCTRL);
	prcm_context.usbhost_cm_clkstctrl =
			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
	prcm_context.core_cm_autoidle1 =
			 cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
	prcm_context.core_cm_autoidle2 =
			 cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
	prcm_context.core_cm_autoidle3 =
			 cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
	prcm_context.wkup_cm_autoidle =
			 cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
	prcm_context.dss_cm_autoidle =
			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
	prcm_context.cam_cm_autoidle =
			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
	prcm_context.per_cm_autoidle =
			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
	prcm_context.usbhost_cm_autoidle =
			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
	prcm_context.sgx_cm_sleepdep =
		 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP3430_CM_SLEEPDEP);
	prcm_context.dss_cm_sleepdep =
		 cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
	prcm_context.cam_cm_sleepdep =
		 cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
	prcm_context.per_cm_sleepdep =
		 cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
	prcm_context.usbhost_cm_sleepdep =
		 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
	prcm_context.cm_clkout_ctrl = cm_read_mod_reg(OMAP3430_CCR_MOD,
		 OMAP3_CM_CLKOUT_CTRL_OFFSET);
	prcm_context.prm_clkout_ctrl = prm_read_mod_reg(OMAP3430_CCR_MOD,
		OMAP3_PRM_CLKOUT_CTRL_OFFSET);
	prcm_context.sgx_pm_wkdep =
		 prm_read_mod_reg(OMAP3430ES2_SGX_MOD, PM_WKDEP);
	prcm_context.dss_pm_wkdep =
		 prm_read_mod_reg(OMAP3430_DSS_MOD, PM_WKDEP);
	prcm_context.cam_pm_wkdep =
		 prm_read_mod_reg(OMAP3430_CAM_MOD, PM_WKDEP);
	prcm_context.per_pm_wkdep =
		 prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKDEP);
	prcm_context.neon_pm_wkdep =
		 prm_read_mod_reg(OMAP3430_NEON_MOD, PM_WKDEP);
	prcm_context.usbhost_pm_wkdep =
		 prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
	prcm_context.core_pm_mpugrpsel1 =
		 prm_read_mod_reg(CORE_MOD, OMAP3430_PM_MPUGRPSEL1);
	prcm_context.iva2_pm_ivagrpsel1 =
		 prm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_PM_IVAGRPSEL1);
	prcm_context.core_pm_mpugrpsel3 =
		 prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_MPUGRPSEL3);
	prcm_context.core_pm_ivagrpsel3 =
		 prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
	prcm_context.wkup_pm_mpugrpsel =
		 prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
	prcm_context.wkup_pm_ivagrpsel =
		 prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
	prcm_context.per_pm_mpugrpsel =
		 prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
	prcm_context.per_pm_ivagrpsel =
		 prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
	prcm_context.wkup_pm_wken = prm_read_mod_reg(WKUP_MOD, PM_WKEN);
	return;
}
Example #19
0
static void omap2_enter_full_retention(void)
{
    u32 l;
    struct timespec ts_preidle, ts_postidle, ts_idle;

    /* There is 1 reference hold for all children of the oscillator
     * clock, the following will remove it. If no one else uses the
     * oscillator itself it will be disabled if/when we enter retention
     * mode.
     */
    clk_disable(osc_ck);

    /* Clear old wake-up events */
    /* REVISIT: These write to reserved bits? */
    prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
    prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
    prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);

    /*
     * Set MPU powerdomain's next power state to RETENTION;
     * preserve logic state during retention
     */
    pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
    pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);

    /* Workaround to kill USB */
    l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
    omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);

    omap2_gpio_prepare_for_idle(PWRDM_POWER_RET);

    if (omap2_pm_debug) {
        omap2_pm_dump(0, 0, 0);
        getnstimeofday(&ts_preidle);
    }

    /* One last check for pending IRQs to avoid extra latency due
     * to sleeping unnecessarily. */
    if (omap_irq_pending())
        goto no_sleep;

    omap_uart_prepare_idle(0);
    omap_uart_prepare_idle(1);
    omap_uart_prepare_idle(2);

    /* Jump to SRAM suspend code */
    omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
                       OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
                       OMAP_SDRC_REGADDR(SDRC_POWER));
no_sleep:
    omap_uart_resume_idle(2);
    omap_uart_resume_idle(1);
    omap_uart_resume_idle(0);

    if (omap2_pm_debug) {
        unsigned long long tmp;

        getnstimeofday(&ts_postidle);
        ts_idle = timespec_sub(ts_postidle, ts_preidle);
        tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
        omap2_pm_dump(0, 1, tmp);
    }
    omap2_gpio_resume_after_idle();

    clk_enable(osc_ck);

    /* clear CORE wake-up events */
    prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
    prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);

    /* wakeup domain events - bit 1: GPT1, bit5 GPIO */
    prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST);

    /* MPU domain wake events */
    l = prm_read_mod_reg(OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
    if (l & 0x01)
        prm_write_mod_reg(0x01, OCP_MOD,
                          OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
    if (l & 0x20)
        prm_write_mod_reg(0x20, OCP_MOD,
                          OMAP2_PRM_IRQSTATUS_MPU_OFFSET);

    /* Mask future PRCM-to-MPU interrupts */
    prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
}
Example #20
0
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
			int controller_nr)
{
	if (cpu_is_omap2420() && controller_nr == 0) {
		omap_cfg_reg(H18_24XX_MMC_CMD);
		omap_cfg_reg(H15_24XX_MMC_CLKI);
		omap_cfg_reg(G19_24XX_MMC_CLKO);
		omap_cfg_reg(F20_24XX_MMC_DAT0);
		omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
		omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
		if (mmc_controller->slots[0].wires == 4) {
			omap_cfg_reg(H14_24XX_MMC_DAT1);
			omap_cfg_reg(E19_24XX_MMC_DAT2);
			omap_cfg_reg(D19_24XX_MMC_DAT3);
			omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
			omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
			omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
		}

		/*
		 * Use internal loop-back in MMC/SDIO Module Input Clock
		 * selection
		 */
		if (mmc_controller->slots[0].internal_clock) {
			u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
			v |= (1 << 24);
			omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
		}
	}

	if (cpu_is_omap3430() || cpu_is_omap3630()) {
		u32 dev_conf = 0, v_shift = 0;
		if (controller_nr == 0) {
			omap_cfg_reg(N28_3430_MMC1_CLK);
			omap_cfg_reg(M27_3430_MMC1_CMD);
			omap_cfg_reg(N27_3430_MMC1_DAT0);
			if (mmc_controller->slots[0].wires == 4 ||
				mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(N26_3430_MMC1_DAT1);
				omap_cfg_reg(N25_3430_MMC1_DAT2);
				omap_cfg_reg(P28_3430_MMC1_DAT3);
			}
			if (mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(P27_3430_MMC1_DAT4);
				omap_cfg_reg(P26_3430_MMC1_DAT5);
				omap_cfg_reg(R27_3430_MMC1_DAT6);
				omap_cfg_reg(R25_3430_MMC1_DAT7);
			}
			dev_conf = OMAP2_CONTROL_DEVCONF0;
			v_shift = OMAP2_MMCSDIO1ADPCLKISEL;
		}
		if (controller_nr == 1) {
			/* MMC2 */
			omap_cfg_reg(AE2_3430_MMC2_CLK);
			omap_cfg_reg(AG5_3430_MMC2_CMD);
			omap_cfg_reg(AH5_3430_MMC2_DAT0);
			if (mmc_controller->slots[0].wires == 4 ||
				mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(AH4_3430_MMC2_DAT1);
				omap_cfg_reg(AG4_3430_MMC2_DAT2);
				omap_cfg_reg(AF4_3430_MMC2_DAT3);
			}
			if (mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(AE4_3430_MMC2_DAT4);
				omap_cfg_reg(AH3_3430_MMC2_DAT5);
				omap_cfg_reg(AF3_3430_MMC2_DAT6);
				omap_cfg_reg(AE3_3430_MMC2_DAT7);
			}
			dev_conf = OMAP343X_CONTROL_DEVCONF1;
			v_shift = OMAP2_MMCSDIO2ADPCLKISEL;
		}
		if (controller_nr == 2) {
			/* MMC3 */
			omap_cfg_reg(AF10_3430_MMC3_CLK);
			omap_cfg_reg(AC3_3430_MMC3_CMD);
			omap_cfg_reg(AE11_3430_MMC3_DAT0);
			if (mmc_controller->slots[0].wires == 4 ||
				mmc_controller->slots[0].wires == 8) {
				omap_cfg_reg(AH9_3430_MMC3_DAT1);
				omap_cfg_reg(AF13_3430_MMC3_DAT2);
				omap_cfg_reg(AE13_3430_MMC3_DAT3);
			}
		}

		/*
		 * Use internal loop-back in MMC/SDIO Module Input Clock
		 * selection
		 */
		if (mmc_controller->slots[0].internal_clock && dev_conf) {
			u32 v = omap_ctrl_readl(dev_conf);
			v |= (1 << v_shift);
			omap_ctrl_writel(v, dev_conf);
		}
	}
}
Example #21
0
void omap3_control_save_context(void)
{
	control_context.sysconfig = omap_ctrl_readl(OMAP2_CONTROL_SYSCONFIG);
	control_context.devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
	control_context.mem_dftrw0 =
			omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW0);
	control_context.mem_dftrw1 =
			omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW1);
	control_context.msuspendmux_0 =
			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_0);
	control_context.msuspendmux_1 =
			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_1);
	control_context.msuspendmux_2 =
			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_2);
	control_context.msuspendmux_3 =
			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_3);
	control_context.msuspendmux_4 =
			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_4);
	control_context.msuspendmux_5 =
			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_5);
	control_context.sec_ctrl = omap_ctrl_readl(OMAP2_CONTROL_SEC_CTRL);
	control_context.devconf1 = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1);
	control_context.csirxfe = omap_ctrl_readl(OMAP343X_CONTROL_CSIRXFE);
	control_context.iva2_bootaddr =
			omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTADDR);
	control_context.iva2_bootmod =
			omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTMOD);
	control_context.debobs_0 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(0));
	control_context.debobs_1 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(1));
	control_context.debobs_2 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(2));
	control_context.debobs_3 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(3));
	control_context.debobs_4 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(4));
	control_context.debobs_5 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(5));
	control_context.debobs_6 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(6));
	control_context.debobs_7 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(7));
	control_context.debobs_8 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(8));
	control_context.prog_io0 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO0);
	control_context.prog_io1 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
	control_context.dss_dpll_spreading =
			omap_ctrl_readl(OMAP343X_CONTROL_DSS_DPLL_SPREADING);
	control_context.core_dpll_spreading =
			omap_ctrl_readl(OMAP343X_CONTROL_CORE_DPLL_SPREADING);
	control_context.per_dpll_spreading =
			omap_ctrl_readl(OMAP343X_CONTROL_PER_DPLL_SPREADING);
	control_context.usbhost_dpll_spreading =
		omap_ctrl_readl(OMAP343X_CONTROL_USBHOST_DPLL_SPREADING);
	control_context.pbias_lite =
			omap_ctrl_readl(OMAP343X_CONTROL_PBIAS_LITE);
	control_context.temp_sensor =
			omap_ctrl_readl(OMAP343X_CONTROL_TEMP_SENSOR);
	control_context.sramldo4 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO4);
	control_context.sramldo5 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO5);
	control_context.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI);
	return;
}
Example #22
0
/*LGE_CHANGE_S*/
static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
				int vdd)
{
	u32 reg, prog_io;
	int ret = 0;
	struct omap_mmc_platform_data *mmc = dev->platform_data;

	pr_debug("%s %s power_on:%d", __func__, mmc->slots[0].name, power_on);

	if (power_on) {
		if (mmc->slots[0].internal_clock) {
			reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
			reg |= OMAP2_MMCSDIO1ADPCLKISEL;
			omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
		}

		reg = omap_ctrl_readl(control_pbias_offset);
		/* Set MMC I/O to 52Mhz */
		prog_io = omap_ctrl_readl
				(OMAP343X_CONTROL_PROG_IO1);
		prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
		omap_ctrl_writel
			(prog_io, OMAP343X_CONTROL_PROG_IO1);
		reg &= ~OMAP2_PBIASLITEPWRDNZ0;

		omap_ctrl_writel(reg, control_pbias_offset);

		reg = omap_ctrl_readl(control_pbias_offset);
		if ((1 << vdd) <= MMC_VDD_165_195)
			reg &= ~OMAP2_PBIASLITEVMODE0;
		else
			reg |= OMAP2_PBIASLITEVMODE0;
		omap_ctrl_writel(reg, control_pbias_offset);

		gpio_direction_output(138,1);
#if 0 /* scchoi */		
		subpm_set_output(LDO1, 1);
		subpm_output_enable();
#endif

		/* 1ms delay required for PBIAS configuration */
		msleep(1);
		reg = omap_ctrl_readl(control_pbias_offset);
		reg |= (OMAP2_PBIASLITEPWRDNZ0 |
					OMAP2_PBIASSPEEDCTRL0);
		omap_ctrl_writel(reg, control_pbias_offset);
	} else {
		reg = omap_ctrl_readl(control_pbias_offset);
		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
		omap_ctrl_writel(reg, control_pbias_offset);

		gpio_direction_output(138,0);
#if 0 /* scchoi */
		subpm_set_output(LDO1, 0);
		subpm_output_enable();
#endif

		/* 100ms delay required for PBIAS configuration */
		msleep(10);
		reg = omap_ctrl_readl(control_pbias_offset);
		reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0
					| OMAP2_PBIASLITEVMODE0);
		omap_ctrl_writel(reg, control_pbias_offset);
	}

	return ret;
}
Example #23
0
static inline u32 igep_get_sysboot_value(void)
{
	return omap_ctrl_readl(OMAP343X_CONTROL_STATUS) & IGEP_SYSBOOT_MASK;
}
Example #24
0
void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
	struct omap2_hsmmc_info *c;
	int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
	int i;
	u32 reg;

	if (!cpu_is_omap44xx()) {
		if (cpu_is_omap2430()) {
			control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
			control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
		} else {
			control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
			control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
		}
	} else {
		control_pbias_offset = OMAP44XX_CONTROL_PBIAS_LITE;
		control_mmc1 = OMAP44XX_CONTROL_MMC1;
		reg = omap_ctrl_readl(control_mmc1);
		reg |= (OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 |
			OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1);
		reg &= ~(OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 |
			OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3);
		reg |= (OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL |
			OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL |
			OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL);
		omap_ctrl_writel(reg, control_mmc1);
	}

	for (c = controllers; c->mmc; c++) {
		struct hsmmc_controller *hc = hsmmc + c->mmc - 1;
		struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];

		if (!c->mmc || c->mmc > nr_hsmmc) {
			pr_debug("MMC%d: no such controller\n", c->mmc);
			continue;
		}
		if (mmc) {
			pr_debug("MMC%d: already configured\n", c->mmc);
			continue;
		}

		mmc = kzalloc(sizeof(struct omap_mmc_platform_data),
			      GFP_KERNEL);
		if (!mmc) {
			pr_err("Cannot allocate memory for mmc device!\n");
			goto done;
		}

		if (c->name)
			strncpy(hc->name, c->name, HSMMC_NAME_LEN);
		else
			snprintf(hc->name, ARRAY_SIZE(hc->name),
				"mmc%islot%i", c->mmc, 1);
		mmc->slots[0].name = hc->name;
		mmc->nr_slots = 1;
		mmc->slots[0].wires = c->wires;
		mmc->slots[0].internal_clock = !c->ext_clock;
		mmc->dma_mask = 0xffffffff;

		mmc->get_context_loss_count = hsmmc_get_context_loss;

		mmc->slots[0].switch_pin = c->gpio_cd;
		mmc->slots[0].gpio_wp = c->gpio_wp;

		mmc->slots[0].remux = c->remux;
		mmc->slots[0].init_card = c->init_card;

		if (c->cover_only)
			mmc->slots[0].cover = 1;

		if (c->nonremovable)
			mmc->slots[0].nonremovable = 1;

		if (c->power_saving)
			mmc->slots[0].power_saving = 1;

		if (c->no_off)
			mmc->slots[0].no_off = 1;

		if (c->vcc_aux_disable_is_sleep)
			mmc->slots[0].vcc_aux_disable_is_sleep = 1;

		/* NOTE:  MMC slots should have a Vcc regulator set up.
		 * This may be from a TWL4030-family chip, another
		 * controllable regulator, or a fixed supply.
		 *
		 * temporary HACK: ocr_mask instead of fixed supply
		 */
		mmc->slots[0].ocr_mask = c->ocr_mask;

		if (cpu_is_omap3517() || cpu_is_omap3505())
			mmc->slots[0].set_power = nop_mmc_set_power;
		else
			mmc->slots[0].features |= HSMMC_HAS_PBIAS;

		switch (c->mmc) {
		case 1:
			if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
				/* on-chip level shifting via PBIAS0/PBIAS1 */
				if (cpu_is_omap44xx()) {
					mmc->slots[0].before_set_reg =
						omap4_hsmmc1_before_set_reg;
					mmc->slots[0].after_set_reg =
						omap4_hsmmc1_after_set_reg;
				} else {
					mmc->slots[0].before_set_reg =
						omap_hsmmc1_before_set_reg;
					mmc->slots[0].after_set_reg =
						omap_hsmmc1_after_set_reg;
				}
			}

			/* Omap3630 HSMMC1 supports only 4-bit */
			if (cpu_is_omap3630() && c->wires > 4) {
				c->wires = 4;
				mmc->slots[0].wires = c->wires;
			}
			break;
		case 2:
			if (c->ext_clock)
				c->transceiver = 1;
			if (c->transceiver && c->wires > 4)
				c->wires = 4;
			/* FALLTHROUGH */
		case 3:
			if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
				/* off-chip level shifting, or none */
				mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
				mmc->slots[0].after_set_reg = NULL;
			}
			break;
		default:
			pr_err("MMC%d configuration not supported!\n", c->mmc);
			kfree(mmc);
			continue;
		}
		hsmmc_data[c->mmc - 1] = mmc;
	}

	omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);

	/* pass the device nodes back to board setup code */
	for (c = controllers; c->mmc; c++) {
		struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];

		if (!c->mmc || c->mmc > nr_hsmmc)
			continue;
		c->dev = mmc->dev;
	}

done:
	for (i = 0; i < nr_hsmmc; i++)
		kfree(hsmmc_data[i]);
}