| // Copyright 2019 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. |
| |
| #pragma once |
| |
| #include <ddktl/device.h> |
| #include <ddktl/protocol/clockimpl.h> |
| #include <fbl/mutex.h> |
| #include <fuchsia/hardware/clock/c/fidl.h> |
| #include <lib/mmio/mmio.h> |
| #include <soc/msm8x53/msm8x53-clock.h> |
| #include <zircon/thread_annotations.h> |
| |
| namespace clk { |
| |
| // Fwd declarations |
| class RcgFrequencyTable; |
| class MsmClkRcg; |
| |
| class Msm8x53Clk; |
| using DeviceType = ddk::Device<Msm8x53Clk, ddk::Unbindable>; |
| |
| class Msm8x53Clk : public DeviceType, |
| public ddk::ClockImplProtocol<Msm8x53Clk, ddk::base_protocol> { |
| public: |
| static zx_status_t Create(void* ctx, zx_device_t* parent); |
| |
| zx_status_t Init(); |
| |
| // Clock Protocol Implementation |
| zx_status_t ClockImplEnable(uint32_t index); |
| zx_status_t ClockImplDisable(uint32_t index); |
| zx_status_t ClockImplRequestRate(uint32_t id, uint64_t hz); |
| |
| // Device Protocol Implementation. |
| zx_status_t Bind(); |
| void DdkUnbind(); |
| void DdkRelease(); |
| |
| // Protected for tests. |
| protected: |
| Msm8x53Clk(zx_device_t* parent, ddk::MmioBuffer mmio) |
| : DeviceType(parent) |
| , mmio_(std::move(mmio)) {} |
| |
| zx_status_t RegisterClockProtocol(); |
| |
| enum class Toggle { |
| Enabled, |
| Disabled |
| }; |
| |
| // Gate Clocks |
| zx_status_t GateClockEnable(uint32_t index); |
| zx_status_t GateClockDisable(uint32_t index); |
| |
| // RCG Clocks |
| zx_status_t RcgClockEnable(uint32_t index); |
| zx_status_t RcgClockDisable(uint32_t index); |
| zx_status_t RcgClockSetRate(uint32_t index, uint64_t hz) __TA_REQUIRES(rcg_rates_lock_); |
| zx_status_t ToggleRcgForceEnable(uint32_t rcgr_cmd_offset, Toggle toggle); |
| zx_status_t AwaitRcgEnableLocked(uint32_t rcgr_cmd_offset) __TA_REQUIRES(lock_); |
| zx_status_t RcgSetRateMnd(const MsmClkRcg& clk, const RcgFrequencyTable* table); |
| zx_status_t RcgSetRateHalfInteger(const MsmClkRcg& clk, const RcgFrequencyTable* table); |
| zx_status_t LatchRcgConfig(const MsmClkRcg& clk); |
| |
| // Branch Clocks |
| zx_status_t BranchClockEnable(uint32_t index); |
| zx_status_t BranchClockDisable(uint32_t index); |
| // Wait for a change to a particular branch clock to take effect. |
| zx_status_t AwaitBranchClock(Toggle s, const uint32_t cbcr_reg); |
| |
| // Voter Clocks |
| zx_status_t VoterClockEnable(uint32_t index); |
| zx_status_t VoterClockDisable(uint32_t index); |
| |
| fbl::Mutex lock_; // Lock guards mmio_. |
| ddk::MmioBuffer mmio_; |
| |
| fbl::Mutex rcg_rates_lock_; |
| uint64_t rcg_rates_[msm8x53::kRcgClkCount]; |
| }; |
| |
| } // namespace clk |