mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
arm: Remove unused ST-Ericsson u8500 arch
This arch does not seem to be supported / used at all in the current U-Boot mainline source tree any more. So lets remove the core u8500 code and code that was only referenced by this platform. Please note that this patch also removes these config options: - CONFIG_PL011_SERIAL_RLCR - CONFIG_PL011_SERIAL_FLUSH_ON_INIT As they only seem to be referenced by u8500 based boards. Without any such board in the current code, these config option don't make sense any more. Lets remove them as well. If someone still wants to use this platform, then please send patches to re-enable support by adding at least one board that references this code. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Mathieu Poirier <mathieu.poirier@linaro.org> Cc: John Rigby <john.rigby@linaro.org> Cc: Simon Glass <sjg@chromium.org> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> Cc: Tom Rini <trini@konsulko.com> Cc: Heiko Schocher <hs@denx.de> Cc: Albert Aribaud <albert.u.boot@aribaud.net> Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
parent
62c390f8a3
commit
68282f55b8
21 changed files with 1 additions and 2142 deletions
12
README
12
README
|
@ -840,18 +840,6 @@ The following options need to be configured:
|
|||
define this to a list of base addresses for each (supported)
|
||||
port. See e.g. include/configs/versatile.h
|
||||
|
||||
CONFIG_PL011_SERIAL_RLCR
|
||||
|
||||
Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
|
||||
have separate receive and transmit line control registers. Set
|
||||
this variable to initialize the extra register.
|
||||
|
||||
CONFIG_PL011_SERIAL_FLUSH_ON_INIT
|
||||
|
||||
On some platforms (e.g. U8500) U-Boot is loaded by a second stage
|
||||
boot loader that has already initialized the UART. Define this
|
||||
variable to flush the UART at init time.
|
||||
|
||||
CONFIG_SERIAL_HW_FLOW_CONTROL
|
||||
|
||||
Define this variable to enable hw flow control in serial driver.
|
||||
|
|
|
@ -52,5 +52,4 @@ obj-$(CONFIG_RMOBILE) += rmobile/
|
|||
obj-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx/
|
||||
obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_U8500) += u8500/
|
||||
obj-$(CONFIG_VF610) += vf610/
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y := timer.o clock.o prcmu.o cpu.o
|
||||
obj-y += lowlevel.o
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2009 ST-Ericsson
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct clkrst {
|
||||
unsigned int pcken;
|
||||
unsigned int pckdis;
|
||||
unsigned int kcken;
|
||||
unsigned int kckdis;
|
||||
};
|
||||
|
||||
static unsigned int clkrst_base[] = {
|
||||
U8500_CLKRST1_BASE,
|
||||
U8500_CLKRST2_BASE,
|
||||
U8500_CLKRST3_BASE,
|
||||
0,
|
||||
U8500_CLKRST5_BASE,
|
||||
U8500_CLKRST6_BASE,
|
||||
U8500_CLKRST7_BASE, /* ED only */
|
||||
};
|
||||
|
||||
/* Turn on peripheral clock at PRCC level */
|
||||
void u8500_clock_enable(int periph, int cluster, int kern)
|
||||
{
|
||||
struct clkrst *clkrst = (struct clkrst *) clkrst_base[periph - 1];
|
||||
|
||||
if (kern != -1)
|
||||
writel(1 << kern, &clkrst->kcken);
|
||||
|
||||
if (cluster != -1)
|
||||
writel(1 << cluster, &clkrst->pcken);
|
||||
}
|
||||
|
||||
void db8500_clocks_init(void)
|
||||
{
|
||||
/*
|
||||
* Enable all clocks. This is u-boot, we can enable it all. There is no
|
||||
* powersave in u-boot.
|
||||
*/
|
||||
|
||||
u8500_clock_enable(1, 9, -1); /* GPIO0 */
|
||||
u8500_clock_enable(2, 11, -1);/* GPIO1 */
|
||||
u8500_clock_enable(3, 8, -1); /* GPIO2 */
|
||||
u8500_clock_enable(5, 1, -1); /* GPIO3 */
|
||||
u8500_clock_enable(3, 6, 6); /* UART2 */
|
||||
u8500_clock_enable(3, 3, 3); /* I2C0 */
|
||||
u8500_clock_enable(1, 5, 5); /* SDI0 */
|
||||
u8500_clock_enable(2, 4, 2); /* SDI4 */
|
||||
u8500_clock_enable(6, 6, -1); /* MTU0 */
|
||||
u8500_clock_enable(3, 4, 4); /* SDI2 */
|
||||
|
||||
/*
|
||||
* Enabling clocks for all devices which are AMBA devices in the
|
||||
* kernel. Otherwise they will not get probe()'d because the
|
||||
* peripheral ID register will not be powered.
|
||||
*/
|
||||
|
||||
/* XXX: some of these differ between ED/V1 */
|
||||
|
||||
u8500_clock_enable(1, 1, 1); /* UART1 */
|
||||
u8500_clock_enable(1, 0, 0); /* UART0 */
|
||||
u8500_clock_enable(3, 2, 2); /* SSP1 */
|
||||
u8500_clock_enable(3, 1, 1); /* SSP0 */
|
||||
u8500_clock_enable(2, 8, -1); /* SPI0 */
|
||||
u8500_clock_enable(2, 5, 3); /* MSP2 */
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Linaro Limited
|
||||
* Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
*
|
||||
* Based on original code from Joakim Axelsson at ST-Ericsson
|
||||
* (C) Copyright 2010 ST-Ericsson
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/prcmu.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
#define CPUID_DB8500V1 0x411fc091
|
||||
#define CPUID_DB8500V2 0x412fc091
|
||||
#define ASICID_DB8500V11 0x008500A1
|
||||
|
||||
#define CACHE_CONTR_BASE 0xA0412000
|
||||
/* Cache controller register offsets
|
||||
* as found in ARM's technical reference manual
|
||||
*/
|
||||
#define CACHE_INVAL_BY_WAY (CACHE_CONTR_BASE + 0x77C)
|
||||
#define CACHE_LOCKDOWN_BY_D (CACHE_CONTR_BASE + 0X900)
|
||||
#define CACHE_LOCKDOWN_BY_I (CACHE_CONTR_BASE + 0X904)
|
||||
|
||||
static unsigned int read_asicid(void);
|
||||
|
||||
static inline unsigned int read_cpuid(void)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
/* Main ID register (MIDR) */
|
||||
asm("mrc p15, 0, %0, c0, c0, 0"
|
||||
: "=r" (val)
|
||||
:
|
||||
: "cc");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int cpu_is_u8500v11(void)
|
||||
{
|
||||
return read_asicid() == ASICID_DB8500V11;
|
||||
}
|
||||
|
||||
static int cpu_is_u8500v2(void)
|
||||
{
|
||||
return read_cpuid() == CPUID_DB8500V2;
|
||||
}
|
||||
|
||||
static unsigned int read_asicid(void)
|
||||
{
|
||||
unsigned int *address;
|
||||
|
||||
if (cpu_is_u8500v2())
|
||||
address = (void *) U8500_ASIC_ID_LOC_V2;
|
||||
else
|
||||
address = (void *) U8500_ASIC_ID_LOC_ED_V1;
|
||||
|
||||
return readl(address);
|
||||
}
|
||||
|
||||
void cpu_cache_initialization(void)
|
||||
{
|
||||
unsigned int value;
|
||||
/* invalidate all cache entries */
|
||||
writel(0xFFFF, CACHE_INVAL_BY_WAY);
|
||||
|
||||
/* ways are set to '0' when they are totally
|
||||
* cleaned and invalidated
|
||||
*/
|
||||
do {
|
||||
value = readl(CACHE_INVAL_BY_WAY);
|
||||
} while (value & 0xFF);
|
||||
|
||||
/* Invalidate register 9 D and I lockdown */
|
||||
writel(0xFF, CACHE_LOCKDOWN_BY_D);
|
||||
writel(0xFF, CACHE_LOCKDOWN_BY_I);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_CPU_INIT
|
||||
/*
|
||||
* SOC specific cpu init
|
||||
*/
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
db8500_prcmu_init();
|
||||
db8500_clocks_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ARCH_CPU_INIT */
|
||||
|
||||
#ifdef CONFIG_MMC
|
||||
|
||||
int u8500_mmc_power_init(void)
|
||||
{
|
||||
int ret;
|
||||
int enable, voltage;
|
||||
int ab8500_revision;
|
||||
|
||||
if (!cpu_is_u8500v11() && !cpu_is_u8500v2())
|
||||
return 0;
|
||||
|
||||
/* Get AB8500 revision */
|
||||
ret = ab8500_read(AB8500_MISC, AB8500_REV_REG);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ab8500_revision = ret;
|
||||
|
||||
/*
|
||||
* On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
|
||||
* card to work. This is done by enabling the regulators in the AB8500
|
||||
* via PRCMU I2C transactions.
|
||||
*
|
||||
* This code is derived from the handling of AB8500_LDO_VAUX3 in
|
||||
* ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
|
||||
*
|
||||
* Turn off and delay is required to have it work across soft reboots.
|
||||
*/
|
||||
|
||||
/* Turn off (read-modify-write) */
|
||||
ret = ab8500_read(AB8500_REGU_CTRL2,
|
||||
AB8500_REGU_VRF1VAUX3_REGU_REG);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
enable = ret;
|
||||
|
||||
/* Turn off */
|
||||
ret = ab8500_write(AB8500_REGU_CTRL2,
|
||||
AB8500_REGU_VRF1VAUX3_REGU_REG,
|
||||
enable & ~LDO_VAUX3_ENABLE_MASK);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
udelay(10 * 1000);
|
||||
|
||||
/* Set the voltage to 2.91 V or 2.9 V without overriding VRF1 value */
|
||||
ret = ab8500_read(AB8500_REGU_CTRL2,
|
||||
AB8500_REGU_VRF1VAUX3_SEL_REG);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
voltage = ret;
|
||||
|
||||
if (ab8500_revision < 0x20) {
|
||||
voltage &= ~LDO_VAUX3_SEL_MASK;
|
||||
voltage |= LDO_VAUX3_SEL_2V9;
|
||||
} else {
|
||||
voltage &= ~LDO_VAUX3_V2_SEL_MASK;
|
||||
voltage |= LDO_VAUX3_V2_SEL_2V91;
|
||||
}
|
||||
|
||||
ret = ab8500_write(AB8500_REGU_CTRL2,
|
||||
AB8500_REGU_VRF1VAUX3_SEL_REG, voltage);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Turn on the supply */
|
||||
enable &= ~LDO_VAUX3_ENABLE_MASK;
|
||||
enable |= LDO_VAUX3_ENABLE_VAL;
|
||||
|
||||
ret = ab8500_write(AB8500_REGU_CTRL2,
|
||||
AB8500_REGU_VRF1VAUX3_REGU_REG, enable);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_MMC */
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2011 ST-Ericsson
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
ENTRY(lowlevel_init)
|
||||
mov pc, lr
|
||||
ENDPROC(lowlevel_init)
|
||||
|
||||
.align 5
|
||||
ENTRY(reset_cpu)
|
||||
ldr r0, =CFG_PRCMU_BASE
|
||||
ldr r1, =0x1
|
||||
str r1, [r0, #0x228]
|
||||
_loop_forever:
|
||||
b _loop_forever
|
||||
ENDPROC(reset_cpu)
|
|
@ -1,214 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 ST-Ericsson SA
|
||||
*
|
||||
* Adapted from the Linux version:
|
||||
* Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This currently does not support the I2C workaround access method.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/prcmu.h>
|
||||
|
||||
/* CPU mailbox registers */
|
||||
#define PRCMU_I2C_WRITE(slave) \
|
||||
(((slave) << 1) | I2CWRITE | (1 << 6))
|
||||
#define PRCMU_I2C_READ(slave) \
|
||||
(((slave) << 1) | I2CREAD | (1 << 6))
|
||||
|
||||
#define I2C_MBOX_BIT (1 << 5)
|
||||
|
||||
static int prcmu_is_ready(void)
|
||||
{
|
||||
int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
|
||||
if (!ready)
|
||||
printf("PRCMU firmware not ready\n");
|
||||
return ready;
|
||||
}
|
||||
|
||||
static int wait_for_i2c_mbx_rdy(void)
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
if (readl(PRCM_ARM_IT1_VAL) & I2C_MBOX_BIT) {
|
||||
printf("prcmu: warning i2c mailbox was not acked\n");
|
||||
/* clear mailbox 5 ack irq */
|
||||
writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
/* check any already on-going transaction */
|
||||
while ((readl(PRCM_MBOX_CPU_VAL) & I2C_MBOX_BIT) && timeout)
|
||||
timeout--;
|
||||
|
||||
if (timeout == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wait_for_i2c_req_done(void)
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
/* Set an interrupt to XP70 */
|
||||
writel(I2C_MBOX_BIT, PRCM_MBOX_CPU_SET);
|
||||
|
||||
/* wait for mailbox 5 (i2c) ack */
|
||||
while (!(readl(PRCM_ARM_IT1_VAL) & I2C_MBOX_BIT) && timeout)
|
||||
timeout--;
|
||||
|
||||
if (timeout == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
|
||||
* @reg: - db8500 register bank to be accessed
|
||||
* @slave: - db8500 register to be accessed
|
||||
* Returns: ACK_MB5 value containing the status
|
||||
*/
|
||||
int prcmu_i2c_read(u8 reg, u16 slave)
|
||||
{
|
||||
uint8_t i2c_status;
|
||||
uint8_t i2c_val;
|
||||
int ret;
|
||||
|
||||
if (!prcmu_is_ready())
|
||||
return -1;
|
||||
|
||||
debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
|
||||
reg, slave);
|
||||
|
||||
ret = wait_for_i2c_mbx_rdy();
|
||||
if (ret) {
|
||||
printf("prcmu_i2c_read: mailbox became not ready\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* prepare the data for mailbox 5 */
|
||||
writeb(PRCMU_I2C_READ(reg), PRCM_REQ_MB5_I2COPTYPE_REG);
|
||||
writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
|
||||
writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
|
||||
writeb(0, PRCM_REQ_MB5_I2CVAL);
|
||||
|
||||
ret = wait_for_i2c_req_done();
|
||||
if (ret) {
|
||||
printf("prcmu_i2c_read: mailbox request timed out\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* retrieve values */
|
||||
debug("ack-mb5:transfer status = %x\n",
|
||||
readb(PRCM_ACK_MB5_STATUS));
|
||||
debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
|
||||
debug("ack-mb5:slave_add = %x\n",
|
||||
readb(PRCM_ACK_MB5_SLAVE));
|
||||
debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
|
||||
|
||||
i2c_status = readb(PRCM_ACK_MB5_STATUS);
|
||||
i2c_val = readb(PRCM_ACK_MB5_VAL);
|
||||
/* clear mailbox 5 ack irq */
|
||||
writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
|
||||
|
||||
if (i2c_status == I2C_RD_OK)
|
||||
return i2c_val;
|
||||
|
||||
printf("prcmu_i2c_read:read return status= %d\n", i2c_status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
|
||||
* @reg: - db8500 register bank to be accessed
|
||||
* @slave: - db800 register to be written to
|
||||
* @reg_data: - the data to write
|
||||
* Returns: ACK_MB5 value containing the status
|
||||
*/
|
||||
int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
|
||||
{
|
||||
uint8_t i2c_status;
|
||||
int ret;
|
||||
|
||||
if (!prcmu_is_ready())
|
||||
return -1;
|
||||
|
||||
debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
|
||||
reg, slave);
|
||||
|
||||
ret = wait_for_i2c_mbx_rdy();
|
||||
if (ret) {
|
||||
printf("prcmu_i2c_write: mailbox became not ready\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* prepare the data for mailbox 5 */
|
||||
writeb(PRCMU_I2C_WRITE(reg), PRCM_REQ_MB5_I2COPTYPE_REG);
|
||||
writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
|
||||
writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
|
||||
writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
|
||||
|
||||
ret = wait_for_i2c_req_done();
|
||||
if (ret) {
|
||||
printf("prcmu_i2c_write: mailbox request timed out\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* retrieve values */
|
||||
debug("ack-mb5:transfer status = %x\n",
|
||||
readb(PRCM_ACK_MB5_STATUS));
|
||||
debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
|
||||
debug("ack-mb5:slave_add = %x\n",
|
||||
readb(PRCM_ACK_MB5_SLAVE));
|
||||
debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
|
||||
|
||||
i2c_status = readb(PRCM_ACK_MB5_STATUS);
|
||||
debug("\ni2c_status = %x\n", i2c_status);
|
||||
/* clear mailbox 5 ack irq */
|
||||
writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
|
||||
|
||||
if (i2c_status == I2C_WR_OK)
|
||||
return 0;
|
||||
|
||||
printf("%s: i2c_status : 0x%x\n", __func__, i2c_status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void u8500_prcmu_enable(u32 *reg)
|
||||
{
|
||||
writel(readl(reg) | (1 << 8), reg);
|
||||
}
|
||||
|
||||
void db8500_prcmu_init(void)
|
||||
{
|
||||
/* Enable timers */
|
||||
writel(1 << 17, PRCM_TCR);
|
||||
|
||||
u8500_prcmu_enable((u32 *)PRCM_PER1CLK_MGT_REG);
|
||||
u8500_prcmu_enable((u32 *)PRCM_PER2CLK_MGT_REG);
|
||||
u8500_prcmu_enable((u32 *)PRCM_PER3CLK_MGT_REG);
|
||||
/* PER4CLK does not exist */
|
||||
u8500_prcmu_enable((u32 *)PRCM_PER5CLK_MGT_REG);
|
||||
u8500_prcmu_enable((u32 *)PRCM_PER6CLK_MGT_REG);
|
||||
/* Only exists in ED but is always ok to write to */
|
||||
u8500_prcmu_enable((u32 *)PRCM_PER7CLK_MGT_REG);
|
||||
|
||||
u8500_prcmu_enable((u32 *)PRCM_UARTCLK_MGT_REG);
|
||||
u8500_prcmu_enable((u32 *)PRCM_I2CCLK_MGT_REG);
|
||||
|
||||
u8500_prcmu_enable((u32 *)PRCM_SDMMCCLK_MGT_REG);
|
||||
|
||||
/* Clean up the mailbox interrupts after pre-u-boot code. */
|
||||
writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Linaro Limited
|
||||
* John Rigby <john.rigby@linaro.org>
|
||||
*
|
||||
* Based on original from Linux kernel source and
|
||||
* internal ST-Ericsson U-Boot source.
|
||||
* (C) Copyright 2009 Alessandro Rubini
|
||||
* (C) Copyright 2010 ST-Ericsson
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* The MTU device has some interrupt control registers
|
||||
* followed by 4 timers.
|
||||
*/
|
||||
|
||||
/* The timers */
|
||||
struct u8500_mtu_timer {
|
||||
u32 lr; /* Load value */
|
||||
u32 cv; /* Current value */
|
||||
u32 cr; /* Control reg */
|
||||
u32 bglr; /* ??? */
|
||||
};
|
||||
|
||||
/* The MTU that contains the timers */
|
||||
struct u8500_mtu {
|
||||
u32 imsc; /* Interrupt mask set/clear */
|
||||
u32 ris; /* Raw interrupt status */
|
||||
u32 mis; /* Masked interrupt status */
|
||||
u32 icr; /* Interrupt clear register */
|
||||
struct u8500_mtu_timer pt[4];
|
||||
};
|
||||
|
||||
/* bits for the control register */
|
||||
#define MTU_CR_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR */
|
||||
#define MTU_CR_32BITS 0x02
|
||||
|
||||
#define MTU_CR_PRESCALE_1 0x00
|
||||
#define MTU_CR_PRESCALE_16 0x04
|
||||
#define MTU_CR_PRESCALE_256 0x08
|
||||
#define MTU_CR_PRESCALE_MASK 0x0c
|
||||
|
||||
#define MTU_CR_PERIODIC 0x40 /* if 0 = free-running */
|
||||
#define MTU_CR_ENA 0x80
|
||||
|
||||
/*
|
||||
* The MTU is clocked at 133 MHz by default. (V1 and later)
|
||||
*/
|
||||
#define TIMER_CLOCK (133 * 1000 * 1000 / 16)
|
||||
#define COUNT_TO_USEC(x) ((x) * 16 / 133)
|
||||
#define USEC_TO_COUNT(x) ((x) * 133 / 16)
|
||||
#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ)
|
||||
#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ)
|
||||
#define TIMER_LOAD_VAL 0xffffffff
|
||||
|
||||
/*
|
||||
* MTU timer to use (from 0 to 3).
|
||||
*/
|
||||
#define MTU_TIMER 2
|
||||
|
||||
static struct u8500_mtu_timer *timer_base =
|
||||
&((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
|
||||
|
||||
/* macro to read the 32 bit timer: since it decrements, we invert read value */
|
||||
#define READ_TIMER() (~readl(&timer_base->cv))
|
||||
|
||||
/* Configure a free-running, auto-wrap counter with /16 prescaler */
|
||||
int timer_init(void)
|
||||
{
|
||||
writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
|
||||
&timer_base->cr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
/* current tick value */
|
||||
ulong now = TICKS_TO_HZ(READ_TIMER());
|
||||
|
||||
if (now >= gd->arch.lastinc) { /* normal (non rollover) */
|
||||
gd->arch.tbl += (now - gd->arch.lastinc);
|
||||
} else { /* rollover */
|
||||
gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) -
|
||||
gd->arch.lastinc) + now;
|
||||
}
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/* Delay x useconds */
|
||||
void __udelay(ulong usec)
|
||||
{
|
||||
long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
|
||||
ulong now, last = READ_TIMER();
|
||||
|
||||
while (tmo > 0) {
|
||||
now = READ_TIMER();
|
||||
if (now > last) /* normal (non rollover) */
|
||||
tmo -= now - last;
|
||||
else /* rollover */
|
||||
tmo -= TIMER_LOAD_VAL - last + now;
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emulation of Power architecture long long timebase.
|
||||
*
|
||||
* TODO: Support gd->arch.tbu for real long long timebase.
|
||||
*/
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Emulation of Power architecture timebase.
|
||||
* NB: Low resolution compared to Power tbclk.
|
||||
*/
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2009
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_CLOCK
|
||||
#define __ASM_ARCH_CLOCK
|
||||
|
||||
struct prcmu {
|
||||
unsigned int armclkfix_mgt;
|
||||
unsigned int armclk_mgt;
|
||||
unsigned int svammdspclk_mgt;
|
||||
unsigned int siammdspclk_mgt;
|
||||
unsigned int reserved;
|
||||
unsigned int sgaclk_mgt;
|
||||
unsigned int uartclk_mgt;
|
||||
unsigned int msp02clk_mgt;
|
||||
unsigned int i2cclk_mgt;
|
||||
unsigned int sdmmcclk_mgt;
|
||||
unsigned int slimclk_mgt;
|
||||
unsigned int per1clk_mgt;
|
||||
unsigned int per2clk_mgt;
|
||||
unsigned int per3clk_mgt;
|
||||
unsigned int per5clk_mgt;
|
||||
unsigned int per6clk_mgt;
|
||||
unsigned int per7clk_mgt;
|
||||
unsigned int lcdclk_mgt;
|
||||
unsigned int reserved1;
|
||||
unsigned int bmlclk_mgt;
|
||||
unsigned int hsitxclk_mgt;
|
||||
unsigned int hsirxclk_mgt;
|
||||
unsigned int hdmiclk_mgt;
|
||||
unsigned int apeatclk_mgt;
|
||||
unsigned int apetraceclk_mgt;
|
||||
unsigned int mcdeclk_mgt;
|
||||
unsigned int ipi2cclk_mgt;
|
||||
unsigned int dsialtclk_mgt;
|
||||
unsigned int spare2clk_mgt;
|
||||
unsigned int dmaclk_mgt;
|
||||
unsigned int b2r2clk_mgt;
|
||||
unsigned int tvclk_mgt;
|
||||
unsigned int unused[82];
|
||||
unsigned int tcr;
|
||||
unsigned int unused1[23];
|
||||
unsigned int ape_softrst;
|
||||
};
|
||||
|
||||
extern void u8500_clock_enable(int periph, int kern, int cluster);
|
||||
|
||||
void db8500_clocks_init(void);
|
||||
|
||||
#endif /* __ASM_ARCH_CLOCK */
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Structures and registers for GPIO access in the Nomadik SoC
|
||||
*
|
||||
* Code ported from Nomadik GPIO driver in ST-Ericsson Linux kernel code.
|
||||
* The purpose is that GPIO config found in kernel should work by simply
|
||||
* copy-paste it to U-boot.
|
||||
*
|
||||
* Ported to U-boot by:
|
||||
* Copyright (C) 2010 Joakim Axelsson <joakim.axelsson AT stericsson.com>
|
||||
* Copyright (C) 2008 STMicroelectronics
|
||||
* Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
|
||||
* Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __DB8500_GPIO_H__
|
||||
#define __DB8500_GPIO_H__
|
||||
|
||||
/* Alternate functions: function C is set in hw by setting both A and B */
|
||||
enum db8500_gpio_alt {
|
||||
DB8500_GPIO_ALT_GPIO = 0,
|
||||
DB8500_GPIO_ALT_A = 1,
|
||||
DB8500_GPIO_ALT_B = 2,
|
||||
DB8500_GPIO_ALT_C = (DB8500_GPIO_ALT_A | DB8500_GPIO_ALT_B)
|
||||
};
|
||||
|
||||
enum db8500_gpio_pull {
|
||||
DB8500_GPIO_PULL_NONE,
|
||||
DB8500_GPIO_PULL_UP,
|
||||
DB8500_GPIO_PULL_DOWN
|
||||
};
|
||||
|
||||
void db8500_gpio_set_pull(unsigned gpio, enum db8500_gpio_pull pull);
|
||||
void db8500_gpio_make_input(unsigned gpio);
|
||||
int db8500_gpio_get_input(unsigned gpio);
|
||||
void db8500_gpio_make_output(unsigned gpio, int val);
|
||||
void db8500_gpio_set_output(unsigned gpio, int val);
|
||||
|
||||
#endif /* __DB8500_GPIO_H__ */
|
|
@ -1,170 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Code ported from Nomadik GPIO driver in ST-Ericsson Linux kernel code.
|
||||
* The purpose is that GPIO config found in kernel should work by simply
|
||||
* copy-paste it to U-boot. Ported 2010 to U-boot by:
|
||||
* Author: Joakim Axelsson <joakim.axelsson AT stericsson.com>
|
||||
*
|
||||
* License terms: GNU General Public License, version 2
|
||||
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
|
||||
*
|
||||
*
|
||||
* Based on arch/arm/mach-pxa/include/mach/mfp.h:
|
||||
* Copyright (C) 2007 Marvell International Ltd.
|
||||
* eric miao <eric.miao@marvell.com>
|
||||
*/
|
||||
|
||||
#ifndef __DB8500_PINCFG_H
|
||||
#define __DB8500_PINCFG_H
|
||||
|
||||
#include "db8500_gpio.h"
|
||||
|
||||
/*
|
||||
* U-boot info:
|
||||
* SLPM (sleep mode) config will be ignored by U-boot but it is still
|
||||
* possible to configure it in order to keep cut-n-paste compability
|
||||
* with Linux kernel config.
|
||||
*
|
||||
* pin configurations are represented by 32-bit integers:
|
||||
*
|
||||
* bit 0.. 8 - Pin Number (512 Pins Maximum)
|
||||
* bit 9..10 - Alternate Function Selection
|
||||
* bit 11..12 - Pull up/down state
|
||||
* bit 13 - Sleep mode behaviour (not used in U-boot)
|
||||
* bit 14 - Direction
|
||||
* bit 15 - Value (if output)
|
||||
* bit 16..18 - SLPM pull up/down state (not used in U-boot)
|
||||
* bit 19..20 - SLPM direction (not used in U-boot)
|
||||
* bit 21..22 - SLPM Value (if output) (not used in U-boot)
|
||||
*
|
||||
* to facilitate the definition, the following macros are provided
|
||||
*
|
||||
* PIN_CFG_DEFAULT - default config (0):
|
||||
* pull up/down = disabled
|
||||
* sleep mode = input/wakeup
|
||||
* direction = input
|
||||
* value = low
|
||||
* SLPM direction = same as normal
|
||||
* SLPM pull = same as normal
|
||||
* SLPM value = same as normal
|
||||
*
|
||||
* PIN_CFG - default config with alternate function
|
||||
* PIN_CFG_PULL - default config with alternate function and pull up/down
|
||||
*/
|
||||
|
||||
/* Sleep mode */
|
||||
enum db8500_gpio_slpm {
|
||||
DB8500_GPIO_SLPM_INPUT,
|
||||
DB8500_GPIO_SLPM_WAKEUP_ENABLE = DB8500_GPIO_SLPM_INPUT,
|
||||
DB8500_GPIO_SLPM_NOCHANGE,
|
||||
DB8500_GPIO_SLPM_WAKEUP_DISABLE = DB8500_GPIO_SLPM_NOCHANGE,
|
||||
};
|
||||
|
||||
#define PIN_NUM_MASK 0x1ff
|
||||
#define PIN_NUM(x) ((x) & PIN_NUM_MASK)
|
||||
|
||||
#define PIN_ALT_SHIFT 9
|
||||
#define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT)
|
||||
#define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
|
||||
#define PIN_GPIO (DB8500_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
|
||||
#define PIN_ALT_A (DB8500_GPIO_ALT_A << PIN_ALT_SHIFT)
|
||||
#define PIN_ALT_B (DB8500_GPIO_ALT_B << PIN_ALT_SHIFT)
|
||||
#define PIN_ALT_C (DB8500_GPIO_ALT_C << PIN_ALT_SHIFT)
|
||||
|
||||
#define PIN_PULL_SHIFT 11
|
||||
#define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT)
|
||||
#define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
|
||||
#define PIN_PULL_NONE (DB8500_GPIO_PULL_NONE << PIN_PULL_SHIFT)
|
||||
#define PIN_PULL_UP (DB8500_GPIO_PULL_UP << PIN_PULL_SHIFT)
|
||||
#define PIN_PULL_DOWN (DB8500_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
|
||||
|
||||
#define PIN_SLPM_SHIFT 13
|
||||
#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
|
||||
#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
|
||||
#define PIN_SLPM_MAKE_INPUT (DB8500_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
|
||||
#define PIN_SLPM_NOCHANGE (DB8500_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
|
||||
/* These two replace the above in DB8500v2+ */
|
||||
#define PIN_SLPM_WAKEUP_ENABLE \
|
||||
(DB8500_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
|
||||
#define PIN_SLPM_WAKEUP_DISABLE \
|
||||
(DB8500_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
|
||||
|
||||
#define PIN_DIR_SHIFT 14
|
||||
#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
|
||||
#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
|
||||
#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT)
|
||||
#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT)
|
||||
|
||||
#define PIN_VAL_SHIFT 15
|
||||
#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT)
|
||||
#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
|
||||
#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
|
||||
#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
|
||||
|
||||
#define PIN_SLPM_PULL_SHIFT 16
|
||||
#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT)
|
||||
#define PIN_SLPM_PULL(x) \
|
||||
(((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
|
||||
#define PIN_SLPM_PULL_NONE \
|
||||
((1 + DB8500_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
|
||||
#define PIN_SLPM_PULL_UP \
|
||||
((1 + DB8500_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
|
||||
#define PIN_SLPM_PULL_DOWN \
|
||||
((1 + DB8500_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
|
||||
|
||||
#define PIN_SLPM_DIR_SHIFT 19
|
||||
#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT)
|
||||
#define PIN_SLPM_DIR(x) \
|
||||
(((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
|
||||
#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT)
|
||||
#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT)
|
||||
|
||||
#define PIN_SLPM_VAL_SHIFT 21
|
||||
#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT)
|
||||
#define PIN_SLPM_VAL(x) \
|
||||
(((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
|
||||
#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
|
||||
#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
|
||||
|
||||
/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
|
||||
#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
|
||||
#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
|
||||
#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE)
|
||||
#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
|
||||
#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
|
||||
|
||||
#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
|
||||
#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
|
||||
#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
|
||||
#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
|
||||
#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
|
||||
|
||||
#define PIN_CFG_DEFAULT (0)
|
||||
|
||||
#define PIN_CFG(num, alt) \
|
||||
(PIN_CFG_DEFAULT |\
|
||||
(PIN_NUM(num) | PIN_##alt))
|
||||
|
||||
#define PIN_CFG_INPUT(num, alt, pull) \
|
||||
(PIN_CFG_DEFAULT |\
|
||||
(PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
|
||||
|
||||
#define PIN_CFG_OUTPUT(num, alt, val) \
|
||||
(PIN_CFG_DEFAULT |\
|
||||
(PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
|
||||
|
||||
#define PIN_CFG_PULL(num, alt, pull) \
|
||||
((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\
|
||||
(PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull))
|
||||
|
||||
/**
|
||||
* db8500_gpio_config_pins - configure several pins at once
|
||||
* @cfgs: array of pin configurations
|
||||
* @num: number of elments in the array
|
||||
*
|
||||
* Configures several GPIO pins.
|
||||
*/
|
||||
void db8500_gpio_config_pins(unsigned long *cfgs, size_t num);
|
||||
|
||||
#endif
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2009
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _UX500_GPIO_h
|
||||
#define _UX500_GPIO_h
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/arch/u8500.h>
|
||||
|
||||
#define GPIO_TOTAL_PINS 268
|
||||
|
||||
#define GPIO_PINS_PER_BLOCK 32
|
||||
#define GPIO_BLOCKS_COUNT (GPIO_TOTAL_PINS/GPIO_PINS_PER_BLOCK + 1)
|
||||
#define GPIO_BLOCK(pin) (((pin + GPIO_PINS_PER_BLOCK) >> 5) - 1)
|
||||
|
||||
|
||||
struct gpio_register {
|
||||
u32 gpio_dat; /* data register : 0x000 */
|
||||
u32 gpio_dats; /* data Set register : 0x004 */
|
||||
u32 gpio_datc; /* data Clear register : 0x008 */
|
||||
u32 gpio_pdis; /* Pull disable register : 0x00C */
|
||||
u32 gpio_dir; /* data direction register : 0x010 */
|
||||
u32 gpio_dirs; /* data dir Set register : 0x014 */
|
||||
u32 gpio_dirc; /* data dir Clear register : 0x018 */
|
||||
u32 gpio_slpm; /* Sleep mode register : 0x01C */
|
||||
u32 gpio_afsa; /* AltFun A Select reg : 0x020 */
|
||||
u32 gpio_afsb; /* AltFun B Select reg : 0x024 */
|
||||
u32 gpio_lowemi;/* low EMI Select reg : 0x028 */
|
||||
u32 reserved_1[(0x040 - 0x02C) >> 2]; /*0x028-0x3C Reserved*/
|
||||
u32 gpio_rimsc; /* rising edge intr set/clear : 0x040 */
|
||||
u32 gpio_fimsc; /* falling edge intr set/clear register : 0x044 */
|
||||
u32 gpio_mis; /* masked interrupt status register : 0x048 */
|
||||
u32 gpio_ic; /* Interrupt Clear register : 0x04C */
|
||||
u32 gpio_rwimsc;/* Rising-edge Wakeup IMSC register : 0x050 */
|
||||
u32 gpio_fwimsc;/* Falling-edge Wakeup IMSC register : 0x054 */
|
||||
u32 gpio_wks; /* Wakeup Status register : 0x058 */
|
||||
};
|
||||
|
||||
/* Error values returned by functions */
|
||||
enum gpio_error {
|
||||
GPIO_OK = 0,
|
||||
GPIO_UNSUPPORTED_HW = -2,
|
||||
GPIO_UNSUPPORTED_FEATURE = -3,
|
||||
GPIO_INVALID_PARAMETER = -4,
|
||||
GPIO_REQUEST_NOT_APPLICABLE = -5,
|
||||
GPIO_REQUEST_PENDING = -6,
|
||||
GPIO_NOT_CONFIGURED = -7,
|
||||
GPIO_INTERNAL_ERROR = -8,
|
||||
GPIO_INTERNAL_EVENT = 1,
|
||||
GPIO_REMAINING_EVENT = 2,
|
||||
GPIO_NO_MORE_PENDING_EVENT = 3,
|
||||
GPIO_INVALID_CLIENT = -25,
|
||||
GPIO_INVALID_PIN = -26,
|
||||
GPIO_PIN_BUSY = -27,
|
||||
GPIO_PIN_NOT_ALLOCATED = -28,
|
||||
GPIO_WRONG_CLIENT = -29,
|
||||
GPIO_UNSUPPORTED_ALTFUNC = -30,
|
||||
};
|
||||
|
||||
/*GPIO DEVICE ID */
|
||||
enum gpio_device_id {
|
||||
GPIO_DEVICE_ID_0,
|
||||
GPIO_DEVICE_ID_1,
|
||||
GPIO_DEVICE_ID_2,
|
||||
GPIO_DEVICE_ID_3,
|
||||
GPIO_DEVICE_ID_INVALID
|
||||
};
|
||||
|
||||
/*
|
||||
* Alternate Function:
|
||||
* refered in altfun_table to pointout particular altfun to be enabled
|
||||
* when using GPIO_ALT_FUNCTION A/B/C enable/disable operation
|
||||
*/
|
||||
enum gpio_alt_function {
|
||||
GPIO_ALT_UART_0_MODEM,
|
||||
GPIO_ALT_UART_0_NO_MODEM,
|
||||
GPIO_ALT_UART_1,
|
||||
GPIO_ALT_UART_2,
|
||||
GPIO_ALT_I2C_0,
|
||||
GPIO_ALT_I2C_1,
|
||||
GPIO_ALT_I2C_2,
|
||||
GPIO_ALT_I2C_3,
|
||||
GPIO_ALT_MSP_0,
|
||||
GPIO_ALT_MSP_1,
|
||||
GPIO_ALT_MSP_2,
|
||||
GPIO_ALT_MSP_3,
|
||||
GPIO_ALT_MSP_4,
|
||||
GPIO_ALT_MSP_5,
|
||||
GPIO_ALT_SSP_0,
|
||||
GPIO_ALT_SSP_1,
|
||||
GPIO_ALT_MM_CARD0,
|
||||
GPIO_ALT_SD_CARD0,
|
||||
GPIO_ALT_DMA_0,
|
||||
GPIO_ALT_DMA_1,
|
||||
GPIO_ALT_HSI0,
|
||||
GPIO_ALT_CCIR656_INPUT,
|
||||
GPIO_ALT_CCIR656_OUTPUT,
|
||||
GPIO_ALT_LCD_PANEL,
|
||||
GPIO_ALT_MDIF,
|
||||
GPIO_ALT_SDRAM,
|
||||
GPIO_ALT_HAMAC_AUDIO_DBG,
|
||||
GPIO_ALT_HAMAC_VIDEO_DBG,
|
||||
GPIO_ALT_CLOCK_RESET,
|
||||
GPIO_ALT_TSP,
|
||||
GPIO_ALT_IRDA,
|
||||
GPIO_ALT_USB_MINIMUM,
|
||||
GPIO_ALT_USB_I2C,
|
||||
GPIO_ALT_OWM,
|
||||
GPIO_ALT_PWL,
|
||||
GPIO_ALT_FSMC,
|
||||
GPIO_ALT_COMP_FLASH,
|
||||
GPIO_ALT_SRAM_NOR_FLASH,
|
||||
GPIO_ALT_FSMC_ADDLINE_0_TO_15,
|
||||
GPIO_ALT_SCROLL_KEY,
|
||||
GPIO_ALT_MSHC,
|
||||
GPIO_ALT_HPI,
|
||||
GPIO_ALT_USB_OTG,
|
||||
GPIO_ALT_SDIO,
|
||||
GPIO_ALT_HSMMC,
|
||||
GPIO_ALT_FSMC_ADD_DATA_0_TO_25,
|
||||
GPIO_ALT_HSI1,
|
||||
GPIO_ALT_NOR,
|
||||
GPIO_ALT_NAND,
|
||||
GPIO_ALT_KEYPAD,
|
||||
GPIO_ALT_VPIP,
|
||||
GPIO_ALT_CAM,
|
||||
GPIO_ALT_CCP1,
|
||||
GPIO_ALT_EMMC,
|
||||
GPIO_ALT_POP_EMMC,
|
||||
GPIO_ALT_FUNMAX /* Add new alt func before this */
|
||||
};
|
||||
|
||||
/* Defines pin assignment(Software mode or Alternate mode) */
|
||||
enum gpio_mode {
|
||||
GPIO_MODE_LEAVE_UNCHANGED, /* Parameter will be ignored */
|
||||
GPIO_MODE_SOFTWARE, /* Pin connected to GPIO (SW controlled) */
|
||||
GPIO_ALTF_A, /* Pin connected to altfunc 1 (HW periph 1) */
|
||||
GPIO_ALTF_B, /* Pin connected to altfunc 2 (HW periph 2) */
|
||||
GPIO_ALTF_C, /* Pin connected to altfunc 3 (HW periph 3) */
|
||||
GPIO_ALTF_FIND, /* Pin connected to altfunc 3 (HW periph 3) */
|
||||
GPIO_ALTF_DISABLE /* Pin connected to altfunc 3 (HW periph 3) */
|
||||
};
|
||||
|
||||
/* Defines GPIO pin direction */
|
||||
enum gpio_direction {
|
||||
GPIO_DIR_LEAVE_UNCHANGED, /* Parameter will be ignored */
|
||||
GPIO_DIR_INPUT, /* GPIO set as input */
|
||||
GPIO_DIR_OUTPUT /* GPIO set as output */
|
||||
};
|
||||
|
||||
/* Interrupt trigger mode */
|
||||
enum gpio_trig {
|
||||
GPIO_TRIG_LEAVE_UNCHANGED, /* Parameter will be ignored */
|
||||
GPIO_TRIG_DISABLE, /* Trigger no IT */
|
||||
GPIO_TRIG_RISING_EDGE, /* Trigger an IT on rising edge */
|
||||
GPIO_TRIG_FALLING_EDGE, /* Trigger an IT on falling edge */
|
||||
GPIO_TRIG_BOTH_EDGES, /* Trigger an IT on rising and falling edge */
|
||||
GPIO_TRIG_HIGH_LEVEL, /* Trigger an IT on high level */
|
||||
GPIO_TRIG_LOW_LEVEL /* Trigger an IT on low level */
|
||||
};
|
||||
|
||||
/* Configuration parameters for one GPIO pin.*/
|
||||
struct gpio_config {
|
||||
enum gpio_mode mode;
|
||||
enum gpio_direction direction;
|
||||
enum gpio_trig trig;
|
||||
char *dev_name; /* Who owns the gpio pin */
|
||||
};
|
||||
|
||||
/* GPIO pin data*/
|
||||
enum gpio_data {
|
||||
GPIO_DATA_LOW,
|
||||
GPIO_DATA_HIGH
|
||||
};
|
||||
|
||||
/* GPIO behaviour in sleep mode */
|
||||
enum gpio_sleep_mode {
|
||||
GPIO_SLEEP_MODE_LEAVE_UNCHANGED, /* Parameter will be ignored */
|
||||
GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT, /* GPIO is an input with pull
|
||||
up/down enabled when in sleep
|
||||
mode. */
|
||||
GPIO_SLEEP_MODE_CONTROLLED_BY_GPIO /* GPIO pin is controlled by
|
||||
GPIO IP. So mode, direction
|
||||
and data values for GPIO pin
|
||||
in sleep mode are determined
|
||||
by configuration set to GPIO
|
||||
pin before entering to sleep
|
||||
mode. */
|
||||
};
|
||||
|
||||
/* GPIO ability to wake the system up from sleep mode.*/
|
||||
enum gpio_wake {
|
||||
GPIO_WAKE_LEAVE_UNCHANGED, /* Parameter will be ignored */
|
||||
GPIO_WAKE_DISABLE, /* No wake of system from sleep mode. */
|
||||
GPIO_WAKE_LOW_LEVEL, /* Wake the system up on a LOW level. */
|
||||
GPIO_WAKE_HIGH_LEVEL, /* Wake the system up on a HIGH level. */
|
||||
GPIO_WAKE_RISING_EDGE, /* Wake the system up on a RISING edge. */
|
||||
GPIO_WAKE_FALLING_EDGE, /* Wake the system up on a FALLING edge. */
|
||||
GPIO_WAKE_BOTH_EDGES /* Wake the system up on both RISE and FALL. */
|
||||
};
|
||||
|
||||
/* Configuration parameters for one GPIO pin in sleep mode.*/
|
||||
struct gpio_sleep_config {
|
||||
enum gpio_sleep_mode sleep_mode;/* GPIO behaviour in sleep mode. */
|
||||
enum gpio_wake wake; /* GPIO ability to wake up system. */
|
||||
};
|
||||
|
||||
extern int gpio_setpinconfig(int pin_id, struct gpio_config *pin_config);
|
||||
extern int gpio_resetpinconfig(int pin_id, char *dev_name);
|
||||
extern int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name);
|
||||
extern int gpio_readpin(int pin_id, enum gpio_data *value);
|
||||
extern int gpio_altfuncenable(enum gpio_alt_function altfunc,
|
||||
char *dev_name);
|
||||
extern int gpio_altfuncdisable(enum gpio_alt_function altfunc,
|
||||
char *dev_name);
|
||||
|
||||
struct gpio_altfun_data {
|
||||
u16 altfun;
|
||||
u16 start;
|
||||
u16 end;
|
||||
u16 cont;
|
||||
u8 type;
|
||||
};
|
||||
#endif
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2009
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_HARDWARE_H
|
||||
#define __ASM_ARCH_HARDWARE_H
|
||||
|
||||
/* Peripheral clusters */
|
||||
|
||||
#define U8500_PER3_BASE 0x80000000
|
||||
#define U8500_PER2_BASE 0x80110000
|
||||
#define U8500_PER1_BASE 0x80120000
|
||||
#define U8500_PER4_BASE 0x80150000
|
||||
|
||||
#define U8500_PER6_BASE 0xa03c0000
|
||||
#define U8500_PER7_BASE 0xa03d0000
|
||||
#define U8500_PER5_BASE 0xa03e0000
|
||||
|
||||
/* GPIO */
|
||||
|
||||
#define U8500_GPIO0_BASE (U8500_PER1_BASE + 0xE000)
|
||||
#define U8500_GPIO1_BASE (U8500_PER1_BASE + 0xE000 + 0x80)
|
||||
|
||||
#define U8500_GPIO2_BASE (U8500_PER3_BASE + 0xE000)
|
||||
#define U8500_GPIO3_BASE (U8500_PER3_BASE + 0xE000 + 0x80)
|
||||
#define U8500_GPIO4_BASE (U8500_PER3_BASE + 0xE000 + 0x100)
|
||||
#define U8500_GPIO5_BASE (U8500_PER3_BASE + 0xE000 + 0x180)
|
||||
|
||||
#define U8500_GPIO6_BASE (U8500_PER2_BASE + 0xE000)
|
||||
#define U8500_GPIO7_BASE (U8500_PER2_BASE + 0xE000 + 0x80)
|
||||
|
||||
#define U8500_GPIO8_BASE (U8500_PER5_BASE + 0x1E000)
|
||||
|
||||
/* Per7 */
|
||||
#define U8500_CLKRST7_BASE (U8500_PER7_BASE + 0xf000)
|
||||
|
||||
/* Per6 */
|
||||
#define U8500_MTU0_BASE_V1 (U8500_PER6_BASE + 0x6000)
|
||||
#define U8500_MTU1_BASE_V1 (U8500_PER6_BASE + 0x7000)
|
||||
#define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000)
|
||||
|
||||
/* Per5 */
|
||||
#define U8500_CLKRST5_BASE (U8500_PER5_BASE + 0x1f000)
|
||||
|
||||
/* Per4 */
|
||||
#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000)
|
||||
#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
|
||||
|
||||
/* Per3 */
|
||||
#define U8500_UART2_BASE (U8500_PER3_BASE + 0x7000)
|
||||
#define U8500_CLKRST3_BASE (U8500_PER3_BASE + 0xf000)
|
||||
|
||||
/* Per2 */
|
||||
#define U8500_CLKRST2_BASE (U8500_PER2_BASE + 0xf000)
|
||||
|
||||
/* Per1 */
|
||||
#define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000)
|
||||
#define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000)
|
||||
#define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000)
|
||||
|
||||
/* Last page of Boot ROM */
|
||||
#define U8500_BOOTROM_BASE 0x90000000
|
||||
#define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOTROM_BASE + 0x1FFF4)
|
||||
#define U8500_ASIC_ID_LOC_V2 (U8500_BOOTROM_BASE + 0x1DBF4)
|
||||
|
||||
/* AB8500 specifics */
|
||||
|
||||
/* address bank */
|
||||
#define AB8500_REGU_CTRL2 0x0004
|
||||
#define AB8500_MISC 0x0010
|
||||
|
||||
/* registers */
|
||||
#define AB8500_REGU_VRF1VAUX3_REGU_REG 0x040A
|
||||
#define AB8500_REGU_VRF1VAUX3_SEL_REG 0x0421
|
||||
#define AB8500_REV_REG 0x1080
|
||||
|
||||
#define AB8500_GPIO_SEL2_REG 0x1001
|
||||
#define AB8500_GPIO_DIR2_REG 0x1011
|
||||
#define AB8500_GPIO_DIR4_REG 0x1013
|
||||
#define AB8500_GPIO_SEL4_REG 0x1003
|
||||
#define AB8500_GPIO_OUT2_REG 0x1021
|
||||
#define AB8500_GPIO_OUT4_REG 0x1023
|
||||
|
||||
#define LDO_VAUX3_ENABLE_MASK 0x3
|
||||
#define LDO_VAUX3_ENABLE_VAL 0x1
|
||||
#define LDO_VAUX3_SEL_MASK 0xf
|
||||
#define LDO_VAUX3_SEL_2V9 0xd
|
||||
#define LDO_VAUX3_V2_SEL_MASK 0x7
|
||||
#define LDO_VAUX3_V2_SEL_2V91 0x7
|
||||
|
||||
|
||||
#endif /* __ASM_ARCH_HARDWARE_H */
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 ST-Ericsson SA
|
||||
*
|
||||
* Copied from the Linux version:
|
||||
* Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#ifndef __MACH_PRCMU_FW_V1_H
|
||||
#define __MACH_PRCMU_FW_V1_H
|
||||
|
||||
#define AP_EXECUTE 2
|
||||
#define I2CREAD 1
|
||||
#define I2C_WR_OK 1
|
||||
#define I2C_RD_OK 2
|
||||
#define I2CWRITE 0
|
||||
|
||||
#define PRCMU_BASE U8500_PRCMU_BASE
|
||||
#define PRCMU_BASE_TCDM U8500_PRCMU_TCDM_BASE
|
||||
#define PRCM_UARTCLK_MGT_REG (PRCMU_BASE + 0x018)
|
||||
#define PRCM_MSPCLK_MGT_REG (PRCMU_BASE + 0x01C)
|
||||
#define PRCM_I2CCLK_MGT_REG (PRCMU_BASE + 0x020)
|
||||
#define PRCM_SDMMCCLK_MGT_REG (PRCMU_BASE + 0x024)
|
||||
#define PRCM_PER1CLK_MGT_REG (PRCMU_BASE + 0x02C)
|
||||
#define PRCM_PER2CLK_MGT_REG (PRCMU_BASE + 0x030)
|
||||
#define PRCM_PER3CLK_MGT_REG (PRCMU_BASE + 0x034)
|
||||
#define PRCM_PER5CLK_MGT_REG (PRCMU_BASE + 0x038)
|
||||
#define PRCM_PER6CLK_MGT_REG (PRCMU_BASE + 0x03C)
|
||||
#define PRCM_PER7CLK_MGT_REG (PRCMU_BASE + 0x040)
|
||||
#define PRCM_MBOX_CPU_VAL (PRCMU_BASE + 0x0FC)
|
||||
#define PRCM_MBOX_CPU_SET (PRCMU_BASE + 0x100)
|
||||
|
||||
#define PRCM_ARM_IT1_CLEAR (PRCMU_BASE + 0x48C)
|
||||
#define PRCM_ARM_IT1_VAL (PRCMU_BASE + 0x494)
|
||||
#define PRCM_TCR (PRCMU_BASE + 0x1C8)
|
||||
#define PRCM_REQ_MB5 (PRCMU_BASE_TCDM + 0xE44)
|
||||
#define PRCM_ACK_MB5 (PRCMU_BASE_TCDM + 0xDF4)
|
||||
#define PRCM_XP70_CUR_PWR_STATE (PRCMU_BASE_TCDM + 0xFFC)
|
||||
/* Mailbox 5 Requests */
|
||||
#define PRCM_REQ_MB5_I2COPTYPE_REG (PRCM_REQ_MB5 + 0x0)
|
||||
#define PRCM_REQ_MB5_BIT_FIELDS (PRCM_REQ_MB5 + 0x1)
|
||||
#define PRCM_REQ_MB5_I2CSLAVE (PRCM_REQ_MB5 + 0x2)
|
||||
#define PRCM_REQ_MB5_I2CVAL (PRCM_REQ_MB5 + 0x3)
|
||||
|
||||
/* Mailbox 5 ACKs */
|
||||
#define PRCM_ACK_MB5_STATUS (PRCM_ACK_MB5 + 0x1)
|
||||
#define PRCM_ACK_MB5_SLAVE (PRCM_ACK_MB5 + 0x2)
|
||||
#define PRCM_ACK_MB5_VAL (PRCM_ACK_MB5 + 0x3)
|
||||
|
||||
#define LOW_POWER_WAKEUP 1
|
||||
#define EXE_WAKEUP 0
|
||||
|
||||
#define REQ_MB5 5
|
||||
|
||||
#define ab8500_read prcmu_i2c_read
|
||||
#define ab8500_write prcmu_i2c_write
|
||||
|
||||
int prcmu_i2c_read(u8 reg, u16 slave);
|
||||
int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data);
|
||||
|
||||
void u8500_prcmu_enable(u32 *reg);
|
||||
void db8500_prcmu_init(void);
|
||||
|
||||
#endif /* __MACH_PRCMU_FW_V1_H */
|
|
@ -1,12 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#ifndef _SYS_PROTO_H_
|
||||
#define _SYS_PROTO_H_
|
||||
|
||||
void gpio_init(void);
|
||||
int u8500_mmc_power_init(void);
|
||||
|
||||
#endif /* _SYS_PROTO_H_ */
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2009
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __U8500_H
|
||||
#define __U8500_H
|
||||
|
||||
/*
|
||||
* base register values for U8500
|
||||
*/
|
||||
#define CFG_PRCMU_BASE 0x80157000 /* Power, reset and clock
|
||||
Management Unit */
|
||||
#define CFG_SDRAMC_BASE 0x903CF000 /* SDRAMC cnf registers */
|
||||
#define CFG_FSMC_BASE 0x80000000 /* FSMC Controller */
|
||||
|
||||
/*
|
||||
* U8500 GPIO register base for 9 banks
|
||||
*/
|
||||
#define U8500_GPIO_0_BASE 0x8012E000
|
||||
#define U8500_GPIO_1_BASE 0x8012E080
|
||||
#define U8500_GPIO_2_BASE 0x8000E000
|
||||
#define U8500_GPIO_3_BASE 0x8000E080
|
||||
#define U8500_GPIO_4_BASE 0x8000E100
|
||||
#define U8500_GPIO_5_BASE 0x8000E180
|
||||
#define U8500_GPIO_6_BASE 0x8011E000
|
||||
#define U8500_GPIO_7_BASE 0x8011E080
|
||||
#define U8500_GPIO_8_BASE 0xA03FE000
|
||||
|
||||
#endif /* __U8500_H */
|
|
@ -14,7 +14,6 @@ obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o
|
|||
obj-$(CONFIG_I2C_MV) += mv_i2c.o
|
||||
obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
|
||||
obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
|
||||
obj-$(CONFIG_U8500_I2C) += u8500_i2c.o
|
||||
obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C) += i2c_core.o
|
||||
obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
|
||||
|
|
|
@ -1,601 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Basic U-Boot I2C interface for STn8500/DB8500
|
||||
* Author: Michael Brandt <Michael.Brandt@stericsson.com> for ST-Ericsson
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*
|
||||
* Only 7-bit I2C device addresses are supported.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#include "u8500_i2c.h"
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
#define U8500_I2C_ENDAD_COUNTER (CONFIG_SYS_HZ/100) /* I2C bus timeout */
|
||||
#define U8500_I2C_FIFO_FLUSH_COUNTER 500000 /* flush "timeout" */
|
||||
#define U8500_I2C_SCL_FREQ 100000 /* I2C bus clock freq */
|
||||
#define U8500_I2C_INPUT_FREQ 48000000 /* Input clock freq */
|
||||
#define TX_FIFO_THRESHOLD 0x4
|
||||
#define RX_FIFO_THRESHOLD 0x4
|
||||
#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk */
|
||||
|
||||
#define WRITE_FIELD(var, mask, shift, value) \
|
||||
(var = ((var & ~(mask)) | ((value) << (shift))))
|
||||
|
||||
static unsigned int bus_initialized[CONFIG_SYS_U8500_I2C_BUS_MAX];
|
||||
static unsigned int i2c_bus_num;
|
||||
static unsigned int i2c_bus_speed[] = {
|
||||
CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
|
||||
CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
|
||||
};
|
||||
static struct u8500_i2c_regs *i2c_dev[] = {
|
||||
(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C0_BASE,
|
||||
(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C1_BASE,
|
||||
(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C2_BASE,
|
||||
(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C3_BASE,
|
||||
};
|
||||
|
||||
static struct {
|
||||
int periph;
|
||||
int pcken;
|
||||
int kcken;
|
||||
} i2c_clock_bits[] = {
|
||||
{3, 3, 3}, /* I2C0 */
|
||||
{1, 2, 2}, /* I2C1 */
|
||||
{1, 6, 6}, /* I2C2 */
|
||||
{2, 0, 0}, /* I2C3 */
|
||||
};
|
||||
|
||||
static void i2c_set_bit(void *reg, u32 mask)
|
||||
{
|
||||
writel(readl(reg) | mask, reg);
|
||||
}
|
||||
|
||||
static void i2c_clr_bit(void *reg, u32 mask)
|
||||
{
|
||||
writel(readl(reg) & ~mask, reg);
|
||||
}
|
||||
|
||||
static void i2c_write_field(void *reg, u32 mask, uint shift, u32 value)
|
||||
{
|
||||
writel((readl(reg) & ~mask) | (value << shift), reg);
|
||||
}
|
||||
|
||||
static int __i2c_set_bus_speed(unsigned int speed)
|
||||
{
|
||||
u32 value;
|
||||
struct u8500_i2c_regs *i2c_regs;
|
||||
|
||||
i2c_regs = i2c_dev[i2c_bus_num];
|
||||
|
||||
/* Select standard (100 kbps) speed mode */
|
||||
i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_SM,
|
||||
U8500_I2C_CR_SHIFT_SM, 0x0);
|
||||
|
||||
/*
|
||||
* Set the Baud Rate Counter 2 value
|
||||
* Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle )
|
||||
* Foncycle = 0 (no digital filtering)
|
||||
*/
|
||||
value = (u32) (U8500_I2C_INPUT_FREQ / (speed * 2));
|
||||
i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT2,
|
||||
U8500_I2C_BRCR_SHIFT_BRCNT2, value);
|
||||
|
||||
/* ensure that BRCNT value is zero */
|
||||
i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT1,
|
||||
U8500_I2C_BRCR_SHIFT_BRCNT1, 0);
|
||||
|
||||
return U8500_I2C_INPUT_FREQ/(value * 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* i2c_init - initialize the i2c bus
|
||||
*
|
||||
* speed: bus speed (in HZ)
|
||||
* slaveaddr: address of device in slave mode
|
||||
*
|
||||
* Slave mode is not implemented.
|
||||
*/
|
||||
void i2c_init(int speed, int slaveaddr)
|
||||
{
|
||||
struct u8500_i2c_regs *i2c_regs;
|
||||
|
||||
debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed);
|
||||
|
||||
u8500_clock_enable(i2c_clock_bits[i2c_bus_num].periph,
|
||||
i2c_clock_bits[i2c_bus_num].pcken,
|
||||
i2c_clock_bits[i2c_bus_num].kcken);
|
||||
|
||||
i2c_regs = i2c_dev[i2c_bus_num];
|
||||
|
||||
/* Disable the controller */
|
||||
i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
|
||||
|
||||
/* Clear registers */
|
||||
writel(0, &i2c_regs->cr);
|
||||
writel(0, &i2c_regs->scr);
|
||||
writel(0, &i2c_regs->hsmcr);
|
||||
writel(0, &i2c_regs->tftr);
|
||||
writel(0, &i2c_regs->rftr);
|
||||
writel(0, &i2c_regs->dmar);
|
||||
|
||||
i2c_bus_speed[i2c_bus_num] = __i2c_set_bus_speed(speed);
|
||||
|
||||
/*
|
||||
* Set our own address.
|
||||
* Set slave address mode to 7 bit addressing mode
|
||||
*/
|
||||
i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_SAM);
|
||||
i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_ADDR,
|
||||
U8500_I2C_SCR_SHIFT_ADDR, slaveaddr);
|
||||
/* Slave Data Set up Time */
|
||||
i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_DATA_SETUP_TIME,
|
||||
U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME, SLAVE_SETUP_TIME);
|
||||
|
||||
/* Disable the DMA sync logic */
|
||||
i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_DMA_SLE,
|
||||
U8500_I2C_CR_SHIFT_DMA_SLE, 0);
|
||||
|
||||
/* Disable interrupts */
|
||||
writel(0, &i2c_regs->imscr);
|
||||
|
||||
/* Configure bus master mode */
|
||||
i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_OM, U8500_I2C_CR_SHIFT_OM,
|
||||
U8500_I2C_BUS_MASTER_MODE);
|
||||
/* Set FIFO threshold values */
|
||||
writel(TX_FIFO_THRESHOLD, &i2c_regs->tftr);
|
||||
writel(RX_FIFO_THRESHOLD, &i2c_regs->rftr);
|
||||
|
||||
/* Enable the I2C Controller */
|
||||
i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
|
||||
|
||||
bus_initialized[i2c_bus_num] = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* loop_till_bit_clear - polls on a bit till it clears
|
||||
* ioreg: register where you want to check status
|
||||
* mask: bit mask for the bit you wish to check
|
||||
* timeout: timeout in ticks/s
|
||||
*/
|
||||
static int loop_till_bit_clear(void *io_reg, u32 mask, unsigned long timeout)
|
||||
{
|
||||
unsigned long timebase = get_timer(0);
|
||||
|
||||
do {
|
||||
if ((readl(io_reg) & mask) == 0x0UL)
|
||||
return 0;
|
||||
} while (get_timer(timebase) < timeout);
|
||||
|
||||
debug("loop_till_bit_clear timed out\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* loop_till_bit_set - polls on a bit till it is set.
|
||||
* ioreg: register where you want to check status
|
||||
* mask: bit mask for the bit you wish to check
|
||||
* timeout: timeout in ticks/s
|
||||
*/
|
||||
static int loop_till_bit_set(void *io_reg, u32 mask, unsigned long timeout)
|
||||
{
|
||||
unsigned long timebase = get_timer(0);
|
||||
|
||||
do {
|
||||
if ((readl(io_reg) & mask) != 0x0UL)
|
||||
return 0;
|
||||
} while (get_timer(timebase) < timeout);
|
||||
|
||||
debug("loop_till_bit_set timed out\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* flush_fifo - flush the I2C TX and RX FIFOs
|
||||
*/
|
||||
static void flush_fifo(struct u8500_i2c_regs *i2c_regs)
|
||||
{
|
||||
int counter = U8500_I2C_FIFO_FLUSH_COUNTER;
|
||||
|
||||
/* Flush Tx FIFO */
|
||||
i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FTX);
|
||||
/* Flush Rx FIFO */
|
||||
i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FRX);
|
||||
while (counter--) {
|
||||
if (!(readl(&i2c_regs->cr) &
|
||||
(U8500_I2C_CR_FTX | U8500_I2C_CR_FRX)))
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void print_abort_reason(struct u8500_i2c_regs *i2c_regs)
|
||||
{
|
||||
int cause;
|
||||
|
||||
printf("abort: risr %08x, sr %08x\n", i2c_regs->risr, i2c_regs->sr);
|
||||
cause = (readl(&i2c_regs->sr) & U8500_I2C_SR_CAUSE) >>
|
||||
U8500_I2C_SR_SHIFT_CAUSE;
|
||||
switch (cause) {
|
||||
case U8500_I2C_NACK_ADDR:
|
||||
printf("No Ack received after Slave Address xmission\n");
|
||||
break;
|
||||
case U8500_I2C_NACK_DATA:
|
||||
printf("Valid for MASTER_WRITE: No Ack received "
|
||||
"during data phase\n");
|
||||
break;
|
||||
case U8500_I2C_ACK_MCODE:
|
||||
printf("Master recv ack after xmission of master code"
|
||||
"in hs mode\n");
|
||||
break;
|
||||
case U8500_I2C_ARB_LOST:
|
||||
printf("Master Lost arbitration\n");
|
||||
break;
|
||||
case U8500_I2C_BERR_START:
|
||||
printf("Slave restarts\n");
|
||||
break;
|
||||
case U8500_I2C_BERR_STOP:
|
||||
printf("Slave reset\n");
|
||||
break;
|
||||
case U8500_I2C_OVFL:
|
||||
printf("Overflow\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown error type\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* i2c_abort - called when a I2C transaction failed
|
||||
*/
|
||||
static void i2c_abort(struct u8500_i2c_regs *i2c_regs)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
print_abort_reason(i2c_regs);
|
||||
#endif
|
||||
/* flush RX and TX fifos */
|
||||
flush_fifo(i2c_regs);
|
||||
|
||||
/* Acknowledge the Master Transaction Done */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
|
||||
|
||||
/* Acknowledge the Master Transaction Done Without Stop */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
|
||||
|
||||
i2c_init(i2c_bus_speed[i2c_bus_num], CONFIG_SYS_I2C_SLAVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* write addr, alias index, to I2C bus.
|
||||
*/
|
||||
static int i2c_write_addr(struct u8500_i2c_regs *i2c_regs, uint addr, int alen)
|
||||
{
|
||||
while (alen--) {
|
||||
/* Wait until the Tx Fifo is not full */
|
||||
if (loop_till_bit_clear((void *)&i2c_regs->risr,
|
||||
U8500_I2C_INT_TXFF,
|
||||
U8500_I2C_ENDAD_COUNTER)) {
|
||||
i2c_abort(i2c_regs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* MSB first */
|
||||
writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->tfr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal simplified read function:
|
||||
* i2c_regs: Pointer to I2C registers for current bus
|
||||
* chip: I2C chip address, range 0..127
|
||||
* addr: Memory (register) address within the chip
|
||||
* alen: Number of bytes to use for addr (typically 1, 2 for larger
|
||||
* memories, 0 for register type devices with only one register)
|
||||
* value: Where to put the data
|
||||
*
|
||||
* Returns: 0 on success, not 0 on failure
|
||||
*/
|
||||
static int i2c_read_byte(struct u8500_i2c_regs *i2c_regs, uchar chip,
|
||||
uint addr, int alen, uchar *value)
|
||||
{
|
||||
u32 mcr = 0;
|
||||
|
||||
/* Set the address mode to 7 bit */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
|
||||
|
||||
/* Store the slave address in the master control register */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
|
||||
|
||||
if (alen != 0) {
|
||||
/* Master write operation */
|
||||
mcr &= ~(U8500_I2C_MCR_OP);
|
||||
|
||||
/* Configure the Frame length to one byte */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH,
|
||||
U8500_I2C_MCR_SHIFT_LENGTH, 1);
|
||||
|
||||
/* Repeated start, no stop */
|
||||
mcr &= ~(U8500_I2C_MCR_STOP);
|
||||
|
||||
/* Write Master Control Register */
|
||||
writel(mcr, &i2c_regs->mcr);
|
||||
|
||||
/* send addr/index */
|
||||
if (i2c_write_addr(i2c_regs, addr, alen) != 0)
|
||||
return -1;
|
||||
|
||||
/* Check for the Master Transaction Done Without Stop */
|
||||
if (loop_till_bit_set((void *)&i2c_regs->risr,
|
||||
U8500_I2C_INT_MTDWS,
|
||||
U8500_I2C_ENDAD_COUNTER)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Acknowledge the Master Transaction Done Without Stop */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
|
||||
}
|
||||
|
||||
/* Master control configuration for read operation */
|
||||
mcr |= U8500_I2C_MCR_OP;
|
||||
|
||||
/* Configure the STOP condition, we read only one byte */
|
||||
mcr |= U8500_I2C_MCR_STOP;
|
||||
|
||||
/* Set the frame length to one byte, we support only 1 byte reads */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
|
||||
|
||||
i2c_write_field(&i2c_regs->mcr, U8500_I2C_MCR_LENGTH_STOP_OP,
|
||||
U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);
|
||||
|
||||
/*
|
||||
* receive_data_polling
|
||||
*/
|
||||
|
||||
/* Wait until the Rx FIFO is not empty */
|
||||
if (loop_till_bit_clear((void *)&i2c_regs->risr,
|
||||
U8500_I2C_INT_RXFE,
|
||||
U8500_I2C_ENDAD_COUNTER))
|
||||
return -1;
|
||||
|
||||
/* Read the data byte from Rx FIFO */
|
||||
*value = readb(&i2c_regs->rfr);
|
||||
|
||||
/* Wait until the work is done */
|
||||
if (loop_till_bit_set((void *)&i2c_regs->risr, U8500_I2C_INT_MTD,
|
||||
U8500_I2C_ENDAD_COUNTER))
|
||||
return -1;
|
||||
|
||||
/* Acknowledge the Master Transaction Done */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
|
||||
|
||||
/* If MTD is set, Master Transaction Done Without Stop is set too */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal simplified write function:
|
||||
* i2c_regs: Pointer to I2C registers for current bus
|
||||
* chip: I2C chip address, range 0..127
|
||||
* addr: Memory (register) address within the chip
|
||||
* alen: Number of bytes to use for addr (typically 1, 2 for larger
|
||||
* memories, 0 for register type devices with only one register)
|
||||
* data: Where to read the data
|
||||
* len: How many bytes to write
|
||||
*
|
||||
* Returns: 0 on success, not 0 on failure
|
||||
*/
|
||||
static int __i2c_write(struct u8500_i2c_regs *i2c_regs, u8 chip, uint addr,
|
||||
int alen, u8 *data, int len)
|
||||
{
|
||||
int i;
|
||||
u32 mcr = 0;
|
||||
|
||||
/* Set the address mode to 7 bit */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
|
||||
|
||||
/* Store the slave address in the master control register */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
|
||||
|
||||
/* Write operation */
|
||||
mcr &= ~(U8500_I2C_MCR_OP);
|
||||
|
||||
/* Current transaction is terminated by STOP condition */
|
||||
mcr |= U8500_I2C_MCR_STOP;
|
||||
|
||||
/* Frame length: addr byte + len */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH,
|
||||
(alen + len));
|
||||
|
||||
/* Write MCR register */
|
||||
writel(mcr, &i2c_regs->mcr);
|
||||
|
||||
if (i2c_write_addr(i2c_regs, addr, alen) != 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
/* Wait until the Tx FIFO is not full */
|
||||
if (loop_till_bit_clear((void *)&i2c_regs->risr,
|
||||
U8500_I2C_INT_TXFF,
|
||||
U8500_I2C_ENDAD_COUNTER))
|
||||
return -1;
|
||||
|
||||
/* it is a 32 bit register with upper 24 reserved R/O */
|
||||
writeb(data[i], &i2c_regs->tfr);
|
||||
}
|
||||
|
||||
/* Check for Master Transaction Done */
|
||||
if (loop_till_bit_set((void *)&i2c_regs->risr,
|
||||
U8500_I2C_INT_MTD,
|
||||
U8500_I2C_ENDAD_COUNTER)) {
|
||||
printf("i2c_write_byte error2: risr %08x\n",
|
||||
i2c_regs->risr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Acknowledge Master Transaction Done */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
|
||||
|
||||
/* Acknowledge Master Transaction Done Without Stop */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe the given I2C chip address. Returns 0 if a chip responded,
|
||||
* not 0 on failure.
|
||||
*/
|
||||
int i2c_probe(uchar chip)
|
||||
{
|
||||
u32 mcr = 0;
|
||||
struct u8500_i2c_regs *i2c_regs;
|
||||
|
||||
if (chip == CONFIG_SYS_I2C_SLAVE)
|
||||
return 1;
|
||||
|
||||
i2c_regs = i2c_dev[i2c_bus_num];
|
||||
|
||||
/* Set the address mode to 7 bit */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
|
||||
|
||||
/* Store the slave address in the master control register */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_A10, U8500_I2C_MCR_SHIFT_A7, chip);
|
||||
|
||||
/* Read operation */
|
||||
mcr |= U8500_I2C_MCR_OP;
|
||||
|
||||
/* Set the frame length to one byte */
|
||||
WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
|
||||
|
||||
/* Current transaction is terminated by STOP condition */
|
||||
mcr |= U8500_I2C_MCR_STOP;
|
||||
|
||||
/* Write MCR register */
|
||||
writel(mcr, &i2c_regs->mcr);
|
||||
|
||||
/* Wait until the Rx Fifo is not empty */
|
||||
if (loop_till_bit_clear((void *)&i2c_regs->risr,
|
||||
U8500_I2C_INT_RXFE,
|
||||
U8500_I2C_ENDAD_COUNTER)) {
|
||||
i2c_abort(i2c_regs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
flush_fifo(i2c_regs);
|
||||
|
||||
/* Acknowledge the Master Transaction Done */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
|
||||
|
||||
/* Acknowledge the Master Transaction Done Without Stop */
|
||||
i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read/Write interface:
|
||||
* chip: I2C chip address, range 0..127
|
||||
* addr: Memory (register) address within the chip
|
||||
* alen: Number of bytes to use for addr (typically 1, 2 for larger
|
||||
* memories, 0 for register type devices with only one
|
||||
* register)
|
||||
* buffer: Where to read/write the data
|
||||
* len: How many bytes to read/write
|
||||
*
|
||||
* Returns: 0 on success, not 0 on failure
|
||||
*/
|
||||
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
struct u8500_i2c_regs *i2c_regs;
|
||||
|
||||
if (alen > 2) {
|
||||
debug("I2C read: addr len %d not supported\n", alen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
i2c_regs = i2c_dev[i2c_bus_num];
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
rc = i2c_read_byte(i2c_regs, chip, addr + i, alen, &buffer[i]);
|
||||
if (rc != 0) {
|
||||
debug("I2C read: I/O error: %d\n", rc);
|
||||
i2c_abort(i2c_regs);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
|
||||
{
|
||||
int rc;
|
||||
struct u8500_i2c_regs *i2c_regs;
|
||||
i2c_regs = i2c_dev[i2c_bus_num];
|
||||
|
||||
rc = __i2c_write(i2c_regs, chip, addr, alen, buffer,
|
||||
len);
|
||||
if (rc != 0) {
|
||||
debug("I2C write: I/O error\n");
|
||||
i2c_abort(i2c_regs);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_set_bus_num(unsigned int bus)
|
||||
{
|
||||
if (bus > ARRAY_SIZE(i2c_dev) - 1) {
|
||||
debug("i2c_set_bus_num: only up to bus %d supported\n",
|
||||
ARRAY_SIZE(i2c_dev)-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i2c_bus_num = bus;
|
||||
|
||||
if (!bus_initialized[i2c_bus_num])
|
||||
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_set_bus_speed(unsigned int speed)
|
||||
{
|
||||
|
||||
if (speed > U8500_I2C_MAX_STANDARD_SCL) {
|
||||
debug("i2c_set_bus_speed: only up to %d supported\n",
|
||||
U8500_I2C_MAX_STANDARD_SCL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sets as side effect i2c_bus_speed[i2c_bus_num] */
|
||||
i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int i2c_get_bus_num(void)
|
||||
{
|
||||
return i2c_bus_num;
|
||||
}
|
||||
|
||||
unsigned int i2c_get_bus_speed(void)
|
||||
{
|
||||
return i2c_bus_speed[i2c_bus_num];
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2009
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _U8500_I2C_H_
|
||||
#define _U8500_I2C_H_
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/u8500.h>
|
||||
|
||||
struct u8500_i2c_regs {
|
||||
u32 cr; /* Control Register 0x00 */
|
||||
u32 scr; /* Slave Address Register 0x04 */
|
||||
u32 hsmcr; /* HS Master code Register 0x08 */
|
||||
u32 mcr; /* Master Control Register 0x0C */
|
||||
u32 tfr; /* Transmit Fifo Register 0x10 */
|
||||
u32 sr; /* Status Register 0x14 */
|
||||
u32 rfr; /* Receiver Fifo Register 0x18 */
|
||||
u32 tftr; /* Transmit Fifo Threshold Register 0x1C */
|
||||
u32 rftr; /* Receiver Fifo Threshold Register 0x20 */
|
||||
u32 dmar; /* DMA register 0x24 */
|
||||
u32 brcr; /* Baud Rate Counter Register 0x28 */
|
||||
u32 imscr; /* Interrupt Mask Set and Clear Register 0x2C */
|
||||
u32 risr; /* Raw interrupt status register 0x30 */
|
||||
u32 misr; /* Masked interrupt status register 0x34 */
|
||||
u32 icr; /* Interrupt Set and Clear Register 0x38 */
|
||||
u32 reserved_1[(0xFE0 - 0x3c) >> 2]; /* Reserved 0x03C to 0xFE0 */
|
||||
u32 periph_id_0; /* peripheral ID 0 0xFE0 */
|
||||
u32 periph_id_1; /* peripheral ID 1 0xFE4 */
|
||||
u32 periph_id_2; /* peripheral ID 2 0xFE8 */
|
||||
u32 periph_id_3; /* peripheral ID 3 0xFEC */
|
||||
u32 cell_id_0; /* I2C cell ID 0 0xFF0 */
|
||||
u32 cell_id_1; /* I2C cell ID 1 0xFF4 */
|
||||
u32 cell_id_2; /* I2C cell ID 2 0xFF8 */
|
||||
u32 cell_id_3; /* I2C cell ID 3 0xFFC */
|
||||
};
|
||||
|
||||
|
||||
/* Control Register */
|
||||
|
||||
/* Mask values for control register mask */
|
||||
#define U8500_I2C_CR_PE 0x0001 /* Peripheral enable */
|
||||
#define U8500_I2C_CR_OM 0x0006 /* Operation mode */
|
||||
#define U8500_I2C_CR_SAM 0x0008 /* Slave Addressing mode */
|
||||
#define U8500_I2C_CR_SM 0x0030 /* Speed mode */
|
||||
#define U8500_I2C_CR_SGCM 0x0040 /* Slave General call mode */
|
||||
#define U8500_I2C_CR_FTX 0x0080 /* Flush Transmit */
|
||||
#define U8500_I2C_CR_FRX 0x0100 /* Flush Receive */
|
||||
#define U8500_I2C_CR_DMA_TX_EN 0x0200 /* DMA TX Enable */
|
||||
#define U8500_I2C_CR_DMA_RX_EN 0x0400 /* DMA Rx Enable */
|
||||
#define U8500_I2C_CR_DMA_SLE 0x0800 /* DMA Synchronization Logic enable */
|
||||
#define U8500_I2C_CR_LM 0x1000 /* Loop back mode */
|
||||
#define U8500_I2C_CR_FON 0x6000 /* Filtering On */
|
||||
|
||||
/* shift valus for control register bit fields */
|
||||
#define U8500_I2C_CR_SHIFT_PE 0 /* Peripheral enable */
|
||||
#define U8500_I2C_CR_SHIFT_OM 1 /* Operation mode */
|
||||
#define U8500_I2C_CR_SHIFT_SAM 3 /* Slave Addressing mode */
|
||||
#define U8500_I2C_CR_SHIFT_SM 4 /* Speed mode */
|
||||
#define U8500_I2C_CR_SHIFT_SGCM 6 /* Slave General call mode */
|
||||
#define U8500_I2C_CR_SHIFT_FTX 7 /* Flush Transmit */
|
||||
#define U8500_I2C_CR_SHIFT_FRX 8 /* Flush Receive */
|
||||
#define U8500_I2C_CR_SHIFT_DMA_TX_EN 9 /* DMA TX Enable */
|
||||
#define U8500_I2C_CR_SHIFT_DMA_RX_EN 10 /* DMA Rx Enable */
|
||||
#define U8500_I2C_CR_SHIFT_DMA_SLE 11 /* DMA Synch Logic enable */
|
||||
#define U8500_I2C_CR_SHIFT_LM 12 /* Loop back mode */
|
||||
#define U8500_I2C_CR_SHIFT_FON 13 /* Filtering On */
|
||||
|
||||
/* bus operation modes */
|
||||
#define U8500_I2C_BUS_SLAVE_MODE 0
|
||||
#define U8500_I2C_BUS_MASTER_MODE 1
|
||||
#define U8500_I2C_BUS_MASTER_SLAVE_MODE 2
|
||||
|
||||
|
||||
/* Slave control register*/
|
||||
|
||||
/* Mask values slave control register */
|
||||
#define U8500_I2C_SCR_ADDR 0x3FF
|
||||
#define U8500_I2C_SCR_DATA_SETUP_TIME 0xFFFF0000
|
||||
|
||||
/* Shift values for Slave control register */
|
||||
#define U8500_I2C_SCR_SHIFT_ADDR 0
|
||||
#define U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME 16
|
||||
|
||||
|
||||
/* Master Control Register */
|
||||
|
||||
/* Mask values for Master control register */
|
||||
#define U8500_I2C_MCR_OP 0x00000001 /* Operation */
|
||||
#define U8500_I2C_MCR_A7 0x000000FE /* LSB bits of Address */
|
||||
#define U8500_I2C_MCR_EA10 0x00000700 /* Extended Address */
|
||||
#define U8500_I2C_MCR_SB 0x00000800 /* Start byte procedure */
|
||||
#define U8500_I2C_MCR_AM 0x00003000 /* Address type */
|
||||
#define U8500_I2C_MCR_STOP 0x00004000 /* stop condition */
|
||||
#define U8500_I2C_MCR_LENGTH 0x03FF8000 /* Frame length */
|
||||
#define U8500_I2C_MCR_A10 0x000007FE /* Enable 10 bit address */
|
||||
/* mask for length field,stop and operation */
|
||||
#define U8500_I2C_MCR_LENGTH_STOP_OP 0x3FFC001
|
||||
|
||||
/* Shift values for Master control values */
|
||||
#define U8500_I2C_MCR_SHIFT_OP 0 /* Operation */
|
||||
#define U8500_I2C_MCR_SHIFT_A7 1 /* LSB bits of Address */
|
||||
#define U8500_I2C_MCR_SHIFT_EA10 8 /* Extended Address */
|
||||
#define U8500_I2C_MCR_SHIFT_SB 11 /* Start byte procedure */
|
||||
#define U8500_I2C_MCR_SHIFT_AM 12 /* Address type */
|
||||
#define U8500_I2C_MCR_SHIFT_STOP 14 /* stop condition */
|
||||
#define U8500_I2C_MCR_SHIFT_LENGTH 15 /* Frame length */
|
||||
#define U8500_I2C_MCR_SHIFT_A10 1 /* Enable 10 bit address */
|
||||
|
||||
#define U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP 0
|
||||
|
||||
|
||||
/* Status Register */
|
||||
|
||||
/* Mask values for Status register */
|
||||
#define U8500_I2C_SR_OP 0x00000003 /* Operation */
|
||||
#define U8500_I2C_SR_STATUS 0x0000000C /* Controller Status */
|
||||
#define U8500_I2C_SR_CAUSE 0x00000070 /* Abort Cause */
|
||||
#define U8500_I2C_SR_TYPE 0x00000180 /* Receive Type */
|
||||
#define U8500_I2C_SR_LENGTH 0x000FF700 /* Transfer length */
|
||||
|
||||
/* Shift values for Status register */
|
||||
#define U8500_I2C_SR_SHIFT_OP 0 /* Operation */
|
||||
#define U8500_I2C_SR_SHIFT_STATUS 2 /* Controller Status */
|
||||
#define U8500_I2C_SR_SHIFT_CAUSE 4 /* Abort Cause */
|
||||
#define U8500_I2C_SR_SHIFT_TYPE 7 /* Receive Type */
|
||||
#define U8500_I2C_SR_SHIFT_LENGTH 9 /* Transfer length */
|
||||
|
||||
/* abort cause */
|
||||
#define U8500_I2C_NACK_ADDR 0
|
||||
#define U8500_I2C_NACK_DATA 1
|
||||
#define U8500_I2C_ACK_MCODE 2
|
||||
#define U8500_I2C_ARB_LOST 3
|
||||
#define U8500_I2C_BERR_START 4
|
||||
#define U8500_I2C_BERR_STOP 5
|
||||
#define U8500_I2C_OVFL 6
|
||||
|
||||
|
||||
/* Baud rate counter registers */
|
||||
|
||||
/* Mask values for Baud rate counter register */
|
||||
#define U8500_I2C_BRCR_BRCNT2 0xFFFF /* Baud Rate Cntr BRCR for HS */
|
||||
#define U8500_I2C_BRCR_BRCNT1 0xFFFF0000 /* BRCR for Standard and Fast */
|
||||
|
||||
/* Shift values for the Baud rate counter register */
|
||||
#define U8500_I2C_BRCR_SHIFT_BRCNT2 0
|
||||
#define U8500_I2C_BRCR_SHIFT_BRCNT1 16
|
||||
|
||||
|
||||
/* Interrupt Register */
|
||||
|
||||
/* Mask values for Interrupt registers */
|
||||
#define U8500_I2C_INT_TXFE 0x00000001 /* Tx fifo empty */
|
||||
#define U8500_I2C_INT_TXFNE 0x00000002 /* Tx Fifo nearly empty */
|
||||
#define U8500_I2C_INT_TXFF 0x00000004 /* Tx Fifo Full */
|
||||
#define U8500_I2C_INT_TXFOVR 0x00000008 /* Tx Fifo over run */
|
||||
#define U8500_I2C_INT_RXFE 0x00000010 /* Rx Fifo Empty */
|
||||
#define U8500_I2C_INT_RXFNF 0x00000020 /* Rx Fifo nearly empty */
|
||||
#define U8500_I2C_INT_RXFF 0x00000040 /* Rx Fifo Full */
|
||||
#define U8500_I2C_INT_RFSR 0x00010000 /* Read From slave request */
|
||||
#define U8500_I2C_INT_RFSE 0x00020000 /* Read from slave empty */
|
||||
#define U8500_I2C_INT_WTSR 0x00040000 /* Write to Slave request */
|
||||
#define U8500_I2C_INT_MTD 0x00080000 /* Master Transcation Done*/
|
||||
#define U8500_I2C_INT_STD 0x00100000 /* Slave Transaction Done */
|
||||
#define U8500_I2C_INT_MAL 0x01000000 /* Master Arbitation Lost */
|
||||
#define U8500_I2C_INT_BERR 0x02000000 /* Bus Error */
|
||||
#define U8500_I2C_INT_MTDWS 0x10000000 /* Master Tran Done wo/ Stop */
|
||||
|
||||
/* Max clocks (Hz) */
|
||||
#define U8500_I2C_MAX_STANDARD_SCL 100000
|
||||
#define U8500_I2C_MAX_FAST_SCL 400000
|
||||
#define U8500_I2C_MAX_HIGH_SPEED_SCL 3400000
|
||||
|
||||
#endif /* _U8500_I2C_H_ */
|
|
@ -80,13 +80,6 @@ static int pl01x_generic_serial_init(struct pl01x_regs *regs,
|
|||
writel(0, ®s->pl010_cr);
|
||||
break;
|
||||
case TYPE_PL011:
|
||||
#ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT
|
||||
/* Empty RX fifo if necessary */
|
||||
if (readl(®s->pl011_cr) & UART_PL011_CR_UARTEN) {
|
||||
while (!(readl(®s->fr) & UART_PL01x_FR_RXFE))
|
||||
readl(®s->dr);
|
||||
}
|
||||
#endif
|
||||
/* disable everything */
|
||||
writel(0, ®s->pl011_cr);
|
||||
break;
|
||||
|
@ -105,21 +98,6 @@ static int pl011_set_line_control(struct pl01x_regs *regs)
|
|||
* control register write
|
||||
*/
|
||||
lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN;
|
||||
#ifdef CONFIG_PL011_SERIAL_RLCR
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Program receive line control register after waiting
|
||||
* 10 bus cycles. Delay be writing to readonly register
|
||||
* 10 times
|
||||
*/
|
||||
for (i = 0; i < 10; i++)
|
||||
writel(lcr, ®s->fr);
|
||||
|
||||
writel(lcr, ®s->pl011_rlcr);
|
||||
}
|
||||
#endif
|
||||
writel(lcr, ®s->pl011_lcrh);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1550,7 +1550,7 @@ static int __devinit musb_core_init(u16 musb_type, struct musb *musb)
|
|||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \
|
||||
defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500)
|
||||
defined(CONFIG_ARCH_OMAP4)
|
||||
|
||||
static irqreturn_t generic_interrupt(int irq, void *__hci)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue