All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 1/5] regmap: Add size parameter
@ 2018-04-27 12:51 Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range Mario Six
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Mario Six @ 2018-04-27 12:51 UTC (permalink / raw)
  To: u-boot

The regmap functions currently assume that all register map accesses
have a data width of 32 bits, but there are maps that have different
widths.

Implement a size parameter for the regmap_read and regmap_write
functions to specify the width of a desired read or write operation on a
regmap.

Correct all current clients of the regmap API to use 32 bit width reads
and writes to keep backwards compatibility.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

v1 -> v2:
New in v2

---
 drivers/clk/at91/clk-utmi.c               |  6 +++--
 drivers/clk/clk_boston.c                  |  3 ++-
 drivers/core/regmap.c                     | 45 ++++++++++++++++++++++++-------
 drivers/phy/meson-gxl-usb2.c              | 18 ++++++-------
 drivers/phy/meson-gxl-usb3.c              | 22 +++++++--------
 drivers/power/regulator/pbias_regulator.c |  5 ++--
 drivers/reset/reset-meson.c               | 14 +++++-----
 drivers/sysreset/sysreset_syscon.c        |  2 +-
 include/regmap.h                          | 11 ++++++--
 9 files changed, 82 insertions(+), 44 deletions(-)

diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index 875bf293f9..1da625cab1 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -68,13 +68,15 @@ static int utmi_clk_enable(struct clk *clk)
 	}
 
 	if (plat->regmap_sfr) {
-		err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp);
+		err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp,
+				  REGMAP_SIZE_32);
 		if (err)
 			return -EINVAL;
 
 		tmp &= ~AT91_UTMICKTRIM_FREQ;
 		tmp |= utmi_ref_clk_freq;
-		err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp);
+		err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp,
+				   REGMAP_SIZE_32);
 		if (err)
 			return -EINVAL;
 	} else if (utmi_ref_clk_freq) {
diff --git a/drivers/clk/clk_boston.c b/drivers/clk/clk_boston.c
index 5c05e3d78d..e09fd06fa0 100644
--- a/drivers/clk/clk_boston.c
+++ b/drivers/clk/clk_boston.c
@@ -33,7 +33,8 @@ static ulong clk_boston_get_rate(struct clk *clk)
 	uint mmcmdiv;
 	int err;
 
-	err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv);
+	err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv,
+			  REGMAP_SIZE_32);
 	if (err)
 		return 0;
 
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 8a0e00ff9a..c2cdff3979 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -130,20 +130,47 @@ int regmap_uninit(struct regmap *map)
 	return 0;
 }
 
-int regmap_read(struct regmap *map, uint offset, uint *valp)
+int regmap_read(struct regmap *map, ulong offset, ulong *valp,
+		enum regmap_size_t size)
 {
-	uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
-
-	*valp = le32_to_cpu(readl(ptr));
-
+	void *ptr;
+
+	switch (size) {
+	case REGMAP_SIZE_8:
+		ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
+		*valp = readb(ptr);
+		break;
+	case REGMAP_SIZE_16:
+		ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
+		*valp = le16_to_cpu(readw(ptr));
+		break;
+	case REGMAP_SIZE_32:
+		ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
+		*valp = le32_to_cpu(readl(ptr));
+		break;
+	}
 	return 0;
 }
 
-int regmap_write(struct regmap *map, uint offset, uint val)
+int regmap_write(struct regmap *map, ulong offset, ulong val,
+		 enum regmap_size_t size)
 {
-	uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
-
-	writel(cpu_to_le32(val), ptr);
+	void *ptr;
+
+	switch (size) {
+	case REGMAP_SIZE_8:
+		ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
+		writel((u8)val, ptr);
+		break;
+	case REGMAP_SIZE_16:
+		ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
+		writel(cpu_to_le16((u16)val), ptr);
+		break;
+	case REGMAP_SIZE_32:
+		ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
+		writel(cpu_to_le32((u32)val), ptr);
+		break;
+	}
 
 	return 0;
 }
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
index 15c9c89fd9..704b78747c 100644
--- a/drivers/phy/meson-gxl-usb2.c
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -111,15 +111,15 @@ static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
 {
 	uint val;
 
-	regmap_read(priv->regmap, U2P_R0, &val);
+	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
 
 	/* reset the PHY and wait until settings are stabilized */
 	val |= U2P_R0_POWER_ON_RESET;
-	regmap_write(priv->regmap, U2P_R0, val);
+	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
 	udelay(RESET_COMPLETE_TIME);
 
 	val &= ~U2P_R0_POWER_ON_RESET;
-	regmap_write(priv->regmap, U2P_R0, val);
+	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
 	udelay(RESET_COMPLETE_TIME);
 }
 
@@ -128,11 +128,11 @@ phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
 {
 	uint val;
 
-	regmap_read(priv->regmap, U2P_R0, &val);
+	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
 	val |= U2P_R0_DM_PULLDOWN;
 	val |= U2P_R0_DP_PULLDOWN;
 	val &= ~U2P_R0_ID_PULLUP;
-	regmap_write(priv->regmap, U2P_R0, val);
+	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
 
 	phy_meson_gxl_usb2_reset(priv);
 }
@@ -143,10 +143,10 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
 	struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
 	uint val;
 
-	regmap_read(priv->regmap, U2P_R0, &val);
+	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
 	/* power on the PHY by taking it out of reset mode */
 	val &= ~U2P_R0_POWER_ON_RESET;
-	regmap_write(priv->regmap, U2P_R0, val);
+	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
 
 	phy_meson_gxl_usb2_set_host_mode(priv);
 
@@ -167,10 +167,10 @@ static int phy_meson_gxl_usb2_power_off(struct phy *phy)
 	struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
 	uint val;
 
-	regmap_read(priv->regmap, U2P_R0, &val);
+	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
 	/* power off the PHY by putting it into reset mode */
 	val |= U2P_R0_POWER_ON_RESET;
-	regmap_write(priv->regmap, U2P_R0, val);
+	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
 
 #if CONFIG_IS_ENABLED(DM_REGULATOR)
 	if (priv->phy_supply) {
diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c
index a385fbdf12..33c24fd989 100644
--- a/drivers/phy/meson-gxl-usb3.c
+++ b/drivers/phy/meson-gxl-usb3.c
@@ -100,13 +100,13 @@ phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
 {
 	uint val;
 
-	regmap_read(priv->regmap, USB_R0, &val);
+	regmap_read(priv->regmap, USB_R0, &val, REGMAP_SIZE_32);
 	val &= ~USB_R0_U2D_ACT;
-	regmap_write(priv->regmap, USB_R0, val);
+	regmap_write(priv->regmap, USB_R0, val, REGMAP_SIZE_32);
 
-	regmap_read(priv->regmap, USB_R4, &val);
+	regmap_read(priv->regmap, USB_R4, &val, REGMAP_SIZE_32);
 	val &= ~USB_R4_P21_SLEEP_M0;
-	regmap_write(priv->regmap, USB_R4, val);
+	regmap_write(priv->regmap, USB_R4, val, REGMAP_SIZE_32);
 
 	return 0;
 }
@@ -117,12 +117,12 @@ static int phy_meson_gxl_usb3_power_on(struct phy *phy)
 	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
 	uint val;
 
-	regmap_read(priv->regmap, USB_R5, &val);
+	regmap_read(priv->regmap, USB_R5, &val, REGMAP_SIZE_32);
 	val |= USB_R5_ID_DIG_EN_0;
 	val |= USB_R5_ID_DIG_EN_1;
 	val &= ~USB_R5_ID_DIG_TH_MASK;
 	val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
-	regmap_write(priv->regmap, USB_R5, val);
+	regmap_write(priv->regmap, USB_R5, val, REGMAP_SIZE_32);
 
 	return phy_meson_gxl_usb3_set_host_mode(priv);
 }
@@ -133,10 +133,10 @@ static int phy_meson_gxl_usb3_power_off(struct phy *phy)
 	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
 	uint val;
 
-	regmap_read(priv->regmap, USB_R5, &val);
+	regmap_read(priv->regmap, USB_R5, &val, REGMAP_SIZE_32);
 	val &= ~USB_R5_ID_DIG_EN_0;
 	val &= ~USB_R5_ID_DIG_EN_1;
-	regmap_write(priv->regmap, USB_R5, val);
+	regmap_write(priv->regmap, USB_R5, val, REGMAP_SIZE_32);
 
 	return 0;
 }
@@ -147,10 +147,10 @@ static int phy_meson_gxl_usb3_init(struct phy *phy)
 	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
 	uint val;
 
-	regmap_read(priv->regmap, USB_R1, &val);
+	regmap_read(priv->regmap, USB_R1, &val, REGMAP_SIZE_32);
 	val &= ~USB_R1_U3H_FLADJ_30MHZ_REG_MASK;
 	val |= FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20);
-	regmap_write(priv->regmap, USB_R1, val);
+	regmap_write(priv->regmap, USB_R1, val, REGMAP_SIZE_32);
 
 	return 0;
 }
@@ -169,7 +169,7 @@ int meson_gxl_usb3_phy_probe(struct udevice *dev)
 	ret = regmap_init_mem(dev, &priv->regmap);
 	if (ret)
 		return ret;
-	
+
 #if CONFIG_IS_ENABLED(CLK)
 	ret = clk_get_by_index(dev, 0, &priv->clk);
 	if (ret < 0)
diff --git a/drivers/power/regulator/pbias_regulator.c b/drivers/power/regulator/pbias_regulator.c
index adf589b224..386da3a58f 100644
--- a/drivers/power/regulator/pbias_regulator.c
+++ b/drivers/power/regulator/pbias_regulator.c
@@ -46,7 +46,7 @@ static int pbias_write(struct udevice *dev, uint reg, const uint8_t *buff,
 	if (len != 4)
 		return -EINVAL;
 
-	return regmap_write(priv->regmap, priv->offset, val);
+	return regmap_write(priv->regmap, priv->offset, val, REGMAP_SIZE_32);
 }
 
 static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
@@ -56,7 +56,8 @@ static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 	if (len != 4)
 		return -EINVAL;
 
-	return regmap_read(priv->regmap, priv->offset, (u32 *)buff);
+	return regmap_read(priv->regmap, priv->offset, (u32 *)buff,
+			   REGMAP_SIZE_32);
 }
 
 static int pbias_ofdata_to_platdata(struct udevice *dev)
diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c
index 5324f86f5f..c31f302143 100644
--- a/drivers/reset/reset-meson.c
+++ b/drivers/reset/reset-meson.c
@@ -41,12 +41,12 @@ static int meson_reset_level(struct reset_ctl *reset_ctl, bool assert)
 	uint reg_offset = LEVEL_OFFSET + (bank << 2);
 	uint val;
 
-	regmap_read(priv->regmap, reg_offset, &val);
+	regmap_read(priv->regmap, reg_offset, &val, REGMAP_SIZE_32);
 	if (assert)
 		val &= ~BIT(offset);
 	else
 		val |= BIT(offset);
-	regmap_write(priv->regmap, reg_offset, val);
+	regmap_write(priv->regmap, reg_offset, val, REGMAP_SIZE_32);
 
 	return 0;
 }
@@ -68,15 +68,15 @@ struct reset_ops meson_reset_ops = {
 	.rst_deassert = meson_reset_deassert,
 };
 
