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>
This commit is contained in:
parent
1fffcaefc1
commit
6fc323c1ae
@ -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);
|
return sh_pfc_read_raw_reg((void __iomem *)(uintptr_t)reg, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sh_pfc_unlock_reg(struct sh_pfc *pfc, u32 reg, u32 data)
|
||||||
|
{
|
||||||
|
u32 unlock;
|
||||||
|
|
||||||
|
if (!pfc->info->unlock_reg)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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)
|
void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
|
||||||
{
|
{
|
||||||
void __iomem *unlock_reg =
|
sh_pfc_unlock_reg(pfc, reg, data);
|
||||||
(void __iomem *)(uintptr_t)pfc->info->unlock_reg;
|
|
||||||
|
|
||||||
if (pfc->info->unlock_reg)
|
|
||||||
sh_pfc_write_raw_reg(unlock_reg, 32, ~data);
|
|
||||||
|
|
||||||
sh_pfc_write_raw_reg((void __iomem *)(uintptr_t)reg, 32, 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)
|
unsigned int field, u32 value)
|
||||||
{
|
{
|
||||||
void __iomem *mapped_reg;
|
void __iomem *mapped_reg;
|
||||||
void __iomem *unlock_reg =
|
|
||||||
(void __iomem *)(uintptr_t)pfc->info->unlock_reg;
|
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
u32 mask, data;
|
u32 mask, data;
|
||||||
|
|
||||||
@ -186,9 +195,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
|
|||||||
data &= mask;
|
data &= mask;
|
||||||
data |= value;
|
data |= value;
|
||||||
|
|
||||||
if (pfc->info->unlock_reg)
|
sh_pfc_unlock_reg(pfc, crp->reg, data);
|
||||||
sh_pfc_write_raw_reg(unlock_reg, 32, ~data);
|
|
||||||
|
|
||||||
sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, 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 size;
|
||||||
unsigned int step;
|
unsigned int step;
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
void __iomem *unlock_reg =
|
|
||||||
(void __iomem *)(uintptr_t)pfc->info->unlock_reg;
|
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
reg = sh_pfc_pinconf_find_drive_strength_reg(pfc, pin, &offset, &size);
|
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 &= ~GENMASK(offset + 4 - 1, offset);
|
||||||
val |= strength << offset;
|
val |= strength << offset;
|
||||||
|
|
||||||
if (unlock_reg)
|
sh_pfc_unlock_reg(pfc, (uintptr_t)reg, val);
|
||||||
sh_pfc_write_raw_reg(unlock_reg, 32, ~val);
|
|
||||||
|
|
||||||
sh_pfc_write_raw_reg(reg, 32, val);
|
sh_pfc_write_raw_reg(reg, 32, val);
|
||||||
|
|
||||||
return 0;
|
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;
|
struct sh_pfc *pfc = pmx->pfc;
|
||||||
void __iomem *pocctrl;
|
void __iomem *pocctrl;
|
||||||
void __iomem *unlock_reg =
|
|
||||||
(void __iomem *)(uintptr_t)pfc->info->unlock_reg;
|
|
||||||
u32 addr, val;
|
u32 addr, val;
|
||||||
int bit, ret;
|
int bit, ret;
|
||||||
|
|
||||||
@ -790,9 +791,7 @@ static int sh_pfc_pinconf_set(struct sh_pfc_pinctrl *pmx, unsigned _pin,
|
|||||||
else
|
else
|
||||||
val &= ~BIT(bit);
|
val &= ~BIT(bit);
|
||||||
|
|
||||||
if (unlock_reg)
|
sh_pfc_unlock_reg(pfc, addr, val);
|
||||||
sh_pfc_write_raw_reg(unlock_reg, 32, ~val);
|
|
||||||
|
|
||||||
sh_pfc_write_raw_reg(pocctrl, 32, val);
|
sh_pfc_write_raw_reg(pocctrl, 32, val);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -284,7 +284,7 @@ struct sh_pfc_soc_info {
|
|||||||
const struct pinmux_irq *gpio_irq;
|
const struct pinmux_irq *gpio_irq;
|
||||||
unsigned int gpio_irq_size;
|
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);
|
u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg);
|
||||||
|
Loading…
Reference in New Issue
Block a user