static inline int at91mci_is_mci1rev2xx(void)
{
	return (   cpu_is_at91sam9260()
		|| cpu_is_at91sam9263()
		|| cpu_is_at91sam9rl()
		|| cpu_is_at91sam9g10()
		|| cpu_is_at91sam9g20()
		);
}
Beispiel #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);
}
Beispiel #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;
}
Beispiel #4
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;
}
void __init at91_add_device_nand(struct at91_nand_data *data)
{
	unsigned long csa, mode;

	if (!data)
		return;

	csa = at91_sys_read(AT91_MATRIX_EBICSA);
	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);

	if (cpu_is_at91sam9260()) {
		/* Timing for sam9260 */
		/* set the bus interface characteristics */
		at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0)
				| AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0));

		at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
				| AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));

		at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));

		if (data->bus_width_16)
			mode = AT91_SMC_DBW_16;
		else
			mode = AT91_SMC_DBW_8;
		at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
	}

	if (cpu_is_at91sam9g20()) {
		/* Timing for sam9g20 */
		/* set the bus interface characteristics */
		at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(0)
				| AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(0));

		at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(4)
				| AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(4));

		at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7));

		if (data->bus_width_16)
			mode = AT91_SMC_DBW_16;
		else
			mode = AT91_SMC_DBW_8;
		at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(3));
	}

	/* enable pin */
	if (data->enable_pin)
		at91_set_gpio_output(data->enable_pin, 1);

	/* ready/busy pin */
	if (data->rdy_pin)
		at91_set_gpio_input(data->rdy_pin, 1);

	/* card detect pin */
	if (data->det_pin)
		at91_set_gpio_input(data->det_pin, 1);

	nand_data = *data;
	platform_device_register(&at91sam9260_nand_device);
}