-static const struct udevice_id meson_reset_ids[] = {                          
-	{ .compatible = "amlogic,meson-gxbb-reset" },                                  
-	{ }                                                                     
-};  
+static const struct udevice_id meson_reset_ids[] = {
+	{ .compatible = "amlogic,meson-gxbb-reset" },
+	{ }
+};
 
 static int meson_reset_probe(struct udevice *dev)
 {
 	struct meson_reset_priv *priv = dev_get_priv(dev);
-	
+
 	return regmap_init_mem(dev, &priv->regmap);
 }
 
diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c
index 22c602a4d2..0c374a7443 100644
--- a/drivers/sysreset/sysreset_syscon.c
+++ b/drivers/sysreset/sysreset_syscon.c
@@ -25,7 +25,7 @@ static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type)
 {
 	struct syscon_reboot_priv *priv = dev_get_priv(dev);
 
-	regmap_write(priv->regmap, priv->offset, priv->mask);
+	regmap_write(priv->regmap, priv->offset, priv->mask, REGMAP_SIZE_32);
 
 	return -EINPROGRESS;
 }
diff --git a/include/regmap.h b/include/regmap.h
index 493a5d8eff..a6e2fafd27 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -8,6 +8,13 @@
 #ifndef __REGMAP_H
 #define __REGMAP_H
 
+/* Access sizes for fpgamap reads and writes */
+enum regmap_size_t {
+	REGMAP_SIZE_8 = 1,
+	REGMAP_SIZE_16 = 2,
+	REGMAP_SIZE_32 = 4,
+};
+
 /**
  * struct regmap_range - a register map range
  *
@@ -37,8 +44,8 @@ struct regmap {
  * Interface to provide access to registers either through a direct memory
  * bus or through a peripheral bus like I2C, SPI.
  */
-int regmap_write(struct regmap *map, uint offset, uint val);
-int regmap_read(struct regmap *map, uint offset, uint *valp);
+int regmap_write(struct regmap *map, ulong offset, ulong val, enum regmap_size_t size);
+int regmap_read(struct regmap *map, ulong offset, ulong *valp, enum regmap_size_t size);
 
 #define regmap_write32(map, ptr, member, val) \
 	regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range
  2018-04-27 12:51 [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-05-03  2:33   ` Simon Glass
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 3/5] regmap: Define regmap_{get,set} Mario Six
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

It is useful to be able to treat the different ranges of a regmap
separately to be able to use distinct offset for them, but this is
currently not implemented in the regmap API.

To preserve backwards compatibility, add regmap_read_ext and
regmap_write_ext functions that take an additional parameter 'range_num'
that identifies the range to operate on.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

v1 -> v2:
New in v2

---
 drivers/core/regmap.c | 69 +++++++++++++++++++++++++++++++++++++++------------
 include/regmap.h      |  2 ++
 2 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index c2cdff3979..80718b3820 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -130,47 +130,84 @@ int regmap_uninit(struct regmap *map)
 	return 0;
 }
 
-int regmap_read(struct regmap *map, ulong offset, ulong *valp,
-		enum regmap_size_t size)
+int regmap_read_ext(struct regmap *map, uint range_num, ulong offset,
+		    ulong *valp, enum regmap_size_t size)
 {
+	struct regmap_range *range;
 	void *ptr;
 
+	if (range_num >= map->range_count)
+		return 0;
+	range = &map->range[range_num];
+
+	ptr = map_physmem(range->start + offset, size, MAP_NOCACHE);
+
+	if (offset + size > range->size) {
+		debug("%s: offset/size combination invalid\n", __func__);
+		return -EINVAL;
+	}
+
 	switch (size) {
 	case REGMAP_SIZE_8:
-		ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
-		*valp = readb(ptr);
+		*((u8 *)valp) = readb((u8 *)ptr);
 		break;
 	case REGMAP_SIZE_16:
-		ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
-		*valp = le16_to_cpu(readw(ptr));
+		*((u16 *)valp) = readw((u16 *)ptr);
 		break;
 	case REGMAP_SIZE_32:
-		ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
-		*valp = le32_to_cpu(readl(ptr));
+		*((u32 *)valp) = readl((u32 *)ptr);
 		break;
+	default:
+		debug("%s: size %d not supported\n", __func__, size);
+		return -ENOTSUPP;
 	}
+
 	return 0;
 }
 
-int regmap_write(struct regmap *map, ulong offset, ulong val,
-		 enum regmap_size_t size)
+int regmap_read(struct regmap *map, ulong offset, ulong *valp,
+		enum regmap_size_t size)
 {
+	return regmap_read_ext(map, 0, offset, valp, size);
+}
+
+int regmap_write_ext(struct regmap *map, uint range_num, ulong offset,
+		     ulong val, enum regmap_size_t size)
+{
+	struct regmap_range *range;
 	void *ptr;
 
+	if (range_num >= map->range_count)
+		return 0;
+	range = &map->range[range_num];
+
+	ptr = map_physmem(range->start + offset, size, MAP_NOCACHE);
+
+	if (offset + size > range->size) {
+		debug("%s: offset/size combination invalid\n", __func__);
+		return -EINVAL;
+	}
+
 	switch (size) {
 	case REGMAP_SIZE_8:
-		ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
-		writel((u8)val, ptr);
+		writeb((u8)val, (u8 *)ptr);
 		break;
 	case REGMAP_SIZE_16:
-		ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
-		writel(cpu_to_le16((u16)val), ptr);
+		out_le16((u16 *)ptr, (u16)val);
 		break;
 	case REGMAP_SIZE_32:
-		ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
-		writel(cpu_to_le32((u32)val), ptr);
+		writel((u32)val, (u32 *)ptr);
 		break;
+	default:
+		debug("%s: size %d not supported\n", __func__, size);
+		return -ENOTSUPP;
 	}
 
 	return 0;
 }
+
+int regmap_write(struct regmap *map, ulong offset, ulong val,
+		 enum regmap_size_t size)
+{
+	return regmap_write_ext(map, 0, offset, val, size);
+}
diff --git a/include/regmap.h b/include/regmap.h
index a6e2fafd27..bb7e947ce2 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -44,7 +44,9 @@ struct regmap {
  * Interface to provide access to registers either through a direct memory
  * bus or through a peripheral bus like I2C, SPI.
  */
+int regmap_write_ext(struct regmap *map, uint range_num, ulong offset, ulong val, enum regmap_size_t size);
 int regmap_write(struct regmap *map, ulong offset, ulong val, enum regmap_size_t size);
+int regmap_read_ext(struct regmap *map, uint range_num, ulong offset, ulong *valp, enum regmap_size_t size);
 int regmap_read(struct regmap *map, ulong offset, ulong *valp, enum regmap_size_t size);
 
 #define regmap_write32(map, ptr, member, val) \
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 3/5] regmap: Define regmap_{get,set}
  2018-04-27 12:51 [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-05-03  2:33   ` Simon Glass
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 4/5] misc: Add gdsys_soc driver Mario Six
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

It would be convenient if one could use the regmap API in conjunction
with register maps defined as structs (i.e. structs that directly mirror
the memory layout of the registers in question). A similar approach was
planned with the regmap_write32/regmap_read32 macros, but was never
used.

Hence, implement regmap_set/regmap_range_set and
regmap_get/regmap_range_get macros, which, given a register map, a
struct describing the layout of the register map, and a member name
automatically produce regmap_read/regmap_write calls that access the
specified member in the register map.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

v1 -> v2:
New in v2

---
 include/regmap.h | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/include/regmap.h b/include/regmap.h
index bb7e947ce2..69cbe8a96a 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -49,11 +49,17 @@ int regmap_write(struct regmap *map, ulong offset, ulong val, enum regmap_size_t
 int regmap_read_ext(struct regmap *map, uint range_num, ulong offset, ulong *valp, enum regmap_size_t size);
 int regmap_read(struct regmap *map, ulong offset, ulong *valp, enum regmap_size_t size);
 
-#define regmap_write32(map, ptr, member, val) \
-	regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)
+#define regmap_range_set(map, range, type, member, val) \
+	regmap_write_ext(map, range, offsetof(type, member), val, sizeof(((type *)0)->member))
 
