打印

有关vivi中 nor flash的启动问题

[复制链接]
2622|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mafei20023|  楼主 | 2008-6-17 21:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
mafei20023|  楼主 | 2008-6-18 09:57 | 只看该作者

amd_flash.c代码 probe_new_chip


#define pFlashAStartAddress             ((volatile  __u16 *)0x10000000)
#define pFlashAUnlock1Address             ((volatile  __u16 *)(0x10000000 + 0x555*2))
#define pFlashAUnlock2Address             ((volatile  __u16 *)(0x10000000 + 0x2aa*2))
#define pFlashAManufacturerIDAddress    ((volatile  __u16 *)(0x0))
#define pFlashADeviceIDAddress             ((volatile  __u16 *)(0x0 + 0x01*2))

void send_reset(void)
{
    *pFlashAUnlock1Address = 0xaa;
    //delay(DelayLength);
    *pFlashAUnlock2Address = 0x55;
    //delay(DelayLength);
    *pFlashAStartAddress = 0xf0;
}

__u16 get_manID(void)
{
    __u16 value;
    *pFlashAUnlock1Address = 0xaa;
    //delay(DelayLength);
    *pFlashAUnlock2Address = 0x55;
    //delay(DelayLength);
    *pFlashAUnlock1Address = 0x90;
    //delay(DelayLength);
    value = *pFlashAManufacturerIDAddress;
    return(value);
}
__u16 get_devID(void)
{
    __u16 value;
    *pFlashAUnlock1Address = 0xaa;
    //delay(DelayLength);
    *pFlashAUnlock2Address = 0x55;
    //delay(DelayLength);
    *pFlashAUnlock1Address = 0x90;
    //delay(DelayLength);
    value = *pFlashADeviceIDAddress;
    return(value);
}
static int probe_new_chip(struct mtd_info *mtd, __u32 base,
              struct flchip *chips,
              struct amd_flash_private *private,
              const struct amd_flash_info *table, int table_size)
{
    //__u32 mfr_id;
    //__u32 dev_id;
    __u16 mfr_id;
    __u16 dev_id;
    struct map_info *map = mtd->priv;
    struct amd_flash_private temp;
    int i;

    temp.device_type = DEVICE_TYPE_X16;    // Assume X16 (FIXME)
    temp.interleave = 2;
    map->fldrv_priv = &temp;

    /* Enter autoselect mode. */
    
    send_reset();
    mfr_id =get_manID();
    send_reset();
    
    dev_id =get_devID();
    send_reset();
    
    if ((map->buswidth == 4) && ((mfr_id >> 16) == (mfr_id & 0xffff)) &&
        ((dev_id >> 16) == (dev_id & 0xffff))) {
        mfr_id &= 0xffff;
        dev_id &= 0xffff;
    } else {
        temp.interleave = 1;
    }

    for (i = 0; i < table_size; i++) {
        if ((mfr_id == table.mfr_id) &&
            (dev_id == table.dev_id)) {
            if (chips) {
                int j;

                /* Is this an alias for an already found chip?
                 * In that case that chip should be in
                 * autoselect mode now.
                 */
                for (j = 0; j < private->numchips; j++) {
                    __u32 mfr_id_other;
                    __u32 dev_id_other;

                    mfr_id_other =
                        wide_read(map, chips[j].start +
                                   (map->buswidth *
                                ADDR_MANUFACTURER
                                   ));
                    dev_id_other =
                        wide_read(map, chips[j].start +
                                       (map->buswidth *
                                    ADDR_DEVICE_ID));
                    if (temp.interleave == 2) {
                        mfr_id_other &= 0xffff;
                        dev_id_other &= 0xffff;
                    }
                    if ((mfr_id_other == mfr_id) &&
                        (dev_id_other == dev_id)) {

                        /* Exit autoselect mode. */
                        send_cmd(map, base,
                             CMD_RESET_DATA);

                        return -1;
                    }
                }

                if (private->numchips == MAX_AMD_CHIPS) {
                    printk("%s: Too many flash chips "
                           "detected. Increase "
                           "MAX_AMD_CHIPS from %d. ",
                           map->name, MAX_AMD_CHIPS);

                    return -1;
                }

                chips[private->numchips].start = base;
                private->numchips++;
            }

            printk("%s: Found %d x %ldMiB %s at 0x%x ", map->name,
                   temp.interleave, (table.size)/(1024*1024),
                   table.name, base);

            mtd->size += table.size * temp.interleave;
            mtd->numeraseregions += table.numeraseregions;

            break;
        }
    }

    /* Exit autoselect mode. */
    send_cmd(map, base, CMD_RESET_DATA);

    if (i == table_size) {
        printk("%s: unknown flash device at 0x%x, "
               "mfr id 0x%x, dev id 0x%x ", map->name,
               base, mfr_id, dev_id);
        map->fldrv_priv = NULL;

        return -1;
    }

    private->device_type = temp.device_type;
    private->interleave = temp.interleave;

    return i;
}

