[U-Boot] [PATCH] s5p: gpio: change gpio coding method for s5p gpio.

Przemyslaw Marczak p.marczak at samsung.com
Wed Nov 13 13:01:55 CET 2013


Old s5p gpio coding method returns bad bank address in few cases.
Now it is working properly with every gpio part bank and pin
and it is easy to extend.

Gpio coding mask:
0x000000ff - pin number
0x00ffff00 - bank offset
0xff000000 - part number

Tested on: Goni, Universal, Trats, Trats2.

Signed-off-by: Przemyslaw Marczak <p.marczak at samsung.com>
CC: Minkyu Kang <mk7.kang at samsung.com>
---
 arch/arm/include/asm/arch-exynos/gpio.h  |  169 +++++++++++-------------------
 arch/arm/include/asm/arch-s5pc1xx/gpio.h |   47 +++++++--
 drivers/gpio/s5p_gpio.c                  |   15 +--
 include/configs/s5p_goni.h               |    4 +-
 include/configs/s5pc210_universal.h      |   12 +--
 include/configs/trats.h                  |    8 +-
 include/configs/trats2.h                 |   12 +--
 7 files changed, 125 insertions(+), 142 deletions(-)

diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h
index a1a7439..b7dc8f5 100644
--- a/arch/arm/include/asm/arch-exynos/gpio.h
+++ b/arch/arm/include/asm/arch-exynos/gpio.h
@@ -196,117 +196,72 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode);
 /* GPIO pins per bank  */
 #define GPIO_PER_BANK 8
 
