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 <unistd.h>
8#include <zircon/compiler.h>
9#include <ddk/driver.h>
10#include <ddk/protocol/platform-device.h>
11#include <fbl/unique_ptr.h>
12#include <hwreg/mmio.h>
13#include <ddktl/device.h>
14
15#include "aml-dsi.h"
16#include "hhi-regs.h"
17#include "vpu-regs.h"
18#include "common.h"
19
20namespace astro_display {
21
22class AstroDisplayClock {
23public:
24    AstroDisplayClock() {}
25    ~AstroDisplayClock() {
26        io_buffer_release(&mmio_vpu_);
27        io_buffer_release(&mmio_hhi_);
28    }
29    zx_status_t Init(zx_device_t* parent);
30    zx_status_t Enable(const DisplaySetting& d);
31    void Disable();
32    void Dump();
33
34    uint32_t GetBitrate() {
35        return pll_cfg_.bitrate;
36    }
37
38private:
39    void CalculateLcdTiming(const DisplaySetting& disp_setting);
40
41    // This function wait for hdmi_pll to lock. The retry algorithm is
42    // undocumented and comes from U-Boot.
43    zx_status_t PllLockWait();
44
45    // This function calculates the required pll configurations needed to generate
46    // the desired lcd clock
47    zx_status_t GenerateHPLL(const DisplaySetting& disp_setting);
48
49    io_buffer_t                             mmio_vpu_;
50    io_buffer_t                             mmio_hhi_;
51    platform_device_protocol_t              pdev_ = {};
52    fbl::unique_ptr<hwreg::RegisterIo>      vpu_regs_;
53    fbl::unique_ptr<hwreg::RegisterIo>      hhi_regs_;
54
55    PllConfig                               pll_cfg_;
56    LcdTiming                               lcd_timing_;
57
58    bool                                    initialized_ = false;
59    bool                                    clock_enabled_ = false;
60};
61
62} // namespace astro_display
63