Date:2011-08-02 10:49:28 (12 years 7 months ago)
Author:Maarten ter Huurne
Commit:010bfe2843c058bf0454a3d4e11d6436fbeff943
Message:MTD: NAND: JZ4740: Multi-bank support with autodetection

The platform data can now specify which external memory banks to probe
for NAND chips, and in which order. Banks that contain a NAND are used
and the other banks are freed.

Squashed version of development done in jz-2.6.38 branch.
Original patch by Lars-Peter Clausen with some bug fixes from me.
Thanks to Paul Cercueil for the initial autodetection patch.
Files: arch/mips/include/asm/mach-jz4740/jz4740_nand.h (2 diffs)
arch/mips/jz4740/platform.c (1 diff)
drivers/mtd/nand/jz4740_nand.c (12 diffs)

Change Details

arch/mips/include/asm/mach-jz4740/jz4740_nand.h
1919#include <linux/mtd/nand.h>
2020#include <linux/mtd/partitions.h>
2121
22#define JZ_NAND_NUM_BANKS 4
23
2224struct jz_nand_platform_data {
2325    int num_partitions;
2426    struct mtd_partition *partitions;
...... 
2729
2830    unsigned int busy_gpio;
2931
32    unsigned char banks[JZ_NAND_NUM_BANKS];
33
3034    void (*ident_callback)(struct platform_device *, struct nand_chip *,
3135                struct mtd_partition **, int *num_partitions);
3236};
arch/mips/jz4740/platform.c
157157        .flags = IORESOURCE_MEM,
158158    },
159159    {
160        .name = "bank",
160        .name = "bank1",
161161        .start = 0x18000000,
162162        .end = 0x180C0000 - 1,
163163        .flags = IORESOURCE_MEM,
164164    },
165    {
166        .name = "bank2",
167        .start = 0x14000000,
168        .end = 0x140C0000 - 1,
169        .flags = IORESOURCE_MEM,
170    },
171    {
172        .name = "bank3",
173        .start = 0x0C000000,
174        .end = 0x0C0C0000 - 1,
175        .flags = IORESOURCE_MEM,
176    },
177    {
178        .name = "bank4",
179        .start = 0x08000000,
180        .end = 0x080C0000 - 1,
181        .flags = IORESOURCE_MEM,
182    },
165183};
166184
167185struct platform_device jz4740_nand_device = {
drivers/mtd/nand/jz4740_nand.c
5252
5353#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT((x) << 1)
5454#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT(((x) << 1) + 1)
55#define JZ_NAND_CTRL_ASSERT_CHIP_MASK 0xaa
5556
56#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
5757#define JZ_NAND_MEM_CMD_OFFSET 0x08000
58#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
5859
5960struct jz_nand {
6061    struct mtd_info mtd;
...... 
6263    void __iomem *base;
6364    struct resource *mem;
6465
65    void __iomem *bank_base;
66    struct resource *bank_mem;
66    unsigned char banks[JZ_NAND_NUM_BANKS];
67    void __iomem *bank_base[JZ_NAND_NUM_BANKS];
68    struct resource *bank_mem[JZ_NAND_NUM_BANKS];
69
70    int selected_bank;
6771
6872    struct jz_nand_platform_data *pdata;
6973    bool is_reading;
...... 
7478    return container_of(mtd, struct jz_nand, mtd);
7579}
7680
81static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr)
82{
83    struct jz_nand *nand = mtd_to_jz_nand(mtd);
84    struct nand_chip *chip = mtd->priv;
85    uint32_t ctrl;
86    int banknr;
87
88    ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
89    ctrl &= ~JZ_NAND_CTRL_ASSERT_CHIP_MASK;
90
91    if (chipnr == -1) {
92        banknr = -1;
93    } else {
94        banknr = nand->banks[chipnr] - 1;
95        chip->IO_ADDR_R = nand->bank_base[banknr];
96        chip->IO_ADDR_W = nand->bank_base[banknr];
97    }
98    writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
99
100    nand->selected_bank = banknr;
101}
102
77103static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
78104{
79105    struct jz_nand *nand = mtd_to_jz_nand(mtd);
80106    struct nand_chip *chip = mtd->priv;
81107    uint32_t reg;
108    void __iomem *bank_base = nand->bank_base[nand->selected_bank];
109
110    BUG_ON(nand->selected_bank < 0);
82111
83112    if (ctrl & NAND_CTRL_CHANGE) {
84113        BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE));
85114        if (ctrl & NAND_ALE)
86            chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_ADDR_OFFSET;
115            bank_base += JZ_NAND_MEM_ADDR_OFFSET;
87116        else if (ctrl & NAND_CLE)
88            chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_CMD_OFFSET;
89        else
90            chip->IO_ADDR_W = nand->bank_base;
117            bank_base += JZ_NAND_MEM_CMD_OFFSET;
118        chip->IO_ADDR_W = bank_base;
91119
92120        reg = readl(nand->base + JZ_REG_NAND_CTRL);
93121        if (ctrl & NAND_NCE)
94            reg |= JZ_NAND_CTRL_ASSERT_CHIP(0);
122            reg |= JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
95123        else
96            reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(0);
124            reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
97125        writel(reg, nand->base + JZ_REG_NAND_CTRL);
98126    }
99127    if (dat != NAND_CMD_NONE)
...... 
256284#endif
257285
258286static int jz_nand_ioremap_resource(struct platform_device *pdev,
259    const char *name, struct resource **res, void __iomem **base)
287    const char *name, struct resource **res, void *__iomem *base)
260288{
261289    int ret;
262290
...... 
292320    return ret;
293321}
294322
323static inline void jz_nand_iounmap_resource(struct resource *res, void __iomem *base)
324{
325    iounmap(base);
326    release_mem_region(res->start, resource_size(res));
327}
328
329static int __devinit jz_nand_detect_bank(struct platform_device *pdev, struct jz_nand *nand, unsigned char bank, size_t chipnr, uint8_t *nand_maf_id, uint8_t *nand_dev_id) {
330    int ret;
331    int gpio;
332    char gpio_name[9];
333    char res_name[6];
334    uint32_t ctrl;
335    struct mtd_info *mtd = &nand->mtd;
336    struct nand_chip *chip = &nand->chip;
337
338    /* Request GPIO port. */
339    gpio = JZ_GPIO_MEM_CS0 + bank - 1;
340    sprintf(gpio_name, "NAND CS%d", bank);
341    ret = gpio_request(gpio, gpio_name);
342    if (ret) {
343        dev_warn(&pdev->dev,
344            "Failed to request %s gpio %d: %d\n",
345            gpio_name, gpio, ret);
346        goto notfound_gpio;
347    }
348
349    /* Request I/O resource. */
350    sprintf(res_name, "bank%d", bank);
351    ret = jz_nand_ioremap_resource(pdev, res_name,
352                    &nand->bank_mem[bank - 1],
353                    &nand->bank_base[bank - 1]);
354    if (ret)
355        goto notfound_resource;
356
357    /* Enable chip in bank. */
358    jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
359    ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
360    ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
361    writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
362
363    if (chipnr == 0) {
364        /* Detect first chip. */
365        ret = nand_scan_ident(mtd, 1, NULL);
366        if (ret)
367            goto notfound_id;
368
369        /* Retrieve the IDs from the first chip. */
370        chip->select_chip(mtd, 0);
371        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
372        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
373        *nand_maf_id = chip->read_byte(mtd);
374        *nand_dev_id = chip->read_byte(mtd);
375    } else {
376        /* Detect additional chip. */
377        chip->select_chip(mtd, chipnr);
378        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
379        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
380        if (*nand_maf_id != chip->read_byte(mtd)
381         || *nand_dev_id != chip->read_byte(mtd)) {
382            ret = -ENODEV;
383            goto notfound_id;
384        }
385
386        /* Update size of the MTD. */
387        chip->numchips++;
388        mtd->size += chip->chipsize;
389    }
390
391    dev_info(&pdev->dev, "Found chip %i on bank %i\n", chipnr, bank);
392    return 0;
393
394notfound_id:
395    dev_info(&pdev->dev, "No chip found on bank %i\n", bank);
396    ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1));
397    writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
398    jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
399    jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
400                 nand->bank_base[bank - 1]);
401notfound_resource:
402    gpio_free(gpio);
403notfound_gpio:
404    return ret;
405}
406
295407static int __devinit jz_nand_probe(struct platform_device *pdev)
296408{
297409    int ret;
...... 
301413    struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
302414    struct mtd_partition *partition_info;
303415    int num_partitions = 0;
416    size_t chipnr, bank_idx;
417    uint8_t nand_maf_id = 0, nand_dev_id = 0;
304418
305419    nand = kzalloc(sizeof(*nand), GFP_KERNEL);
306420    if (!nand) {
...... 
311425    ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
312426    if (ret)
313427        goto err_free;
314    ret = jz_nand_ioremap_resource(pdev, "bank", &nand->bank_mem,
315            &nand->bank_base);
316    if (ret)
317        goto err_iounmap_mmio;
318428
319429    if (pdata && gpio_is_valid(pdata->busy_gpio)) {
320430        ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
...... 
322432            dev_err(&pdev->dev,
323433                "Failed to request busy gpio %d: %d\n",
324434                pdata->busy_gpio, ret);
325            goto err_iounmap_mem;
435            goto err_iounmap_mmio;
326436        }
327437    }
328438
...... 
344454
345455    chip->chip_delay = 50;
346456    chip->cmd_ctrl = jz_nand_cmd_ctrl;
457    chip->select_chip = jz_nand_select_chip;
347458
348459    if (pdata && gpio_is_valid(pdata->busy_gpio))
349460        chip->dev_ready = jz_nand_dev_ready;
350461
351    chip->IO_ADDR_R = nand->bank_base;
352    chip->IO_ADDR_W = nand->bank_base;
353
354462    nand->pdata = pdata;
355463    platform_set_drvdata(pdev, nand);
356464
357    writel(JZ_NAND_CTRL_ENABLE_CHIP(0), nand->base + JZ_REG_NAND_CTRL);
358
359    ret = nand_scan_ident(mtd, 1, NULL);
360    if (ret) {
361        dev_err(&pdev->dev, "Failed to scan nand\n");
362        goto err_gpio_free;
465    /* We are going to autodetect NAND chips in the banks specified in the
466     * platform data. Although nand_scan_ident() can detect multiple chips,
467     * it requires those chips to be numbered consecuitively, which is not
468     * always the case for external memory banks. And a fixed chip-to-bank
469     * mapping is not practical either, since for example Dingoo units
470     * produced at different times have NAND chips in different banks.
471     */
472    chipnr = 0;
473    for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) {
474        unsigned char bank;
475
476        /* If there is no platform data, look for NAND in bank 1,
477         * which is the most likely bank since it is the only one
478         * that can be booted from.
479         */
480        bank = pdata ? pdata->banks[bank_idx] : bank_idx ^ 1;
481        if (bank == 0)
482            break;
483        if (bank > JZ_NAND_NUM_BANKS) {
484            dev_warn(&pdev->dev,
485                "Skipping non-existing bank: %d\n", bank);
486            continue;
487        }
488        /* The detection routine will directly or indirectly call
489         * jz_nand_select_chip(), so nand->banks has to contain the
490         * bank we're checking.
491         */
492        nand->banks[chipnr] = bank;
493        if (jz_nand_detect_bank(pdev, nand, bank, chipnr,
494                    &nand_maf_id, &nand_dev_id) == 0)
495            chipnr++;
496        else
497            nand->banks[chipnr] = 0;
498    }
499    if (chipnr == 0) {
500        dev_err(&pdev->dev, "No NAND chips found\n");
501        goto err_gpio_busy;
363502    }
364503
365504    if (pdata && pdata->ident_callback) {
...... 
369508
370509    ret = nand_scan_tail(mtd);
371510    if (ret) {
372        dev_err(&pdev->dev, "Failed to scan nand\n");
373        goto err_gpio_free;
511        dev_err(&pdev->dev, "Failed to scan NAND\n");
512        goto err_unclaim_banks;
374513    }
375514
376515#ifdef CONFIG_MTD_CMDLINE_PARTS
...... 
393532    return 0;
394533
395534err_nand_release:
396    nand_release(&nand->mtd);
397err_gpio_free:
535    nand_release(mtd);
536err_unclaim_banks:
537    while (chipnr--) {
538        unsigned char bank = nand->banks[chipnr];
539        gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
540        jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
541                     nand->bank_base[bank - 1]);
542    }
543    writel(0, nand->base + JZ_REG_NAND_CTRL);
544err_gpio_busy:
545    if (pdata && gpio_is_valid(pdata->busy_gpio))
546        gpio_free(pdata->busy_gpio);
398547    platform_set_drvdata(pdev, NULL);
399    gpio_free(pdata->busy_gpio);
400err_iounmap_mem:
401    iounmap(nand->bank_base);
402548err_iounmap_mmio:
403    iounmap(nand->base);
549    jz_nand_iounmap_resource(nand->mem, nand->base);
404550err_free:
405551    kfree(nand);
406552    return ret;
...... 
409555static int __devexit jz_nand_remove(struct platform_device *pdev)
410556{
411557    struct jz_nand *nand = platform_get_drvdata(pdev);
558    struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
559    size_t i;
412560
413561    nand_release(&nand->mtd);
414562
415563    /* Deassert and disable all chips */
416564    writel(0, nand->base + JZ_REG_NAND_CTRL);
417565
418    iounmap(nand->bank_base);
419    release_mem_region(nand->bank_mem->start, resource_size(nand->bank_mem));
420    iounmap(nand->base);
421    release_mem_region(nand->mem->start, resource_size(nand->mem));
566    for (i = 0; i < JZ_NAND_NUM_BANKS; ++i) {
567        unsigned char bank = nand->banks[i];
568        if (bank != 0) {
569            jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
570                         nand->bank_base[bank - 1]);
571            gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
572        }
573    }
574    if (pdata && gpio_is_valid(pdata->busy_gpio))
575        gpio_free(pdata->busy_gpio);
576
577    jz_nand_iounmap_resource(nand->mem, nand->base);
422578
423579    platform_set_drvdata(pdev, NULL);
424580    kfree(nand);

Archive Download the corresponding diff file



interactive