sunxi: Add video pll clock functions
authorHans de Goede <hdegoede@redhat.com>
Sat, 8 Nov 2014 13:07:27 +0000 (14:07 +0100)
committerHans de Goede <hdegoede@redhat.com>
Tue, 25 Nov 2014 12:38:46 +0000 (13:38 +0100)
This is a preparation patch for adding support for HDMI out.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
arch/arm/cpu/armv7/sunxi/clock_sun4i.c
arch/arm/cpu/armv7/sunxi/clock_sun6i.c
arch/arm/include/asm/arch-sunxi/clock.h
arch/arm/include/asm/arch-sunxi/clock_sun4i.h
arch/arm/include/asm/arch-sunxi/clock_sun6i.h

index a0e49d179feff469f212f479925bc6ab881b3585..49f4032e9cfda56acab108adf57278c63e5e63a0 100644 (file)
@@ -180,6 +180,21 @@ void clock_set_pll1(unsigned int hz)
 }
 #endif
 
+void clock_set_pll3(unsigned int clk)
+{
+       struct sunxi_ccm_reg * const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+       if (clk == 0) {
+               clrbits_le32(&ccm->pll3_cfg, CCM_PLL3_CTRL_EN);
+               return;
+       }
+
+       /* PLL3 rate = 3000000 * m */
+       writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE |
+              CCM_PLL3_CTRL_M(clk / 3000000), &ccm->pll3_cfg);
+}
+
 unsigned int clock_get_pll5p(void)
 {
        struct sunxi_ccm_reg *const ccm =
@@ -200,3 +215,15 @@ unsigned int clock_get_pll6(void)
        int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1;
        return 24000000 * n * k / 2;
 }
+
+void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz)
+{
+       int pll = clock_get_pll5p();
+       int div = 1;
+
+       while ((pll / div) > hz)
+               div++;
+
+       writel(CCM_DE_CTRL_GATE | CCM_DE_CTRL_RST | CCM_DE_CTRL_PLL5P |
+              CCM_DE_CTRL_M(div), clk_cfg);
+}
index 16ab6f372976923f8903266a566bde7c907e2a1c..8e949c6901d2e1e6299825b1c6b4f9c17e2fc01e 100644 (file)
@@ -127,6 +127,23 @@ void clock_set_pll1(unsigned int clk)
 }
 #endif
 
+void clock_set_pll3(unsigned int clk)
+{
+       struct sunxi_ccm_reg * const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+       const int m = 8; /* 3 MHz steps just like sun4i, sun5i and sun7i */
+
+       if (clk == 0) {
+               clrbits_le32(&ccm->pll3_cfg, CCM_PLL3_CTRL_EN);
+               return;
+       }
+
+       /* PLL3 rate = 24000000 * n / m */
+       writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE |
+              CCM_PLL3_CTRL_N(clk / (24000000 / m)) | CCM_PLL3_CTRL_M(m),
+              &ccm->pll3_cfg);
+}
+
 void clock_set_pll5(unsigned int clk)
 {
        struct sunxi_ccm_reg * const ccm =
@@ -151,3 +168,15 @@ unsigned int clock_get_pll6(void)
        int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1;
        return 24000000 * n * k / 2;
 }
+
+void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz)
+{
+       int pll = clock_get_pll6() * 2;
+       int div = 1;
+
+       while ((pll / div) > hz)
+               div++;
+
+       writel(CCM_DE_CTRL_GATE | CCM_DE_CTRL_PLL6_2X | CCM_DE_CTRL_M(div),
+              clk_cfg);
+}
index b40c16b6e7bc262fee8b2faebf9b1921a9e62ab6..64acff3504154a75253a430819e25fe2c3ba1e13 100644 (file)
 int clock_init(void);
 int clock_twi_onoff(int port, int state);
 void clock_set_pll1(unsigned int hz);
+void clock_set_pll3(unsigned int hz);
 void clock_set_pll5(unsigned int hz);
 unsigned int clock_get_pll5p(void);
 unsigned int clock_get_pll6(void);
