/*
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * 07-10-2002 Frank Gottschling: added 29F032 flash (ELPPC).
 *        fixed monitor protection part
 *
 * 09-18-2001 Andreas Heppel: Reduced the code in here to the usage
 *        of AMD's 29F040 and 29F016 flashes, since the BAB7xx does use
 *        any other.
 */

#include <common.h>
#include <asm/processor.h>
#include <asm/pci_io.h>

flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */

ulong flash_get_size (vu_long *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);

/*flash command address offsets*/

#define ADDR0           (0x555)
#define ADDR1           (0x2AA)
#define ADDR3           (0x001)

#define FLASH_WORD_SIZE unsigned char

/*----------------------------------------------------------------------------*/

unsigned long flash_init (void)
{
    unsigned long size1, size2;
    int i;

    /* Init: no FLASHes known */
    for (i=0; i<CFG_MAX_FLASH_BANKS; ++i)
    {
        flash_info[i].flash_id = FLASH_UNKNOWN;
    }

    /* initialise 1st flash */
    size1 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);

    if (flash_info[0].flash_id == FLASH_UNKNOWN)
    {
        printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
            size1, size1<<20);
    }

    /* initialise 2nd flash */
    size2 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);

    if (flash_info[1].flash_id == FLASH_UNKNOWN)
    {
        printf ("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
            size2, size2<<20);
    }

    /* monitor protection ON by default */
    if (size1 == 512*1024)
    {
        (void)flash_protect(FLAG_PROTECT_SET,
                FLASH_BASE0_PRELIM,
                FLASH_BASE0_PRELIM+CFG_MONITOR_LEN-1,
                &flash_info[0]);
    }
    if (size2 == 512*1024)
    {
        (void)flash_protect(FLAG_PROTECT_SET,
                FLASH_BASE1_PRELIM,
                FLASH_BASE1_PRELIM+CFG_MONITOR_LEN-1,
                &flash_info[1]);
    }
    if (size2 == 4*1024*1024)
    {
        (void)flash_protect(FLAG_PROTECT_SET,
                CFG_FLASH_BASE,
                CFG_FLASH_BASE+CFG_MONITOR_LEN-1,
                &flash_info[1]);
    }

    return (size1 + size2);
}

/*----------------------------------------------------------------------------*/

