static inline int at91mci_is_mci1rev2xx(void)
{
	return (   cpu_is_at91sam9260()
		|| cpu_is_at91sam9263()
		|| cpu_is_at91sam9rl()
		|| cpu_is_at91sam9g10()
		|| cpu_is_at91sam9g20()
		);
}
Exemplo n.º 2
0
/*
 * Enable the controller
 */
static void at91_mci_enable(struct at91mci_host *host)
{
	unsigned int mr;

	at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
	at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
	mr = AT91_MCI_PDCMODE | 0x34a;

	if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
		mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;

	at91_mci_write(host, AT91_MCI_MR, mr);

	/* use Slot A or B (only one at same time) */
	at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
}
Exemplo n.º 3
0
static int at91_pm_verify_clocks(void)
{
    unsigned long scsr;
    int i;

    scsr = at91_sys_read(AT91_PMC_SCSR);

    /* USB must not be using PLLB */
    if (cpu_is_at91rm9200()) {
        if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
            pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
            return 0;
        }
    } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
               || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
        if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
            pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
            return 0;
        }
    } else if (cpu_is_at91cap9()) {
        if ((scsr & AT91CAP9_PMC_UHP) != 0) {
            pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
            return 0;
        }
    }

#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
    /* PCK0..PCK3 must be disabled, or configured to use clk32k */
    for (i = 0; i < 4; i++) {
        u32 css;

        if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
            continue;

        css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
        if (css != AT91_PMC_CSS_SLOW) {
            pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
            return 0;
        }
    }
#endif

    return 1;
}
Exemplo n.º 4
0
/* Actual code that puts the SoC in different idle states */
static int at91_enter_idle(struct cpuidle_device *dev,
			struct cpuidle_driver *drv,
			       int index)
{
	if (cpu_is_at91rm9200())
		at91rm9200_standby();
	else if (cpu_is_at91sam9g45())
		at91sam9g45_standby();
	else if (cpu_is_at91sam9263())
		at91sam9263_standby();
	else if (cpu_is_at91sam9x5()
		|| cpu_is_at91sam9n12()
		|| cpu_is_sama5d3()
		|| cpu_is_sama5d4())
		at91sam_ddrc_standby();
	else
		at91sam9_standby();

	return index;
}
Exemplo n.º 5
0
/*
 * Probe for the device
 */
