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#include <soc/aml-s905d2/s905d2-hiu.h>
6#include <zircon/types.h>
7
8// PLL Rate tables
9#define HHI_PLL_RATE(_rate, _n, _m, _frac, _od) \
10    {                                           \
11        .rate = _rate,                          \
12        .n = _n,                                \
13        .m = _m,                                \
14        .frac = _frac,                          \
15        .od = _od,                              \
16    }
17
18/* These settings work for hifi, sys, pcie, and gp0 plls
19   While it would be possible to dynamically calculate the four components
20   to generate a desired rate, it makes more sense at this time to have a table
21   of settings for some known needed rates.  The documentation fo the Amlogic
22   plls is somewhat thin and by using the tables we will have known tested good
23   rates to choose from.
24   fout = 24MHz*m/(n*(1 << od))
25*/
26static const hhi_pll_rate_t s905d2_hiu_pll_rates[] = {
27    HHI_PLL_RATE( 846000000, 1, 141, 0, 2), /*DCO=3384M*/
28    HHI_PLL_RATE(1200000000, 1, 200, 0, 2), /*DCO=4800M*/
29    HHI_PLL_RATE(1296000000, 1, 216, 0, 2), /*DCO=5184M*/
30    HHI_PLL_RATE(1398000000, 1, 233, 0, 2), /*DCO=5592M*/
31    HHI_PLL_RATE(1494000000, 1, 249, 0, 2), /*DCO=5976M*/
32    HHI_PLL_RATE(1512000000, 1, 126, 0, 1), /*DCO=3024M*/
33    HHI_PLL_RATE(1536000000, 1, 128, 0, 1), /*DCO=3072M*/
34    HHI_PLL_RATE(1608000000, 1, 134, 0, 1), /*DCO=3216M*/
35    HHI_PLL_RATE(1704000000, 1, 142, 0, 1), /*DCO=3408M*/
36    HHI_PLL_RATE(1800000000, 1, 150, 0, 1), /*DCO=3600M*/
37    HHI_PLL_RATE(1896000000, 1, 158, 0, 1), /*DCO=3792M*/
38    HHI_PLL_RATE(3072000000, 1, 128, 0, 0), /*DCO=3072M*/
39};
40
41/* Find frequence in the rate table and return pointer to the entry.
42   At this point this assumes even integer requencies. This will be expanded later
43   to handle fractional cases.
44*/
45zx_status_t s905d2_pll_fetch_rate(aml_pll_dev_t* pll_dev, uint64_t freq,
46                                  const hhi_pll_rate_t** pll_rate) {
47    for (uint32_t i = 0; i < pll_dev->rate_count; i++) {
48        if (freq == pll_dev->rate_table[i].rate) {
49            *pll_rate = &pll_dev->rate_table[i];
50            return ZX_OK;
51        }
52    }
53    *pll_rate = NULL;
54    return ZX_ERR_NOT_SUPPORTED;
55}
56
57const hhi_pll_rate_t* s905d2_pll_get_rate_table(hhi_plls_t pll_num) {
58    switch (pll_num) {
59    case GP0_PLL:
60    case PCIE_PLL:
61    case HIFI_PLL:
62    case SYS_PLL:
63        return s905d2_hiu_pll_rates;
64    }
65    return NULL;
66}
67
68size_t s905d2_get_rate_table_count(hhi_plls_t pll_num) {
69    switch (pll_num) {
70    case GP0_PLL:
71    case PCIE_PLL:
72    case HIFI_PLL:
73    case SYS_PLL:
74        return countof(s905d2_hiu_pll_rates);
75    }
76    return 0;
77}
78