NONE(CRAM2),
 };
 
+/* number of clock outputs of a PLL */
+static const u8 pll_num_clkouts[] = {
+       1,      /* PLLC */
+       1,      /* PLLM */
+       4,      /* PLLP */
+       1,      /* PLLA */
+       0,      /* PLLU */
+       0,      /* PLLD */
+};
+
 /*
  * Get the oscillator frequency, from the corresponding hardware configuration
  * field.
                (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
 }
 
+int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate)
+{
+       struct clk_pll *pll = get_pll(clkid);
+       int data = 0, div = 0, offset = 0;
+
+       if (!clock_id_is_pll(clkid))
+               return -1;
+
+       if (pllout + 1 > pll_num_clkouts[clkid])
+               return -1;
+
+       div = clk_get_divider(8, pll_rate[clkid], rate);
+
+       if (div < 0)
+               return -1;
+
+       /* out2 and out4 are in the high part of the register */
+       if (pllout == PLL_OUT2 || pllout == PLL_OUT4)
+               offset = 16;
+
+       data = (div << PLL_OUT_RATIO_SHIFT) |
+                       PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN;
+       clrsetbits_le32(&pll->pll_out[pllout >> 1],
+                       PLL_OUT_RATIO_MASK << offset, data << offset);
+
+       return 0;
+}
+
 /**
  * Find the best available 7.1 format divisor given a parent clock rate and
  * required child clock rate. This function assumes that a second-stage
 
 
        reg = PLLM_OUT1_RSTN_RESET_DISABLE | PLLM_OUT1_CLKEN_ENABLE |
              PLLM_OUT1_RATIO_VAL_8;
-       writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out);
+       writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out[0]);
 
        reg = SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 | SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 |
              SCLK_SWAKE_RUN_SRC_PLLM_OUT1 | SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 |
 
 /* PLL registers - there are several PLLs in the clock controller */
 struct clk_pll {
        uint pll_base;          /* the control register */
-       uint pll_out;           /* output control */
-       uint reserved;
+       uint pll_out[2];        /* output control */
        uint pll_misc;          /* other misc things */
 };
 
 #define PLL_DIVM_SHIFT         0
 #define PLL_DIVM_MASK          (0x1f << PLL_DIVM_SHIFT)
 
+/* CLK_RST_CONTROLLER_PLLx_OUTx_0 */
+#define PLL_OUT_RSTN           (1 << 0)
+#define PLL_OUT_CLKEN          (1 << 1)
+#define PLL_OUT_OVRRIDE                (1 << 2)
+
+#define PLL_OUT_RATIO_SHIFT    8
+#define PLL_OUT_RATIO_MASK     (0xffU << PLL_OUT_RATIO_SHIFT)
+
 /* CLK_RST_CONTROLLER_PLLx_MISC_0 */
 #define PLL_CPCON_SHIFT                8
 #define PLL_CPCON_MASK         (15U << PLL_CPCON_SHIFT)
 
 unsigned long clock_start_pll(enum clock_id id, u32 divm, u32 divn,
                u32 divp, u32 cpcon, u32 lfcon);
 
+/**
+ * Set PLL output frequency
+ *
+ * @param clkid        clock id
+ * @param pllout       pll output id
+ * @param rate         desired output rate
+ *
+ * @return 0 if ok, -1 on error (invalid clock id or no suitable divider)
+ */
+int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout,
+               unsigned rate);
+
 /**
  * Read low-level parameters of a PLL.
  *
 
        PERIPH_ID_NONE = -1,
 };
 
+enum pll_out_id {
+       PLL_OUT1,
+       PLL_OUT2,
+       PLL_OUT3,
+       PLL_OUT4
+};
+
 /* Converts a clock number to a clock register: 0=L, 1=H, 2=U */
 #define PERIPH_REG(id) ((id) >> 5)