-#define exynos4_gpio_part1_get_nr(bank, pin) \
-	((((((unsigned int) &(((struct exynos4_gpio_part1 *) \
-			       EXYNOS4_GPIO_PART1_BASE)->bank)) \
-	    - EXYNOS4_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin)
-
-#define EXYNOS4_GPIO_PART1_MAX ((sizeof(struct exynos4_gpio_part1) \
-			    / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
-
-#define exynos4_gpio_part2_get_nr(bank, pin) \
-	(((((((unsigned int) &(((struct exynos4_gpio_part2 *) \
-				EXYNOS4_GPIO_PART2_BASE)->bank)) \
-	    - EXYNOS4_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin) + EXYNOS4_GPIO_PART1_MAX)
-
-#define exynos4x12_gpio_part1_get_nr(bank, pin) \
-	((((((unsigned int) &(((struct exynos4x12_gpio_part1 *) \
-			       EXYNOS4X12_GPIO_PART1_BASE)->bank)) \
-	    - EXYNOS4X12_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin)
-
-#define EXYNOS4X12_GPIO_PART1_MAX ((sizeof(struct exynos4x12_gpio_part1) \
-			    / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
-
-#define exynos4x12_gpio_part2_get_nr(bank, pin) \
-	(((((((unsigned int) &(((struct exynos4x12_gpio_part2 *) \
-				EXYNOS4X12_GPIO_PART2_BASE)->bank)) \
-	    - EXYNOS4X12_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin) + EXYNOS4X12_GPIO_PART1_MAX)
-
-#define EXYNOS4X12_GPIO_PART2_MAX ((sizeof(struct exynos4x12_gpio_part2) \
-			    / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
-
-#define exynos4x12_gpio_part3_get_nr(bank, pin) \
-	(((((((unsigned int) &(((struct exynos4x12_gpio_part3 *) \
-				EXYNOS4X12_GPIO_PART3_BASE)->bank)) \
-	    - EXYNOS4X12_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin) + EXYNOS4X12_GPIO_PART2_MAX)
-
-#define exynos5_gpio_part1_get_nr(bank, pin) \
-	((((((unsigned int) &(((struct exynos5_gpio_part1 *) \
-			       EXYNOS5_GPIO_PART1_BASE)->bank)) \
-	    - EXYNOS5_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin)
-
-#define EXYNOS5_GPIO_PART1_MAX ((sizeof(struct exynos5_gpio_part1) \
-			    / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
-
-#define exynos5_gpio_part2_get_nr(bank, pin) \
-	(((((((unsigned int) &(((struct exynos5_gpio_part2 *) \
-				EXYNOS5_GPIO_PART2_BASE)->bank)) \
-	    - EXYNOS5_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART1_MAX)
-
-#define EXYNOS5_GPIO_PART2_MAX ((sizeof(struct exynos5_gpio_part2) \
-			    / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
-
-#define exynos5_gpio_part3_get_nr(bank, pin) \
-	(((((((unsigned int) &(((struct exynos5_gpio_part3 *) \
-				EXYNOS5_GPIO_PART3_BASE)->bank)) \
-	    - EXYNOS5_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART2_MAX)
-
-static inline unsigned int s5p_gpio_base(int nr)
+#define S5P_GPIO_PART_SHIFT	(24)
+#define S5P_GPIO_PART_MASK	(0xff)
+#define S5P_GPIO_BANK_SHIFT	(8)
+#define S5P_GPIO_BANK_MASK	(0xffff)
+#define S5P_GPIO_PIN_MASK	(0xff)
+
+#define S5P_GPIO_SET_PART(x) \
+			((x & S5P_GPIO_PART_MASK) << S5P_GPIO_PART_SHIFT)
+
+#define S5P_GPIO_GET_PART(x) \
+			((x >> S5P_GPIO_PART_SHIFT) & S5P_GPIO_PART_MASK)
+
+#define S5P_GPIO_SET_PIN(x) \
+			(x & S5P_GPIO_PIN_MASK)
+
+#define EXYNOS4_GPIO_SET_BANK(part, bank) \
+			((((unsigned)&(((struct exynos4_gpio_part##part *) \
+			EXYNOS4_GPIO_PART##part##_BASE)->bank) \
+			- EXYNOS4_GPIO_PART##part##_BASE) \
+			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
+
+#define EXYNOS4X12_GPIO_SET_BANK(part, bank) \
+			((((unsigned)&(((struct exynos4x12_gpio_part##part *) \
+			EXYNOS4X12_GPIO_PART##part##_BASE)->bank) \
+			- EXYNOS4X12_GPIO_PART##part##_BASE) \
+			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
+
+#define EXYNOS5_GPIO_SET_BANK(part, bank) \
+			((((unsigned)&(((struct exynos5_gpio_part##part *) \
+			EXYNOS5_GPIO_PART##part##_BASE)->bank) \
+			- EXYNOS5_GPIO_PART##part##_BASE) \
+			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
+
+#define exynos4_gpio_get(part, bank, pin) \
+			(S5P_GPIO_SET_PART(part) | \
+			EXYNOS4_GPIO_SET_BANK(part, bank) | \
+			S5P_GPIO_SET_PIN(pin))
+
+#define exynos4x12_gpio_get(part, bank, pin) \
+			(S5P_GPIO_SET_PART(part) | \
+			EXYNOS4X12_GPIO_SET_BANK(part, bank) | \
+			S5P_GPIO_SET_PIN(pin))
+
+#define exynos5_gpio_get(part, bank, pin) \
+			(S5P_GPIO_SET_PART(part) | \
+			EXYNOS5_GPIO_SET_BANK(part, bank) | \
+			S5P_GPIO_SET_PIN(pin))
+
+static inline unsigned int s5p_gpio_base(int gpio)
 {
-	if (cpu_is_exynos5()) {
-		if (nr < EXYNOS5_GPIO_PART1_MAX)
-			return EXYNOS5_GPIO_PART1_BASE;
-		else if (nr < EXYNOS5_GPIO_PART2_MAX)
-			return EXYNOS5_GPIO_PART2_BASE;
-		else
-			return EXYNOS5_GPIO_PART3_BASE;
-
-	} else if (cpu_is_exynos4()) {
-		if (nr < EXYNOS4_GPIO_PART1_MAX)
-			return EXYNOS4_GPIO_PART1_BASE;
-		else
-			return EXYNOS4_GPIO_PART2_BASE;
+	unsigned gpio_part = S5P_GPIO_GET_PART(gpio);
+
+	switch (gpio_part) {
+	case 1:
+		return samsung_get_base_gpio_part1();
+	case 2:
+		return samsung_get_base_gpio_part2();
+	case 3:
+		return samsung_get_base_gpio_part3();
+	case 4:
+		return samsung_get_base_gpio_part4();
+	default:
+		return 0;
 	}
-
-	return 0;
 }
 
-static inline unsigned int s5p_gpio_part_max(int nr)
-{
-	if (cpu_is_exynos5()) {
-		if (nr < EXYNOS5_GPIO_PART1_MAX)
-			return 0;
-		else if (nr < EXYNOS5_GPIO_PART2_MAX)
-			return EXYNOS5_GPIO_PART1_MAX;
-		else
-			return EXYNOS5_GPIO_PART2_MAX;
-
-	} else if (cpu_is_exynos4()) {
-		if (proid_is_exynos4412()) {
-			if (nr < EXYNOS4X12_GPIO_PART1_MAX)
-				return 0;
-			else if (nr < EXYNOS4X12_GPIO_PART2_MAX)
-				return EXYNOS4X12_GPIO_PART1_MAX;
-			else
-				return EXYNOS4X12_GPIO_PART2_MAX;
-		} else {
-			if (nr < EXYNOS4_GPIO_PART1_MAX)
-				return 0;
-			else
-				return EXYNOS4_GPIO_PART1_MAX;
-		}
-	}
-
-	return 0;
-}
 #endif
 
 /* Pin configurations */
diff --git a/arch/arm/include/asm/arch-s5pc1xx/gpio.h b/arch/arm/include/asm/arch-s5pc1xx/gpio.h
index ac60fe6..c2d9244 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/gpio.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/gpio.h
@@ -125,20 +125,45 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode);
 /* GPIO pins per bank  */
 #define GPIO_PER_BANK 8
 
-static inline unsigned int s5p_gpio_base(int nr)
-{
-	return S5PC110_GPIO_BASE;
-}
+#define S5P_GPIO_PART_SHIFT	(24)
+#define S5P_GPIO_PART_MASK	(0xff)
+#define S5P_GPIO_BANK_SHIFT	(8)
+#define S5P_GPIO_BANK_MASK	(0xffff)
+#define S5P_GPIO_PIN_MASK	(0xff)
+
+#define S5P_GPIO_SET_PART(x) \
+			((x & S5P_GPIO_PART_MASK) << S5P_GPIO_PART_SHIFT)
+
+#define S5P_GPIO_GET_PART(x) \
+			((x >> S5P_GPIO_PART_SHIFT) & S5P_GPIO_PART_MASK)
+
+#define S5P_GPIO_SET_PIN(x) \
+			(x & S5P_GPIO_PIN_MASK)
 
-static inline unsigned int s5p_gpio_part_max(int nr)
+#define S5PC100_SET_BANK(bank) \
+			(((unsigned)&(((struct s5pc100_gpio *) \
+			S5PC100_GPIO_BASE)->bank) - S5PC100_GPIO_BASE) \
+			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
+
+#define S5PC110_SET_BANK(bank) \
+			((((unsigned)&(((struct s5pc110_gpio *) \
+			S5PC110_GPIO_BASE)->bank) - S5PC110_GPIO_BASE) \
+			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
+
+#define s5pc100_gpio_get(bank, pin) \
+			(S5P_GPIO_SET_PART(0) | \
+			S5PC100_SET_BANK(bank) | \
+			S5P_GPIO_SET_PIN(pin))
+
+#define s5pc110_gpio_get(bank, pin) \
+			(S5P_GPIO_SET_PART(0) | \
+			S5PC110_SET_BANK(bank) | \
+			S5P_GPIO_SET_PIN(pin))
+
+static inline unsigned int s5p_gpio_base(int nr)
 {
-	return 0;
+	return samsung_get_base_gpio();
 }
-
-#define s5pc110_gpio_get_nr(bank, pin)	  \
-	((((((unsigned int)&(((struct s5pc110_gpio *)S5PC110_GPIO_BASE)->bank))\
-	    - S5PC110_GPIO_BASE) / sizeof(struct s5p_gpio_bank)) \
-	  * GPIO_PER_BANK) + pin)
 #endif
 
 /* Pin configurations */
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 7eeb96d..13aefba 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -9,6 +9,11 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 
+#define S5P_GPIO_GET_BANK(x)	((x >> S5P_GPIO_BANK_SHIFT) \
+				& S5P_GPIO_BANK_MASK)
+
+#define S5P_GPIO_GET_PIN(x)	(x & S5P_GPIO_PIN_MASK)
+
 #define CON_MASK(x)		(0xf << ((x) << 2))
 #define CON_SFR(x, v)		((v) << ((x) << 2))
 
@@ -124,17 +129,15 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
 
 struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
 {
-	int bank;
-	unsigned g = gpio - s5p_gpio_part_max(gpio);
+	unsigned bank = S5P_GPIO_GET_BANK(gpio);
+	unsigned base = s5p_gpio_base(gpio);
 
-	bank = g / GPIO_PER_BANK;
-	bank *= sizeof(struct s5p_gpio_bank);
-	return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank);
+	return (struct s5p_gpio_bank *) (base + bank);
 }
 
 int s5p_gpio_get_pin(unsigned gpio)
 {
-	return gpio % GPIO_PER_BANK;
+	return S5P_GPIO_GET_PIN(gpio);
 }
 
 /* Common GPIO API */
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index c303244..780685e 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -210,8 +210,8 @@
 /*
  * I2C Settings
  */
-#define CONFIG_SOFT_I2C_GPIO_SCL s5pc110_gpio_get_nr(j4, 3)
-#define CONFIG_SOFT_I2C_GPIO_SDA s5pc110_gpio_get_nr(j4, 0)
+#define CONFIG_SOFT_I2C_GPIO_SCL s5pc110_gpio_get(j4, 3)
+#define CONFIG_SOFT_I2C_GPIO_SDA s5pc110_gpio_get(j4, 0)
 
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_SOFT		/* I2C bit-banged */
diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h
index 97a4008..524e5d3 100644
--- a/include/configs/s5pc210_universal.h
+++ b/include/configs/s5pc210_universal.h
@@ -231,8 +231,8 @@
 /*
  * I2C Settings
  */
-#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part1_get_nr(b, 7)
-#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part1_get_nr(b, 6)
+#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_get(1, b, 7)
+#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_get(1, b, 6)
 
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_SOFT		/* I2C bit-banged */
@@ -255,10 +255,10 @@
  */
 #define CONFIG_SOFT_SPI
 #define CONFIG_SOFT_SPI_MODE SPI_MODE_3
-#define CONFIG_SOFT_SPI_GPIO_SCLK exynos4_gpio_part2_get_nr(y3, 1)
-#define CONFIG_SOFT_SPI_GPIO_MOSI exynos4_gpio_part2_get_nr(y3, 3)
-#define CONFIG_SOFT_SPI_GPIO_MISO exynos4_gpio_part2_get_nr(y3, 0)
-#define CONFIG_SOFT_SPI_GPIO_CS exynos4_gpio_part2_get_nr(y4, 3)
+#define CONFIG_SOFT_SPI_GPIO_SCLK exynos4_gpio_get(2, y3, 1)
+#define CONFIG_SOFT_SPI_GPIO_MOSI exynos4_gpio_get(2, y3, 3)
+#define CONFIG_SOFT_SPI_GPIO_MISO exynos4_gpio_get(2, y3, 0)
+#define CONFIG_SOFT_SPI_GPIO_CS exynos4_gpio_get(2, y4, 3)
 
 #define SPI_DELAY udelay(1)
 #undef SPI_INIT
diff --git a/include/configs/trats.h b/include/configs/trats.h
index 24ea06b..b0719cf 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -275,12 +275,12 @@
 #include <asm/arch/gpio.h>
 
 /* I2C PMIC */
-#define CONFIG_SOFT_I2C_I2C5_SCL exynos4_gpio_part1_get_nr(b, 7)
-#define CONFIG_SOFT_I2C_I2C5_SDA exynos4_gpio_part1_get_nr(b, 6)
+#define CONFIG_SOFT_I2C_I2C5_SCL exynos4_gpio_get(1, b, 7)
+#define CONFIG_SOFT_I2C_I2C5_SDA exynos4_gpio_get(1, b, 6)
 
 /* I2C FG */
-#define CONFIG_SOFT_I2C_I2C9_SCL exynos4_gpio_part2_get_nr(y4, 1)
-#define CONFIG_SOFT_I2C_I2C9_SDA exynos4_gpio_part2_get_nr(y4, 0)
+#define CONFIG_SOFT_I2C_I2C9_SCL exynos4_gpio_get(2, y4, 1)
+#define CONFIG_SOFT_I2C_I2C9_SDA exynos4_gpio_get(2, y4, 0)
 
 #define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin()
 #define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin()
diff --git a/include/configs/trats2.h b/include/configs/trats2.h
index 0e93836..bf009f6 100644
--- a/include/configs/trats2.h
+++ b/include/configs/trats2.h
@@ -275,12 +275,12 @@
 #define CONFIG_SOFT_I2C_MULTI_BUS
 #define CONFIG_SYS_MAX_I2C_BUS		15
 
-#define CONFIG_SOFT_I2C_I2C5_SCL exynos4x12_gpio_part1_get_nr(d0, 3)
-#define CONFIG_SOFT_I2C_I2C5_SDA exynos4x12_gpio_part1_get_nr(d0, 2)
-#define CONFIG_SOFT_I2C_I2C9_SCL exynos4x12_gpio_part1_get_nr(f1, 4)
-#define CONFIG_SOFT_I2C_I2C9_SDA exynos4x12_gpio_part1_get_nr(f1, 5)
-#define CONFIG_SOFT_I2C_I2C10_SCL exynos4x12_gpio_part2_get_nr(m2, 1)
-#define CONFIG_SOFT_I2C_I2C10_SDA exynos4x12_gpio_part2_get_nr(m2, 0)
+#define CONFIG_SOFT_I2C_I2C5_SCL exynos4x12_gpio_get(1, d0, 3)
+#define CONFIG_SOFT_I2C_I2C5_SDA exynos4x12_gpio_get(1, d0, 2)
+#define CONFIG_SOFT_I2C_I2C9_SCL exynos4x12_gpio_get(1, f1, 4)
+#define CONFIG_SOFT_I2C_I2C9_SDA exynos4x12_gpio_get(1, f1, 5)
+#define CONFIG_SOFT_I2C_I2C10_SCL exynos4x12_gpio_get(2, m2, 1)
+#define CONFIG_SOFT_I2C_I2C10_SDA exynos4x12_gpio_get(2, m2, 0)
 #define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin()
 #define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin()
 #define I2C_INIT multi_i2c_init()
-- 
1.7.9.5



More information about the U-Boot mailing list