/*
 * (C) Copyright 2000
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * Code in faintly related to linux/arch/powerpc/8xx_io:
 * MPC8xx CPM I2C interface. Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
 *
 * This file implements functions to read the MBX's Vital Product Data
 * (VPD). I can't use the more general i2c code in mpc8xx/... since I need
 * the VPD at a time where there is no RAM available yet. Hence the VPD is
 * read into a special area in the DPRAM (see config_MBX.h::CFG_DPRAMVPD).
 *
 * -----------------------------------------------------------------
 * 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
 */

#include <common.h>
#ifdef CONFIG_8xx
#include <commproc.h>
#endif
#include "vpd.h"

/* Location of receive/transmit buffer descriptors
 * Allocate one transmit bd and one receive bd.
 * IIC_BD_FREE points to free bd space which we'll use as tx buffer.
 */
#define IIC_BD_TX1     (BD_IIC_START + 0*sizeof(cbd_t))
#define IIC_BD_TX2     (BD_IIC_START + 1*sizeof(cbd_t))
#define IIC_BD_RX      (BD_IIC_START + 2*sizeof(cbd_t))
#define IIC_BD_FREE    (BD_IIC_START + 3*sizeof(cbd_t))

/* FIXME -- replace 0x2000 with offsetof */
#define VPD_P ((vpd_t *)(CONFIG_SYS_IMMR + 0x2000 + CONFIG_SYS_DPRAMVPD))

/* transmit/receive buffers */
#define IIC_RX_LENGTH 128

#define WITH_MICROCODE_PATCH

vpd_packet_t * vpd_find_packet(u_char ident)
{
    vpd_packet_t *packet;
    vpd_t *vpd = VPD_P;

    packet = (vpd_packet_t *)&vpd->packets;
    while ((packet->identifier != ident) && packet->identifier != 0xFF)
    {
	packet = (vpd_packet_t *)((char *)packet + packet->size + 2);
    }
    return packet;
}

void vpd_init(void)
{
    volatile immap_t  *im = (immap_t *)CONFIG_SYS_IMMR;
    volatile cpm8xx_t *cp = &(im->im_cpm);
    volatile i2c8xx_t *i2c = (i2c8xx_t *)&(im->im_i2c);
    volatile iic_t *iip;
#ifdef WITH_MICROCODE_PATCH
    ulong reloc = 0;
#endif

    iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];

    /*
     * kludge: when running from flash, no microcode patch can be
     * installed. However, the DPMEM usually contains non-zero
     * garbage at the relocatable patch base location, so lets clear
     * it now. This way the rest of the code can support the microcode
     * patch dynamically.
     */
    if ((ulong)vpd_init & 0xff000000)
      iip->iic_rpbase = 0;

#ifdef WITH_MICROCODE_PATCH
    /* Check for and use a microcode relocation patch. */
    if ((reloc = iip->iic_rpbase))
      iip = (iic_t *)&cp->cp_dpmem[iip->iic_rpbase];
#endif
    /* Initialize Port B IIC pins */
    cp->cp_pbpar |= 0x00000030;
    cp->cp_pbdir |= 0x00000030;
    cp->cp_pbodr |= 0x00000030;

    i2c->i2c_i2mod = 0x04;  /* filter clock */
    i2c->i2c_i2add = 0x34;	/* select an arbitrary (unique) address */
    i2c->i2c_i2brg = 0x07;  /* make clock run maximum slow	*/
    i2c->i2c_i2cmr = 0x00;  /* disable interrupts */
    i2c->i2c_i2cer = 0x1f;  /* clear events */
    i2c->i2c_i2com = 0x01;  /* configure i2c to work as master */

    if (vpd_read(0xa4, (uchar*)VPD_P, VPD_EEPROM_SIZE, 0) != VPD_EEPROM_SIZE)
    {
	hang();
    }
}


/* Read from I2C.
 * This is a two step process.  First, we send the "dummy" write
 * to set the device offset for the read.  Second, we perform
 * the read operation.
 */
int vpd_read(uint iic_device, uchar *buf, int count, int offset)
{
    volatile immap_t  *im = (immap_t *)CONFIG_SYS_IMMR;
    volatile cpm8xx_t *cp = &(im->im_cpm);
    volatile i2c8xx_t *i2c = (i2c8xx_t *)&(im->im_i2c);
    volatile iic_t *iip;
    volatile cbd_t *tbdf1, *tbdf2, *rbdf;
    uchar *tb;
    uchar event;
#ifdef WITH_MICROCODE_PATCH
    ulong reloc = 0;
#endif

    iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
#ifdef WITH_MICROCODE_PATCH
    /* Check for and use a microcode relocation patch. */
    if ((reloc = iip->iic_rpbase))
      iip = (iic_t *)&cp->cp_dpmem[iip->iic_rpbase];
#endif
    tbdf1 = (cbd_t *)&cp->cp_dpmem[IIC_BD_TX1];
    tbdf2 = (cbd_t *)&cp->cp_dpmem[IIC_BD_TX2];
    rbdf  = (cbd_t *)&cp->cp_dpmem[IIC_BD_RX];

    /* Send a "dummy write" operation.  This is a write request with
     * only the offset sent, followed by another start condition.
     * This will ensure we start reading from the first location
     * of the EEPROM.
     */
    tb = (uchar*)&cp->cp_dpmem[IIC_BD_FREE];
    tb[0] = iic_device & 0xfe;	/* device address */
    tb[1] = offset;	        /* offset */
    tbdf1->cbd_bufaddr = (uint)tb;
    tbdf1->cbd_datlen = 2;
    tbdf1->cbd_sc = 0x8400;

    tb += 2;
    tb[0] = iic_device | 1;	/* device address */
    tbdf2->cbd_bufaddr = (uint)tb;
    tbdf2->cbd_datlen = count+1;
    tbdf2->cbd_sc = 0xbc00;

    rbdf->cbd_bufaddr = (uint)buf;
    rbdf->cbd_datlen = 0;
    rbdf->cbd_sc = 0xb000;

    iip->iic_tbase = IIC_BD_TX1;
    iip->iic_tbptr = IIC_BD_TX1;
    iip->iic_rbase = IIC_BD_RX;
    iip->iic_rbptr = IIC_BD_RX;
    iip->iic_rfcr = 0x15;
    iip->iic_tfcr = 0x15;
    iip->iic_mrblr = count;
    iip->iic_rstate = 0;
    iip->iic_tstate = 0;

    i2c->i2c_i2cer = 0x1f;  /* clear event mask */
    i2c->i2c_i2mod |= 1;    /* enable iic operation */
    i2c->i2c_i2com |= 0x80;	/* start master */

    /* wait for IIC transfer */
    do {
	__asm__ volatile ("eieio");
	event = i2c->i2c_i2cer;
    } while (event == 0);

    if ((event & 0x10) || (event & 0x04)) {
	count = -1;
	goto bailout;
    }

bailout:
    i2c->i2c_i2mod &= ~1;   /* turn off iic operation */
    i2c->i2c_i2cer = 0x1f;  /* clear event mask */

    return count;
}