-#define regmap_read32(map, ptr, member, valp) \
-	regmap_read(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), valp)
+#define regmap_set(map, type, member, val) \
+	regmap_range_set(map, 0, type, member, val)
+
+#define regmap_range_get(map, range, type, member, valp) \
+	regmap_read_ext(map, range, offsetof(type, member), (void *)valp, sizeof(((type *)0)->member))
+
+#define regmap_get(map, type, member, valp) \
+	regmap_range_get(map, 0, type, member, valp) \
 
 /**
  * regmap_init_mem() - Set up a new register map that uses memory access
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 4/5] misc: Add gdsys_soc driver
  2018-04-27 12:51 [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 3/5] regmap: Define regmap_{get,set} Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 5/5] misc: Add IHS FPGA driver Mario Six
  2018-04-27 13:00 ` [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Neil Armstrong
  4 siblings, 0 replies; 11+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

This patch adds a driver for the bus associated with a IHS FPGA.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

v1 -> v2:
* Switched to correct uclass for IHS FPGA driver (now in MISC uclass)

---
 drivers/misc/Kconfig     |  6 ++++-
 drivers/misc/Makefile    |  1 +
 drivers/misc/gdsys_soc.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/gdsys_soc.h | 24 +++++++++++++++++
 4 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/gdsys_soc.c
 create mode 100644 drivers/misc/gdsys_soc.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index d774569cbc..9d58d96321 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -263,5 +263,9 @@ config SYS_I2C_EEPROM_ADDR_OVERFLOW
 
 endif
 
-
+config GDSYS_SOC
+	bool "Enable gdsys SOC driver"
+	depends on MISC
+	help
+	  Support for IHS SOC.
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e8d598cd47..d35f7d856d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_QFW) += qfw.o
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
 obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
+obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
diff --git a/drivers/misc/gdsys_soc.c b/drivers/misc/gdsys_soc.c
new file mode 100644
index 0000000000..0bf1dd8303
--- /dev/null
+++ b/drivers/misc/gdsys_soc.c
@@ -0,0 +1,67 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/lists.h>
+
+#include "gdsys_soc.h"
+
+struct gdsys_soc_priv {
+	struct udevice *fpga;
+};
+
+static const struct udevice_id gdsys_soc_ids[] = {
+	{ .compatible = "gdsys,soc" },
+	{ /* sentinel */ }
+};
+
+int gdsys_soc_get_fpga(struct udevice *child, struct udevice **fpga)
+{
+	struct gdsys_soc_priv *bus_priv;
+
+	if (!child->parent)
+		return -EINVAL;
+
+	if (!device_is_compatible(child->parent, "gdsys,soc"))
+		return -EINVAL;
+
+ 	bus_priv = dev_get_priv(child->parent);
+
+	*fpga = bus_priv->fpga;
+
+	return 0;
+}
+
+static int gdsys_soc_probe(struct udevice *dev)
+{
+	struct gdsys_soc_priv *priv = dev_get_priv(dev);
+	struct udevice *fpga;
+	int res = uclass_get_device_by_phandle(UCLASS_MISC, dev, "fpga",
+					       &fpga);
+	if (res == -ENOENT) {
+		printf("%s: Could not find 'fpga' phandle.\n", dev->name);
+		return -EINVAL;
+	}
+
+	if (res == -ENODEV) {
+		printf("%s: Could not get FPGA device.\n", dev->name);
+		return -EINVAL;
+	}
+
+	priv->fpga = fpga;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(gdsys_soc_bus) = {
+	.name           = "gdsys_soc_bus",
+	.id             = UCLASS_SIMPLE_BUS,
+	.of_match       = gdsys_soc_ids,
+	.probe          = gdsys_soc_probe,
+	.priv_auto_alloc_size = sizeof(struct gdsys_soc_priv),
+};
diff --git a/drivers/misc/gdsys_soc.h b/drivers/misc/gdsys_soc.h
new file mode 100644
index 0000000000..0f88149fd6
--- /dev/null
+++ b/drivers/misc/gdsys_soc.h
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _GDSYS_SOC_H_
+#define _GDSYS_SOC_H_
+
+/**
+ * gdsys_soc_get_fpga() - Retrieve pointer to parent bus' FPGA device
+ *
+ * To access their register maps, devices on gdsys soc buses usually have
+ * facilitate the accessor function of the IHS FPGA their parent bus is
+ * attached to. To access the FPGA device from within the bus' children, this
+ * function returns a pointer to it.
+ *
+ * @child:	The child device on the FPGA bus needing access to the FPGA.
+ * @fpga:	Pointer to the retrieved FPGA device.
+ * @return 0 on success, -ve on failure
+ */
+int gdsys_soc_get_fpga(struct udevice *child, struct udevice **fpga);
+#endif /* _GDSYS_SOC_H_ */
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 5/5] misc: Add IHS FPGA driver
  2018-04-27 12:51 [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Mario Six
                   ` (2 preceding siblings ...)
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 4/5] misc: Add gdsys_soc driver Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-04-27 13:00 ` [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Neil Armstrong
  4 siblings, 0 replies; 11+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

Add a driver for gdsys IHS (Integrated Hardware Systems) FPGAs, which
supports initialization of the FPGA, as well as information gathering.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

v1 -> v2:
New in v2

---
 drivers/misc/Kconfig    |   6 +
 drivers/misc/Makefile   |   1 +
 drivers/misc/ihs_fpga.c | 686 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/ihs_fpga.h |  26 ++
 4 files changed, 719 insertions(+)
 create mode 100644 drivers/misc/ihs_fpga.c
 create mode 100644 drivers/misc/ihs_fpga.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 9d58d96321..2dd65fd621 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -268,4 +268,10 @@ config GDSYS_SOC
 	depends on MISC
 	help
 	  Support for IHS SOC.
+
+config IHS_FPGA
+	bool "Enable IHS FPGA driver"
+	depends on MISC
+	help
+	  Support IHS FPGA driver.
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d35f7d856d..a94627bc8b 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
 obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
 obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
+obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o
diff --git a/drivers/misc/ihs_fpga.c b/drivers/misc/ihs_fpga.c
new file mode 100644
index 0000000000..dc7e497163
--- /dev/null
+++ b/drivers/misc/ihs_fpga.c
@@ -0,0 +1,686 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * based on the ioep-fpga driver, which is
+ *
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <regmap.h>
+#include <misc.h>
+#include <mapmem.h>
+#include <asm/gpio.h>
+#include <linux/bitops.h>
+
+#include "ihs_fpga.h"
+
+struct ihs_fpga_priv {
+	struct regmap *map;
+	struct gpio_desc reset_gpio;
+	struct gpio_desc done_gpio;
+	struct gpio_desc startupfin_gpios[2];
+	bool has_osd;
+};
+
+const u16 reflection_testpattern = 0xdead;
+
+enum pcb_video_type {
+	PCB_DVI_SL,
+	PCB_DP_165MPIX,
+	PCB_DP_300MPIX,
+	PCB_HDMI,
+	PCB_DP_1_2,
+	PCB_HDMI_2_0,
+};
+
+enum pcb_transmission_type {
+	PCB_CAT_1G,
+	PCB_FIBER_3G,
+	PCB_CAT_10G,
+	PCB_FIBER_10G,
+};
+
+enum carrier_speed {
+	CARRIER_SPEED_1G,
+	CARRIER_SPEED_3G,
+	CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
+	CARRIER_SPEED_10G,
+};
+
+enum ram_config {
+	RAM_DDR2_32BIT_295MBPS,
+	RAM_DDR3_32BIT_590MBPS,
+	RAM_DDR3_48BIT_590MBPS,
+	RAM_DDR3_64BIT_1800MBPS,
+	RAM_DDR3_48BIT_1800MBPS,
+};
+
+enum sysclock {
+	SYSCLK_147456,
+};
+
+struct fpga_versions {
+	bool video_channel;
+	bool con_side;
+	enum pcb_video_type pcb_video_type;
+	enum pcb_transmission_type pcb_transmission_type;
+	unsigned int hw_version;
+};
+
+struct fpga_features {
+	u8 video_channels;
+	u8 carriers;
+	enum carrier_speed carrier_speed;
+	enum ram_config ram_config;
+	enum sysclock sysclock;
+
+	bool pcm_tx;
+	bool pcm_rx;
+	bool spdif_tx;
+	bool spdif_rx;
+	bool usb2;
+	bool rs232;
+	bool compression_type1;
+	bool compression_type2;
+	bool compression_type3;
+	bool interlace;
+	bool osd;
+	bool compression_pipes;
+};
+
+#ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
+
+static int get_versions(struct udevice *dev, struct fpga_versions *versions)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	enum {
+		VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
+		VERSIONS_FPGA_CON_SIDE = BIT(13),
+		VERSIONS_FPGA_SC = BIT(14),
+		VERSIONS_PCB_CON = BIT(9),
+		VERSIONS_PCB_SC = BIT(8),
+		VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
+		VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
+		VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
+		VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
+		VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
+		VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
+		VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
+		VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
+		VERSIONS_HW_VER_MASK = 0xf << 0,
+	};
+	u16 raw_versions;
+
+	memset(versions, 0, sizeof(struct fpga_versions));
+
+	ihs_fpga_get(priv->map, versions, &raw_versions);
+
+	versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
+	versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
+
+	switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
+	case VERSIONS_PCB_VIDEO_DP_1_2:
+		versions->pcb_video_type = PCB_DP_1_2;
+		break;
+
+	case VERSIONS_PCB_VIDEO_HDMI_2_0:
+		versions->pcb_video_type = PCB_HDMI_2_0;
+		break;
+	}
+
+	switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
+	case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
+		versions->pcb_transmission_type = PCB_FIBER_10G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_CAT_10G:
+		versions->pcb_transmission_type = PCB_CAT_10G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
+		versions->pcb_transmission_type = PCB_FIBER_3G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_CAT_1G:
+		versions->pcb_transmission_type = PCB_CAT_1G;
+		break;
+	}
+
+	versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
+
+	return 0;
+}
+
+static int get_features(struct udevice *dev, struct fpga_features *features)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	enum {
+		FEATURE_SPDIF_RX = BIT(15),
+		FEATURE_SPDIF_TX = BIT(14),
+		FEATURE_PCM_RX = BIT(13),
+		FEATURE_PCM_TX = BIT(12),
+		FEATURE_RAM_MASK = GENMASK(11, 8),
+		FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
+		FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
+		FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
+		FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
+		FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
+		FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
+		FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
+		FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
+		FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
+		FEATURE_CARRIERS_MASK = GENMASK(5, 4),
+		FEATURE_CARRIERS_0 = 0x0 << 4,
+		FEATURE_CARRIERS_1 = 0x1 << 4,
+		FEATURE_CARRIERS_2 = 0x2 << 4,
+		FEATURE_CARRIERS_4 = 0x3 << 4,
+		FEATURE_USB2 = BIT(3),
+		FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
+		FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
+		FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
+		FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
+		FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
+	};
+
+	enum {
+		EXT_FEATURE_OSD = BIT(15),
+		EXT_FEATURE_ETHERNET = BIT(9),
+		EXT_FEATURE_INTERLACE = BIT(8),
+		EXT_FEATURE_RS232 = BIT(7),
+		EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
+		EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
+		EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
+		EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
+		EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
+		EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
+		EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
+	};
+
+	u16 raw_features;
+	u16 raw_extended_features;
+
+	memset(features, 0, sizeof(struct fpga_features));
+
+	ihs_fpga_get(priv->map, features, &raw_features);
+	ihs_fpga_get(priv->map, extended_features, &raw_extended_features);
+
+	switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
+	case FEATURE_VIDEOCHANNELS_0:
+		features->video_channels = 0;
+		break;
+
+	case FEATURE_VIDEOCHANNELS_1:
+		features->video_channels = 1;
+		break;
+
+	case FEATURE_VIDEOCHANNELS_1_1:
+	case FEATURE_VIDEOCHANNELS_2:
+		features->video_channels = 2;
+		break;
+	};
+
+	switch (raw_features & FEATURE_CARRIERS_MASK) {
+	case FEATURE_CARRIERS_0:
+		features->carriers = 0;
+		break;
+
+	case FEATURE_CARRIERS_1:
+		features->carriers = 1;
+		break;
+
+	case FEATURE_CARRIERS_2:
+		features->carriers = 2;
+		break;
+
+	case FEATURE_CARRIERS_4:
+		features->carriers = 4;
+		break;
+	}
+
+	switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
+	case FEATURE_CARRIER_SPEED_1G:
+		features->carrier_speed = CARRIER_SPEED_1G;
+		break;
+	case FEATURE_CARRIER_SPEED_2_5G:
+		features->carrier_speed = CARRIER_SPEED_2_5G;
+		break;
+	case FEATURE_CARRIER_SPEED_10G:
+		features->carrier_speed = CARRIER_SPEED_10G;
+		break;
+	}
+
+	switch (raw_features & FEATURE_RAM_MASK) {
+	case FEATURE_RAM_DDR2_32BIT_295MBPS:
+		features->ram_config = RAM_DDR2_32BIT_295MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_32BIT_590MBPS:
+		features->ram_config = RAM_DDR3_32BIT_590MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_48BIT_590MBPS:
+		features->ram_config = RAM_DDR3_48BIT_590MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_64BIT_1800MBPS:
+		features->ram_config = RAM_DDR3_64BIT_1800MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_48BIT_1800MBPS:
+		features->ram_config = RAM_DDR3_48BIT_1800MBPS;
+		break;
+	}
+
+	features->pcm_tx = raw_features & FEATURE_PCM_TX;
+	features->pcm_rx = raw_features & FEATURE_PCM_RX;
+	features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
+	features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
+	features->usb2 = raw_features & FEATURE_USB2;
+	features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
+	features->compression_type1 = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_TYPE1;
+	features->compression_type2 = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_TYPE2;
+	features->compression_type3 = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_TYPE3;
+	features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
+	features->osd = raw_extended_features & EXT_FEATURE_OSD;
+	features->compression_pipes = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_PERF_MASK;
+
+	return 0;
+}
+
+#else
+
+static int get_versions(unsigned int fpga, struct fpga_versions *versions)
+{
+	enum {
+		/* HW version encoding is a mess, leave it for the moment */
+		VERSIONS_HW_VER_MASK = 0xf << 0,
+		VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
+		VERSIONS_SFP = BIT(5),
+		VERSIONS_VIDEO_MASK = 0x7 << 6,
+		VERSIONS_VIDEO_DVI = 0x0 << 6,
+		VERSIONS_VIDEO_DP_165 = 0x1 << 6,
+		VERSIONS_VIDEO_DP_300 = 0x2 << 6,
+		VERSIONS_VIDEO_HDMI = 0x3 << 6,
+		VERSIONS_UT_MASK = 0xf << 12,
+		VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
+		VERSIONS_UT_MAIN_USER = 0x1 << 12,
+		VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
+		VERSIONS_UT_VIDEO_USER = 0x3 << 12,
+	};
+	u16 raw_versions;
+
+	memset(versions, 0, sizeof(struct fpga_versions));
+
+	FPGA_GET_REG(fpga, versions, &raw_versions);
+
+	switch (raw_versions & VERSIONS_UT_MASK) {
+	case VERSIONS_UT_MAIN_SERVER:
+		versions->video_channel = false;
+		versions->con_side = false;
+		break;
+
+	case VERSIONS_UT_MAIN_USER:
+		versions->video_channel = false;
+		versions->con_side = true;
+		break;
+
+	case VERSIONS_UT_VIDEO_SERVER:
+		versions->video_channel = true;
+		versions->con_side = false;
+		break;
+
+	case VERSIONS_UT_VIDEO_USER:
+		versions->video_channel = true;
+		versions->con_side = true;
+		break;
+	}
+
+	switch (raw_versions & VERSIONS_VIDEO_MASK) {
+	case VERSIONS_VIDEO_DVI:
+		versions->pcb_video_type = PCB_DVI_SL;
+		break;
+
+	case VERSIONS_VIDEO_DP_165:
+		versions->pcb_video_type = PCB_DP_165MPIX;
+		break;
+
+	case VERSIONS_VIDEO_DP_300:
+		versions->pcb_video_type = PCB_DP_300MPIX;
+		break;
+
+	case VERSIONS_VIDEO_HDMI:
+		versions->pcb_video_type = PCB_HDMI;
+		break;
+	}
+
+	versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
+
+	if (raw_versions & VERSIONS_SFP)
+		versions->pcb_transmission_type = PCB_FIBER_3G;
+	else
+		versions->pcb_transmission_type = PCB_CAT_1G;
+
+	return 0;
+}
+
+static int get_features(unsigned int fpga, struct fpga_features *features)
+{
+	enum {
+		FEATURE_CARRIER_SPEED_2_5 = BIT(4),
+		FEATURE_RAM_MASK = 0x7 << 5,
+		FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
+		FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
+		FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
+		FEATURE_PCM_AUDIO_TX = BIT(9),
+		FEATURE_PCM_AUDIO_RX = BIT(10),
+		FEATURE_OSD = BIT(11),
+		FEATURE_USB20 = BIT(12),
+		FEATURE_COMPRESSION_MASK = 7 << 13,
+		FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
+		FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
+		FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
+	};
+
+	enum {
+		EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
+		EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
+		EXTENDED_FEATURE_RS232 = BIT(2),
+		EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
+		EXTENDED_FEATURE_INTERLACE = BIT(4),
+	};
+
+	u16 raw_features;
+	u16 raw_extended_features;
+
+	memset(features, 0, sizeof(struct fpga_features));
+
+	FPGA_GET_REG(fpga, fpga_features, &raw_features);
+	FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
+
+	features->video_channels = raw_features & 0x3;
+	features->carriers = (raw_features >> 2) & 0x3;
+
+	features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
+		? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
+
+	switch (raw_features & FEATURE_RAM_MASK) {
+	case FEATURE_RAM_DDR2_32BIT:
+		features->ram_config = RAM_DDR2_32BIT_295MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_32BIT:
+		features->ram_config = RAM_DDR3_32BIT_590MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_48BIT:
+		features->ram_config = RAM_DDR3_48BIT_590MBPS;
+		break;
+	}
+
+	features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
+	features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
+	features->spdif_tx = raw_extended_features &
+				EXTENDED_FEATURE_SPDIF_AUDIO_TX;
+	features->spdif_rx = raw_extended_features &
+				EXTENDED_FEATURE_SPDIF_AUDIO_RX;
+
+	features->usb2 = raw_features & FEATURE_USB20;
+	features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
+
+	features->compression_type1 = false;
+	features->compression_type2 = false;
+	features->compression_type3 = false;
+	switch (raw_features & FEATURE_COMPRESSION_MASK) {
+	case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
+		features->compression_type3 = true;
+	case FEATURE_COMPRESSION_TYPE1_TYPE2:
+		features->compression_type2 = true;
+	case FEATURE_COMPRESSION_TYPE1:
+		features->compression_type1 = true;
+		break;
+	}
+
+	features->interlace = raw_extended_features &
+				EXTENDED_FEATURE_INTERLACE;
+	features->osd = raw_features & FEATURE_OSD;
+	features->compression_pipes = raw_extended_features &
+					EXTENDED_FEATURE_COMPRESSION_PIPES;
+
+	return 0;
+}
+
+#endif
+
+static void fpga_print_info(struct udevice *dev)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	u16 fpga_version;
+	struct fpga_versions versions;
+	struct fpga_features features;
+
+	ihs_fpga_get(priv->map, fpga_version, &fpga_version);
+	get_versions(dev, &versions);
+	get_features(dev, &features);
+
+	priv->has_osd = features.osd;
+
+	if (versions.video_channel)
+		printf("Videochannel");
+	else
+		printf("Mainchannel");
+
+	if (versions.con_side)
+		printf(" User");
+	else
+		printf(" Server");
+
+// FIXME
+#if 0
+		if (versions & (1<<4))
+			printf(" UC");
+#endif
+
+	switch (versions.pcb_transmission_type) {
+	case PCB_CAT_1G:
+	case PCB_CAT_10G:
+		printf(" CAT");
+		break;
+	case PCB_FIBER_3G:
+	case PCB_FIBER_10G:
+		printf(" Fiber");
+		break;
+	};
+
+	switch (versions.pcb_video_type) {
+	case PCB_DVI_SL:
+		printf(" DVI,");
+		break;
+	case PCB_DP_165MPIX:
+		printf(" DP 165MPix/s,");
+		break;
+	case PCB_DP_300MPIX:
+		printf(" DP 300MPix/s,");
+		break;
+	case PCB_HDMI:
+		printf(" HDMI,");
+		break;
+	case PCB_DP_1_2:
+		printf(" DP 1.2,");
+		break;
+	case PCB_HDMI_2_0:
+		printf(" HDMI 2.0,");
+		break;
+	}
+
+	printf(" FPGA V %d.%02d\n       features: ",
+	       fpga_version / 100, fpga_version % 100);
+
+	if (!features.compression_type1 &&
+	    !features.compression_type2 &&
+	    !features.compression_type3)
+		printf("no compression, ");
+
+	if (features.compression_type1)
+		printf("type1, ");
+
+	if (features.compression_type2)
+		printf("type2, ");
+
+	if (features.compression_type3)
+		printf("type3, ");
+
+	printf("%sosd", features.osd ? "" : "no ");
+
+	if (features.pcm_rx && features.pcm_tx)
+		printf(", pcm rx+tx");
+	else if (features.pcm_rx)
+		printf(", pcm rx");
+	else if (features.pcm_tx)
+		printf(", pcm tx");
+
+	if (features.spdif_rx && features.spdif_tx)
+		printf(", spdif rx+tx");
+	else if (features.spdif_rx)
+		printf(", spdif rx");
+	else if (features.spdif_tx)
+		printf(", spdif tx");
+
+	puts(",\n       ");
+
+	switch (features.sysclock) {
+	case SYSCLK_147456:
+		printf("clock 147.456 MHz");
+		break;
+	}
+
+	switch (features.ram_config) {
+	case RAM_DDR2_32BIT_295MBPS:
+		printf(", RAM 32 bit DDR2");
+		break;
+	case RAM_DDR3_32BIT_590MBPS:
+		printf(", RAM 32 bit DDR3");
+		break;
+	case RAM_DDR3_48BIT_590MBPS:
+	case RAM_DDR3_48BIT_1800MBPS:
+		printf(", RAM 48 bit DDR3");
+		break;
+	case RAM_DDR3_64BIT_1800MBPS:
+		printf(", RAM 64 bit DDR3");
+		break;
+	}
+
+	printf(", %d carrier(s)", features.carriers);
+
+	switch (features.carrier_speed) {
+	case CARRIER_SPEED_1G:
+		printf(", 1Gbit/s");
+		break;
+	case CARRIER_SPEED_3G:
+		printf(", 3Gbit/s");
+		break;
+	case CARRIER_SPEED_10G:
+		printf(", 10Gbit/s");
+		break;
+	}
+
+	printf(", %d video channel(s)\n", features.video_channels);
+}
+
+static int do_reflection_test(struct udevice *dev)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	int ctr = 0;
+
+	while (1) {
+		u16 val;
+
+		ihs_fpga_set(priv->map, reflection_low, reflection_testpattern);
+
+		ihs_fpga_get(priv->map, reflection_low, &val);
+		if (val == (~reflection_testpattern & 0xffff))
+			return -EIO;
+
+		mdelay(100);
+		if (ctr++ > 5)
+			return 0;
+	}
+}
+
+static int ihs_fpga_probe(struct udevice *dev)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+
+	/* TODO: FPGA attached to MCLink bus */
+
+	regmap_init_mem(dev, &priv->map);
+
+	gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio,
+			     GPIOD_IS_OUT);
+	if (!priv->reset_gpio.dev) {
+		printf("%s: Could not get reset-GPIO.\n", dev->name);
+		return -ENOENT;
+	}
+
+	gpio_request_by_name(dev, "done-gpios", 0, &priv->done_gpio,
+			     GPIOD_IS_IN);
+	if (!priv->done_gpio.dev) {
+		printf("%s: Could not get done-GPIO.\n", dev->name);
+		return -ENOENT;
+	}
+
+	dm_gpio_set_value(&priv->reset_gpio, 1);
+
+	if (!do_reflection_test(dev)) {
+		int ctr = 0;
+
+		dm_gpio_set_value(&priv->reset_gpio, 0);
+
+		while (!dm_gpio_get_value(&priv->done_gpio)) {
+			mdelay(100);
+			if (ctr++ > 5) {
+				printf("Initializing FPGA failed\n");
+				break;
+			}
+		}
+
+		udelay(10);
+
+		dm_gpio_set_value(&priv->reset_gpio, 1);
+
+		if (!do_reflection_test(dev)) {
+			printf("%s: Reflection test FAILED.\n", dev->name);
+			return -EIO;
+		}
+	}
+
+	printf("%s: Reflection test passed.\n", dev->name);
+
+	fpga_print_info(dev);
+
+	return 0;
+}
+
+static const struct udevice_id ihs_fpga_ids[] = {
+	{ .compatible = "gdsys,iocon_fpga" },
+	{ .compatible = "gdsys,iocpu_fpga" },
+	{ }
+};
+
+U_BOOT_DRIVER(ihs_fpga_bus) = {
+	.name           = "ihs_fpga_bus",
+	.id             = UCLASS_MISC,
+	.of_match       = ihs_fpga_ids,
+	.probe          = ihs_fpga_probe,
+	.priv_auto_alloc_size = sizeof(struct ihs_fpga_priv),
+};
diff --git a/drivers/misc/ihs_fpga.h b/drivers/misc/ihs_fpga.h
new file mode 100644
index 0000000000..be36b0dc62
--- /dev/null
+++ b/drivers/misc/ihs_fpga.h
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+struct ihs_fpga_regs {
+	u16 reflection_low;
+	u16 versions;
+	u16 fpga_version;
+	u16 features;
+	u16 extended_features;
+	u16 top_interrupt;
+	u16 top_interrupt_enable;
+	u16 status;
+	u16 control;
+	u16 extended_control;
+};
+
+#define ihs_fpga_set(map, member, val) \
+	regmap_set(map, struct ihs_fpga_regs, member, val)
+
+#define ihs_fpga_get(map, member, valp) \
+	regmap_get(map, struct ihs_fpga_regs, member, valp)
+
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 1/5] regmap: Add size parameter
  2018-04-27 12:51 [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Mario Six
                   ` (3 preceding siblings ...)
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 5/5] misc: Add IHS FPGA driver Mario Six
@ 2018-04-27 13:00 ` Neil Armstrong
  2018-05-04  8:18   ` Mario Six
  4 siblings, 1 reply; 11+ messages in thread
From: Neil Armstrong @ 2018-04-27 13:00 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 27/04/2018 14:51, Mario Six wrote:
> The regmap functions currently assume that all register map accesses
> have a data width of 32 bits, but there are maps that have different
> widths.
> 
> Implement a size parameter for the regmap_read and regmap_write
> functions to specify the width of a desired read or write operation on a
> regmap.

This changes the regmap API which is based on the Linux API.

Linux passes a struct defining the regmap access type instead, I think the same should
happen here.

Neil

> 
> Correct all current clients of the regmap API to use 32 bit width reads
> and writes to keep backwards compatibility.
> 
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
> 
> v1 -> v2:
> New in v2
> 
> ---
>  drivers/clk/at91/clk-utmi.c               |  6 +++--
>  drivers/clk/clk_boston.c                  |  3 ++-
>  drivers/core/regmap.c                     | 45 ++++++++++++++++++++++++-------
>  drivers/phy/meson-gxl-usb2.c              | 18 ++++++-------
>  drivers/phy/meson-gxl-usb3.c              | 22 +++++++--------
>  drivers/power/regulator/pbias_regulator.c |  5 ++--
>  drivers/reset/reset-meson.c               | 14 +++++-----
>  drivers/sysreset/sysreset_syscon.c        |  2 +-
>  include/regmap.h                          | 11 ++++++--
>  9 files changed, 82 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
> index 875bf293f9..1da625cab1 100644
> --- a/drivers/clk/at91/clk-utmi.c
> +++ b/drivers/clk/at91/clk-utmi.c
> @@ -68,13 +68,15 @@ static int utmi_clk_enable(struct clk *clk)
>  	}
>  
>  	if (plat->regmap_sfr) {
> -		err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp);
> +		err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp,
> +				  REGMAP_SIZE_32);
>  		if (err)
>  			return -EINVAL;
>  
>  		tmp &= ~AT91_UTMICKTRIM_FREQ;
>  		tmp |= utmi_ref_clk_freq;
> -		err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp);
> +		err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp,
> +				   REGMAP_SIZE_32);
>  		if (err)
>  			return -EINVAL;
>  	} else if (utmi_ref_clk_freq) {
> diff --git a/drivers/clk/clk_boston.c b/drivers/clk/clk_boston.c
> index 5c05e3d78d..e09fd06fa0 100644
> --- a/drivers/clk/clk_boston.c
> +++ b/drivers/clk/clk_boston.c
> @@ -33,7 +33,8 @@ static ulong clk_boston_get_rate(struct clk *clk)
>  	uint mmcmdiv;
>  	int err;
>  
> -	err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv);
> +	err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv,
> +			  REGMAP_SIZE_32);
>  	if (err)
>  		return 0;
>  
> diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
> index 8a0e00ff9a..c2cdff3979 100644
> --- a/drivers/core/regmap.c
> +++ b/drivers/core/regmap.c
> @@ -130,20 +130,47 @@ int regmap_uninit(struct regmap *map)
>  	return 0;
>  }
>  
> -int regmap_read(struct regmap *map, uint offset, uint *valp)
> +int regmap_read(struct regmap *map, ulong offset, ulong *valp,
> +		enum regmap_size_t size)
>  {
> -	uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
> -
> -	*valp = le32_to_cpu(readl(ptr));
> -
> +	void *ptr;
> +
> +	switch (size) {
> +	case REGMAP_SIZE_8:
> +		ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
> +		*valp = readb(ptr);
> +		break;
> +	case REGMAP_SIZE_16:
> +		ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
> +		*valp = le16_to_cpu(readw(ptr));
> +		break;
> +	case REGMAP_SIZE_32:
> +		ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
> +		*valp = le32_to_cpu(readl(ptr));
> +		break;
> +	}
>  	return 0;
>  }
>  
> -int regmap_write(struct regmap *map, uint offset, uint val)
> +int regmap_write(struct regmap *map, ulong offset, ulong val,
> +		 enum regmap_size_t size)
>  {
> -	uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
> -
> -	writel(cpu_to_le32(val), ptr);
> +	void *ptr;
> +
> +	switch (size) {
> +	case REGMAP_SIZE_8:
> +		ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
> +		writel((u8)val, ptr);
> +		break;
> +	case REGMAP_SIZE_16:
> +		ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
> +		writel(cpu_to_le16((u16)val), ptr);
> +		break;
> +	case REGMAP_SIZE_32:
> +		ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
> +		writel(cpu_to_le32((u32)val), ptr);
> +		break;
> +	}
>  
>  	return 0;
>  }
> diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
> index 15c9c89fd9..704b78747c 100644
> --- a/drivers/phy/meson-gxl-usb2.c
> +++ b/drivers/phy/meson-gxl-usb2.c
> @@ -111,15 +111,15 @@ static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
>  {
>  	uint val;
>  
> -	regmap_read(priv->regmap, U2P_R0, &val);
> +	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>  
>  	/* reset the PHY and wait until settings are stabilized */
>  	val |= U2P_R0_POWER_ON_RESET;
> -	regmap_write(priv->regmap, U2P_R0, val);
> +	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>  	udelay(RESET_COMPLETE_TIME);
>  
>  	val &= ~U2P_R0_POWER_ON_RESET;
> -	regmap_write(priv->regmap, U2P_R0, val);
> +	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>  	udelay(RESET_COMPLETE_TIME);
>  }
>  
> @@ -128,11 +128,11 @@ phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
>  {
>  	uint val;
>  
> -	regmap_read(priv->regmap, U2P_R0, &val);
> +	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>  	val |= U2P_R0_DM_PULLDOWN;
>  	val |= U2P_R0_DP_PULLDOWN;
>  	val &= ~U2P_R0_ID_PULLUP;
> -	regmap_write(priv->regmap, U2P_R0, val);
> +	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>  
>  	phy_meson_gxl_usb2_reset(priv);
>  }
> @@ -143,10 +143,10 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
>  	struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
>  	uint val;
>  
> -	regmap_read(priv->regmap, U2P_R0, &val);
> +	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>  	/* power on the PHY by taking it out of reset mode */
>  	val &= ~U2P_R0_POWER_ON_RESET;
> -	regmap_write(priv->regmap, U2P_R0, val);
> +	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>  
>  	phy_meson_gxl_usb2_set_host_mode(priv);
>  
> @@ -167,10 +167,10 @@ static int phy_meson_gxl_usb2_power_off(struct phy *phy)
>  	struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
>  	uint val;
>  
> -	regmap_read(priv->regmap, U2P_R0, &val);
> +	regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>  	/* power off the PHY by putting it into reset mode */
>  	val |= U2P_R0_POWER_ON_RESET;
> -	regmap_write(priv->regmap, U2P_R0, val);
> +	regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>  
>  #if CONFIG_IS_ENABLED(DM_REGULATOR)
>  	if (priv->phy_supply) {
> diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c
> index a385fbdf12..33c24fd989 100644
> --- a/drivers/phy/meson-gxl-usb3.c
> +++ b/drivers/phy/meson-gxl-usb3.c
> @@ -100,13 +100,13 @@ phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
>  {
>  	uint val;
>  
> -	regmap_read(priv->regmap, USB_R0, &val);
> +	regmap_read(priv->regmap, USB_R0, &val, REGMAP_SIZE_32);
>  	val &= ~USB_R0_U2D_ACT;
> -	regmap_write(priv->regmap, USB_R0, val);
> +	regmap_write(priv->regmap, USB_R0, val, REGMAP_SIZE_32);
>  
> -	regmap_read(priv->regmap, USB_R4, &val);
> +	regmap_read(priv->regmap, USB_R4, &val, REGMAP_SIZE_32);
>  	val &= ~USB_R4_P21_SLEEP_M0;
> -	regmap_write(priv->regmap, USB_R4, val);
> +	regmap_write(priv->regmap, USB_R4, val, REGMAP_SIZE_32);
>  
>  	return 0;
>  }
> @@ -117,12 +117,12 @@ static int phy_meson_gxl_usb3_power_on(struct phy *phy)
>  	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
>  	uint val;
>  
> -	regmap_read(priv->regmap, USB_R5, &val);
> +	regmap_read(priv->regmap, USB_R5, &val, REGMAP_SIZE_32);
>  	val |= USB_R5_ID_DIG_EN_0;
>  	val |= USB_R5_ID_DIG_EN_1;
>  	val &= ~USB_R5_ID_DIG_TH_MASK;
>  	val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
> -	regmap_write(priv->regmap, USB_R5, val);
> +	regmap_write(priv->regmap, USB_R5, val, REGMAP_SIZE_32);
>  
>  	return phy_meson_gxl_usb3_set_host_mode(priv);
>  }
> @@ -133,10 +133,10 @@ static int phy_meson_gxl_usb3_power_off(struct phy *phy)
>  	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
>  	uint val;
>  
> -	regmap_read(priv->regmap, USB_R5, &val);
> +	regmap_read(priv->regmap, USB_R5, &val, REGMAP_SIZE_32);
>  	val &= ~USB_R5_ID_DIG_EN_0;
>  	val &= ~USB_R5_ID_DIG_EN_1;
> -	regmap_write(priv->regmap, USB_R5, val);
> +	regmap_write(priv->regmap, USB_R5, val, REGMAP_SIZE_32);
>  
>  	return 0;
>  }
> @@ -147,10 +147,10 @@ static int phy_meson_gxl_usb3_init(struct phy *phy)
>  	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
>  	uint val;
>  
> -	regmap_read(priv->regmap, USB_R1, &val);
> +	regmap_read(priv->regmap, USB_R1, &val, REGMAP_SIZE_32);
>  	val &= ~USB_R1_U3H_FLADJ_30MHZ_REG_MASK;
>  	val |= FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20);
> -	regmap_write(priv->regmap, USB_R1, val);
> +	regmap_write(priv->regmap, USB_R1, val, REGMAP_SIZE_32);
>  
>  	return 0;
>  }
> @@ -169,7 +169,7 @@ int meson_gxl_usb3_phy_probe(struct udevice *dev)
>  	ret = regmap_init_mem(dev, &priv->regmap);
>  	if (ret)
>  		return ret;
> -	
> +
>  #if CONFIG_IS_ENABLED(CLK)
>  	ret = clk_get_by_index(dev, 0, &priv->clk);
>  	if (ret < 0)
> diff --git a/drivers/power/regulator/pbias_regulator.c b/drivers/power/regulator/pbias_regulator.c
> index adf589b224..386da3a58f 100644
> --- a/drivers/power/regulator/pbias_regulator.c
> +++ b/drivers/power/regulator/pbias_regulator.c
> @@ -46,7 +46,7 @@ static int pbias_write(struct udevice *dev, uint reg, const uint8_t *buff,
>  	if (len != 4)
>  		return -EINVAL;
>  
> -	return regmap_write(priv->regmap, priv->offset, val);
> +	return regmap_write(priv->regmap, priv->offset, val, REGMAP_SIZE_32);
>  }
>  
>  static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
> @@ -56,7 +56,8 @@ static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
>  	if (len != 4)
>  		return -EINVAL;
>  
> -	return regmap_read(priv->regmap, priv->offset, (u32 *)buff);
> +	return regmap_read(priv->regmap, priv->offset, (u32 *)buff,
> +			   REGMAP_SIZE_32);
>  }
>  
>  static int pbias_ofdata_to_platdata(struct udevice *dev)
> diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c
> index 5324f86f5f..c31f302143 100644
> --- a/drivers/reset/reset-meson.c
> +++ b/drivers/reset/reset-meson.c
> @@ -41,12 +41,12 @@ static int meson_reset_level(struct reset_ctl *reset_ctl, bool assert)
>  	uint reg_offset = LEVEL_OFFSET + (bank << 2);
>  	uint val;
>  
> -	regmap_read(priv->regmap, reg_offset, &val);
> +	regmap_read(priv->regmap, reg_offset, &val, REGMAP_SIZE_32);
>  	if (assert)
>  		val &= ~BIT(offset);
>  	else
>  		val |= BIT(offset);
> -	regmap_write(priv->regmap, reg_offset, val);
> +	regmap_write(priv->regmap, reg_offset, val, REGMAP_SIZE_32);
>  
>  	return 0;
>  }
> @@ -68,15 +68,15 @@ struct reset_ops meson_reset_ops = {
>  	.rst_deassert = meson_reset_deassert,
>  };
>  
> -static const struct udevice_id meson_reset_ids[] = {                          
> -	{ .compatible = "amlogic,meson-gxbb-reset" },                                  
> -	{ }                                                                     
> -};  
> +static const struct udevice_id meson_reset_ids[] = {
> +	{ .compatible = "amlogic,meson-gxbb-reset" },
> +	{ }
> +};
>  
>  static int meson_reset_probe(struct udevice *dev)
>  {
>  	struct meson_reset_priv *priv = dev_get_priv(dev);
> -	
> +
>  	return regmap_init_mem(dev, &priv->regmap);
>  }
>  
> diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c
> index 22c602a4d2..0c374a7443 100644
> --- a/drivers/sysreset/sysreset_syscon.c
> +++ b/drivers/sysreset/sysreset_syscon.c
> @@ -25,7 +25,7 @@ static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type)
>  {
>  	struct syscon_reboot_priv *priv = dev_get_priv(dev);
>  
> -	regmap_write(priv->regmap, priv->offset, priv->mask);
> +	regmap_write(priv->regmap, priv->offset, priv->mask, REGMAP_SIZE_32);
>  
>  	return -EINPROGRESS;
>  }
> diff --git a/include/regmap.h b/include/regmap.h
> index 493a5d8eff..a6e2fafd27 100644
> --- a/include/regmap.h
> +++ b/include/regmap.h
> @@ -8,6 +8,13 @@
>  #ifndef __REGMAP_H
>  #define __REGMAP_H
>  
> +/* Access sizes for fpgamap reads and writes */
> +enum regmap_size_t {
> +	REGMAP_SIZE_8 = 1,
> +	REGMAP_SIZE_16 = 2,
> +	REGMAP_SIZE_32 = 4,
> +};
> +
>  /**
>   * struct regmap_range - a register map range
>   *
> @@ -37,8 +44,8 @@ struct regmap {
>   * Interface to provide access to registers either through a direct memory
>   * bus or through a peripheral bus like I2C, SPI.
>   */
> -int regmap_write(struct regmap *map, uint offset, uint val);
> -int regmap_read(struct regmap *map, uint offset, uint *valp);
> +int regmap_write(struct regmap *map, ulong offset, ulong val, enum regmap_size_t size);
> +int regmap_read(struct regmap *map, ulong offset, ulong *valp, enum regmap_size_t size);
>  
>  #define regmap_write32(map, ptr, member, val) \
>  	regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range Mario Six
@ 2018-05-03  2:33   ` Simon Glass
  2018-05-04  7:19     ` Mario Six
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Glass @ 2018-05-03  2:33 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>
> It is useful to be able to treat the different ranges of a regmap
> separately to be able to use distinct offset for them, but this is
> currently not implemented in the regmap API.
>
> To preserve backwards compatibility, add regmap_read_ext and
> regmap_write_ext functions that take an additional parameter 'range_num'
> that identifies the range to operate on.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
>  drivers/core/regmap.c | 69 +++++++++++++++++++++++++++++++++++++++------------
>  include/regmap.h      |  2 ++
>  2 files changed, 55 insertions(+), 16 deletions(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>


> diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
> index c2cdff3979..80718b3820 100644
> --- a/drivers/core/regmap.c
> +++ b/drivers/core/regmap.c
> @@ -130,47 +130,84 @@ int regmap_uninit(struct regmap *map)
>         return 0;
>  }
>
> -int regmap_read(struct regmap *map, ulong offset, ulong *valp,
> -               enum regmap_size_t size)
> +int regmap_read_ext(struct regmap *map, uint range_num, ulong offset,
> +                   ulong *valp, enum regmap_size_t size)

How about regmap_read_range() ?

>  {
> +       struct regmap_range *range;
>         void *ptr;
>
> +       if (range_num >= map->range_count)
> +               return 0;
> +       range = &map->range[range_num];
> +
> +       ptr = map_physmem(range->start + offset, size, MAP_NOCACHE);
> +
> +       if (offset + size > range->size) {
> +               debug("%s: offset/size combination invalid\n", __func__);
> +               return -EINVAL;
> +       }
> +
>         switch (size) {
>         case REGMAP_SIZE_8:
> -               ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
> -               *valp = readb(ptr);
> +               *((u8 *)valp) = readb((u8 *)ptr);
>                 break;
>         case REGMAP_SIZE_16:
> -               ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
> -               *valp = le16_to_cpu(readw(ptr));
> +               *((u16 *)valp) = readw((u16 *)ptr);
>                 break;
>         case REGMAP_SIZE_32:
> -               ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
> -               *valp = le32_to_cpu(readl(ptr));
> +               *((u32 *)valp) = readl((u32 *)ptr);
>                 break;
> +       default:
> +               debug("%s: size %d not supported\n", __func__, size);
> +               return -ENOTSUPP;
>         }
> +
>         return 0;
>  }
>
> -int regmap_write(struct regmap *map, ulong offset, ulong val,
> -                enum regmap_size_t size)
> +int regmap_read(struct regmap *map, ulong offset, ulong *valp,
> +               enum regmap_size_t size)
>  {
> +       return regmap_read_ext(map, 0, offset, valp, size);
> +}
> +
> +int regmap_write_ext(struct regmap *map, uint range_num, ulong offset,
> +                    ulong val, enum regmap_size_t size)
> +{
> +       struct regmap_range *range;
>         void *ptr;
>
> +       if (range_num >= map->range_count)
> +               return 0;
> +       range = &map->range[range_num];
> +
> +       ptr = map_physmem(range->start + offset, size, MAP_NOCACHE);
> +
> +       if (offset + size > range->size) {
> +               debug("%s: offset/size combination invalid\n", __func__);
> +               return -EINVAL;
> +       }
> +
>         switch (size) {
>         case REGMAP_SIZE_8:
> -               ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
> -               writel((u8)val, ptr);
> +               writeb((u8)val, (u8 *)ptr);
>                 break;
>         case REGMAP_SIZE_16:
> -               ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
> -               writel(cpu_to_le16((u16)val), ptr);
> +               out_le16((u16 *)ptr, (u16)val);
>                 break;
>         case REGMAP_SIZE_32:
> -               ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
> -               writel(cpu_to_le32((u32)val), ptr);
> +               writel((u32)val, (u32 *)ptr);
>                 break;
> +       default:
> +               debug("%s: size %d not supported\n", __func__, size);
> +               return -ENOTSUPP;
>         }
>
>         return 0;
>  }
> +
> +int regmap_write(struct regmap *map, ulong offset, ulong val,
> +                enum regmap_size_t size)
> +{
> +       return regmap_write_ext(map, 0, offset, val, size);
> +}
> diff --git a/include/regmap.h b/include/regmap.h
> index a6e2fafd27..bb7e947ce2 100644
> --- a/include/regmap.h
> +++ b/include/regmap.h
> @@ -44,7 +44,9 @@ struct regmap {
>   * Interface to provide access to registers either through a direct memory
>   * bus or through a peripheral bus like I2C, SPI.
>   */
> +int regmap_write_ext(struct regmap *map, uint range_num, ulong offset, ulong val, enum regmap_size_t size);
>  int regmap_write(struct regmap *map, ulong offset, ulong val, enum regmap_size_t size);
> +int regmap_read_ext(struct regmap *map, uint range_num, ulong offset, ulong *valp, enum regmap_size_t size);
>  int regmap_read(struct regmap *map, ulong offset, ulong *valp, enum regmap_size_t size);

Can you please add full function comments?

>
>  #define regmap_write32(map, ptr, member, val) \
> --
> 2.16.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 3/5] regmap: Define regmap_{get,set}
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 3/5] regmap: Define regmap_{get,set} Mario Six
@ 2018-05-03  2:33   ` Simon Glass
  2018-05-04  8:05     ` Mario Six
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Glass @ 2018-05-03  2:33 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> It would be convenient if one could use the regmap API in conjunction
> with register maps defined as structs (i.e. structs that directly mirror
> the memory layout of the registers in question). A similar approach was
> planned with the regmap_write32/regmap_read32 macros, but was never
> used.
>
> Hence, implement regmap_set/regmap_range_set and
> regmap_get/regmap_range_get macros, which, given a register map, a
> struct describing the layout of the register map, and a member name
> automatically produce regmap_read/regmap_write calls that access the
> specified member in the register map.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
>  include/regmap.h | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Please can you add function comments and also a test that calls these?
I think Masahiro made a start.

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range
  2018-05-03  2:33   ` Simon Glass
@ 2018-05-04  7:19     ` Mario Six
  0 siblings, 0 replies; 11+ messages in thread
From: Mario Six @ 2018-05-04  7:19 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Thu, May 3, 2018 at 4:33 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>>
>> It is useful to be able to treat the different ranges of a regmap
>> separately to be able to use distinct offset for them, but this is
>> currently not implemented in the regmap API.
>>
>> To preserve backwards compatibility, add regmap_read_ext and
>> regmap_write_ext functions that take an additional parameter 'range_num'
>> that identifies the range to operate on.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>> v1 -> v2:
>> New in v2
>>
>> ---
>>  drivers/core/regmap.c | 69 +++++++++++++++++++++++++++++++++++++++------------
>>  include/regmap.h      |  2 ++
>>  2 files changed, 55 insertions(+), 16 deletions(-)
>>
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
>
>> diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
>> index c2cdff3979..80718b3820 100644
>> --- a/drivers/core/regmap.c
>> +++ b/drivers/core/regmap.c
>> @@ -130,47 +130,84 @@ int regmap_uninit(struct regmap *map)
>>         return 0;
>>  }
>>
>> -int regmap_read(struct regmap *map, ulong offset, ulong *valp,
>> -               enum regmap_size_t size)
>> +int regmap_read_ext(struct regmap *map, uint range_num, ulong offset,
>> +                   ulong *valp, enum regmap_size_t size)
>
> How about regmap_read_range() ?
>

Yes, sounds more descriptive. Will change for v3.

>>  {
>> +       struct regmap_range *range;
>>         void *ptr;
>>
>> +       if (range_num >= map->range_count)
>> +               return 0;
>> +       range = &map->range[range_num];
>> +
>> +       ptr = map_physmem(range->start + offset, size, MAP_NOCACHE);
>> +
>> +       if (offset + size > range->size) {
>> +               debug("%s: offset/size combination invalid\n", __func__);
>> +               return -EINVAL;
>> +       }
>> +
>>         switch (size) {
>>         case REGMAP_SIZE_8:
>> -               ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
>> -               *valp = readb(ptr);
>> +               *((u8 *)valp) = readb((u8 *)ptr);
>>                 break;
>>         case REGMAP_SIZE_16:
>> -               ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
>> -               *valp = le16_to_cpu(readw(ptr));
>> +               *((u16 *)valp) = readw((u16 *)ptr);
>>                 break;
>>         case REGMAP_SIZE_32:
>> -               ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
>> -               *valp = le32_to_cpu(readl(ptr));
>> +               *((u32 *)valp) = readl((u32 *)ptr);
>>                 break;
>> +       default:
>> +               debug("%s: size %d not supported\n", __func__, size);
>> +               return -ENOTSUPP;
>>         }
>> +
>>         return 0;
>>  }
>>
>> -int regmap_write(struct regmap *map, ulong offset, ulong val,
>> -                enum regmap_size_t size)
>> +int regmap_read(struct regmap *map, ulong offset, ulong *valp,
>> +               enum regmap_size_t size)
>>  {
>> +       return regmap_read_ext(map, 0, offset, valp, size);
>> +}
>> +
>> +int regmap_write_ext(struct regmap *map, uint range_num, ulong offset,
>> +                    ulong val, enum regmap_size_t size)
>> +{
>> +       struct regmap_range *range;
>>         void *ptr;
>>
>> +       if (range_num >= map->range_count)
>> +               return 0;
>> +       range = &map->range[range_num];
>> +
>> +       ptr = map_physmem(range->start + offset, size, MAP_NOCACHE);
>> +
>> +       if (offset + size > range->size) {
>> +               debug("%s: offset/size combination invalid\n", __func__);
>> +               return -EINVAL;
>> +       }
>> +
>>         switch (size) {
>>         case REGMAP_SIZE_8:
>> -               ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
>> -               writel((u8)val, ptr);
>> +               writeb((u8)val, (u8 *)ptr);
>>                 break;
>>         case REGMAP_SIZE_16:
>> -               ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
>> -               writel(cpu_to_le16((u16)val), ptr);
>> +               out_le16((u16 *)ptr, (u16)val);
>>                 break;
>>         case REGMAP_SIZE_32:
>> -               ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
>> -               writel(cpu_to_le32((u32)val), ptr);
>> +               writel((u32)val, (u32 *)ptr);
>>                 break;
>> +       default:
>> +               debug("%s: size %d not supported\n", __func__, size);
>> +               return -ENOTSUPP;
>>         }
>>
>>         return 0;
>>  }
>> +
>> +int regmap_write(struct regmap *map, ulong offset, ulong val,
>> +                enum regmap_size_t size)
>> +{
>> +       return regmap_write_ext(map, 0, offset, val, size);
>> +}
>> diff --git a/include/regmap.h b/include/regmap.h
>> index a6e2fafd27..bb7e947ce2 100644
>> --- a/include/regmap.h
>> +++ b/include/regmap.h
>> @@ -44,7 +44,9 @@ struct regmap {
>>   * Interface to provide access to registers either through a direct memory
>>   * bus or through a peripheral bus like I2C, SPI.
>>   */
>> +int regmap_write_ext(struct regmap *map, uint range_num, ulong offset, ulong val, enum regmap_size_t size);
>>  int regmap_write(struct regmap *map, ulong offset, ulong val, enum regmap_size_t size);
>> +int regmap_read_ext(struct regmap *map, uint range_num, ulong offset, ulong *valp, enum regmap_size_t size);
>>  int regmap_read(struct regmap *map, ulong offset, ulong *valp, enum regmap_size_t size);
>
> Can you please add full function comments?
>

OK, will be documented in v3.

>>
>>  #define regmap_write32(map, ptr, member, val) \
>> --
>> 2.16.1
>>
>
> Regards,
> Simon

Best regards,
Mario

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 3/5] regmap: Define regmap_{get,set}
  2018-05-03  2:33   ` Simon Glass
@ 2018-05-04  8:05     ` Mario Six
  0 siblings, 0 replies; 11+ messages in thread
From: Mario Six @ 2018-05-04  8:05 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Thu, May 3, 2018 at 4:33 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>> It would be convenient if one could use the regmap API in conjunction
>> with register maps defined as structs (i.e. structs that directly mirror
>> the memory layout of the registers in question). A similar approach was
>> planned with the regmap_write32/regmap_read32 macros, but was never
>> used.
>>
>> Hence, implement regmap_set/regmap_range_set and
>> regmap_get/regmap_range_get macros, which, given a register map, a
>> struct describing the layout of the register map, and a member name
>> automatically produce regmap_read/regmap_write calls that access the
>> specified member in the register map.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>> v1 -> v2:
>> New in v2
>>
>> ---
>>  include/regmap.h | 14 ++++++++++----
>>  1 file changed, 10 insertions(+), 4 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Please can you add function comments and also a test that calls these?
> I think Masahiro made a start.
>

OK, I'll add some tests for v3.

> Regards,
> Simon
>

Best regards,
Mario

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2 1/5] regmap: Add size parameter
  2018-04-27 13:00 ` [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Neil Armstrong
@ 2018-05-04  8:18   ` Mario Six
  0 siblings, 0 replies; 11+ messages in thread
From: Mario Six @ 2018-05-04  8:18 UTC (permalink / raw)
  To: u-boot

Hi Neil,

On Fri, Apr 27, 2018 at 3:00 PM, Neil Armstrong <narmstrong@baylibre.com> wrote:
> Hi Mario,
>
> On 27/04/2018 14:51, Mario Six wrote:
>> The regmap functions currently assume that all register map accesses
>> have a data width of 32 bits, but there are maps that have different
>> widths.
>>
>> Implement a size parameter for the regmap_read and regmap_write
>> functions to specify the width of a desired read or write operation on a
>> regmap.
>
> This changes the regmap API which is based on the Linux API.
>
> Linux passes a struct defining the regmap access type instead, I think the same should
> happen here.
>

OK, I see what you mean.

I see that the Linux API also has regmap_raw_read/regmap_raw_write functions,
which do have size parameters, so I think those would suite this use case
rather nicely (and won't break the existing API).

> Neil
>

Best regards,
Mario

>>
>> Correct all current clients of the regmap API to use 32 bit width reads
>> and writes to keep backwards compatibility.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>> v1 -> v2:
>> New in v2
>>
>> ---
>>  drivers/clk/at91/clk-utmi.c               |  6 +++--
>>  drivers/clk/clk_boston.c                  |  3 ++-
>>  drivers/core/regmap.c                     | 45 ++++++++++++++++++++++++-------
>>  drivers/phy/meson-gxl-usb2.c              | 18 ++++++-------
>>  drivers/phy/meson-gxl-usb3.c              | 22 +++++++--------
>>  drivers/power/regulator/pbias_regulator.c |  5 ++--
>>  drivers/reset/reset-meson.c               | 14 +++++-----
>>  drivers/sysreset/sysreset_syscon.c        |  2 +-
>>  include/regmap.h                          | 11 ++++++--
>>  9 files changed, 82 insertions(+), 44 deletions(-)
>>
>> diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
>> index 875bf293f9..1da625cab1 100644
>> --- a/drivers/clk/at91/clk-utmi.c
>> +++ b/drivers/clk/at91/clk-utmi.c
>> @@ -68,13 +68,15 @@ static int utmi_clk_enable(struct clk *clk)
>>       }
>>
>>       if (plat->regmap_sfr) {
>> -             err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp);
>> +             err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp,
>> +                               REGMAP_SIZE_32);
>>               if (err)
>>                       return -EINVAL;
>>
>>               tmp &= ~AT91_UTMICKTRIM_FREQ;
>>               tmp |= utmi_ref_clk_freq;
>> -             err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp);
>> +             err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp,
>> +                                REGMAP_SIZE_32);
>>               if (err)
>>                       return -EINVAL;
>>       } else if (utmi_ref_clk_freq) {
>> diff --git a/drivers/clk/clk_boston.c b/drivers/clk/clk_boston.c
>> index 5c05e3d78d..e09fd06fa0 100644
>> --- a/drivers/clk/clk_boston.c
>> +++ b/drivers/clk/clk_boston.c
>> @@ -33,7 +33,8 @@ static ulong clk_boston_get_rate(struct clk *clk)
>>       uint mmcmdiv;
>>       int err;
>>
>> -     err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv);
>> +     err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv,
>> +                       REGMAP_SIZE_32);
>>       if (err)
>>               return 0;
>>
>> diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
>> index 8a0e00ff9a..c2cdff3979 100644
>> --- a/drivers/core/regmap.c
>> +++ b/drivers/core/regmap.c
>> @@ -130,20 +130,47 @@ int regmap_uninit(struct regmap *map)
>>       return 0;
>>  }
>>
>> -int regmap_read(struct regmap *map, uint offset, uint *valp)
>> +int regmap_read(struct regmap *map, ulong offset, ulong *valp,
>> +             enum regmap_size_t size)
>>  {
>> -     uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
>> -
>> -     *valp = le32_to_cpu(readl(ptr));
>> -
>> +     void *ptr;
>> +
>> +     switch (size) {
>> +     case REGMAP_SIZE_8:
>> +             ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
>> +             *valp = readb(ptr);
>> +             break;
>> +     case REGMAP_SIZE_16:
>> +             ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
>> +             *valp = le16_to_cpu(readw(ptr));
>> +             break;
>> +     case REGMAP_SIZE_32:
>> +             ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
>> +             *valp = le32_to_cpu(readl(ptr));
>> +             break;
>> +     }
>>       return 0;
>>  }
>>
>> -int regmap_write(struct regmap *map, uint offset, uint val)
>> +int regmap_write(struct regmap *map, ulong offset, ulong val,
>> +              enum regmap_size_t size)
>>  {
>> -     uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
>> -
>> -     writel(cpu_to_le32(val), ptr);
>> +     void *ptr;
>> +
>> +     switch (size) {
>> +     case REGMAP_SIZE_8:
>> +             ptr = map_physmem(map->base + offset, 1, MAP_NOCACHE);
>> +             writel((u8)val, ptr);
>> +             break;
>> +     case REGMAP_SIZE_16:
>> +             ptr = map_physmem(map->base + offset, 2, MAP_NOCACHE);
>> +             writel(cpu_to_le16((u16)val), ptr);
>> +             break;
>> +     case REGMAP_SIZE_32:
>> +             ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
>> +             writel(cpu_to_le32((u32)val), ptr);
>> +             break;
>> +     }
>>
>>       return 0;
>>  }
>> diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
>> index 15c9c89fd9..704b78747c 100644
>> --- a/drivers/phy/meson-gxl-usb2.c
>> +++ b/drivers/phy/meson-gxl-usb2.c
>> @@ -111,15 +111,15 @@ static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
>>  {
>>       uint val;
>>
>> -     regmap_read(priv->regmap, U2P_R0, &val);
>> +     regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>>
>>       /* reset the PHY and wait until settings are stabilized */
>>       val |= U2P_R0_POWER_ON_RESET;
>> -     regmap_write(priv->regmap, U2P_R0, val);
>> +     regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>>       udelay(RESET_COMPLETE_TIME);
>>
>>       val &= ~U2P_R0_POWER_ON_RESET;
>> -     regmap_write(priv->regmap, U2P_R0, val);
>> +     regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>>       udelay(RESET_COMPLETE_TIME);
>>  }
>>
>> @@ -128,11 +128,11 @@ phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
>>  {
>>       uint val;
>>
>> -     regmap_read(priv->regmap, U2P_R0, &val);
>> +     regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>>       val |= U2P_R0_DM_PULLDOWN;
>>       val |= U2P_R0_DP_PULLDOWN;
>>       val &= ~U2P_R0_ID_PULLUP;
>> -     regmap_write(priv->regmap, U2P_R0, val);
>> +     regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>>
>>       phy_meson_gxl_usb2_reset(priv);
>>  }
>> @@ -143,10 +143,10 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
>>       struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
>>       uint val;
>>
>> -     regmap_read(priv->regmap, U2P_R0, &val);
>> +     regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>>       /* power on the PHY by taking it out of reset mode */
>>       val &= ~U2P_R0_POWER_ON_RESET;
>> -     regmap_write(priv->regmap, U2P_R0, val);
>> +     regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>>
>>       phy_meson_gxl_usb2_set_host_mode(priv);
>>
>> @@ -167,10 +167,10 @@ static int phy_meson_gxl_usb2_power_off(struct phy *phy)
>>       struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
>>       uint val;
>>
>> -     regmap_read(priv->regmap, U2P_R0, &val);
>> +     regmap_read(priv->regmap, U2P_R0, &val, REGMAP_SIZE_32);
>>       /* power off the PHY by putting it into reset mode */
>>       val |= U2P_R0_POWER_ON_RESET;
>> -     regmap_write(priv->regmap, U2P_R0, val);
>> +     regmap_write(priv->regmap, U2P_R0, val, REGMAP_SIZE_32);
>>
>>  #if CONFIG_IS_ENABLED(DM_REGULATOR)
>>       if (priv->phy_supply) {
>> diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c
>> index a385fbdf12..33c24fd989 100644
>> --- a/drivers/phy/meson-gxl-usb3.c
>> +++ b/drivers/phy/meson-gxl-usb3.c
>> @@ -100,13 +100,13 @@ phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
>>  {
>>       uint val;
>>
>> -     regmap_read(priv->regmap, USB_R0, &val);
>> +     regmap_read(priv->regmap, USB_R0, &val, REGMAP_SIZE_32);
>>       val &= ~USB_R0_U2D_ACT;
>> -     regmap_write(priv->regmap, USB_R0, val);
>> +     regmap_write(priv->regmap, USB_R0, val, REGMAP_SIZE_32);
>>
>> -     regmap_read(priv->regmap, USB_R4, &val);
>> +     regmap_read(priv->regmap, USB_R4, &val, REGMAP_SIZE_32);
>>       val &= ~USB_R4_P21_SLEEP_M0;
>> -     regmap_write(priv->regmap, USB_R4, val);
>> +     regmap_write(priv->regmap, USB_R4, val, REGMAP_SIZE_32);
>>
>>       return 0;
>>  }
>> @@ -117,12 +117,12 @@ static int phy_meson_gxl_usb3_power_on(struct phy *phy)
>>       struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
>>       uint val;
>>
>> -     regmap_read(priv->regmap, USB_R5, &val);
>> +     regmap_read(priv->regmap, USB_R5, &val, REGMAP_SIZE_32);
>>       val |= USB_R5_ID_DIG_EN_0;
>>       val |= USB_R5_ID_DIG_EN_1;
>>       val &= ~USB_R5_ID_DIG_TH_MASK;
>>       val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
>> -     regmap_write(priv->regmap, USB_R5, val);
>> +     regmap_write(priv->regmap, USB_R5, val, REGMAP_SIZE_32);
>>
>>       return phy_meson_gxl_usb3_set_host_mode(priv);
>>  }
>> @@ -133,10 +133,10 @@ static int phy_meson_gxl_usb3_power_off(struct phy *phy)
>>       struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
>>       uint val;
>>
>> -     regmap_read(priv->regmap, USB_R5, &val);
>> +     regmap_read(priv->regmap, USB_R5, &val, REGMAP_SIZE_32);
>>       val &= ~USB_R5_ID_DIG_EN_0;
>>       val &= ~USB_R5_ID_DIG_EN_1;
>> -     regmap_write(priv->regmap, USB_R5, val);
>> +     regmap_write(priv->regmap, USB_R5, val, REGMAP_SIZE_32);
>>
>>       return 0;
>>  }
>> @@ -147,10 +147,10 @@ static int phy_meson_gxl_usb3_init(struct phy *phy)
>>       struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
>>       uint val;
>>
>> -     regmap_read(priv->regmap, USB_R1, &val);
>> +     regmap_read(priv->regmap, USB_R1, &val, REGMAP_SIZE_32);
>>       val &= ~USB_R1_U3H_FLADJ_30MHZ_REG_MASK;
>>       val |= FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20);
>> -     regmap_write(priv->regmap, USB_R1, val);
>> +     regmap_write(priv->regmap, USB_R1, val, REGMAP_SIZE_32);
>>
>>       return 0;
>>  }
>> @@ -169,7 +169,7 @@ int meson_gxl_usb3_phy_probe(struct udevice *dev)
>>       ret = regmap_init_mem(dev, &priv->regmap);
>>       if (ret)
>>               return ret;
>> -
>> +
>>  #if CONFIG_IS_ENABLED(CLK)
>>       ret = clk_get_by_index(dev, 0, &priv->clk);
>>       if (ret < 0)
>> diff --git a/drivers/power/regulator/pbias_regulator.c b/drivers/power/regulator/pbias_regulator.c
>> index adf589b224..386da3a58f 100644
>> --- a/drivers/power/regulator/pbias_regulator.c
>> +++ b/drivers/power/regulator/pbias_regulator.c
>> @@ -46,7 +46,7 @@ static int pbias_write(struct udevice *dev, uint reg, const uint8_t *buff,
>>       if (len != 4)
>>               return -EINVAL;
>>
>> -     return regmap_write(priv->regmap, priv->offset, val);
>> +     return regmap_write(priv->regmap, priv->offset, val, REGMAP_SIZE_32);
>>  }
>>
>>  static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
>> @@ -56,7 +56,8 @@ static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
>>       if (len != 4)
>>               return -EINVAL;
>>
>> -     return regmap_read(priv->regmap, priv->offset, (u32 *)buff);
>> +     return regmap_read(priv->regmap, priv->offset, (u32 *)buff,
>> +                        REGMAP_SIZE_32);
>>  }
>>
>>  static int pbias_ofdata_to_platdata(struct udevice *dev)
>> diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c
>> index 5324f86f5f..c31f302143 100644
>> --- a/drivers/reset/reset-meson.c
>> +++ b/drivers/reset/reset-meson.c
>> @@ -41,12 +41,12 @@ static int meson_reset_level(struct reset_ctl *reset_ctl, bool assert)
>>       uint reg_offset = LEVEL_OFFSET + (bank << 2);
>>       uint val;
>>
>> -     regmap_read(priv->regmap, reg_offset, &val);
>> +     regmap_read(priv->regmap, reg_offset, &val, REGMAP_SIZE_32);
>>       if (assert)
>>               val &= ~BIT(offset);
>>       else
>>               val |= BIT(offset);
>> -     regmap_write(priv->regmap, reg_offset, val);
>> +     regmap_write(priv->regmap, reg_offset, val, REGMAP_SIZE_32);
>>
>>       return 0;
>>  }
>> @@ -68,15 +68,15 @@ struct reset_ops meson_reset_ops = {
>>       .rst_deassert = meson_reset_deassert,
>>  };
>>
>> -static const struct udevice_id meson_reset_ids[] = {
>> -     { .compatible = "amlogic,meson-gxbb-reset" },
>> -     { }
>> -};
>> +static const struct udevice_id meson_reset_ids[] = {
>> +     { .compatible = "amlogic,meson-gxbb-reset" },
>> +     { }
>> +};
>>
>>  static int meson_reset_probe(struct udevice *dev)
>>  {
>>       struct meson_reset_priv *priv = dev_get_priv(dev);
>> -
>> +
>>       return regmap_init_mem(dev, &priv->regmap);
>>  }
>>
>> diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c
>> index 22c602a4d2..0c374a7443 100644
>> --- a/drivers/sysreset/sysreset_syscon.c
>> +++ b/drivers/sysreset/sysreset_syscon.c
>> @@ -25,7 +25,7 @@ static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type)
>>  {
>>       struct syscon_reboot_priv *priv = dev_get_priv(dev);
>>
>> -     regmap_write(priv->regmap, priv->offset, priv->mask);
>> +     regmap_write(priv->regmap, priv->offset, priv->mask, REGMAP_SIZE_32);
>>
>>       return -EINPROGRESS;
>>  }
>> diff --git a/include/regmap.h b/include/regmap.h
>> index 493a5d8eff..a6e2fafd27 100644
>> --- a/include/regmap.h
>> +++ b/include/regmap.h
>> @@ -8,6 +8,13 @@
>>  #ifndef __REGMAP_H
>>  #define __REGMAP_H
>>
>> +/* Access sizes for fpgamap reads and writes */
>> +enum regmap_size_t {
>> +     REGMAP_SIZE_8 = 1,
>> +     REGMAP_SIZE_16 = 2,
>> +     REGMAP_SIZE_32 = 4,
>> +};
>> +
>>  /**
>>   * struct regmap_range - a register map range
>>   *
>> @@ -37,8 +44,8 @@ struct regmap {
>>   * Interface to provide access to registers either through a direct memory
>>   * bus or through a peripheral bus like I2C, SPI.
>>   */
>> -int regmap_write(struct regmap *map, uint offset, uint val);
>> -int regmap_read(struct regmap *map, uint offset, uint *valp);
>> +int regmap_write(struct regmap *map, ulong offset, ulong val, enum regmap_size_t size);
>> +int regmap_read(struct regmap *map, ulong offset, ulong *valp, enum regmap_size_t size);
>>
>>  #define regmap_write32(map, ptr, member, val) \
>>       regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)
>>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-05-04  8:18 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-27 12:51 [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 2/5] regmap: Support reading from specific range Mario Six
2018-05-03  2:33   ` Simon Glass
2018-05-04  7:19     ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 3/5] regmap: Define regmap_{get,set} Mario Six
2018-05-03  2:33   ` Simon Glass
2018-05-04  8:05     ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 4/5] misc: Add gdsys_soc driver Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 5/5] misc: Add IHS FPGA driver Mario Six
2018-04-27 13:00 ` [U-Boot] [PATCH v2 1/5] regmap: Add size parameter Neil Armstrong
2018-05-04  8:18   ` Mario Six

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.