summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk-versaclock5.c
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut@gmail.com>2017-07-09 15:28:10 +0200
committerStephen Boyd <sboyd@codeaurora.org>2017-07-17 11:50:59 -0700
commit718f4694ea15a1033f48ea2e44f6428df705a1a8 (patch)
treeb89631af30454434e4969106bf48fc7e5623faf9 /drivers/clk/clk-versaclock5.c
parent325b7b90f9a87a4bdee7059d10bd98a11154ceae (diff)
downloadlinux-718f4694ea15a1033f48ea2e44f6428df705a1a8.tar.bz2
clk: vc5: Configure the output buffer input mux on prepare
The output buffer input mux can be configured in either of three states -- disabled, input from FOD, input from previous output. Once the .prepare() callback of the output buffer is called, the output buffer input mux must be set to either input from FOD or input from previous output, it cannot be set to Disabled anymore or the output won't work. Default to the input from FOD if the output buffer input mux was Disabled and the .prepare() was called on it. Note that we do not set the output buffer input mux back to Disabled in the .unprepare() callback as there is no obvious benefit of doing so. We disable the entire output buffer in the .unprepare() callback already. Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: Alexey Firago <alexey_firago@mentor.com> Cc: Michael Turquette <mturquette@baylibre.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: linux-renesas-soc@vger.kernel.org Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> # Salvator-XS with the display LVDS output. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk/clk-versaclock5.c')
-rw-r--r--drivers/clk/clk-versaclock5.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index 185d7a5d36e0..29df1100f96d 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -507,6 +507,25 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
{
struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
struct vc5_driver_data *vc5 = hwdata->vc5;
+ const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
+ VC5_OUT_DIV_CONTROL_SEL_EXT |
+ VC5_OUT_DIV_CONTROL_EN_FOD;
+ unsigned int src;
+ int ret;
+
+ /*
+ * If the input mux is disabled, enable it first and
+ * select source from matching FOD.
+ */
+ regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
+ if ((src & mask) == 0) {
+ src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD;
+ ret = regmap_update_bits(vc5->regmap,
+ VC5_OUT_DIV_CONTROL(hwdata->num),
+ mask | VC5_OUT_DIV_CONTROL_RESET, src);
+ if (ret)
+ return ret;
+ }
/* Enable the clock buffer */
regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),