blob: 732a011b81b048a4564ea7bdbbab9e04f13853fd [file] [log] [blame]
// Copyright 2017 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/amlogiccanvas.h>
#include <ddktl/protocol/clock.h>
#include <ddktl/protocol/gpio.h>
#include <ddktl/protocol/power.h>
#include <ddktl/protocol/sysmem.h>
#include <ddktl/protocol/platform/device.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <lib/zx/channel.h>
#include "proxy-protocol.h"
namespace platform_bus {
class PlatformProxy;
class ProxyGpio : public ddk::GpioProtocol<ProxyGpio> {
public:
explicit ProxyGpio(uint32_t index, PlatformProxy* proxy)
: index_(index), proxy_(proxy) {}
// GPIO protocol implementation.
zx_status_t GpioConfigIn(uint32_t flags);
zx_status_t GpioConfigOut(uint8_t initial_value);
zx_status_t GpioSetAltFunction(uint64_t function);
zx_status_t GpioRead(uint8_t* out_value);
zx_status_t GpioWrite(uint8_t value);
zx_status_t GpioGetInterrupt(uint32_t flags, zx::interrupt* out_irq);
zx_status_t GpioReleaseInterrupt();
zx_status_t GpioSetPolarity(uint32_t polarity);
void GetProtocol(gpio_protocol_t* proto) {
proto->ops = &gpio_protocol_ops_;
proto->ctx = this;
}
private:
uint32_t index_;
PlatformProxy* proxy_;
};
class ProxyClock : public ddk::ClockProtocol<ProxyClock> {
public:
explicit ProxyClock(uint32_t index, PlatformProxy* proxy)
: index_(index), proxy_(proxy) {}
// Clock protocol implementation.
zx_status_t ClockEnable();
zx_status_t ClockDisable();
void GetProtocol(clock_protocol_t* proto) {
proto->ops = &clock_protocol_ops_;
proto->ctx = this;
}
private:
uint32_t index_;
PlatformProxy* proxy_;
};
class ProxySysmem : public ddk::SysmemProtocol<ProxySysmem> {
public:
explicit ProxySysmem(PlatformProxy* proxy)
: proxy_(proxy) {}
// Sysmem protocol implementation.
zx_status_t SysmemConnect(zx::channel allocator2_request);
zx_status_t SysmemRegisterHeap(uint64_t heap, zx::channel heap_connection);
void GetProtocol(sysmem_protocol_t* proto) {
proto->ops = &sysmem_protocol_ops_;
proto->ctx = this;
}
private:
PlatformProxy* proxy_;
};
class ProxyAmlogicCanvas : public ddk::AmlogicCanvasProtocol<ProxyAmlogicCanvas> {
public:
explicit ProxyAmlogicCanvas(PlatformProxy* proxy)
: proxy_(proxy) {}
// Amlogic Canvas protocol implementation.
zx_status_t AmlogicCanvasConfig(zx::vmo vmo, size_t offset, const canvas_info_t* info,
uint8_t* out_canvas_idx);
zx_status_t AmlogicCanvasFree(uint8_t canvas_idx);
void GetProtocol(amlogic_canvas_protocol_t* proto) {
proto->ops = &amlogic_canvas_protocol_ops_;
proto->ctx = this;
}
private:
PlatformProxy* proxy_;
};
using PlatformProxyType = ddk::Device<PlatformProxy, ddk::GetProtocolable>;
// This is the main class for the proxy side platform bus driver.
// It handles RPC communication with the main platform bus driver in the root devhost.
class PlatformProxy : public PlatformProxyType,
public ddk::PDevProtocol<PlatformProxy, ddk::base_protocol> {
public:
explicit PlatformProxy(zx_device_t* parent, zx_handle_t rpc_channel)
: PlatformProxyType(parent), rpc_channel_(rpc_channel), sysmem_(this), canvas_(this) {}
static zx_status_t Create(void* ctx, zx_device_t* parent, const char* name,
const char* args, zx_handle_t rpc_channel);
// Device protocol implementation.
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out);
void DdkRelease();
// Platform device protocol implementation.
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_bti);
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);
zx_status_t PDevGetProtocol(uint32_t proto_id, uint32_t index, void* out_protocol,
size_t protocol_size, size_t* protocol_actual);
zx_status_t Rpc(const platform_proxy_req_t* req, size_t req_length,
platform_proxy_rsp_t* resp, size_t resp_length,
const zx_handle_t* in_handles, size_t in_handle_count,
zx_handle_t* out_handles, size_t out_handle_count,
size_t* out_actual);
inline zx_status_t Rpc(const platform_proxy_req_t* req, size_t req_length,
platform_proxy_rsp_t* resp, size_t resp_length) {
return Rpc(req, req_length, resp, resp_length, nullptr, 0, nullptr, 0, nullptr);
}
private:
struct Mmio {
zx_paddr_t base;
size_t length;
zx::resource resource;
};
struct Irq {
uint32_t irq;
// ZX_INTERRUPT_MODE_* flags
uint32_t mode;
zx::resource resource;
};
DISALLOW_COPY_ASSIGN_AND_MOVE(PlatformProxy);
zx_status_t Init(zx_device_t* parent);
const zx::channel rpc_channel_;
char name_[ZX_MAX_NAME_LEN];
uint32_t metadata_count_;
fbl::Vector<Mmio> mmios_;
fbl::Vector<Irq> irqs_;
fbl::Vector<ProxyGpio> gpios_;
fbl::Vector<ProxyClock> clocks_;
ProxySysmem sysmem_;
ProxyAmlogicCanvas canvas_;
};
} // namespace platform_bus