clk: at91: clk-main: update key before writing AT91_CKGR_MOR
authorClaudiu Beznea <claudiu.beznea@microchip.com>
Tue, 25 Aug 2020 06:59:10 +0000 (09:59 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 08:05:39 +0000 (09:05 +0100)
[ Upstream commit 85d071e7f19a6a9abf30476b90b3819642568756 ]

SAMA5D2 datasheet specifies on chapter 33.22.8 (PMC Clock Generator
Main Oscillator Register) that writing any value other than
0x37 on KEY field aborts the write operation. Use the key when
selecting main clock parent.

Fixes: 27cb1c2083373 ("clk: at91: rework main clk implementation")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/1598338751-20607-3-git-send-email-claudiu.beznea@microchip.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/clk/at91/clk-main.c

index 90988e7a5b47fb28e1cd07734135bcff63c0e513..2e7da9b379d48b52597909a7eb49009f75a27a6c 100644 (file)
@@ -517,12 +517,17 @@ static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
                return -EINVAL;
 
        regmap_read(regmap, AT91_CKGR_MOR, &tmp);
-       tmp &= ~MOR_KEY_MASK;
 
        if (index && !(tmp & AT91_PMC_MOSCSEL))
-               regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
+               tmp = AT91_PMC_MOSCSEL;
        else if (!index && (tmp & AT91_PMC_MOSCSEL))
-               regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
+               tmp = 0;
+       else
+               return 0;
+
+       regmap_update_bits(regmap, AT91_CKGR_MOR,
+                          AT91_PMC_MOSCSEL | MOR_KEY_MASK,
+                          tmp | AT91_PMC_KEY);
 
        while (!clk_sam9x5_main_ready(regmap))
                cpu_relax();