Date:2010-11-21 18:09:56 (9 years 10 months ago)
Author:Maarten ter Huurne
Commit:54e2765ab500d482e019cbb4f0075933919a7836
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 (13 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;
...... 
303415    struct mtd_partition *partition_info;
304416    int num_partitions = 0;
305417#endif
418    size_t chipnr, bank_idx;
419    uint8_t nand_maf_id = 0, nand_dev_id = 0;
306420
307421    nand = kzalloc(sizeof(*nand), GFP_KERNEL);
308422    if (!nand) {
...... 
313427    ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
314428    if (ret)
315429        goto err_free;
316    ret = jz_nand_ioremap_resource(pdev, "bank", &nand->bank_mem,
317            &nand->bank_base);
318    if (ret)
319        goto err_iounmap_mmio;
320430
321431    if (pdata && gpio_is_valid(pdata->busy_gpio)) {
322432        ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
...... 
324434            dev_err(&pdev->dev,
325435                "Failed to request busy gpio %d: %d\n",
326436                pdata->busy_gpio, ret);
327            goto err_iounmap_mem;
437            goto err_iounmap_mmio;
328438        }
329439    }
330440
...... 
346456
347457    chip->chip_delay = 50;
348458    chip->cmd_ctrl = jz_nand_cmd_ctrl;
459    chip->select_chip = jz_nand_select_chip;
349460
350461    if (pdata && gpio_is_valid(pdata->busy_gpio))
351462        chip->dev_ready = jz_nand_dev_ready;
352463
353    chip->IO_ADDR_R = nand->bank_base;
354    chip->IO_ADDR_W = nand->bank_base;
355
356464    nand->pdata = pdata;
357465    platform_set_drvdata(pdev, nand);
358466
359    writel(JZ_NAND_CTRL_ENABLE_CHIP(0), nand->base + JZ_REG_NAND_CTRL);
360
361    ret = nand_scan_ident(mtd, 1, NULL);
362    if (ret) {
363        dev_err(&pdev->dev, "Failed to scan nand\n");
364        goto err_gpio_free;
467    /* We are going to autodetect NAND chips in the banks specified in the
468     * platform data. Although nand_scan_ident() can detect multiple chips,
469     * it requires those chips to be numbered consecuitively, which is not
470     * always the case for external memory banks. And a fixed chip-to-bank
471     * mapping is not practical either, since for example Dingoo units
472     * produced at different times have NAND chips in different banks.
473     */
474    chipnr = 0;
475    for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) {
476        unsigned char bank;
477
478        /* If there is no platform data, look for NAND in bank 1,
479         * which is the most likely bank since it is the only one
480         * that can be booted from.
481         */
482        bank = pdata ? pdata->banks[bank_idx] : bank_idx ^ 1;
483        if (bank == 0)
484            break;
485        if (bank > JZ_NAND_NUM_BANKS) {
486            dev_warn(&pdev->dev,
487                "Skipping non-existing bank: %d\n", bank);
488            continue;
489        }
490        /* The detection routine will directly or indirectly call
491         * jz_nand_select_chip(), so nand->banks has to contain the
492         * bank we're checking.
493         */
494        nand->banks[chipnr] = bank;
495        if (jz_nand_detect_bank(pdev, nand, bank, chipnr,
496                    &nand_maf_id, &nand_dev_id) == 0)
497            chipnr++;
498        else
499            nand->banks[chipnr] = 0;
500    }
501    if (chipnr == 0) {
502        dev_err(&pdev->dev, "No NAND chips found\n");
503        goto err_gpio_busy;
365504    }
366505
367506    if (pdata && pdata->ident_callback) {
...... 
371510
372511    ret = nand_scan_tail(mtd);
373512    if (ret) {
374        dev_err(&pdev->dev, "Failed to scan nand\n");
375        goto err_gpio_free;
513        dev_err(&pdev->dev, "Failed to scan NAND\n");
514        goto err_unclaim_banks;
376515    }
377516
378517#ifdef CONFIG_MTD_PARTITIONS
...... 
389528        ret = add_mtd_partitions(mtd, partition_info, num_partitions);
390529    else
391530#endif
392    ret = add_mtd_device(mtd);
531    ret = add_mtd_device(mtd) ? -ENODEV : 0;
393532
394533    if (ret) {
395534        dev_err(&pdev->dev, "Failed to add mtd device\n");
...... 
401540    return 0;
402541
403542err_nand_release:
404    nand_release(&nand->mtd);
405err_gpio_free:
543    nand_release(mtd);
544err_unclaim_banks:
545    while (chipnr--) {
546        unsigned char bank = nand->banks[chipnr];
547        gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
548        jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
549                     nand->bank_base[bank - 1]);
550    }
551    writel(0, nand->base + JZ_REG_NAND_CTRL);
552err_gpio_busy:
553    if (pdata && gpio_is_valid(pdata->busy_gpio))
554        gpio_free(pdata->busy_gpio);
406555    platform_set_drvdata(pdev, NULL);
407    gpio_free(pdata->busy_gpio);
408err_iounmap_mem:
409    iounmap(nand->bank_base);
410556err_iounmap_mmio:
411    iounmap(nand->base);
557    jz_nand_iounmap_resource(nand->mem, nand->base);
412558err_free:
413559    kfree(nand);
414560    return ret;
...... 
417563static int __devexit jz_nand_remove(struct platform_device *pdev)
418564{
419565    struct jz_nand *nand = platform_get_drvdata(pdev);
566    struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
567    size_t i;
420568
421569    nand_release(&nand->mtd);
422570
423571    /* Deassert and disable all chips */
424572    writel(0, nand->base + JZ_REG_NAND_CTRL);
425573
426    iounmap(nand->bank_base);
427    release_mem_region(nand->bank_mem->start, resource_size(nand->bank_mem));
428    iounmap(nand->base);
429    release_mem_region(nand->mem->start, resource_size(nand->mem));
574    for (i = 0; i < JZ_NAND_NUM_BANKS; ++i) {
575        unsigned char bank = nand->banks[i];
576        if (bank != 0) {
577            jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
578                         nand->bank_base[bank - 1]);
579            gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
580        }
581    }
582    if (pdata && gpio_is_valid(pdata->busy_gpio))
583        gpio_free(pdata->busy_gpio);
584
585    jz_nand_iounmap_resource(nand->mem, nand->base);
430586
431587    platform_set_drvdata(pdev, NULL);
432588    kfree(nand);

Archive Download the corresponding diff file



interactive