root/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c

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

DEFINITIONS

This source file includes following definitions.
  1. dsi_pll_enable
  2. dsi_pll_disable
  3. msm_dsi_pll_helper_clk_round_rate
  4. msm_dsi_pll_helper_clk_prepare
  5. msm_dsi_pll_helper_clk_unprepare
  6. msm_dsi_pll_helper_unregister_clks
  7. msm_dsi_pll_get_clk_provider
  8. msm_dsi_pll_destroy
  9. msm_dsi_pll_save_state
  10. msm_dsi_pll_restore_state
  11. msm_dsi_pll_set_usecase
  12. msm_dsi_pll_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
   4  */
   5 
   6 #include "dsi_pll.h"
   7 
   8 static int dsi_pll_enable(struct msm_dsi_pll *pll)
   9 {
  10         int i, ret = 0;
  11 
  12         /*
  13          * Certain PLLs do not allow VCO rate update when it is on.
  14          * Keep track of their status to turn on/off after set rate success.
  15          */
  16         if (unlikely(pll->pll_on))
  17                 return 0;
  18 
  19         /* Try all enable sequences until one succeeds */
  20         for (i = 0; i < pll->en_seq_cnt; i++) {
  21                 ret = pll->enable_seqs[i](pll);
  22                 DBG("DSI PLL %s after sequence #%d",
  23                         ret ? "unlocked" : "locked", i + 1);
  24                 if (!ret)
  25                         break;
  26         }
  27 
  28         if (ret) {
  29                 DRM_ERROR("DSI PLL failed to lock\n");
  30                 return ret;
  31         }
  32 
  33         pll->pll_on = true;
  34 
  35         return 0;
  36 }
  37 
  38 static void dsi_pll_disable(struct msm_dsi_pll *pll)
  39 {
  40         if (unlikely(!pll->pll_on))
  41                 return;
  42 
  43         pll->disable_seq(pll);
  44 
  45         pll->pll_on = false;
  46 }
  47 
  48 /*
  49  * DSI PLL Helper functions
  50  */
  51 long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw,
  52                 unsigned long rate, unsigned long *parent_rate)
  53 {
  54         struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
  55 
  56         if      (rate < pll->min_rate)
  57                 return  pll->min_rate;
  58         else if (rate > pll->max_rate)
  59                 return  pll->max_rate;
  60         else
  61                 return rate;
  62 }
  63 
  64 int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw)
  65 {
  66         struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
  67 
  68         return dsi_pll_enable(pll);
  69 }
  70 
  71 void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw)
  72 {
  73         struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
  74 
  75         dsi_pll_disable(pll);
  76 }
  77 
  78 void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
  79                                         struct clk **clks, u32 num_clks)
  80 {
  81         of_clk_del_provider(pdev->dev.of_node);
  82 
  83         if (!num_clks || !clks)
  84                 return;
  85 
  86         do {
  87                 clk_unregister(clks[--num_clks]);
  88                 clks[num_clks] = NULL;
  89         } while (num_clks);
  90 }
  91 
  92 /*
  93  * DSI PLL API
  94  */
  95 int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
  96         struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
  97 {
  98         if (pll->get_provider)
  99                 return pll->get_provider(pll,
 100                                         byte_clk_provider,
 101                                         pixel_clk_provider);
 102 
 103         return -EINVAL;
 104 }
 105 
 106 void msm_dsi_pll_destroy(struct msm_dsi_pll *pll)
 107 {
 108         if (pll->destroy)
 109                 pll->destroy(pll);
 110 }
 111 
 112 void msm_dsi_pll_save_state(struct msm_dsi_pll *pll)
 113 {
 114         if (pll->save_state) {
 115                 pll->save_state(pll);
 116                 pll->state_saved = true;
 117         }
 118 }
 119 
 120 int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll)
 121 {
 122         int ret;
 123 
 124         if (pll->restore_state && pll->state_saved) {
 125                 ret = pll->restore_state(pll);
 126                 if (ret)
 127                         return ret;
 128 
 129                 pll->state_saved = false;
 130         }
 131 
 132         return 0;
 133 }
 134 
 135 int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
 136                             enum msm_dsi_phy_usecase uc)
 137 {
 138         if (pll->set_usecase)
 139                 return pll->set_usecase(pll, uc);
 140 
 141         return 0;
 142 }
 143 
 144 struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
 145                         enum msm_dsi_phy_type type, int id)
 146 {
 147         struct device *dev = &pdev->dev;
 148         struct msm_dsi_pll *pll;
 149 
 150         switch (type) {
 151         case MSM_DSI_PHY_28NM_HPM:
 152         case MSM_DSI_PHY_28NM_LP:
 153                 pll = msm_dsi_pll_28nm_init(pdev, type, id);
 154                 break;
 155         case MSM_DSI_PHY_28NM_8960:
 156                 pll = msm_dsi_pll_28nm_8960_init(pdev, id);
 157                 break;
 158         case MSM_DSI_PHY_14NM:
 159                 pll = msm_dsi_pll_14nm_init(pdev, id);
 160                 break;
 161         case MSM_DSI_PHY_10NM:
 162                 pll = msm_dsi_pll_10nm_init(pdev, id);
 163                 break;
 164         default:
 165                 pll = ERR_PTR(-ENXIO);
 166                 break;
 167         }
 168 
 169         if (IS_ERR(pll)) {
 170                 DRM_DEV_ERROR(dev, "%s: failed to init DSI PLL\n", __func__);
 171                 return pll;
 172         }
 173 
 174         pll->type = type;
 175 
 176         DBG("DSI:%d PLL registered", id);
 177 
 178         return pll;
 179 }
 180 

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