static int __init at91_mci_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
	struct at91mci_host *host;
	struct resource *res;
	int ret;

	pr_debug("Probe MCI devices\n");

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENXIO;

	if (!request_mem_region(res->start, res->end - res->start + 1, DRIVER_NAME))
		return -EBUSY;

	mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
	if (!mmc) {
		pr_debug("Failed to allocate mmc host\n");
		release_mem_region(res->start, res->end - res->start + 1);
		return -ENOMEM;
	}

	mmc->ops = &at91_mci_ops;
	mmc->f_min = 375000;
	mmc->f_max = 25000000;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;

	mmc->max_blk_size = 4095;
	mmc->max_blk_count = mmc->max_req_size;

	host = mmc_priv(mmc);
	host->mmc = mmc;
	host->buffer = NULL;
	host->bus_mode = 0;
	host->board = pdev->dev.platform_data;
	if (host->board->wire4) {
		if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
			mmc->caps |= MMC_CAP_4_BIT_DATA;
		else
			printk("AT91 MMC: 4 wire bus mode not supported"
				" - using 1 wire\n");
	}

	/*
	 * Get Clock
	 */
	host->mci_clk = clk_get(&pdev->dev, "mci_clk");
	if (IS_ERR(host->mci_clk)) {
		printk(KERN_ERR "AT91 MMC: no clock defined.\n");
		mmc_free_host(mmc);
		release_mem_region(res->start, res->end - res->start + 1);
		return -ENODEV;
	}

	/*
	 * Map I/O region
	 */
	host->baseaddr = ioremap(res->start, res->end - res->start + 1);
	if (!host->baseaddr) {
		clk_put(host->mci_clk);
		mmc_free_host(mmc);
		release_mem_region(res->start, res->end - res->start + 1);
		return -ENOMEM;
	}

	/*
	 * Reset hardware
	 */
	clk_enable(host->mci_clk);		/* Enable the peripheral clock */
	at91_mci_disable(host);
	at91_mci_enable(host);

	/*
	 * Allocate the MCI interrupt
	 */
	host->irq = platform_get_irq(pdev, 0);
	ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host);
	if (ret) {
		printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n");
		clk_disable(host->mci_clk);
		clk_put(host->mci_clk);
		mmc_free_host(mmc);
		iounmap(host->baseaddr);
		release_mem_region(res->start, res->end - res->start + 1);
		return ret;
	}

	platform_set_drvdata(pdev, mmc);

	/*
	 * Add host to MMC layer
	 */
	if (host->board->det_pin) {
		host->present = !at91_get_gpio_value(host->board->det_pin);
		device_init_wakeup(&pdev->dev, 1);
	}
	else
		host->present = -1;

	mmc_add_host(mmc);

	/*
	 * monitor card insertion/removal if we can
	 */
	if (host->board->det_pin) {
		ret = request_irq(host->board->det_pin, at91_mmc_det_irq,
				0, DRIVER_NAME, host);
		if (ret)
			printk(KERN_ERR "AT91 MMC: Couldn't allocate MMC detect irq\n");
	}

	pr_debug("Added MCI driver\n");

	return 0;
}
Exemplo n.º 6
0
static int at91_pm_enter(suspend_state_t state)
{
	if (of_have_populated_dt())
		at91_pinctrl_gpio_suspend();
	else
		at91_gpio_suspend();
	at91_irq_suspend();

	pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
			/* remember all the always-wake irqs */
			(at91_pmc_read(AT91_PMC_PCSR)
					| (1 << AT91_ID_FIQ)
					| (1 << AT91_ID_SYS)
					| (at91_extern_irq))
				& at91_aic_read(AT91_AIC_IMR),
			state);

	switch (state) {
		/*
		 * Suspend-to-RAM is like STANDBY plus slow clock mode, so
		 * drivers must suspend more deeply:  only the master clock
		 * controller may be using the main oscillator.
		 */
		case PM_SUSPEND_MEM:
			/*
			 * Ensure that clocks are in a valid state.
			 */
			if (!at91_pm_verify_clocks())
				goto error;

			/*
			 * Enter slow clock mode by switching over to clk32k and
			 * turning off the main oscillator; reverse on wakeup.
			 */
			if (slow_clock) {
				int memctrl = AT91_MEMCTRL_SDRAMC;

				if (cpu_is_at91rm9200())
					memctrl = AT91_MEMCTRL_MC;
				else if (cpu_is_at91sam9g45())
					memctrl = AT91_MEMCTRL_DDRSDR;
#ifdef CONFIG_AT91_SLOW_CLOCK
				/* copy slow_clock handler to SRAM, and call it */
				memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
#endif
				slow_clock(at91_pmc_base, at91_ramc_base[0],
					   at91_ramc_base[1], memctrl);
				break;
			} else {
				pr_info("AT91: PM - no slow clock mode enabled ...\n");
				/* FALLTHROUGH leaving master clock alone */
			}

		/*
		 * STANDBY mode has *all* drivers suspended; ignores irqs not
		 * marked as 'wakeup' event sources; and reduces DRAM power.
		 * But otherwise it's identical to PM_SUSPEND_ON:  cpu idle, and
		 * nothing fancy done with main or cpu clocks.
		 */
		case PM_SUSPEND_STANDBY:
			/*
			 * NOTE: the Wait-for-Interrupt instruction needs to be
			 * in icache so no SDRAM accesses are needed until the
			 * wakeup IRQ occurs and self-refresh is terminated.
			 * For ARM 926 based chips, this requirement is weaker
			 * as at91sam9 can access a RAM in self-refresh mode.
			 */
			if (cpu_is_at91rm9200())
				at91rm9200_standby();
			else if (cpu_is_at91sam9g45())
				at91sam9g45_standby();
			else if (cpu_is_at91sam9263())
				at91sam9263_standby();
			else
				at91sam9_standby();
			break;

		case PM_SUSPEND_ON:
			cpu_do_idle();
			break;

		default:
			pr_debug("AT91: PM - bogus suspend state %d\n", state);
			goto error;
	}

	pr_debug("AT91: PM - wakeup %08x\n",
			at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR));

error:
	target_state = PM_SUSPEND_ON;
	at91_irq_resume();
	if (of_have_populated_dt())
		at91_pinctrl_gpio_resume();
	else
		at91_gpio_resume();
	return 0;
}