void flash_print_info  (flash_info_t *info)
{
    int i;
    int k;
    int size;
    int erased;
    volatile unsigned long *flash;

    if (info->flash_id == FLASH_UNKNOWN) {
        printf ("missing or unknown FLASH type\n");
        flash_init();
    }

    if (info->flash_id == FLASH_UNKNOWN) {
        printf ("missing or unknown FLASH type\n");
        return;
    }

    switch (info->flash_id & FLASH_VENDMASK) {
    case FLASH_MAN_AMD:
        printf ("AMD ");
        break;
    default:
        printf ("Unknown Vendor ");
        break;
    }

    switch (info->flash_id & FLASH_TYPEMASK) {
    case AMD_ID_F040B:
        printf ("AM29F040B (4 Mbit)\n");
        break;
    case AMD_ID_F016D:
        printf ("AM29F016D (16 Mbit)\n");
        break;
    case AMD_ID_F032B:
        printf ("AM29F032B (32 Mbit)\n");
        break;
   default:
        printf ("Unknown Chip Type\n");
        break;
    }

    if (info->size >= (1 << 20)) {
        printf ("  Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
    } else {
        printf ("  Size: %ld kB in %d Sectors\n", info->size >> 10, info->sector_count);
    }

    printf ("  Sector Start Addresses:");
    for (i=0; i<info->sector_count; ++i) {
        /*
        * Check if whole sector is erased
        */
        if (i != (info->sector_count-1))
            size = info->start[i+1] - info->start[i];
        else
            size = info->start[0] + info->size - info->start[i];

        erased = 1;
        flash = (volatile unsigned long *)info->start[i];
        size = size >> 2;        /* divide by 4 for longword access */
        for (k=0; k<size; k++) {
            if (*flash++ != 0xffffffff) {
                erased = 0;
                break;
            }
        }

        if ((i % 5) == 0)
            printf ("\n   ");

        printf (" %08lX%s%s",
            info->start[i],
            erased ? " E" : "  ",
            info->protect[i] ? "RO " : "   ");
    }
    printf ("\n");
}

/*----------------------------------------------------------------------------*/
/*
 * The following code cannot be run from FLASH!
 */
ulong flash_get_size (vu_long *addr, flash_info_t *info)
{
    short i;
    ulong vendor, devid;
    ulong base = (ulong)addr;
    volatile unsigned char *caddr = (unsigned char *)addr;

#ifdef DEBUG
    printf("flash_get_size for address 0x%lx: \n", (unsigned long)caddr);
#endif

    /* Write auto select command: read Manufacturer ID */
    caddr[0] = 0xF0;   /* reset bank */
    udelay(10);

    eieio();
    caddr[0x555] = 0xAA;
    udelay(10);
    caddr[0x2AA] = 0x55;
    udelay(10);
    caddr[0x555] = 0x90;

    udelay(10);

    vendor = caddr[0];
    devid = caddr[1];

#ifdef DEBUG
    printf("Manufacturer: 0x%lx\n", vendor);
#endif

    vendor &= 0xff;
    devid &= 0xff;

    /* We accept only two AMD types */
    switch (vendor) {
    case (FLASH_WORD_SIZE)AMD_MANUFACT:
        info->flash_id = FLASH_MAN_AMD;
        break;
    default:
        info->flash_id = FLASH_UNKNOWN;
        info->sector_count = 0;
        info->size = 0;
        return (0);         /* no or unknown flash  */
    }

    switch (devid) {
    case (FLASH_WORD_SIZE)AMD_ID_F040B:
        info->flash_id |= AMD_ID_F040B;
        info->sector_count = 8;
        info->size = 0x00080000;
        break;              /* => 0.5 MB      */

    case (FLASH_WORD_SIZE)AMD_ID_F016D:
        info->flash_id |= AMD_ID_F016D;
        info->sector_count = 32;
        info->size         = 0x00200000;
        break;              /* => 2 MB      */

    case (FLASH_WORD_SIZE)AMD_ID_F032B:
        info->flash_id |= AMD_ID_F032B;
        info->sector_count = 64;
        info->size         = 0x00400000;
        break;              /* => 4 MB      */

    default:
        info->flash_id = FLASH_UNKNOWN;
        return (0);         /* => no or unknown flash */

    }

#ifdef DEBUG
    printf("flash id 0x%lx; sector count 0x%x, size 0x%lx\n", info->flash_id, info->sector_count, info->size);
#endif

    /* check for protected sectors */
    for (i = 0; i < info->sector_count; i++) {
        /* sector base address */
        info->start[i] = base + i * (info->size / info->sector_count);
        /* read sector protection at sector address, (A7 .. A0) = 0x02 */
        /* D0 = 1 if protected */
        caddr = (volatile unsigned char *)(info->start[i]);
        info->protect[i] = caddr[2] & 1;
    }

    /*
     * Prevent writes to uninitialized FLASH.
     */
    if (info->flash_id != FLASH_UNKNOWN) {
        caddr = (volatile unsigned char *)info->start[0];
        caddr[0] = 0xF0;   /* reset bank */
    }

    return (info->size);
}

/*----------------------------------------------------------------------------*/

int flash_erase (flash_info_t *info, int s_first, int s_last)
{
    volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
    int flag, prot, sect, l_sect;
    ulong start, now, last;
    int rc = 0;

    if ((s_first < 0) || (s_first > s_last)) {
        if (info->flash_id == FLASH_UNKNOWN) {
            printf ("- missing\n");
        } else {
            printf ("- no sectors to erase\n");
        }
        return 1;
    }

    if ((info->flash_id == FLASH_UNKNOWN) ||
        (info->flash_id > FLASH_AMD_COMP)) {
        printf ("Can't erase unknown flash type - aborted\n");
        return 1;
    }

    prot = 0;
    for (sect=s_first; sect<=s_last; ++sect) {
        if (info->protect[sect]) {
            prot++;
        }
    }

    if (prot) {
        printf ("- Warning: %d protected sectors will not be erased!\n",
            prot);
    } else {
        printf ("\n");
    }

    l_sect = -1;

    /* Disable interrupts which might cause a timeout here */
    flag = disable_interrupts();

    addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
    addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
    addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
    addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
    addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;

    /* Start erase on unprotected sectors */
    for (sect = s_first; sect<=s_last; sect++) {
        if (info->protect[sect] == 0) { /* not protected */
            addr = (FLASH_WORD_SIZE *)(info->start[sect]);
            if (info->flash_id & FLASH_MAN_SST) {
                addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
                addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
                addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
                addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
                addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
                addr[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */
                udelay(30000);  /* wait 30 ms */
            }
            else
                addr[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */
            l_sect = sect;
        }
    }

    /* re-enable interrupts if necessary */
    if (flag)
        enable_interrupts();

    /* wait at least 80us - let's wait 1 ms */
    udelay (1000);

    /*
     * We wait for the last triggered sector
     */
    if (l_sect < 0)
        goto DONE;

    start = get_timer (0);
    last  = start;
    addr = (FLASH_WORD_SIZE *)(info->start[l_sect]);
    while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
        if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
            printf ("Timeout\n");
            return 1;
        }
        /* show that we're waiting */
        if ((now - last) > 1000) {  /* every second */
            serial_putc ('.');
            last = now;
        }
    }

DONE:
    /* reset to read mode */
    addr = (FLASH_WORD_SIZE *)info->start[0];
    addr[0] = (FLASH_WORD_SIZE)0x00F000F0;  /* reset bank */

    printf (" done\n");
    return rc;
}

/*----------------------------------------------------------------------------*/
/*
 * Copy memory to flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
    ulong cp, wp, data;
    int i, l, rc;

    wp = (addr & ~3);   /* get lower word aligned address */

    /*
     * handle unaligned start bytes
     */
    if ((l = addr - wp) != 0) {
        data = 0;
        for (i=0, cp=wp; i<l; ++i, ++cp) {
            data = (data << 8) | (*(uchar *)cp);
        }
        for (; i<4 && cnt>0; ++i) {
            data = (data << 8) | *src++;
            --cnt;
            ++cp;
        }
        for (; cnt==0 && i<4; ++i, ++cp) {
            data = (data << 8) | (*(uchar *)cp);
        }

        if ((rc = write_word(info, wp, data)) != 0) {
            return (rc);
        }
        wp += 4;
    }

    /*
     * handle word aligned part
     */
    while (cnt >= 4) {
        data = 0;
        for (i=0; i<4; ++i) {
            data = (data << 8) | *src++;
        }
        if ((rc = write_word(info, wp, data)) != 0) {
            return (rc);
        }
        wp  += 4;
        cnt -= 4;
    }

    if (cnt == 0) {
        return (0);
    }

    /*
     * handle unaligned tail bytes
     */
    data = 0;
    for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
        data = (data << 8) | *src++;
        --cnt;
    }
    for (; i<4; ++i, ++cp) {
        data = (data << 8) | (*(uchar *)cp);
    }

    return (write_word(info, wp, data));
}

/*----------------------------------------------------------------------------*/
/* Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_word (flash_info_t *info, ulong dest, ulong data)
{
        volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
        volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
        volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
    ulong start;
    int flag;
        int i;

    /* Check if Flash is (sufficiently) erased */
    if ((*((volatile FLASH_WORD_SIZE *)dest) &
             (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
        return (2);
    }
    /* Disable interrupts which might cause a timeout here */
    flag = disable_interrupts();

        for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
          {
            addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
            addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
            addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;

            dest2[i] = data2[i];

            /* re-enable interrupts if necessary */
            if (flag)
              enable_interrupts();

            /* data polling for D7 */
            start = get_timer (0);
            while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
                   (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
              if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
                return (1);
              }
            }
          }

    return (0);
}

/*----------------------------------------------------------------------------*/

