Commit 880540de authored by Dirk Eibach's avatar Dirk Eibach Committed by Heiko Schocher

i2c, ppc4xx_i2c: switch to new multibus/multiadapter support

Signed-off-by: default avatarDirk Eibach <dirk.eibach@gdsys.cc>
Cc: Heiko Schocher <hs@denx.de>
Cc: Stefan Roese <sr@denx.de>
Tested-by: Stefan Roese's avatarStefan Roese <sr@denx.de>
parent 1f2ba722
......@@ -1985,6 +1985,11 @@ CBFS (Coreboot Filesystem) support
- This driver adds 4 i2c buses with a fix speed from
100000 and the slave addr 0!
- drivers/i2c/ppc4xx_i2c.c
- activate this driver with CONFIG_SYS_I2C_PPC4XX
- CONFIG_SYS_I2C_PPC4XX_CH0 activate hardware channel 0
- CONFIG_SYS_I2C_PPC4XX_CH1 activate hardware channel 1
additional defines:
CONFIG_SYS_NUM_I2C_BUSES
......
......@@ -52,10 +52,6 @@
/*
* Set default values
*/
#ifndef CONFIG_SYS_I2C_SPEED
#define CONFIG_SYS_I2C_SPEED 50000
#endif
#define ONE_BILLION 1000000000
#define SDRAM0_CFG_DCE 0x80000000
......@@ -158,7 +154,7 @@ long int spd_sdram(int(read_spd)(uint addr))
* Make sure I2C controller is initialized
* before continuing.
*/
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
}
/* Make shure we are using SDRAM */
......
......@@ -62,10 +62,6 @@
/*
* Set default values
*/
#ifndef CONFIG_SYS_I2C_SPEED
#define CONFIG_SYS_I2C_SPEED 50000
#endif
#define ONE_BILLION 1000000000
/*
......@@ -168,7 +164,7 @@ long int spd_sdram(void) {
* Make sure I2C controller is initialized
* before continuing.
*/
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
/*
* Read the SPD information using I2C interface. Check to see if the
......
......@@ -459,8 +459,7 @@ phys_size_t initdram(int board_type)
*/
/* switch to correct I2C bus */
I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM);
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
/*------------------------------------------------------------------
* Clear out the serial presence detect buffers.
......
......@@ -56,7 +56,7 @@ static int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
* First switch to correct I2C bus. This is I2C bus 0
* for all currently available 4xx derivats.
*/
I2C_SET_BUS(0);
i2c_set_bus_num(0);
#ifdef CONFIG_CMD_EEPROM
ret = eeprom_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
......
......@@ -1041,8 +1041,7 @@ phys_size_t initdram(int board_type)
* before continuing.
*/
/* switch to correct I2C bus */
I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM);
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
/*------------------------------------------------------------------
* Clear out the serial presence detect buffers.
......
......@@ -34,24 +34,6 @@
#define IIC_TIMEOUT 1 /* 1 second */
#if defined(CONFIG_I2C_MULTI_BUS)
#define I2C_BUS_OFFS (i2c_bus_num * 0x100)
#else
#define I2C_BUS_OFFS (0x000)
#endif /* CONFIG_I2C_MULTI_BUS */
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
#define I2C_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000700 + I2C_BUS_OFFS)
#elif defined(CONFIG_440) || defined(CONFIG_405EX)
/* all remaining 440 variants */
#define I2C_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000400 + I2C_BUS_OFFS)
#else
/* all 405 variants */
#define I2C_BASE_ADDR (0xEF600500 + I2C_BUS_OFFS)
#endif
struct ppc4xx_i2c {
u8 mdbuf;
u8 res1;
......
......@@ -51,7 +51,7 @@ uchar pll_fs6377_regs[16] = {
*/
int pll_init(void)
{
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
return i2c_write(CONFIG_SYS_I2C_PLL_ADDR, 0, 1,
(uchar *) pll_fs6377_regs, sizeof(pll_fs6377_regs));
......
......@@ -385,7 +385,6 @@ int last_stage_init(void)
return 0;
}
#if defined(CONFIG_I2C_MULTI_BUS)
/*
* read field strength from I2C ADC
*/
......@@ -500,7 +499,6 @@ U_BOOT_CMD(
"Initialize USB hub",
""
);
#endif /* CONFIG_I2C_MULTI_BUS */
#define CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS 3
int boot_eeprom_write (unsigned dev_addr,
......
......@@ -111,7 +111,7 @@ static void kbd_init (void)
uchar val, errcd;
int i;
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
gd->arch.kbd_status = 0;
......
......@@ -209,7 +209,7 @@ int board_early_init_f (void)
#endif
/* Read Serial Presence Detect Information */
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
for (i = 0; i < 128; i++)
datain[i] = 127;
i2c_read(SPD_EEPROM_ADDRESS,0,1,datain,128);
......
This diff is collapsed.
/*
* Copyright (C) 2005 Sandburst Corporation
*
* 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
*/
/*
* Ported from i2c driver for ppc4xx by AS HARNOIS by
* Travis B. Sawyer
* Sandburst Corporation
*/
#include <common.h>
#include <asm/ppc4xx.h>
#include <asm/ppc4xx-i2c.h>
#include <i2c.h>
#ifdef CONFIG_HARD_I2C
#define I2C_BUS1_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000500)
#define I2C_REGISTERS_BUS1_BASE_ADDRESS I2C_BUS1_BASE_ADDR
#define IIC_MDBUF1 (&i2c->mdbuf)
#define IIC_SDBUF1 (&i2c->sdbuf)
#define IIC_LMADR1 (&i2c->lmadr)
#define IIC_HMADR1 (&i2c->hmadr)
#define IIC_CNTL1 (&i2c->cntl)
#define IIC_MDCNTL1 (&i2c->mdcntl)
#define IIC_STS1 (&i2c->sts)
#define IIC_EXTSTS1 (&i2c->extsts)
#define IIC_LSADR1 (&i2c->lsadr)
#define IIC_HSADR1 (&i2c->hsadr)
#define IIC_CLKDIV1 (&i2c->clkdiv)
#define IIC_INTRMSK1 (&i2c->intrmsk)
#define IIC_XFRCNT1 (&i2c->xfrcnt)
#define IIC_XTCNTLSS1 (&i2c->xtcntlss)
#define IIC_DIRECTCNTL1 (&i2c->directcntl)
void i2c1_init (int speed, int slaveadd);
int i2c_probe1 (uchar chip);
int i2c_read1 (uchar chip, uint addr, int alen, uchar * buffer, int len);
int i2c_write1 (uchar chip, uint addr, int alen, uchar * buffer, int len);
uchar i2c_reg_read1(uchar i2c_addr, uchar reg);
void i2c_reg_write1(uchar i2c_addr, uchar reg, uchar val);
#endif /* CONFIG_HARD_I2C */
......@@ -26,7 +26,6 @@
#include <asm/io.h>
#include <spd_sdram.h>
#include <i2c.h>
#include "ppc440gx_i2c.h"
#include "sb_common.h"
DECLARE_GLOBAL_DATA_PTR;
......@@ -84,7 +83,7 @@ unsigned short sbcommon_get_serial_number(void)
/* Get the board serial number from eeprom */
/* Initialize I2C */
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
/* Read 256 bytes in EEPROM */
i2c_read (0x50, 0, 1, buff, 0x100);
......@@ -110,85 +109,87 @@ void sbcommon_fans(void)
* Attempt to turn on 2 of the fans...
* Need to go through the bridge
*/
i2c_set_bus_num(1);
puts ("FANS: ");
/* select fan4 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x08); /* val = bus 4 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x08); /* val = bus 4 */
/* Turn on FAN 4 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 4 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
/* select fan3 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x04); /* val = bus 3 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x04); /* val = bus 3 */
/* Turn on FAN 3 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 3 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
/* select fan2 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x02); /* val = bus 4 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x02); /* val = bus 4 */
/* Turn on FAN 2 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 2 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
/* select fan1 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x01); /* val = bus 0 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x01); /* val = bus 0 */
/* Turn on FAN 1 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 1 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
puts ("on\n");
i2c_set_bus_num(0);
return;
......@@ -319,7 +320,7 @@ void board_get_enetaddr(int macaddr_idx, uchar *enet)
if (0 == macaddr_idx) {
/* Initialize I2C */
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
/* Read 256 bytes in EEPROM */
i2c_read (0x50, 0, 1, buff, 0x100);
......
......@@ -28,7 +28,6 @@
#include <asm/io.h>
#include <spd_sdram.h>
#include <i2c.h>
#include "ppc440gx_i2c.h"
/*
* GPIO Settings
......
......@@ -40,8 +40,7 @@ CFLAGS += -DBUILDUSER='"$(BUILDUSER)"'
LIB = $(obj)lib$(BOARD).o
COBJS = $(BOARD).o ../common/flash.o ../common/ppc440gx_i2c.o \
../common/sb_common.o
COBJS = $(BOARD).o ../common/flash.o ../common/sb_common.o
SOBJS = init.o
......
......@@ -337,11 +337,6 @@ int checkboard (void)
************************************************************************/
int misc_init_f (void)
{
/* Turn on i2c bus 1 */
puts ("I2C1: ");
i2c1_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
puts ("ready\n");
/* Turn on fans 3 & 4 */
sbcommon_fans();
......
......@@ -39,8 +39,7 @@ CFLAGS += -DBUILDUSER='"$(BUILDUSER)"'
LIB = $(obj)lib$(BOARD).o
COBJS = $(BOARD).o ../common/flash.o ../common/ppc440gx_i2c.o \
../common/sb_common.o
COBJS = $(BOARD).o ../common/flash.o ../common/sb_common.o
SOBJS = init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
......
......@@ -30,7 +30,6 @@
#include <asm/io.h>
#include <spd_sdram.h>
#include <i2c.h>
#include "../common/ppc440gx_i2c.h"
#include "../common/sb_common.h"
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) || \
defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3)
......@@ -305,11 +304,6 @@ int checkboard (void)
************************************************************************/
int misc_init_f (void)
{
/* Turn on i2c bus 1 */
puts ("I2C1: ");
i2c1_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
puts ("ready\n");
/* Turn on fans */
sbcommon_fans();
......
......@@ -36,7 +36,6 @@ COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += omap24xx_i2c.o
COBJS-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
COBJS-$(CONFIG_PPC4XX_I2C) += ppc4xx_i2c.o
COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o
COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
......@@ -45,6 +44,7 @@ COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
COBJS-$(CONFIG_SYS_I2C) += i2c_core.o
COBJS-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
COBJS-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o
COBJS-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
COBJS-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
COBJS-$(CONFIG_ZYNQ_I2C) += zynq_i2c.o
......
......@@ -32,27 +32,29 @@
#include <i2c.h>
#include <asm/io.h>
#ifdef CONFIG_HARD_I2C
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_I2C_MULTI_BUS)
/*
* Initialize the bus pointer to whatever one the SPD EEPROM is on.
* Default is bus 0. This is necessary because the DDR initialization
* runs from ROM, and we can't switch buses because we can't modify
* the global variables.
*/
#ifndef CONFIG_SYS_SPD_BUS_NUM
#define CONFIG_SYS_SPD_BUS_NUM 0
static inline struct ppc4xx_i2c *ppc4xx_get_i2c(int hwadapnr)
{
unsigned long base;
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
base = CONFIG_SYS_PERIPHERAL_BASE + 0x00000700 + (hwadapnr * 0x100);
#elif defined(CONFIG_440) || defined(CONFIG_405EX)
/* all remaining 440 variants */
base = CONFIG_SYS_PERIPHERAL_BASE + 0x00000400 + (hwadapnr * 0x100);
#else
/* all 405 variants */
base = 0xEF600500 + (hwadapnr * 0x100);
#endif
static unsigned int i2c_bus_num __attribute__ ((section (".data"))) =
CONFIG_SYS_SPD_BUS_NUM;
#endif /* CONFIG_I2C_MULTI_BUS */
return (struct ppc4xx_i2c *)base;
}
static void _i2c_bus_reset(void)
static void _i2c_bus_reset(struct i2c_adapter *adap)
{
struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr);
int i;
u8 dc;
......@@ -91,11 +93,10 @@ static void _i2c_bus_reset(void)
out_8(&i2c->xtcntlss, 0);
}
void i2c_init(int speed, int slaveaddr)
static void ppc4xx_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
{
struct ppc4xx_i2c *i2c;
struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr);
int val, divisor;
int bus;
#ifdef CONFIG_SYS_I2C_INIT_BOARD
/*
......@@ -106,67 +107,57 @@ void i2c_init(int speed, int slaveaddr)
i2c_init_board();
#endif
for (bus = 0; bus < CONFIG_SYS_MAX_I2C_BUS; bus++) {
I2C_SET_BUS(bus);
/* Set i2c pointer after calling I2C_SET_BUS() */
i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
/* Handle possible failed I2C state */
/* FIXME: put this into i2c_init_board()? */
_i2c_bus_reset();
/* Handle possible failed I2C state */
/* FIXME: put this into i2c_init_board()? */
_i2c_bus_reset(adap);
/* clear lo master address */
out_8(&i2c->lmadr, 0);
/* clear lo master address */
out_8(&i2c->lmadr, 0);
/* clear hi master address */
out_8(&i2c->hmadr, 0);
/* clear lo slave address */
out_8(&i2c->lsadr, 0);
/* clear hi master address */
out_8(&i2c->hmadr, 0);
/* clear hi slave address */
out_8(&i2c->hsadr, 0);
/* clear lo slave address */
out_8(&i2c->lsadr, 0);
/* Clock divide Register */
/* set divisor according to freq_opb */
divisor = (get_OPB_freq() - 1) / 10000000;
if (divisor == 0)
divisor = 1;
out_8(&i2c->clkdiv, divisor);
/* clear hi slave address */
out_8(&i2c->hsadr, 0);
/* no interrupts */
out_8(&i2c->intrmsk, 0);
/* Clock divide Register */
/* set divisor according to freq_opb */
divisor = (get_OPB_freq() - 1) / 10000000;
if (divisor == 0)
divisor = 1;
out_8(&i2c->clkdiv, divisor);
/* clear transfer count */
out_8(&i2c->xfrcnt, 0);
/* no interrupts */
out_8(&i2c->intrmsk, 0);
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
out_8(&i2c->xtcntlss, 0xF0);
/* clear transfer count */
out_8(&i2c->xfrcnt, 0);
/* Mode Control Register
Flush Slave/Master data buffer */
out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
out_8(&i2c->xtcntlss, 0xF0);
val = in_8(&i2c->mdcntl);
/* Mode Control Register
Flush Slave/Master data buffer */
out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
/* Ignore General Call, slave transfers are ignored,
* disable interrupts, exit unknown bus state, enable hold
* SCL 100kHz normaly or FastMode for 400kHz and above
*/
val = in_8(&i2c->mdcntl);
val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL;
if (speed >= 400000)
val |= IIC_MDCNTL_FSM;
out_8(&i2c->mdcntl, val);
/* Ignore General Call, slave transfers are ignored,
* disable interrupts, exit unknown bus state, enable hold
* SCL 100kHz normaly or FastMode for 400kHz and above
*/
/* clear control reg */
out_8(&i2c->cntl, 0x00);
}
val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL;
if (speed >= 400000)
val |= IIC_MDCNTL_FSM;
out_8(&i2c->mdcntl, val);
/* set to SPD bus as default bus upon powerup */
I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM);
/* clear control reg */
out_8(&i2c->cntl, 0x00);
}
/*
......@@ -194,14 +185,15 @@ void i2c_init(int speed, int slaveaddr)
*
* It does not check XFRCNT.
*/
static int i2c_transfer(unsigned char cmd_type,
static int _i2c_transfer(struct i2c_adapter *adap,
unsigned char cmd_type,
unsigned char chip,
unsigned char addr[],
unsigned char addr_len,
unsigned char data[],
unsigned short data_len)
{
struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr);
u8 *ptr;
int reading;
int tran, cnt;
......@@ -345,7 +337,7 @@ static int i2c_transfer(unsigned char cmd_type,
return result;
}
int i2c_probe(uchar chip)
static int ppc4xx_i2c_probe(struct i2c_adapter *adap, uchar chip)
{
uchar buf[1];
......@@ -356,11 +348,11 @@ int i2c_probe(uchar chip)
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
return (i2c_transfer(1, chip << 1, 0, 0, buf, 1) != 0);
return (_i2c_transfer(adap, 1, chip << 1, 0, 0, buf, 1) != 0);
}
static int ppc4xx_i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer,
int len, int read)