1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #pragma once
6
7 #include <stdint.h>
8 #include <unistd.h>
9
10 #include <ddk/mmio-buffer.h>
11 #include <hw/reg.h>
12 #include <zircon/assert.h>
13
14 // clang-format off
15 #define SDM_FRACTIONALITY ((uint32_t)16384)
16 #define S905D2_FIXED_PLL_RATE ((uint32_t)2000000000)
17
18 /* Initial configuration values for PLLs. These were taken
19 from the AmLogic SDK. No documentation available to
20 understand settings at this time beyond the multiply/divide
21 ratios.
22 */
23 #define G12A_MPLL_CNTL0 0x00000543
24 #define G12A_MPLL_CNTL2 0x40000033
25
26 // TODO(hollande) - the pll design for HIFI and SYS are
27 // the same. Find out from Amlogic whey the register
28 // settings are different.
29 #define G12A_HIFI_PLL_CNTL1 0x00000000
30 #define G12A_HIFI_PLL_CNTL2 0x00000000
31 #define G12A_HIFI_PLL_CNTL3 0x6a285c00
32 #define G12A_HIFI_PLL_CNTL4 0x65771290
33 #define G12A_HIFI_PLL_CNTL5 0x39272000
34 #define G12A_HIFI_PLL_CNTL6 0x56540000
35
36 #define G12A_SYS_PLL_CNTL1 0x00000000
37 #define G12A_SYS_PLL_CNTL2 0x00000000
38 #define G12A_SYS_PLL_CNTL3 0x48681c00
39 #define G12A_SYS_PLL_CNTL4 0x88770290
40 #define G12A_SYS_PLL_CNTL5 0x39272000
41 #define G12A_SYS_PLL_CNTL6 0x56540000
42
43 #define G12A_GP0_PLL_CNTL1 0x00000000
44 #define G12A_GP0_PLL_CNTL2 0x00000000
45 #define G12A_GP0_PLL_CNTL3 0x48681c00
46 #define G12A_GP0_PLL_CNTL4 0x33771290
47 #define G12A_GP0_PLL_CNTL5 0x39272000
48 #define G12A_GP0_PLL_CNTL6 0x56540000
49
50 // HHI register offsets (all are 32-bit registers)
51 #define HHI_GP0_PLL_CNTL0 (0x10 << 2)
52 #define HHI_PCIE_PLL_CNTL0 (0x26 << 2)
53
54 #define HHI_HIFI_PLL_CNTL0 (0x36 << 2)
55 #define HHI_HIFI_PLL_CNTL1 (0x37 << 2)
56 #define HHI_HIFI_PLL_CNTL2 (0x38 << 2)
57 #define HHI_HIFI_PLL_CNTL3 (0x39 << 2)
58 #define HHI_HIFI_PLL_CNTL4 (0x3a << 2)
59 #define HHI_HIFI_PLL_CNTL5 (0x3b << 2)
60 #define HHI_HIFI_PLL_CNTL6 (0x3c << 2)
61
62 #define HHI_MPLL_CNTL0 (0x9e << 2)
63 #define HHI_MPLL_CNTL1 (0x9f << 2)
64 #define HHI_MPLL_CNTL2 (0xa0 << 2)
65 #define HHI_MPLL_CNTL3 (0xa1 << 2)
66 #define HHI_MPLL_CNTL4 (0xa2 << 2)
67 #define HHI_MPLL_CNTL5 (0xa3 << 2)
68 #define HHI_MPLL_CNTL6 (0xa4 << 2)
69 #define HHI_MPLL_CNTL7 (0xa5 << 2)
70 #define HHI_MPLL_CNTL8 (0xa6 << 2)
71
72 #define HHI_FIX_PLL_CNTL0 (0xa8 << 2)
73 #define HHI_FIX_PLL_CNTL1 (0xa9 << 2)
74 #define HHI_FIX_PLL_CNTL2 (0xaa << 2)
75 #define HHI_FIX_PLL_CNTL3 (0xab << 2)
76 #define HHI_FIX_PLL_CNTL4 (0xac << 2)
77 #define HHI_FIX_PLL_CNTL5 (0xad << 2)
78 #define HHI_FIX_PLL_CNTL6 (0xae << 2)
79
80 #define HHI_SYS_PLL_CNTL0 (0xbd << 2)
81 #define HHI_SYS_PLL_CNTL1 (0xbe << 2)
82 #define HHI_SYS_PLL_CNTL2 (0xbf << 2)
83 #define HHI_SYS_PLL_CNTL3 (0xc0 << 2)
84 #define HHI_SYS_PLL_CNTL4 (0xc1 << 2)
85 #define HHI_SYS_PLL_CNTL5 (0xc2 << 2)
86 #define HHI_SYS_PLL_CNTL6 (0xc3 << 2)
87
88 #define HHI_GP0_PLL_CNTL0 (0x10 << 2)
89 #define HHI_GP0_PLL_CNTL1 (0x11 << 2)
90 #define HHI_GP0_PLL_CNTL2 (0x12 << 2)
91 #define HHI_GP0_PLL_CNTL3 (0x13 << 2)
92 #define HHI_GP0_PLL_CNTL4 (0x14 << 2)
93 #define HHI_GP0_PLL_CNTL5 (0x15 << 2)
94 #define HHI_GP0_PLL_CNTL6 (0x16 << 2)
95
96 // HHI PLL register bitfield definitions
97 #define HHI_PLL_LOCK (1 << 31)
98 #define HHI_PLL_CNTL0_EN (1 << 28)
99 #define HHI_PLL_CNTL0_RESET (1 << 29)
100 #define HHI_PLL_CNTL0_M_SHIFT (0)
101 #define HHI_PLL_CNTL0_M (0xff << HHI_PLL_CNTL0_M_SHIFT)
102 #define HHI_PLL_CNTL0_N_SHIFT (10)
103 #define HHI_PLL_CNTL0_N (0x1f << HHI_PLL_CNTL0_N_SHIFT)
104 #define HHI_PLL_CNTL0_OD_SHIFT (16)
105 #define HHI_PLL_CNTL0_OD (0x3 << HHI_PLL_CNTL0_OD_SHIFT)
106
107 // clang-format on
108
109 typedef enum {
110 GP0_PLL,
111 PCIE_PLL,
112 HIFI_PLL,
113 SYS_PLL,
114 } hhi_plls_t;
115
116 typedef struct {
117 uint64_t rate;
118 uint32_t n;
119 uint32_t m;
120 uint32_t frac;
121 uint32_t od;
122 } hhi_pll_rate_t;
123
124 typedef struct aml_hiu_dev {
125 mmio_buffer_t mmio;
126 uint8_t* regs_vaddr;
127 } aml_hiu_dev_t;
128
129 typedef struct aml_pll_dev {
130 aml_hiu_dev_t* hiu; // Pointer to the register control block.
131 const hhi_pll_rate_t* rate_table; // Pointer to this PLLs rate table.
132 uint32_t rate_idx; // Index in rate table of current setting.
133 uint32_t frequency; // Current operating frequency.
134 hhi_plls_t pll_num; // Which pll is this
135 size_t rate_count; // Number of entries in the rate table.
136 } aml_pll_dev_t;
137
hiu_clk_get_reg(aml_hiu_dev_t * dev,uint32_t offset)138 static inline uint32_t hiu_clk_get_reg(aml_hiu_dev_t* dev, uint32_t offset) {
139 return readl(dev->regs_vaddr + offset);
140 }
141
hiu_clk_set_reg(aml_hiu_dev_t * dev,uint32_t offset,uint32_t value)142 static inline uint32_t hiu_clk_set_reg(aml_hiu_dev_t* dev, uint32_t offset, uint32_t value) {
143 writel(value, dev->regs_vaddr + offset);
144 return hiu_clk_get_reg(dev, offset);
145 }
146
hiu_get_pll_offs(aml_pll_dev_t * pll_dev)147 static inline uint32_t hiu_get_pll_offs(aml_pll_dev_t* pll_dev) {
148 switch (pll_dev->pll_num) {
149 case GP0_PLL:
150 return HHI_GP0_PLL_CNTL0;
151 case PCIE_PLL:
152 return HHI_PCIE_PLL_CNTL0;
153 case HIFI_PLL:
154 return HHI_HIFI_PLL_CNTL0;
155 case SYS_PLL:
156 return HHI_SYS_PLL_CNTL0;
157 default:
158 ZX_DEBUG_ASSERT(0);
159 }
160 return 0;
161 }
162
163 __BEGIN_CDECLS;
164
165 /*
166 Maps the hiu register block (containing all the pll controls).
167 */
168 zx_status_t s905d2_hiu_init(aml_hiu_dev_t* device);
169
170 /*
171 Initializes the selected pll. This resetting the pll and writing initial
172 values to control registers. When exiting init the PLL will be in a
173 halted (de-enabled) state.
174 */
175 zx_status_t s905d2_pll_init(aml_hiu_dev_t* device, aml_pll_dev_t* pll, hhi_plls_t pll_num);
176 /*
177 Sets the rate of the selected pll. If the requested frequency is not found
178 it will return with ZX_ERR_NOT_SUPPORTED.
179 */
180 zx_status_t s905d2_pll_set_rate(aml_pll_dev_t* pll, uint64_t freq);
181
182 /*
183 Enables the selected pll. This assumes the pll has been initialized and
184 valid divider values have been written to the control registers.
185 */
186 zx_status_t s905d2_pll_ena(aml_pll_dev_t* pll);
187
188 /*
189 Disable the selected pll. Returns if the pll was actually enabled
190 when the call was made.
191 */
192 bool s905d2_pll_disable(aml_pll_dev_t* pll_dev);
193
194 /*
195 Look for freq in pll rate table. Returns ZX_ERR_NOT_SUPPORTED if the rate
196 can not be found.
197 */
198 zx_status_t s905d2_pll_fetch_rate(aml_pll_dev_t* pll_dev, uint64_t freq, const hhi_pll_rate_t** pll_rate);
199
200 /*
201 Returns correct pll rate table for selected pll.
202 */
203 const hhi_pll_rate_t* s905d2_pll_get_rate_table(hhi_plls_t pll_num);
204
205 /*
206 Returns the count of the rate table for the pll.
207 */
208 size_t s905d2_get_rate_table_count(hhi_plls_t pll_num);
209
210 __END_CDECLS;
211