summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut+renesas@gmail.com>2021-04-27 22:03:38 +0200
committerMarek Vasut <marek.vasut+renesas@gmail.com>2021-05-21 15:00:17 +0200
commit6fc323c1ae7312db4e04891b83bbe60f3b68c56b (patch)
tree628fafe6bbf508b44f7e6e6533a73ec99130f0bc
parent1fffcaefc142d056c481c61b364821e0713ad206 (diff)
downloadu-boot-6fc323c1ae7312db4e04891b83bbe60f3b68c56b.tar.gz
u-boot-6fc323c1ae7312db4e04891b83bbe60f3b68c56b.tar.xz
u-boot-6fc323c1ae7312db4e04891b83bbe60f3b68c56b.zip
pinctrl: renesas: Implement unlock register masks
The V3U SoC has several unlock registers, one per register group. They reside at offset zero in each 0x200 bytes-sized block. To avoid adding yet another table to the PFC implementation, this patch adds the option to specify an address mask instead of the fixed address in sh_pfc_soc_info::unlock_reg. This is a direct port of Linux 5.12 commit e127ef2ed0a6 ("pinctrl: renesas: Implement unlock register masks") by Ulrich Hecht <uli+renesas@fpond.eu> Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
-rw-r--r--drivers/pinctrl/renesas/pfc.c39
-rw-r--r--drivers/pinctrl/renesas/sh_pfc.h2
2 files changed, 20 insertions, 21 deletions
diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c
index 07fcc3d393..2498eb5716 100644
--- a/drivers/pinctrl/renesas/pfc.c
+++ b/drivers/pinctrl/renesas/pfc.c
@@ -131,14 +131,25 @@ u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg)
return sh_pfc_read_raw_reg((void __iomem *)(uintptr_t)reg, 32);
}
-void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
+static void sh_pfc_unlock_reg(struct sh_pfc *pfc, u32 reg, u32 data)
{
- void __iomem *unlock_reg =
- (void __iomem *)(uintptr_t)pfc->info->unlock_reg;
+ u32 unlock;
+
+ if (!pfc->info->unlock_reg)
+ return;
- if (pfc->info->unlock_reg)
- sh_pfc_write_raw_reg(unlock_reg, 32, ~data);
+ if (pfc->info->unlock_reg >= 0x80000000UL)
+ unlock = pfc->info->unlock_reg;
+ else
+ /* unlock_reg is a mask */
+ unlock = reg & ~pfc->info->unlock_reg;
+
+ sh_pfc_write_raw_reg((void __iomem *)(uintptr_t)unlock, 32, ~data);
+}
+void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
+{
+ sh_pfc_unlock_reg(pfc, reg, data);
sh_pfc_write_raw_reg((void __iomem *)(uintptr_t)reg, 32, data);
}
@@ -168,8 +179,6 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
unsigned int field, u32 value)
{
void __iomem *mapped_reg;
- void __iomem *unlock_reg =
- (void __iomem *)(uintptr_t)pfc->info->unlock_reg;
unsigned int pos;
u32 mask, data;
@@ -186,9 +195,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
data &= mask;
data |= value;
- if (pfc->info->unlock_reg)
- sh_pfc_write_raw_reg(unlock_reg, 32, ~data);
-
+ sh_pfc_unlock_reg(pfc, crp->reg, data);
sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data);
}
@@ -679,8 +686,6 @@ static int sh_pfc_pinconf_set_drive_strength(struct sh_pfc *pfc,
unsigned int size;
unsigned int step;
void __iomem *reg;
- void __iomem *unlock_reg =
- (void __iomem *)(uintptr_t)pfc->info->unlock_reg;
u32 val;
reg = sh_pfc_pinconf_find_drive_strength_reg(pfc, pin, &offset, &size);
@@ -701,9 +706,7 @@ static int sh_pfc_pinconf_set_drive_strength(struct sh_pfc *pfc,
val &= ~GENMASK(offset + 4 - 1, offset);
val |= strength << offset;
- if (unlock_reg)
- sh_pfc_write_raw_reg(unlock_reg, 32, ~val);
-
+ sh_pfc_unlock_reg(pfc, (uintptr_t)reg, val);
sh_pfc_write_raw_reg(reg, 32, val);
return 0;
@@ -743,8 +746,6 @@ static int sh_pfc_pinconf_set(struct sh_pfc_pinctrl *pmx, unsigned _pin,
{
struct sh_pfc *pfc = pmx->pfc;
void __iomem *pocctrl;
- void __iomem *unlock_reg =
- (void __iomem *)(uintptr_t)pfc->info->unlock_reg;
u32 addr, val;
int bit, ret;
@@ -790,9 +791,7 @@ static int sh_pfc_pinconf_set(struct sh_pfc_pinctrl *pmx, unsigned _pin,
else
val &= ~BIT(bit);
- if (unlock_reg)
- sh_pfc_write_raw_reg(unlock_reg, 32, ~val);
-
+ sh_pfc_unlock_reg(pfc, addr, val);
sh_pfc_write_raw_reg(pocctrl, 32, val);
break;
diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h
index f563916f10..d5a245f4fd 100644
--- a/drivers/pinctrl/renesas/sh_pfc.h
+++ b/drivers/pinctrl/renesas/sh_pfc.h
@@ -284,7 +284,7 @@ struct sh_pfc_soc_info {
const struct pinmux_irq *gpio_irq;
unsigned int gpio_irq_size;
- u32 unlock_reg;
+ u32 unlock_reg; /* can be literal address or mask */
};
u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg);