Skip to content

Commit

Permalink
soc: xilinx: vcu: use bitfields for register definition
Browse files Browse the repository at this point in the history
This makes the register accesses more readable and is closer to what is
usually used in the kernel.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Acked-by: Michal Simek <michal.simek@xilinx.com>
Link: https://lore.kernel.org/r/20210121071659.1226489-13-m.tretter@pengutronix.de
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
  • Loading branch information
tretter authored and bebarino committed Feb 9, 2021
1 parent 5a9b125 commit bc27020
Showing 1 changed file with 34 additions and 81 deletions.
115 changes: 34 additions & 81 deletions drivers/soc/xilinx/xlnx_vcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*
* Contacts Dhaval Shah <dshah@xilinx.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
Expand All @@ -20,41 +21,26 @@

#include <dt-bindings/clock/xlnx-vcu.h>

/* vcu slcr registers, bitmask and shift */
#define VCU_PLL_CTRL 0x24
#define VCU_PLL_CTRL_RESET_MASK 0x01
#define VCU_PLL_CTRL_RESET_SHIFT 0
#define VCU_PLL_CTRL_BYPASS_MASK 0x01
#define VCU_PLL_CTRL_BYPASS_SHIFT 3
#define VCU_PLL_CTRL_FBDIV_MASK 0x7f
#define VCU_PLL_CTRL_FBDIV_SHIFT 8
#define VCU_PLL_CTRL_POR_IN_MASK 0x01
#define VCU_PLL_CTRL_POR_IN_SHIFT 1
#define VCU_PLL_CTRL_PWR_POR_MASK 0x01
#define VCU_PLL_CTRL_PWR_POR_SHIFT 2
#define VCU_PLL_CTRL_CLKOUTDIV_MASK 0x03
#define VCU_PLL_CTRL_CLKOUTDIV_SHIFT 16
#define VCU_PLL_CTRL_DEFAULT 0
#define VCU_PLL_DIV2 2
#define VCU_PLL_CTRL_RESET BIT(0)
#define VCU_PLL_CTRL_POR_IN BIT(1)
#define VCU_PLL_CTRL_PWR_POR BIT(2)
#define VCU_PLL_CTRL_BYPASS BIT(3)
#define VCU_PLL_CTRL_FBDIV GENMASK(14, 8)
#define VCU_PLL_CTRL_CLKOUTDIV GENMASK(18, 16)

#define VCU_PLL_CFG 0x28
#define VCU_PLL_CFG_RES_MASK 0x0f
#define VCU_PLL_CFG_RES_SHIFT 0
#define VCU_PLL_CFG_CP_MASK 0x0f
#define VCU_PLL_CFG_CP_SHIFT 5
#define VCU_PLL_CFG_LFHF_MASK 0x03
#define VCU_PLL_CFG_LFHF_SHIFT 10
#define VCU_PLL_CFG_LOCK_CNT_MASK 0x03ff
#define VCU_PLL_CFG_LOCK_CNT_SHIFT 13
#define VCU_PLL_CFG_LOCK_DLY_MASK 0x7f
#define VCU_PLL_CFG_LOCK_DLY_SHIFT 25
#define VCU_PLL_CFG_RES GENMASK(3, 0)
#define VCU_PLL_CFG_CP GENMASK(8, 5)
#define VCU_PLL_CFG_LFHF GENMASK(12, 10)
#define VCU_PLL_CFG_LOCK_CNT GENMASK(22, 13)
#define VCU_PLL_CFG_LOCK_DLY GENMASK(31, 25)
#define VCU_ENC_CORE_CTRL 0x30
#define VCU_ENC_MCU_CTRL 0x34
#define VCU_DEC_CORE_CTRL 0x38
#define VCU_DEC_MCU_CTRL 0x3c

#define VCU_PLL_STATUS 0x60
#define VCU_PLL_STATUS_LOCK_STATUS_MASK 0x01
#define VCU_PLL_STATUS_LOCK_STATUS BIT(0)