使用特权

评论回复
板凳
mafei20023|  楼主 | 2008-6-18 09:59 | 只看该作者

amd_flash_probe

struct mtd_info *amd_flash_probe(struct map_info *map)
{
    /* Keep this table on the stack so that it gets deallocated after the
     * probe is done.
     */
    const struct amd_flash_info table[] = {
    {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29LV160DT,
        name: "AMD AM29LV160DT",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
            { offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29LV160DB,
        name: "AMD AM29LV160DB",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
            { offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
        }
    }, {
        mfr_id: MANUFACTURER_TOSHIBA,
        dev_id: TC58FVT160,
        name: "Toshiba TC58FVT160",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
            { offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_FUJITSU,
        dev_id: MBM29LV160TE,
        name: "Fujitsu MBM29LV160TE",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
            { offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_TOSHIBA,
        dev_id: TC58FVB160,
        name: "Toshiba TC58FVB160",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
            { offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
        }
    }, {
        mfr_id: MANUFACTURER_FUJITSU,
        dev_id: MBM29LV160BE,
        name: "Fujitsu MBM29LV160BE",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
            { offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29LV800BB,
        name: "AMD AM29LV800BB",
        size: 0x00100000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
            { offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29F800BB,
        name: "AMD AM29F800BB",
        size: 0x00100000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
            { offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29LV800BT,
        name: "AMD AM29LV800BT",
        size: 0x00100000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
            { offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29F800BT,
        name: "AMD AM29F800BT",
        size: 0x00100000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
            { offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29LV800BB,
        name: "AMD AM29LV800BB",
        size: 0x00100000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
            { offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_ST,
        dev_id: M29W800T,
        name: "ST M29W800T",
        size: 0x00100000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
            { offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_ST,
        dev_id: M29W160DT,
        name: "ST M29W160DT",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
            { offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
        }
    }, {
        mfr_id: MANUFACTURER_ST,
        dev_id: M29W160DB,
        name: "ST M29W160DB",
        size: 0x00200000,
        numeraseregions: 4,
        regions: {
            { offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
            { offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
            { offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
            { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29BDS323D,
        name: "AMD AM29BDS323D",
        size: 0x00400000,
        numeraseregions: 3,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 48 },
            { offset: 0x300000, erasesize: 0x10000, numblocks: 15 },
            { offset: 0x3f0000, erasesize: 0x02000, numblocks:  8 },
        }
    }, {
        mfr_id: MANUFACTURER_AMD,
        dev_id: AM29BDS643D,
        name: "AMD AM29BDS643D",
        size: 0x00800000,
        numeraseregions: 3,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 96 },
            { offset: 0x600000, erasesize: 0x10000, numblocks: 31 },
            { offset: 0x7f0000, erasesize: 0x02000, numblocks:  8 },
        }
    }, {
        mfr_id: MANUFACTURER_ATMEL,
        dev_id: AT49xV16x,
        name: "Atmel AT49xV16x",
        size: 0x00200000,
        numeraseregions: 2,
        regions: {
            { offset: 0x000000, erasesize: 0x02000, numblocks:  8 },
            { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
        }
    }, {
        mfr_id: MANUFACTURER_ATMEL,
        dev_id: AT49xV16xT,
        name: "Atmel AT49xV16xT",
        size: 0x00200000,
        numeraseregions: 2,
        regions: {
            { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
            { offset: 0x1F0000, erasesize: 0x02000, numblocks:  8 }
        }
    } 
    };

    struct mtd_info *mtd;
    struct flchip chips[MAX_AMD_CHIPS];
    int table_pos[MAX_AMD_CHIPS];
    struct amd_flash_private temp;
    struct amd_flash_private *private;
    u_long size;
    unsigned long base;
    int i;
    int reg_idx;
    int offset;

    mtd = (struct mtd_info*)mmalloc(sizeof(*mtd));
    if (!mtd) {
        printk("%s: malloc failed for info structure ", map->name);
        return NULL;
    }
    memset(mtd, 0, sizeof(*mtd));
    mtd->priv = map;

    memset(&temp, 0, sizeof(temp));

    printk("%s: Probing for AMD compatible flash... ", map->name);

    if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table,
                       sizeof(table)/sizeof(table[0])))
        == -1) {
        printk("%s: Found no AMD compatible device at location zero ",
               map->name);
        mfree(mtd);

        return NULL;
    }

    chips[0].start = 0;
    temp.numchips = 1;

    for (size = mtd->size; size > 1; size >>= 1) {
        temp.chipshift++;
    }
    switch (temp.interleave) {
        case 2:
            temp.chipshift += 1;
            break;
        case 4:
            temp.chipshift += 2;
            break;
    }

    /* Find out if there are any more chips in the map. */
    for (base = (1 << temp.chipshift);
         base < map->size;
         base += (1 << temp.chipshift)) {
             int numchips = temp.numchips;
        table_pos[numchips] = probe_new_chip(mtd, base, chips,
            &temp, table, sizeof(table)/sizeof(table[0]));
    }

    mtd->eraseregions = mmalloc(sizeof(struct mtd_erase_region_info) *
                    mtd->numeraseregions);
    if (!mtd->eraseregions) { 
        printk("%s: Failed to allocate "
               "memory for MTD erase region info ", map->name);
        mfree(mtd);
        map->fldrv_priv = NULL;
        return 0;
    }

    reg_idx = 0;
    offset = 0;
    for (i = 0; i < temp.numchips; i++) {
        int dev_size;
        int j;

        dev_size = 0;
        for (j = 0; j < table[table_pos]].numeraseregions; j++) {
            mtd->eraseregions[reg_idx].offset = offset +
                (table[table_pos]].regions[j].offset *
                 temp.interleave);
            mtd->eraseregions[reg_idx].erasesize =
                table[table_pos]].regions[j].erasesize *
                temp.interleave;
            mtd->eraseregions[reg_idx].numblocks =
                table[table_pos]].regions[j].numblocks;
            if (mtd->erasesize <
                mtd->eraseregions[reg_idx].erasesize) {
                mtd->erasesize =
                    mtd->eraseregions[reg_idx].erasesize;
            }
            dev_size += mtd->eraseregions[reg_idx].erasesize *
                    mtd->eraseregions[reg_idx].numblocks;
            reg_idx++;
        }
        offset += dev_size;
    }
    mtd->type = MTD_NORFLASH;
    mtd->flags = MTD_CAP_NORFLASH;
    mtd->name = map->name;
    mtd->erase = amd_flash_erase;    
    mtd->write = amd_flash_write;    
    mtd->lock = amd_flash_lock;
    mtd->unlock = amd_flash_unlock;

    private = mmalloc(sizeof(*private) + (sizeof(struct flchip) *
                          temp.numchips));
    if (!private) {
        printk("%s: kmalloc failed for private structure ", map->name);
        mfree(mtd);
        map->fldrv_priv = NULL;
        return NULL;
    }
    memcpy(private, &temp, sizeof(temp));
    memcpy(private->chips, chips,
           sizeof(struct flchip) * private->numchips);

    map->fldrv_priv = private;
    /* map->fldrv = &amd_flash_chipdrv; */

    return mtd;
}

使用特权

评论回复
地板
wb_sxck| | 2011-7-26 22:30 | 只看该作者
我也遇到了同样的问题,求回复

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

36

帖子

1

粉丝