blob: 270fc49982d90c6dcec6c1a999f7548e69b45327 [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 MSD_QCOM_DEVICE_H
#define MSD_QCOM_DEVICE_H
#include <msd.h>
#include <platform_bus_mapper.h>
#include <magma_util/register_io.h>
#include "allocating_address_space.h"
#include "firmware.h"
#include "msd_qcom_connection.h"
#include "msd_qcom_platform_device.h"
#include "ringbuffer.h"
class MsdQcomDevice : public msd_device_t,
public magma::AddressSpaceOwner,
public MsdQcomConnection::Owner {
public:
static std::unique_ptr<MsdQcomDevice> Create(void* device_handle);
MsdQcomDevice() { magic_ = kMagic; }
std::unique_ptr<MsdQcomConnection> Open(msd_client_id_t client_id);
uint32_t GetChipId() const { return qcom_platform_device_->GetChipId(); }
uint32_t GetGmemSize() const { return qcom_platform_device_->GetGmemSize(); }
magma_status_t Query(uint64_t id, uint64_t* value_out) const;
static void GetCpInitPacket(std::vector<uint32_t>& packet);
static MsdQcomDevice* cast(msd_device_t* dev) {
DASSERT(dev);
DASSERT(dev->magic_ == kMagic);
return static_cast<MsdQcomDevice*>(dev);
}
private:
std::shared_ptr<AddressSpace> address_space() { return address_space_; }
magma::RegisterIo* register_io() { return register_io_.get(); }
magma::Ringbuffer<GpuMapping>* ringbuffer() { return ringbuffer_.get(); }
Firmware* firmware() { return firmware_.get(); }
// magma::AddressSpaceOwner, MsdQcomConnection::Owner
magma::PlatformBusMapper* GetBusMapper() override { return bus_mapper_.get(); }
static const uint32_t kMagic = 0x64657669; //"devi"
// Maximum size for GMEM.
static constexpr uint64_t kGmemGpuAddrSize = 0x01000000;
// Maximum size for system allocations (firmware, ringbuffers).
static constexpr uint64_t kSystemGpuAddrSize = 0x01000000;
// Remainder of the address space allocated to client.
// TODO(fxbug.dev/44002) - support for greater than 32 bits of address space.
static constexpr uint64_t kClientGpuAddrSize =
(1ull << 32) - kGmemGpuAddrSize - kSystemGpuAddrSize;
static constexpr uint64_t kClientGpuAddrBase = 0;
static constexpr uint64_t kSystemGpuAddrBase = kClientGpuAddrBase + kClientGpuAddrSize;
static constexpr uint64_t kGmemGpuAddrBase = kSystemGpuAddrBase + kGmemGpuAddrSize;
bool Init(void* device_handle, std::unique_ptr<magma::RegisterIo::Hook> hook);
bool HardwareInit();
bool EnableClockGating(bool enable);
bool InitRingbuffer();
bool InitControlProcessor();
void FlushRingbuffer(uint32_t tail);
bool WaitForIdleRingbuffer(uint32_t tail);
std::unique_ptr<MsdQcomPlatformDevice> qcom_platform_device_;
std::unique_ptr<magma::RegisterIo> register_io_;
std::unique_ptr<magma::PlatformBusMapper> bus_mapper_;
std::shared_ptr<magma::PlatformIommu> iommu_;
std::shared_ptr<PartialAllocatingAddressSpace> address_space_;
std::unique_ptr<Ringbuffer> ringbuffer_;
std::unique_ptr<Firmware> firmware_;
friend class TestQcomDevice;
};
#endif // MSD_QCOM_DEVICE_H