diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index ddefe96..8f3b637 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -45,10 +45,12 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
 	u8 n = 1, k = 0, p = 0, m = 0;
+	u8 par_index = 0;
 	u32 reg;
 	unsigned long rate;
 	struct clk_factors *factors = to_clk_factors(hw);
 	const struct clk_factors_config *config = factors->config;
+	const struct clk_factors_prediv *prediv = factors->prediv_config;
 
 	/* Fetch the register value */
 	reg = readl(factors->reg);
@@ -63,24 +65,16 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
 	if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
 		p = FACTOR_GET(config->pshift, config->pwidth, reg);
 
-	if (factors->recalc) {
-		struct factors_request factors_req = {
-			.parent_rate = parent_rate,
-			.n = n,
-			.k = k,
-			.m = m,
-			.p = p,
-		};
-
+	if (prediv) {
 		/* get mux details from mux clk structure */
 		if (factors->mux)
-			factors_req.parent_index =
-				(reg >> factors->mux->shift) &
-				factors->mux->mask;
-
-		factors->recalc(&factors_req);
+			par_index = (reg >> factors->mux->shift) &
+					factors->mux->mask;
 
-		return factors_req.rate;
+		if (prediv[par_index].width != SUNXI_FACTORS_NOT_APPLICABLE) {
+			m = FACTOR_GET(prediv[par_index].shift,
+				prediv[par_index].width, reg);
+		}
 	}
 
 	/* Calculate the rate */
@@ -102,8 +96,12 @@ static int clk_factors_determine_rate(struct clk_hw *hw,
 	for (i = 0; i < num_parents; i++) {
 		struct factors_request factors_req = {
 			.rate = req->rate,
-			.parent_index = i,
 		};
+
+		if (factors->prediv_config)
+			factors_req.prediv_width =
+						factors->prediv_config[i].width;
+
 		parent = clk_hw_get_parent_by_index(hw, i);
 		if (!parent)
 			continue;
@@ -211,6 +209,7 @@ struct clk *sunxi_factors_register(struct device_node *node,
 	/* set up factors properties */
 	factors->reg = reg;
 	factors->config = data->table;
+	factors->prediv_config = data->prediv_table;
 	factors->get_factors = data->getter;
 	factors->recalc = data->recalc;
 	factors->lock = lock;
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index 1e63c5b..b1b7745 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -18,10 +18,16 @@ struct clk_factors_config {
 	u8 n_start;
 };
 
+struct clk_factors_prediv {
+	u8 parent_index;
+	u8 shift;
+	u8 width;
+};
+
 struct factors_request {
 	unsigned long rate;
 	unsigned long parent_rate;
-	u8 parent_index;
+	u8 prediv_width;
 	u8 n;
 	u8 k;
 	u8 m;
@@ -33,6 +39,7 @@ struct factors_data {
 	int mux;
 	int muxmask;
 	const struct clk_factors_config *table;
+	const struct clk_factors_prediv *prediv_table;
 	void (*getter)(struct factors_request *req);
 	void (*recalc)(struct factors_request *req);
 	const char *name;
@@ -42,6 +49,7 @@ struct clk_factors {
 	struct clk_hw hw;
 	void __iomem *reg;
 	const struct clk_factors_config *config;
+	const struct clk_factors_prediv *prediv_config;
 	void (*get_factors)(struct factors_request *req);
 	void (*recalc)(struct factors_request *req);
 	spinlock_t *lock;
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 91de0a0..5a5f26b 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -282,8 +282,6 @@ static void sun5i_a13_get_ahb_factors(struct factors_request *req)
 	req->p = div;
 }
 
-#define SUN6I_AHB1_PARENT_PLL6	3
-
 /**
  * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB
  * AHB rate is calculated as follows
@@ -307,7 +305,7 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
 	div = DIV_ROUND_UP(req->parent_rate, req->rate);
 
 	/* calculate pre-divider if parent is pll6 */
-	if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
+	if (req->prediv_width) {
 		if (div < 4)
 			calcp = 0;
 		else if (div / 2 < 4)
@@ -329,22 +327,6 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
 }
 
 /**
- * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and
- *			 parent index
- */
-static void sun6i_ahb1_recalc(struct factors_request *req)
-{
-	req->rate = req->parent_rate;
-
-	/* apply pre-divider first if parent is pll6 */
-	if (req->parent_index == SUN6I_AHB1_PARENT_PLL6)
-		req->rate /= req->m + 1;
-
-	/* clk divider */
-	req->rate >>= req->p;
-}
-
-/**
  * sun4i_get_apb1_factors() - calculates m, p factors for APB1
  * APB1 rate is calculated as follows
  * rate = (parent_rate >> p) / (m + 1);
@@ -474,12 +456,17 @@ static const struct clk_factors_config sun5i_a13_ahb_config = {
 };
 
 static const struct clk_factors_config sun6i_ahb1_config = {
-	.mshift = 6,
-	.mwidth = 2,
 	.pshift = 4,
 	.pwidth = 2,
 };
 
+static const struct clk_factors_prediv sun6i_ahb1_prediv[] = {
+	{.parent_index = 0, .shift = 0, .width = 0 },	/* LOSC  */
+	{.parent_index = 1, .shift = 0, .width = 0 },	/* OSC24MHz */
+	{.parent_index = 2, .shift = 0, .width = 0 },	/* AXI */
+	{.parent_index = 3, .shift = 6, .width = 2 }	/* PLL6/Pre_div */
+};
+
 static const struct clk_factors_config sun4i_apb1_config = {
 	.mshift = 0,
 	.mwidth = 5,
@@ -551,8 +538,8 @@ static const struct factors_data sun6i_ahb1_data __initconst = {
 	.mux = 12,
 	.muxmask = BIT(1) | BIT(0),
 	.table = &sun6i_ahb1_config,
+	.prediv_table = sun6i_ahb1_prediv,
 	.getter = sun6i_get_ahb1_factors,
-	.recalc = sun6i_ahb1_recalc,
 };
 
 static const struct factors_data sun4i_apb1_data __initconst = {