+void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz);
 void clock_init_safe(void);
 void clock_init_uart(void);
 #endif
index 6c0430ccde4d7ce88362e6f1d8abc347ba3aa23d..eb889695d9143e5cc9756a2c2a0661068336fc57 100644 (file)
@@ -186,12 +186,20 @@ struct sunxi_ccm_reg {
 
 /* ahb clock gate bit offset (second register) */
 #define AHB_GATE_OFFSET_GMAC           17
+#define AHB_GATE_OFFSET_DE_BE0         12
+#define AHB_GATE_OFFSET_HDMI           11
+#define AHB_GATE_OFFSET_LCD1           5
+#define AHB_GATE_OFFSET_LCD0           4
 
 #define CCM_AHB_GATE_GPS (0x1 << 26)
 #define CCM_AHB_GATE_SDRAM (0x1 << 14)
 #define CCM_AHB_GATE_DLL (0x1 << 15)
 #define CCM_AHB_GATE_ACE (0x1 << 16)
 
+#define CCM_PLL3_CTRL_M(n)             (((n) & 0x7f) << 0)
+#define CCM_PLL3_CTRL_INTEGER_MODE     (0x1 << 15)
+#define CCM_PLL3_CTRL_EN               (0x1 << 31)
+
 #define CCM_PLL5_CTRL_M(n) (((n) & 0x3) << 0)
 #define CCM_PLL5_CTRL_M_MASK CCM_PLL5_CTRL_M(0x3)
 #define CCM_PLL5_CTRL_M_X(n) ((n) - 1)
@@ -253,6 +261,34 @@ struct sunxi_ccm_reg {
 
 #define CCM_MMC_CTRL_ENABLE (0x1 << 31)
 
+#define CCM_DRAM_GATE_OFFSET_DE_BE0    26
+
+#define CCM_LCD_CH0_CTRL_PLL3          (0 << 24)
+#define CCM_LCD_CH0_CTRL_PLL7          (1 << 24)
+#define CCM_LCD_CH0_CTRL_PLL3_2X       (2 << 24)
+#define CCM_LCD_CH0_CTRL_PLL7_2X       (3 << 24)
+#define CCM_LCD_CH0_CTRL_RST           (0x1 << 30)
+#define CCM_LCD_CH0_CTRL_GATE          (0x1 << 31)
+
+#define CCM_LCD_CH1_CTRL_M(n)          ((((n) - 1) & 0xf) << 0)
+/* We leave bit 11 set to 0, so sclk1 == sclk2 */
+#define CCM_LCD_CH1_CTRL_PLL3          (0 << 24)
+#define CCM_LCD_CH1_CTRL_PLL7          (1 << 24)
+#define CCM_LCD_CH1_CTRL_PLL3_2X       (2 << 24)
+#define CCM_LCD_CH1_CTRL_PLL7_2X       (3 << 24)
+/* Enable / disable both ch1 sclk1 and sclk2 at the same time */
+#define CCM_LCD_CH1_CTRL_GATE          (0x1 << 31 | 0x1 << 15)
+
+#define CCM_HDMI_CTRL_M(n)             ((((n) - 1) & 0xf) << 0)
+#define CCM_HDMI_CTRL_PLL_MASK         (3 << 24)
+#define CCM_HDMI_CTRL_PLL3             (0 << 24)
+#define CCM_HDMI_CTRL_PLL7             (1 << 24)
+#define CCM_HDMI_CTRL_PLL3_2X          (2 << 24)
+#define CCM_HDMI_CTRL_PLL7_2X          (3 << 24)
+/* No separate ddc gate on sun4i, sun5i and sun7i */
+#define CCM_HDMI_CTRL_DDC_GATE         0
+#define CCM_HDMI_CTRL_GATE             (0x1 << 31)
+
 #define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0
 #define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1
 #define CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII 0x2
@@ -266,4 +302,13 @@ struct sunxi_ccm_reg {
 #define CCM_USB_CTRL_PHY1_CLK 0
 #define CCM_USB_CTRL_PHY2_CLK 0
 
+/* CCM bits common to all Display Engine (and IEP) clock ctrl regs */
+#define CCM_DE_CTRL_M(n)               ((((n) - 1) & 0xf) << 0)
+#define CCM_DE_CTRL_PLL_MASK           (3 << 24)
+#define CCM_DE_CTRL_PLL3               (0 << 24)
+#define CCM_DE_CTRL_PLL7               (1 << 24)
+#define CCM_DE_CTRL_PLL5P              (2 << 24)
+#define CCM_DE_CTRL_RST                        (1 << 30)
+#define CCM_DE_CTRL_GATE               (1 << 31)
+
 #endif /* _SUNXI_CLOCK_SUN4I_H */
index e16a7647ed9f711800e17ae06b98e54b838da429..50a4b699aa4d54bbf2e338b336ab989dfbbd467e 100644 (file)
@@ -176,13 +176,18 @@ struct sunxi_ccm_reg {
 #define CCM_PLL1_CTRL_MAGIC            (0x1 << 16)
 #define CCM_PLL1_CTRL_EN               (0x1 << 31)
 
+#define CCM_PLL3_CTRL_M(n)             ((((n) - 1) & 0xf) << 0)
+#define CCM_PLL3_CTRL_N(n)             ((((n) - 1) & 0x7f) << 8)
+#define CCM_PLL3_CTRL_INTEGER_MODE     (0x1 << 24)
+#define CCM_PLL3_CTRL_EN               (0x1 << 31)
+
 #define CCM_PLL5_CTRL_M(n)             ((((n) - 1) & 0x3) << 0)
 #define CCM_PLL5_CTRL_K(n)             ((((n) - 1) & 0x3) << 4)
 #define CCM_PLL5_CTRL_N(n)             ((((n) - 1) & 0x1f) << 8)
 #define CCM_PLL5_CTRL_UPD              (0x1 << 20)
 #define CCM_PLL5_CTRL_EN               (0x1 << 31)
 
-#define PLL6_CFG_DEFAULT               0x90041811
+#define PLL6_CFG_DEFAULT               0x90041811 /* 600 MHz */
 
 #define CCM_PLL6_CTRL_N_SHIFT          8
 #define CCM_PLL6_CTRL_N_MASK           (0x1f << CCM_PLL6_CTRL_N_SHIFT)
@@ -193,6 +198,7 @@ struct sunxi_ccm_reg {
 
 #define AXI_GATE_OFFSET_DRAM           0
 
+/* ahb_gate0 offsets */
 #define AHB_GATE_OFFSET_USB_OHCI1      30
 #define AHB_GATE_OFFSET_USB_OHCI0      29
 #define AHB_GATE_OFFSET_USB_EHCI1      27
@@ -204,6 +210,13 @@ struct sunxi_ccm_reg {
 #define AHB_GATE_OFFSET_MMC0           8
 #define AHB_GATE_OFFSET_MMC(n)         (AHB_GATE_OFFSET_MMC0 + (n))
 
+/* ahb_gate1 offsets */
+#define AHB_GATE_OFFSET_DRC0           25
+#define AHB_GATE_OFFSET_DE_BE0         12
+#define AHB_GATE_OFFSET_HDMI           11
+#define AHB_GATE_OFFSET_LCD1           5
+#define AHB_GATE_OFFSET_LCD0           4
+
 #define CCM_MMC_CTRL_OSCM24 (0x0 << 24)
 #define CCM_MMC_CTRL_PLL6   (0x1 << 24)
 
@@ -223,8 +236,34 @@ struct sunxi_ccm_reg {
 #define CCM_DRAMCLK_CFG_UPD            (0x1 << 16)
 #define CCM_DRAMCLK_CFG_RST            (0x1 << 31)
 
+#define CCM_DRAM_GATE_OFFSET_DE_BE0    26
+
+#define CCM_LCD_CH0_CTRL_PLL3          (0 << 24)
+#define CCM_LCD_CH0_CTRL_PLL7          (1 << 24)
+#define CCM_LCD_CH0_CTRL_PLL3_2X       (2 << 24)
+#define CCM_LCD_CH0_CTRL_PLL7_2X       (3 << 24)
+#define CCM_LCD_CH0_CTRL_MIPI_PLL      (4 << 24)
+#define CCM_LCD_CH0_CTRL_GATE          (0x1 << 31)
+
+#define CCM_LCD_CH1_CTRL_M(n)          ((((n) - 1) & 0xf) << 0)
+#define CCM_LCD_CH1_CTRL_PLL3          (0 << 24)
+#define CCM_LCD_CH1_CTRL_PLL7          (1 << 24)
+#define CCM_LCD_CH1_CTRL_PLL3_2X       (2 << 24)
+#define CCM_LCD_CH1_CTRL_PLL7_2X       (3 << 24)
+#define CCM_LCD_CH1_CTRL_GATE          (0x1 << 31)
+
+#define CCM_HDMI_CTRL_M(n)             ((((n) - 1) & 0xf) << 0)
+#define CCM_HDMI_CTRL_PLL_MASK         (3 << 24)
+#define CCM_HDMI_CTRL_PLL3             (0 << 24)
+#define CCM_HDMI_CTRL_PLL7             (1 << 24)
+#define CCM_HDMI_CTRL_PLL3_2X          (2 << 24)
+#define CCM_HDMI_CTRL_PLL7_2X          (3 << 24)
+#define CCM_HDMI_CTRL_DDC_GATE         (0x1 << 30)
+#define CCM_HDMI_CTRL_GATE             (0x1 << 31)
+
 #define MBUS_CLK_DEFAULT               0x81000001 /* PLL6 / 2 */
 
+/* ahb_reset0 offsets */
 #define AHB_RESET_OFFSET_MCTL          14
 #define AHB_RESET_OFFSET_MMC3          11
 #define AHB_RESET_OFFSET_MMC2          10
@@ -232,10 +271,28 @@ struct sunxi_ccm_reg {
 #define AHB_RESET_OFFSET_MMC0          8
 #define AHB_RESET_OFFSET_MMC(n)                (AHB_RESET_OFFSET_MMC0 + (n))
 
+/* ahb_reset0 offsets */
+#define AHB_RESET_OFFSET_DRC0          25
+#define AHB_RESET_OFFSET_DE_BE0                12
+#define AHB_RESET_OFFSET_HDMI          11
+#define AHB_RESET_OFFSET_LCD1          5
+#define AHB_RESET_OFFSET_LCD0          4
+
 /* apb2 reset */
 #define APB2_RESET_UART_SHIFT          (16)
 #define APB2_RESET_UART_MASK           (0xff << APB2_RESET_UART_SHIFT)
 #define APB2_RESET_TWI_SHIFT           (0)
 #define APB2_RESET_TWI_MASK            (0xf << APB2_RESET_TWI_SHIFT)
 
+/* CCM bits common to all Display Engine (and IEP) clock ctrl regs */
+#define CCM_DE_CTRL_M(n)               ((((n) - 1) & 0xf) << 0)
+#define CCM_DE_CTRL_PLL_MASK           (0xf << 24)
+#define CCM_DE_CTRL_PLL3               (0 << 24)
+#define CCM_DE_CTRL_PLL7               (1 << 24)
+#define CCM_DE_CTRL_PLL6_2X            (2 << 24)
+#define CCM_DE_CTRL_PLL8               (3 << 24)
+#define CCM_DE_CTRL_PLL9               (4 << 24)
+#define CCM_DE_CTRL_PLL10              (5 << 24)
+#define CCM_DE_CTRL_GATE               (1 << 31)
+
 #endif /* _SUNXI_CLOCK_SUN6I_H */