#define MHZ 1000000
#define FVCO_MIN (1500U * MHZ)
Expand Down Expand Up @@ -237,25 +223,6 @@ static inline void xvcu_write(void __iomem *iomem, u32 offset, u32 value)
iowrite32(value, iomem + offset);
}

/**
* xvcu_write_field_reg - Write to the vcu reg field
* @iomem: vcu reg space base address
* @offset: vcu reg offset from base
* @field: vcu reg field to write to
* @mask: vcu reg mask
* @shift: vcu reg number of bits to shift the bitfield
*/
static void xvcu_write_field_reg(void __iomem *iomem, int offset,
u32 field, u32 mask, int shift)
{
u32 val = xvcu_read(iomem, offset);

val &= ~(mask << shift);
val |= (field & mask) << shift;

xvcu_write(iomem, offset, val);
}

#define to_vcu_pll(_hw) container_of(_hw, struct vcu_pll, hw)

struct vcu_pll {
Expand All @@ -274,7 +241,7 @@ static int xvcu_pll_wait_for_lock(struct vcu_pll *pll)
timeout = jiffies + msecs_to_jiffies(2000);
do {
lock_status = xvcu_read(base, VCU_PLL_STATUS);
if (lock_status & VCU_PLL_STATUS_LOCK_STATUS_MASK)
if (lock_status & VCU_PLL_STATUS_LOCK_STATUS)
return 0;
} while (!time_after(jiffies, timeout));

Expand All @@ -294,8 +261,7 @@ static struct clk_hw *xvcu_register_pll_post(struct device *dev,
* timing in the design.
*/
vcu_pll_ctrl = xvcu_read(reg_base, VCU_PLL_CTRL);
div = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT;
div = div & VCU_PLL_CTRL_CLKOUTDIV_MASK;
div = FIELD_GET(VCU_PLL_CTRL_CLKOUTDIV, vcu_pll_ctrl);
if (div != 1)
return ERR_PTR(-EINVAL);

Expand Down Expand Up @@ -328,16 +294,15 @@ static int xvcu_pll_set_div(struct vcu_pll *pll, int div)
return -EINVAL;

vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL);
vcu_pll_ctrl &= ~(VCU_PLL_CTRL_FBDIV_MASK << VCU_PLL_CTRL_FBDIV_SHIFT);
vcu_pll_ctrl |= (cfg->fbdiv & VCU_PLL_CTRL_FBDIV_MASK) <<
VCU_PLL_CTRL_FBDIV_SHIFT;
vcu_pll_ctrl &= ~VCU_PLL_CTRL_FBDIV;
vcu_pll_ctrl |= FIELD_PREP(VCU_PLL_CTRL_FBDIV, cfg->fbdiv);
xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl);

cfg_val = (cfg->res << VCU_PLL_CFG_RES_SHIFT) |
(cfg->cp << VCU_PLL_CFG_CP_SHIFT) |
(cfg->lfhf << VCU_PLL_CFG_LFHF_SHIFT) |
(cfg->lock_cnt << VCU_PLL_CFG_LOCK_CNT_SHIFT) |
(cfg->lock_dly << VCU_PLL_CFG_LOCK_DLY_SHIFT);
cfg_val = FIELD_PREP(VCU_PLL_CFG_RES, cfg->res) |
FIELD_PREP(VCU_PLL_CFG_CP, cfg->cp) |
FIELD_PREP(VCU_PLL_CFG_LFHF, cfg->lfhf) |
FIELD_PREP(VCU_PLL_CFG_LOCK_CNT, cfg->lock_cnt) |
FIELD_PREP(VCU_PLL_CFG_LOCK_DLY, cfg->lock_dly);
xvcu_write(base, VCU_PLL_CFG, cfg_val);

return 0;
Expand Down Expand Up @@ -366,7 +331,7 @@ static unsigned long xvcu_pll_recalc_rate(struct clk_hw *hw,
u32 vcu_pll_ctrl;

vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL);
div = (vcu_pll_ctrl >> VCU_PLL_CTRL_FBDIV_SHIFT) & VCU_PLL_CTRL_FBDIV_MASK;
div = FIELD_GET(VCU_PLL_CTRL_FBDIV, vcu_pll_ctrl);

