aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk/clk-axi-clkgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/clk-axi-clkgen.c')
-rw-r--r--drivers/clk/clk-axi-clkgen.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
index 5e918e7afaba..95a6e9834392 100644
--- a/drivers/clk/clk-axi-clkgen.c
+++ b/drivers/clk/clk-axi-clkgen.c
@@ -40,6 +40,10 @@
#define MMCM_REG_FILTER1 0x4e
#define MMCM_REG_FILTER2 0x4f
+#define MMCM_CLKOUT_NOCOUNT BIT(6)
+
+#define MMCM_CLK_DIV_NOCOUNT BIT(12)
+
struct axi_clkgen {
void __iomem *base;
struct clk_hw clk_hw;
@@ -315,12 +319,27 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
unsigned int reg;
unsigned long long tmp;
- axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
- dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_2, &reg);
+ if (reg & MMCM_CLKOUT_NOCOUNT) {
+ dout = 1;
+ } else {
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
+ dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ }
+
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &reg);
- d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
- axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
- m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ if (reg & MMCM_CLK_DIV_NOCOUNT)
+ d = 1;
+ else
+ d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB2, &reg);
+ if (reg & MMCM_CLKOUT_NOCOUNT) {
+ m = 1;
+ } else {
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
+ m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ }
if (d == 0 || dout == 0)
return 0;