root/drivers/gpu/drm/omapdrm/dss/video-pll.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dss_dpll_enable_scp_clk
  2. dss_dpll_disable_scp_clk
  3. dss_dpll_power_enable
  4. dss_dpll_power_disable
  5. dss_video_pll_enable
  6. dss_video_pll_disable
  7. dss_video_pll_init
  8. dss_video_pll_uninit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
   4  */
   5 
   6 #include <linux/clk.h>
   7 #include <linux/delay.h>
   8 #include <linux/err.h>
   9 #include <linux/io.h>
  10 #include <linux/kernel.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/sched.h>
  13 
  14 #include "omapdss.h"
  15 #include "dss.h"
  16 
  17 struct dss_video_pll {
  18         struct dss_pll pll;
  19 
  20         struct device *dev;
  21 
  22         void __iomem *clkctrl_base;
  23 };
  24 
  25 #define REG_MOD(reg, val, start, end) \
  26         writel_relaxed(FLD_MOD(readl_relaxed(reg), val, start, end), reg)
  27 
  28 static void dss_dpll_enable_scp_clk(struct dss_video_pll *vpll)
  29 {
  30         REG_MOD(vpll->clkctrl_base, 1, 14, 14); /* CIO_CLK_ICG */
  31 }
  32 
  33 static void dss_dpll_disable_scp_clk(struct dss_video_pll *vpll)
  34 {
  35         REG_MOD(vpll->clkctrl_base, 0, 14, 14); /* CIO_CLK_ICG */
  36 }
  37 
  38 static void dss_dpll_power_enable(struct dss_video_pll *vpll)
  39 {
  40         REG_MOD(vpll->clkctrl_base, 2, 31, 30); /* PLL_POWER_ON_ALL */
  41 
  42         /*
  43          * DRA7x PLL CTRL's PLL_PWR_STATUS seems to always return 0,
  44          * so we have to use fixed delay here.
  45          */
  46         msleep(1);
  47 }
  48 
  49 static void dss_dpll_power_disable(struct dss_video_pll *vpll)
  50 {
  51         REG_MOD(vpll->clkctrl_base, 0, 31, 30); /* PLL_POWER_OFF */
  52 }
  53 
  54 static int dss_video_pll_enable(struct dss_pll *pll)
  55 {
  56         struct dss_video_pll *vpll = container_of(pll, struct dss_video_pll, pll);
  57         int r;
  58 
  59         r = dss_runtime_get(pll->dss);
  60         if (r)
  61                 return r;
  62 
  63         dss_ctrl_pll_enable(pll, true);
  64 
  65         dss_dpll_enable_scp_clk(vpll);
  66 
  67         r = dss_pll_wait_reset_done(pll);
  68         if (r)
  69                 goto err_reset;
  70 
  71         dss_dpll_power_enable(vpll);
  72 
  73         return 0;
  74 
  75 err_reset:
  76         dss_dpll_disable_scp_clk(vpll);
  77         dss_ctrl_pll_enable(pll, false);
  78         dss_runtime_put(pll->dss);
  79 
  80         return r;
  81 }
  82 
  83 static void dss_video_pll_disable(struct dss_pll *pll)
  84 {
  85         struct dss_video_pll *vpll = container_of(pll, struct dss_video_pll, pll);
  86 
  87         dss_dpll_power_disable(vpll);
  88 
  89         dss_dpll_disable_scp_clk(vpll);
  90 
  91         dss_ctrl_pll_enable(pll, false);
  92 
  93         dss_runtime_put(pll->dss);
  94 }
  95 
  96 static const struct dss_pll_ops dss_pll_ops = {
  97         .enable = dss_video_pll_enable,
  98         .disable = dss_video_pll_disable,
  99         .set_config = dss_pll_write_config_type_a,
 100 };
 101 
 102 static const struct dss_pll_hw dss_dra7_video_pll_hw = {
 103         .type = DSS_PLL_TYPE_A,
 104 
 105         .n_max = (1 << 8) - 1,
 106         .m_max = (1 << 12) - 1,
 107         .mX_max = (1 << 5) - 1,
 108         .fint_min = 500000,
 109         .fint_max = 2500000,
 110         .clkdco_max = 1800000000,
 111 
 112         .n_msb = 8,
 113         .n_lsb = 1,
 114         .m_msb = 20,
 115         .m_lsb = 9,
 116 
 117         .mX_msb[0] = 25,
 118         .mX_lsb[0] = 21,
 119         .mX_msb[1] = 30,
 120         .mX_lsb[1] = 26,
 121         .mX_msb[2] = 4,
 122         .mX_lsb[2] = 0,
 123         .mX_msb[3] = 9,
 124         .mX_lsb[3] = 5,
 125 
 126         .has_refsel = true,
 127 
 128         .errata_i886 = true,
 129         .errata_i932 = true,
 130 };
 131 
 132 struct dss_pll *dss_video_pll_init(struct dss_device *dss,
 133                                    struct platform_device *pdev, int id,
 134                                    struct regulator *regulator)
 135 {
 136         const char * const reg_name[] = { "pll1", "pll2" };
 137         const char * const clkctrl_name[] = { "pll1_clkctrl", "pll2_clkctrl" };
 138         const char * const clkin_name[] = { "video1_clk", "video2_clk" };
 139 
 140         struct resource *res;
 141         struct dss_video_pll *vpll;
 142         void __iomem *pll_base, *clkctrl_base;
 143         struct clk *clk;
 144         struct dss_pll *pll;
 145         int r;
 146 
 147         /* PLL CONTROL */
 148 
 149         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, reg_name[id]);
 150         pll_base = devm_ioremap_resource(&pdev->dev, res);
 151         if (IS_ERR(pll_base))
 152                 return ERR_CAST(pll_base);
 153 
 154         /* CLOCK CONTROL */
 155 
 156         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 157                 clkctrl_name[id]);
 158         clkctrl_base = devm_ioremap_resource(&pdev->dev, res);
 159         if (IS_ERR(clkctrl_base))
 160                 return ERR_CAST(clkctrl_base);
 161 
 162         /* CLKIN */
 163 
 164         clk = devm_clk_get(&pdev->dev, clkin_name[id]);
 165         if (IS_ERR(clk)) {
 166                 DSSERR("can't get video pll clkin\n");
 167                 return ERR_CAST(clk);
 168         }
 169 
 170         vpll = devm_kzalloc(&pdev->dev, sizeof(*vpll), GFP_KERNEL);
 171         if (!vpll)
 172                 return ERR_PTR(-ENOMEM);
 173 
 174         vpll->dev = &pdev->dev;
 175         vpll->clkctrl_base = clkctrl_base;
 176 
 177         pll = &vpll->pll;
 178 
 179         pll->name = id == 0 ? "video0" : "video1";
 180         pll->id = id == 0 ? DSS_PLL_VIDEO1 : DSS_PLL_VIDEO2;
 181         pll->clkin = clk;
 182         pll->regulator = regulator;
 183         pll->base = pll_base;
 184         pll->hw = &dss_dra7_video_pll_hw;
 185         pll->ops = &dss_pll_ops;
 186 
 187         r = dss_pll_register(dss, pll);
 188         if (r)
 189                 return ERR_PTR(r);
 190 
 191         return pll;
 192 }
 193 
 194 void dss_video_pll_uninit(struct dss_pll *pll)
 195 {
 196         dss_pll_unregister(pll);
 197 }

/* [<][>][^][v][top][bottom][index][help] */