Commit bc270202 authored by Michael Tretter's avatar Michael Tretter Committed by Stephen Boyd
Browse files

soc: xilinx: vcu: use bitfields for register definition



This makes the register accesses more readable and is closer to what is
usually used in the kernel.

Signed-off-by: default avatarMichael Tretter <m.tretter@pengutronix.de>
Reviewed-by: default avatarStephen Boyd <sboyd@kernel.org>
Acked-by: default avatarMichal Simek <michal.simek@xilinx.com>
Link: https://lore.kernel.org/r/20210121071659.1226489-13-m.tretter@pengutronix.de


Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 5a9b1258
Loading
Loading
Loading
Loading
+34 −81
Original line number Diff line number Diff line
@@ -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>
@@ -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)
@@ -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 {
@@ -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));

@@ -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);

@@ -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;
@@ -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;
}
@@ -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);
@@ -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;
@@ -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);
}