summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv7/sunxi/clock_sun6i.c10
-rw-r--r--arch/arm/cpu/armv7/sunxi/prcm.c12
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sun4i.h1
-rw-r--r--arch/arm/include/asm/arch-sunxi/gpio.h2
-rw-r--r--arch/arm/include/asm/arch-sunxi/i2c.h3
-rw-r--r--arch/arm/include/asm/arch-sunxi/prcm.h2
-rw-r--r--arch/nds32/cpu/n1213/start.S2
-rw-r--r--arch/nds32/include/asm/macro.h22
-rw-r--r--arch/nds32/include/asm/posix_types.h4
-rw-r--r--board/sunxi/Kconfig6
-rw-r--r--board/sunxi/board.c6
-rw-r--r--configs/orangepi_pc_defconfig1
-rw-r--r--drivers/i2c/mvtwsi.c31
-rw-r--r--include/configs/sunxi-common.h2
14 files changed, 87 insertions, 17 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
index 4501884e1c..1da5455c9a 100644
--- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
+++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
@@ -77,6 +77,16 @@ int clock_twi_onoff(int port, int state)
struct sunxi_ccm_reg *const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ if (port == 5) {
+ if (state)
+ prcm_apb0_enable(
+ PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_I2C);
+ else
+ prcm_apb0_disable(
+ PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_I2C);
+ return 0;
+ }
+
/* set the apb clock gate for twi */
if (state)
setbits_le32(&ccm->apb2_gate,
diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/cpu/armv7/sunxi/prcm.c
index 19b4938dc9..e1d091fd57 100644
--- a/arch/arm/cpu/armv7/sunxi/prcm.c
+++ b/arch/arm/cpu/armv7/sunxi/prcm.c
@@ -33,3 +33,15 @@ void prcm_apb0_enable(u32 flags)
/* deassert reset for module */
setbits_le32(&prcm->apb0_reset, flags);
}
+
+void prcm_apb0_disable(u32 flags)
+{
+ struct sunxi_prcm_reg *prcm =
+ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+
+ /* assert reset for module */
+ clrbits_le32(&prcm->apb0_reset, flags);
+
+ /* close the clock for module */
+ clrbits_le32(&prcm->apb0_gate, flags);
+}
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index 63b161ab03..0cdefdcdf4 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -134,6 +134,7 @@
#define SUNXI_RTC_BASE 0x01f00000
#define SUNXI_PRCM_BASE 0x01f01400
#define SUN6I_CPUCFG_BASE 0x01f01c00
+#define SUNXI_R_TWI_BASE 0x01f02400
#define SUNXI_R_UART_BASE 0x01f02800
#define SUNXI_R_PIO_BASE 0x01f02c00
#define SUN6I_P2WI_BASE 0x01f03400
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index a2a9a38dbe..649f6cd840 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -199,6 +199,8 @@ enum sunxi_gpio_number {
#define SUN6I_GPL1_R_P2WI_SDA 3
#define SUN8I_GPL_R_RSB 2
+#define SUN8I_H3_GPL_R_TWI 2
+#define SUN8I_A23_GPL_R_TWI 3
#define SUN8I_GPL_R_UART 2
#define SUN9I_GPN_R_RSB 3
diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h
index 561cd2be16..4dfd313f1a 100644
--- a/arch/arm/include/asm/arch-sunxi/i2c.h
+++ b/arch/arm/include/asm/arch-sunxi/i2c.h
@@ -23,6 +23,9 @@
#ifdef CONFIG_I2C4_ENABLE
#define CONFIG_I2C_MVTWSI_BASE4 SUNXI_TWI4_BASE
#endif
+#ifdef CONFIG_R_I2C_ENABLE
+#define CONFIG_I2C_MVTWSI_BASE5 SUNXI_R_TWI_BASE
+#endif
/* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */
#define CONFIG_SYS_TCLK 24000000
diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h
index 82ed541e91..556c1af600 100644
--- a/arch/arm/include/asm/arch-sunxi/prcm.h
+++ b/arch/arm/include/asm/arch-sunxi/prcm.h
@@ -236,5 +236,7 @@ struct sunxi_prcm_reg {
};
void prcm_apb0_enable(u32 flags);
+void prcm_apb0_disable(u32 flags);
+
#endif /* __ASSEMBLY__ */
#endif /* _PRCM_H */
diff --git a/arch/nds32/cpu/n1213/start.S b/arch/nds32/cpu/n1213/start.S
index 2f0b76c04c..8b7f8f4540 100644
--- a/arch/nds32/cpu/n1213/start.S
+++ b/arch/nds32/cpu/n1213/start.S
@@ -400,7 +400,7 @@ end_flush_dcache:
! FIXME: Other way to get PC?
! FIXME: Update according to the newest spec!!
1:
- la $r28, 1
+ li $r28, 1
push $r28
mfsr $r28, PSW ! $PSW
push $r28
diff --git a/arch/nds32/include/asm/macro.h b/arch/nds32/include/asm/macro.h
index f5c853991a..66be258052 100644
--- a/arch/nds32/include/asm/macro.h
+++ b/arch/nds32/include/asm/macro.h
@@ -23,20 +23,20 @@
*/
.macro write32, addr, data
- li $r4, addr
- li $r5, data
+ li $r4, \addr
+ li $r5, \data
swi $r5, [$r4]
.endm
.macro write16, addr, data
- li $r4, addr
- li $r5, data
+ li $r4, \addr
+ li $r5, \data
shi $r5, [$r4]
.endm
.macro write8, addr, data
- li $r4, addr
- li $r5, data
+ li $r4, \addr
+ li $r5, \data
sbi $r5, [$r4]
.endm
@@ -46,17 +46,17 @@
* Note: Instruction 'ori' supports immediate value up to 15 bits.
*/
.macro setbf32, addr, data
- li $r4, addr
+ li $r4, \addr
lwi $r5, [$r4]
- li $r6, data
+ li $r6, \data
or $r5, $r5, $r6
swi $r5, [$r4]
.endm
.macro setbf15, addr, data
- li $r4, addr
+ li $r4, \addr
lwi $r5, [$r4]
- ori $r5, $r5, data
+ ori $r5, $r5, \data
swi $r5, [$r4]
.endm
@@ -69,7 +69,7 @@
*/
.macro wait_timer, time
- li $r4, time
+ li $r4, \time
1:
nop
addi $r4, $r4, -1
diff --git a/arch/nds32/include/asm/posix_types.h b/arch/nds32/include/asm/posix_types.h
index a92803878e..e6c591dfe4 100644
--- a/arch/nds32/include/asm/posix_types.h
+++ b/arch/nds32/include/asm/posix_types.h
@@ -33,7 +33,11 @@ typedef int __kernel_pid_t;
typedef unsigned short __kernel_ipc_pid_t;
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
+#ifdef __GNUC__
+typedef __SIZE_TYPE__ __kernel_size_t;
+#else
typedef unsigned int __kernel_size_t;
+#endif
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
typedef long __kernel_time_t;
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 9d67847850..7c69be918f 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -363,6 +363,12 @@ config I2C3_ENABLE
See I2C0_ENABLE help text.
endif
+config R_I2C_ENABLE
+ bool "Enable the PRCM I2C/TWI controller"
+ default n
+ ---help---
+ Set this to y to enable the I2C controller which is part of the PRCM.
+
if MACH_SUN7I
config I2C4_ENABLE
bool "Enable I2C/TWI controller 4"
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 386e2e04c2..1cc39e4d18 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -422,6 +422,12 @@ void i2c_init_board(void)
clock_twi_onoff(4, 1);
#endif
#endif
+
+#ifdef CONFIG_R_I2C_ENABLE
+ clock_twi_onoff(5, 1);
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
+#endif
}
#ifdef CONFIG_SPL_BUILD
diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig
index 358caa51e7..ea9ed874e8 100644
--- a/configs/orangepi_pc_defconfig
+++ b/configs/orangepi_pc_defconfig
@@ -12,3 +12,4 @@ CONFIG_SPL=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
CONFIG_CMD_GPIO=y
+CONFIG_R_I2C_ENABLE=y
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 5dc4fbba1f..5f993b9905 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -73,6 +73,17 @@ struct mvtwsi_registers {
#define MVTWSI_CONTROL_INTEN 0x00000080
/*
+ * On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1,
+ * on other platforms it is a normal r/w bit which is cleared by writing 0.
+ */
+
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000008
+#else
+#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000000
+#endif
+
+/*
* Status register values -- only those expected in normal master
* operation on non-10-bit-address devices; whatever status we don't
* expect in nominal conditions (bus errors, arbitration losses,
@@ -117,6 +128,10 @@ static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap)
case 4:
return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4;
#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE5
+ case 5:
+ return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE5;
+#endif
default:
printf("Missing mvtwsi controller %d base\n", adap->hwadapnr);
break;
@@ -189,7 +204,8 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status)
/* globally set TWSIEN in case it was not */
twsi_control_flags |= MVTWSI_CONTROL_TWSIEN;
/* assert START */
- writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control);
+ twsi_control_flags |= MVTWSI_CONTROL_START | MVTWSI_CONTROL_CLEAR_IFLG;
+ writel(twsi_control_flags, &twsi->control);
/* wait for controller to process START */
return twsi_wait(adap, expected_status);
}
@@ -204,7 +220,7 @@ static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
/* put byte in data register for sending */
writel(byte, &twsi->data);
/* clear any pending interrupt -- that'll cause sending */
- writel(twsi_control_flags, &twsi->control);
+ writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
/* wait for controller to receive byte and check ACK */
return twsi_wait(adap, expected_status);
}
@@ -224,7 +240,7 @@ static int twsi_recv(struct i2c_adapter *adap, u8 *byte)
else
expected_status = MVTWSI_STATUS_DATA_R_NAK;
/* acknowledge *previous state* and launch receive */
- writel(twsi_control_flags, &twsi->control);
+ writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
/* wait for controller to receive byte and assert ACK or NAK */
status = twsi_wait(adap, expected_status);
/* if we did receive expected byte then store it */
@@ -246,7 +262,7 @@ static int twsi_stop(struct i2c_adapter *adap, int status)
/* assert STOP */
control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
- writel(control, &twsi->control);
+ writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
/* wait for IDLE; IFLG won't rise so twsi_wait() is no use. */
do {
stop_status = readl(&twsi->status);
@@ -475,3 +491,10 @@ U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe,
CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4)
#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE5
+U_BOOT_I2C_ADAP_COMPLETE(twsi5, twsi_i2c_init, twsi_i2c_probe,
+ twsi_i2c_read, twsi_i2c_write,
+ twsi_i2c_set_bus_speed,
+ CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 5)
+
+#endif
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 790e7047d1..b4dfb3cc47 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -212,7 +212,7 @@
#if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \
defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \
- defined CONFIG_I2C4_ENABLE
+ defined CONFIG_I2C4_ENABLE || defined CONFIG_R_I2C_ENABLE
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MVTWSI
#define CONFIG_SYS_I2C_SPEED 400000
OpenPOWER on IntegriCloud