return div * parent_rate;
}
Expand All @@ -386,23 +351,14 @@ static int xvcu_pll_enable(struct clk_hw *hw)
u32 vcu_pll_ctrl;
int ret;

xvcu_write_field_reg(base, VCU_PLL_CTRL,
1, VCU_PLL_CTRL_BYPASS_MASK,
VCU_PLL_CTRL_BYPASS_SHIFT);

vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL);
vcu_pll_ctrl &= ~(VCU_PLL_CTRL_POR_IN_MASK <<
VCU_PLL_CTRL_POR_IN_SHIFT);
vcu_pll_ctrl |= (VCU_PLL_CTRL_DEFAULT & VCU_PLL_CTRL_POR_IN_MASK) <<
VCU_PLL_CTRL_POR_IN_SHIFT;
vcu_pll_ctrl &= ~(VCU_PLL_CTRL_PWR_POR_MASK <<
VCU_PLL_CTRL_PWR_POR_SHIFT);
vcu_pll_ctrl |= (VCU_PLL_CTRL_DEFAULT & VCU_PLL_CTRL_PWR_POR_MASK) <<
VCU_PLL_CTRL_PWR_POR_SHIFT;
vcu_pll_ctrl |= VCU_PLL_CTRL_BYPASS;
xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl);

vcu_pll_ctrl &= ~(VCU_PLL_CTRL_RESET_MASK << VCU_PLL_CTRL_RESET_SHIFT);
vcu_pll_ctrl |= (0 & VCU_PLL_CTRL_RESET_MASK) << VCU_PLL_CTRL_RESET_SHIFT;
vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL);
vcu_pll_ctrl &= ~VCU_PLL_CTRL_POR_IN;
vcu_pll_ctrl &= ~VCU_PLL_CTRL_PWR_POR;
vcu_pll_ctrl &= ~VCU_PLL_CTRL_RESET;
xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl);

ret = xvcu_pll_wait_for_lock(pll);
Expand All @@ -411,9 +367,9 @@ static int xvcu_pll_enable(struct clk_hw *hw)
goto err;
}

xvcu_write_field_reg(base, VCU_PLL_CTRL,
0, VCU_PLL_CTRL_BYPASS_MASK,
VCU_PLL_CTRL_BYPASS_SHIFT);
vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL);
vcu_pll_ctrl &= ~VCU_PLL_CTRL_BYPASS;
xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl);

err:
return ret;
Expand All @@ -426,12 +382,9 @@ static void xvcu_pll_disable(struct clk_hw *hw)
u32 vcu_pll_ctrl;

vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL);
vcu_pll_ctrl &= ~(VCU_PLL_CTRL_POR_IN_MASK << VCU_PLL_CTRL_POR_IN_SHIFT);
vcu_pll_ctrl |= (1 & VCU_PLL_CTRL_POR_IN_MASK) << VCU_PLL_CTRL_POR_IN_SHIFT;
vcu_pll_ctrl &= ~(VCU_PLL_CTRL_PWR_POR_MASK << VCU_PLL_CTRL_PWR_POR_SHIFT);
vcu_pll_ctrl |= (1 & VCU_PLL_CTRL_PWR_POR_MASK) << VCU_PLL_CTRL_PWR_POR_SHIFT;
vcu_pll_ctrl &= ~(VCU_PLL_CTRL_RESET_MASK << VCU_PLL_CTRL_RESET_SHIFT);
vcu_pll_ctrl |= (1 & VCU_PLL_CTRL_RESET_MASK) << VCU_PLL_CTRL_RESET_SHIFT;
vcu_pll_ctrl |= VCU_PLL_CTRL_POR_IN;
vcu_pll_ctrl |= VCU_PLL_CTRL_PWR_POR;
vcu_pll_ctrl |= VCU_PLL_CTRL_RESET;
xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl);
}

Expand Down

0 comments on commit bc27020

Please sign in to comment.