blob: 6e5a6333ec875dfbb747e424843a07afe1df34b4 [file] [log] [blame]
// 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.
#ifndef SRC_DEVICES_ML_DRIVERS_AML_NNA_AML_NNA_H_
#define SRC_DEVICES_ML_DRIVERS_AML_NNA_AML_NNA_H_
#include <fidl/fuchsia.hardware.registers/cpp/wire.h>
#include <fuchsia/hardware/platform/device/c/banjo.h>
#include <lib/ddk/platform-defs.h>
#include <lib/device-protocol/pdev-fidl.h>
#include <lib/mmio/mmio.h>
#include <zircon/fidl.h>
#include <ddktl/device.h>
#include <ddktl/protocol/empty-protocol.h>
#include <soc/aml-common/aml-power-domain.h>
#include <soc/aml-common/aml-registers.h>
constexpr uint32_t kNnaPowerDomainLegacy = 0;
constexpr uint32_t kNnaPowerDomain = 1;
namespace aml_nna {
class AmlNnaDevice;
using AmlNnaDeviceType = ddk::Device<AmlNnaDevice, ddk::GetProtocolable>;
class AmlNnaDevice : public AmlNnaDeviceType,
public ddk::PDevProtocol<AmlNnaDevice, ddk::base_protocol> {
public:
struct NnaPowerDomainBlock {
// Power Domain MMIO.
uint32_t domain_power_sleep_offset;
uint32_t domain_power_iso_offset;
// Set power state (1 = power off)
uint32_t domain_power_sleep_bits;
// Set control output signal isolation (1 = set isolation)
uint32_t domain_power_iso_bits;
// Memory PD MMIO.
uint32_t hhi_mem_pd_reg0_offset;
uint32_t hhi_mem_pd_reg1_offset;
// Reset MMIO.
uint32_t reset_level2_offset;
};
// Each offset is the byte offset of the register in their respective mmio region.
struct NnaBlock {
// For the new chips from Amlogic, smc already supports the control of power domain
// So A5 uses smc to manage the NN power.
uint32_t nna_power_version;
union {
struct NnaPowerDomainBlock nna_regs; // Access with mmio read/write.
uint32_t nna_domain_id; // Access with smc call.
};
// Hiu MMIO.
uint32_t clock_control_offset;
uint32_t clock_core_control_bits;
uint32_t clock_axi_control_bits;
};
explicit AmlNnaDevice(zx_device_t* parent, fdf::MmioBuffer hiu_mmio, fdf::MmioBuffer power_mmio,
fdf::MmioBuffer memory_pd_mmio,
fidl::ClientEnd<fuchsia_hardware_registers::Device> reset,
ddk::PDevFidl pdev, NnaBlock nna_block, zx::resource smc_monitor)
: AmlNnaDeviceType(parent),
pdev_(std::move(pdev)),
hiu_mmio_(std::move(hiu_mmio)),
power_mmio_(std::move(power_mmio)),
memory_pd_mmio_(std::move(memory_pd_mmio)),
reset_(std::move(reset)),
nna_block_(nna_block),
smc_monitor_(std::move(smc_monitor)) {}
static zx_status_t Create(void* ctx, zx_device_t* parent);
zx_status_t Init();
zx_status_t PowerDomainControl(bool turn_on);
// Methods required by the ddk.
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out);
void DdkRelease();
// Platform device protocol implementation.
// TODO(https://fxbug.dev/42075039): Remove implementation of PDevProtocol and
// ddk::GetProtocolable. Update child drivers to use the PlatformDevice FIDL
// instead.
zx_status_t PDevGetMmio(uint32_t index, pdev_mmio_t* out_mmio);
zx_status_t PDevGetInterrupt(uint32_t index, uint32_t flags, zx::interrupt* out_irq);
zx_status_t PDevGetBti(uint32_t index, zx::bti* out_handle);
zx_status_t PDevGetSmc(uint32_t index, zx::resource* out_resource);
zx_status_t PDevGetDeviceInfo(pdev_device_info_t* out_info);
zx_status_t PDevGetBoardInfo(pdev_board_info_t* out_info);
private:
ddk::PDevFidl pdev_;
fdf::MmioBuffer hiu_mmio_;
fdf::MmioBuffer power_mmio_;
fdf::MmioBuffer memory_pd_mmio_;
fidl::WireSyncClient<fuchsia_hardware_registers::Device> reset_;
NnaBlock nna_block_;
// Control PowerDomain
zx::resource smc_monitor_;
};
} // namespace aml_nna
#endif // SRC_DEVICES_ML_DRIVERS_AML_NNA_AML_NNA_H_