]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/board/src/am64x_evm/board_pll.c
AM64x: Board_PLL: TEMP: enable MCU_PLL
[processor-sdk/pdk.git] / packages / ti / board / src / am64x_evm / board_pll.c
1 /******************************************************************************\r
2  * Copyright (c) 2019 Texas Instruments Incorporated - http://www.ti.com\r
3  *\r
4  *  Redistribution and use in source and binary forms, with or without\r
5  *  modification, are permitted provided that the following conditions\r
6  *  are met:\r
7  *\r
8  *    Redistributions of source code must retain the above copyright\r
9  *    notice, this list of conditions and the following disclaimer.\r
10  *\r
11  *    Redistributions in binary form must reproduce the above copyright\r
12  *    notice, this list of conditions and the following disclaimer in the\r
13  *    documentation and/or other materials provided with the\r
14  *    distribution.\r
15  *\r
16  *    Neither the name of Texas Instruments Incorporated nor the names of\r
17  *    its contributors may be used to endorse or promote products derived\r
18  *    from this software without specific prior written permission.\r
19  *\r
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31  *\r
32  *****************************************************************************/\r
33 \r
34 /**\r
35  * \file   board_pll.c\r
36  *\r
37  * \brief  Board pll configurations\r
38  *\r
39  */\r
40 \r
41 #include "board_internal.h"\r
42 #include "board_pll.h"\r
43 #include <ti/drv/sciclient/sciclient.h>\r
44 \r
45 static Board_PllClkCfg_t gBoardPllClkCfg[] =\r
46 {\r
47 \r
48  { TISCI_DEV_MCU_UART0,\r
49    TISCI_DEV_MCU_UART0_FCLK_CLK,\r
50    96000000\r
51  }, //MCU_PLL0_HSDIV2_CLKOUT,\r
52 \r
53  { TISCI_DEV_MCU_I2C0,\r
54    TISCI_DEV_MCU_UART0_FCLK_CLK,\r
55    96000000\r
56  }, //MCU_PLL0_HSDIV1_CLKOUT,\r
57 \r
58  { TISCI_DEV_UART0,\r
59    TISCI_DEV_UART0_FCLK_CLK,\r
60    48000000\r
61  }, //MAIN_PLL1_HSDIV1_CLKOUT,\r
62 \r
63  { TISCI_DEV_FSS0_OSPI_0,\r
64    TISCI_DEV_FSS0_OSPI_0_OSPI_RCLK_CLK,\r
65    166666666\r
66  }, //MAIN_PLL0_HSDIV1_CLKOUT,\r
67 \r
68  { TISCI_DEV_PRU_ICSSG1,\r
69    TISCI_DEV_PRU_ICSSG1_CORE_CLK,\r
70    250000000\r
71  }, //MAIN_PLL0_HSDIV9_CLKOUT,\r
72 \r
73  { TISCI_DEV_PRU_ICSSG1,\r
74    TISCI_DEV_PRU_ICSSG1_UCLK_CLK,\r
75    192000000\r
76  }, //MAIN_PLL1_HSDIV0_CLKOUT,\r
77 \r
78  { TISCI_DEV_PRU_ICSSG1,\r
79    TISCI_DEV_PRU_ICSSG1_RGMII_MHZ_250_CLK,\r
80    250000000\r
81  }, //MAIN_PLL0_HSDIV4_CLKOUT,\r
82 \r
83  { TISCI_DEV_MCAN0,\r
84    TISCI_DEV_MCAN0_MCANSS_CCLK_CLK,\r
85    80000000\r
86  }, //MAIN_PLL0_HSDIV2_CLKOUT,\r
87 \r
88 };\r
89 \r
90 /**\r
91  * \brief  PLL clock enable\r
92  *\r
93  * This function is used to set the PLL Module clock frequency\r
94  *\r
95  * \param  moduleId [IN]  Module for which the state should be set.\r
96  *                        Refer Sciclient_PmDeviceIds in sciclient_fmwMsgParams.h\r
97  * \param  clockId  [IN]  Clock Id for the module.\r
98  *                        Refer Sciclient_PmModuleClockIds in sciclient_fmwMsgParams.h\r
99  * \param  clkRate  [IN]  Value of the clock frequency to be set\r
100  *\r
101  * \return int32_t\r
102  *                CSL_PASS - on Success\r
103  *                CSL_EFAIL - on Failure\r
104  *\r
105  */\r
106 static int32_t Board_PLLSetModuleClkFreq(uint32_t modId,\r
107                                          uint32_t clkId,\r
108                                          uint64_t clkRate)\r
109 {\r
110     uint32_t i = 0U;\r
111     int32_t status   = CSL_EFAIL;\r
112     uint64_t respClkRate = 0;\r
113     uint32_t numParents = 0U;\r
114     uint32_t moduleClockParentChanged = 0U;\r
115     uint32_t clockStatus = 0U;\r
116     uint32_t origParent = 0U;\r
117     uint32_t foundParent = 0U;\r
118 \r
119     /* Check if the clock is enabled or not */\r
120     status = Sciclient_pmModuleGetClkStatus(modId,\r
121                                             clkId,\r
122                                             &clockStatus,\r
123                                             SCICLIENT_SERVICE_WAIT_FOREVER);\r
124     if (status == CSL_PASS)\r
125     {\r
126         /* Get the number of parents for the clock */\r
127         status = Sciclient_pmGetModuleClkNumParent(modId,\r
128                                                 clkId,\r
129                                                 &numParents,\r
130                                                 SCICLIENT_SERVICE_WAIT_FOREVER);\r
131         if ((status == CSL_PASS) && (numParents > 1U))\r
132         {\r
133             status = Sciclient_pmGetModuleClkParent(modId, clkId, &origParent,\r
134                                        SCICLIENT_SERVICE_WAIT_FOREVER);\r
135         }\r
136     }\r
137     if (status == CSL_PASS)\r
138     {\r
139         /* Disabling the clock */\r
140         status = Sciclient_pmModuleClkRequest(\r
141                                             modId,\r
142                                             clkId,\r
143                                             TISCI_MSG_VALUE_CLOCK_SW_STATE_UNREQ,\r
144                                             0U,\r
145                                             SCICLIENT_SERVICE_WAIT_FOREVER);\r
146     }\r
147     if (status == CSL_PASS)\r
148     {\r
149         foundParent = 0U;\r
150         /* Try to loop and change parents of the clock */\r
151         for(i=0U;i<numParents;i++)\r
152         {\r
153             if (numParents > 1U)\r
154             {\r
155                 /* Setting the new parent */\r
156                 status = Sciclient_pmSetModuleClkParent(\r
157                                             modId,\r
158                                             clkId,\r
159                                             clkId+i+1,\r
160                                             SCICLIENT_SERVICE_WAIT_FOREVER);\r
161                 /* Check if the clock can be set to desirable freq. */\r
162                 if (status == CSL_PASS)\r
163                 {\r
164                     moduleClockParentChanged = 1U;\r
165                 }\r
166             }\r
167             if (status == CSL_PASS)\r
168             {\r
169                 status = Sciclient_pmQueryModuleClkFreq(modId,\r
170                                                         clkId,\r
171                                                         clkRate,\r
172                                                         &respClkRate,\r
173                                                         SCICLIENT_SERVICE_WAIT_FOREVER);\r
174             }\r
175             if ((status == CSL_PASS) && (respClkRate == clkRate))\r
176             {\r
177                 foundParent = 1U;\r
178                 break;\r
179             }\r
180         }\r
181     }\r
182     if (foundParent == 1U)\r
183     {\r
184         /* Set the clock at the desirable frequency*/\r
185         status = Sciclient_pmSetModuleClkFreq(\r
186                                 modId,\r
187                                 clkId,\r
188                                 clkRate,\r
189                                 TISCI_MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,\r
190                                 SCICLIENT_SERVICE_WAIT_FOREVER);\r
191     }\r
192     else\r
193     {\r
194         status = CSL_EFAIL;\r
195     }\r
196     if ((status == CSL_PASS) &&\r
197         (clockStatus == TISCI_MSG_VALUE_CLOCK_SW_STATE_UNREQ))\r
198     {\r
199         /* Restore the clock again to original state */\r
200         status = Sciclient_pmModuleClkRequest(\r
201                                             modId,\r
202                                             clkId,\r
203                                             clockStatus,\r
204                                             0U,\r
205                                             SCICLIENT_SERVICE_WAIT_FOREVER);\r
206     }\r
207     if ((status != CSL_PASS) && (moduleClockParentChanged == 1U))\r
208     {\r
209         /* Setting the original parent if failure */\r
210         status = Sciclient_pmSetModuleClkParent(\r
211                                     modId,\r
212                                     clkId,\r
213                                     origParent,\r
214                                     SCICLIENT_SERVICE_WAIT_FOREVER);\r
215     }\r
216     return status;\r
217 }\r
218 \r
219 \r
220 /**\r
221  * \brief  Function to initialize module clock frequency\r
222  *\r
223  * \param  moduleId [IN]  Module for which the state should be set.\r
224  *                        Refer Sciclient_PmDeviceIds in sciclient_fmwMsgParams.h\r
225  * \param  clockId  [IN]  Clock Id for the module.\r
226  *                        Refer Sciclient_PmModuleClockIds in sciclient_fmwMsgParams.h\r
227  * \param  clkRate  [IN]  Value of the clock frequency to be set\r
228 \r
229  * \return Board_STATUS\r
230  */\r
231 Board_STATUS Board_PLLInit(uint32_t modId,\r
232                            uint32_t clkId,\r
233                            uint64_t clkRate)\r
234 {\r
235     int32_t  status = CSL_EFAIL;\r
236 \r
237     status = Board_PLLSetModuleClkFreq(modId, clkId, clkRate);\r
238     if(status != CSL_PASS)\r
239     {\r
240         return BOARD_FAIL;\r
241     }\r
242 \r
243     return BOARD_SOK;\r
244 }\r
245 \r
246 /**\r
247  * \brief  Function to initialize all the PLL clocks with default values\r
248  *\r
249  * \return Board_STATUS\r
250  */\r
251 Board_STATUS Board_PLLInitAll(void)\r
252 {\r
253     Board_STATUS  status = BOARD_SOK;\r
254     uint32_t index;\r
255     uint32_t loopCount;\r
256 \r
257     loopCount = sizeof (gBoardPllClkCfg)/sizeof(Board_PllClkCfg_t);\r
258 \r
259     for (index = 0; index < loopCount; index++)\r
260     {\r
261         status = Board_PLLInit(gBoardPllClkCfg[index].tisciDevID,\r
262                                gBoardPllClkCfg[index].tisciClkID,\r
263                                gBoardPllClkCfg[index].clkRate);\r
264         if(status != BOARD_SOK)\r
265         {\r
266             BOARD_DEBUG_LOG("Failed to set the PLL clock freq at index =%d\n\n",index);\r
267         }\r
268     }\r
269 \r
270     /*\r
271      * Temporary solution for enabling M4F application load via SBL.\r
272      * Actual fix will be in SYSFW doing early PLL initialization for MCU_PLLCTRL0\r
273      * \r
274      * MCU_PLLCTRL0's PLLCTL, set PLLENSRC = 0 and PLLEN = 1\r
275      */\r
276     HW_WR_REG32((CSL_MCU_PLLCTRL0_BASE + 0x100UL), 0x49U);\r
277 \r
278     return status;\r
279 }\r