| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_DEVICES_LIB_AMLOGIC_INCLUDE_SOC_AML_S905D2_S905D2_HIU_H_ |
| #define SRC_DEVICES_LIB_AMLOGIC_INCLUDE_SOC_AML_S905D2_S905D2_HIU_H_ |
| |
| #include <stdint.h> |
| #include <unistd.h> |
| #include <zircon/assert.h> |
| |
| #include <ddk/mmio-buffer.h> |
| #include <hw/reg.h> |
| |
| typedef enum { |
| GP0_PLL = 0, |
| PCIE_PLL, |
| HIFI_PLL, |
| SYS_PLL, |
| SYS1_PLL, |
| HIU_PLL_COUNT, |
| } hhi_plls_t; |
| |
| typedef struct { |
| uint64_t rate; |
| uint32_t n; |
| uint32_t m; |
| uint32_t frac; |
| uint32_t od; |
| } hhi_pll_rate_t; |
| |
| typedef struct aml_hiu_dev { |
| mmio_buffer_t mmio; |
| MMIO_PTR uint8_t* regs_vaddr; |
| } aml_hiu_dev_t; |
| |
| typedef struct aml_pll_dev { |
| aml_hiu_dev_t* hiu; // Pointer to the register control block. |
| const hhi_pll_rate_t* rate_table; // Pointer to this PLLs rate table. |
| uint32_t rate_idx; // Index in rate table of current setting. |
| uint32_t frequency; // Current operating frequency. |
| hhi_plls_t pll_num; // Which pll is this |
| size_t rate_count; // Number of entries in the rate table. |
| } aml_pll_dev_t; |
| |
| __BEGIN_CDECLS |
| |
| /* |
| Maps the hiu register block (containing all the pll controls). |
| */ |
| zx_status_t s905d2_hiu_init(aml_hiu_dev_t* device); |
| |
| /* |
| Initializes the aml_hiu_dev_t struct assuming the register block is already |
| mapped |
| */ |
| zx_status_t s905d2_hiu_init_etc(aml_hiu_dev_t* device, MMIO_PTR uint8_t* hiubase); |
| |
| /* |
| Initializes the selected pll. This resetting the pll and writing initial |
| values to control registers. When exiting init the PLL will be in a |
| halted (de-enabled) state. |
| */ |
| zx_status_t s905d2_pll_init(aml_hiu_dev_t* device, aml_pll_dev_t* pll, hhi_plls_t pll_num); |
| |
| /* |
| Sets up the PLLs internal data structures without manipulating the hardware. |
| */ |
| void s905d2_pll_init_etc(aml_hiu_dev_t* device, aml_pll_dev_t* pll_dev, hhi_plls_t pll_num); |
| |
| /* |
| Sets the rate of the selected pll. If the requested frequency is not found |
| it will return with ZX_ERR_NOT_SUPPORTED. |
| */ |
| zx_status_t s905d2_pll_set_rate(aml_pll_dev_t* pll, uint64_t freq); |
| |
| /* |
| Enables the selected pll. This assumes the pll has been initialized and |
| valid divider values have been written to the control registers. |
| */ |
| zx_status_t s905d2_pll_ena(aml_pll_dev_t* pll); |
| |
| /* |
| Disable the selected pll. Returns if the pll was actually enabled |
| when the call was made. |
| */ |
| bool s905d2_pll_disable(aml_pll_dev_t* pll_dev); |
| |
| /* |
| Look for freq in pll rate table. Returns ZX_ERR_NOT_SUPPORTED if the rate |
| can not be found. |
| */ |
| zx_status_t s905d2_pll_fetch_rate(aml_pll_dev_t* pll_dev, uint64_t freq, |
| const hhi_pll_rate_t** pll_rate); |
| |
| /* |
| Returns correct pll rate table for selected pll. |
| */ |
| const hhi_pll_rate_t* s905d2_pll_get_rate_table(hhi_plls_t pll_num); |
| |
| /* |
| Returns the count of the rate table for the pll. |
| */ |
| size_t s905d2_get_rate_table_count(hhi_plls_t pll_num); |
| |
| __END_CDECLS |
| |
| #endif // SRC_DEVICES_LIB_AMLOGIC_INCLUDE_SOC_AML_S905D2_S905D2_HIU_H_ |