blob: b92277a6514c437a377e57a451d10415a38b7076 [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.
#include <fuchsia/hardware/powerimpl/cpp/banjo.h>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/metadata.h>
#include <ddk/metadata/power.h>
#include <ddk/platform-defs.h>
#include <soc/mt8167/mt8167-hw.h>
#include "mt8167.h"
namespace {
static const zx_bind_inst_t root_match[] = {
BI_MATCH(),
};
static const zx_bind_inst_t power_impl_driver_match[] = {
BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_POWER_IMPL),
};
static const device_fragment_part_t power_impl_fragment[] = {
{countof(root_match), root_match},
{countof(power_impl_driver_match), power_impl_driver_match},
};
zx_device_prop_t props[] = {
{BIND_POWER_DOMAIN_COMPOSITE, 0, PDEV_DID_POWER_DOMAIN_COMPOSITE},
};
// kVDLdoVGp2
static const device_fragment_t power_domain_kVDLdoVGp2_fragments[] = {
{"power", countof(power_impl_fragment), power_impl_fragment},
};
static const power_domain_t power_domain_kVDLdoVGp2[] = {
{kVDLdoVGp2},
};
static const device_metadata_t power_metadata_kVDLdoVGp2[] = {{
.type = DEVICE_METADATA_POWER_DOMAINS,
.data = &power_domain_kVDLdoVGp2,
.length = sizeof(power_domain_kVDLdoVGp2),
}};
const composite_device_desc_t power_domain_kVDLdoVGp2_desc = {
.props = props,
.props_count = countof(props),
.fragments = power_domain_kVDLdoVGp2_fragments,
.fragments_count = countof(power_domain_kVDLdoVGp2_fragments),
.coresident_device_index = 0,
.metadata_list = power_metadata_kVDLdoVGp2,
.metadata_count = countof(power_metadata_kVDLdoVGp2),
};
} // namespace
namespace board_mt8167 {
zx_status_t Mt8167::Vgp1Enable() {
ddk::PowerImplProtocolClient power(parent());
if (!power.is_valid()) {
zxlogf(ERROR, "Failed to get power impl protocol");
return ZX_ERR_NO_RESOURCES;
}
zx_status_t status = power.EnablePowerDomain(kVDLdoVGp1);
if (status != ZX_OK) {
zxlogf(ERROR, "%s: Failed to enable VGP1 regulator: %d", __FUNCTION__, status);
}
return status;
}
zx_status_t Mt8167::PowerInit() {
static const pbus_mmio_t power_mmios[] = {{
.base = MT8167_PMIC_WRAP_BASE,
.length = MT8167_PMIC_WRAP_SIZE,
}};
pbus_dev_t power_dev = {};
power_dev.name = "power";
power_dev.vid = PDEV_VID_MEDIATEK;
power_dev.did = PDEV_DID_MEDIATEK_POWER;
power_dev.mmio_list = power_mmios;
power_dev.mmio_count = countof(power_mmios);
zx_status_t status = pbus_.ProtocolDeviceAdd(ZX_PROTOCOL_POWER_IMPL, &power_dev);
if (status != ZX_OK) {
zxlogf(ERROR, "%s: Adding power-impl device failed %d", __FUNCTION__, status);
return status;
}
status = DdkAddComposite("composite-pd-kVDLdoVGp2", &power_domain_kVDLdoVGp2_desc);
if (status != ZX_OK) {
zxlogf(ERROR, "%s: DdkAddComposite for power domain kVDLdoVGp2 failed: %d", __FUNCTION__,
status);
return status;
}
// Vgp1Enable() must be called before ThermalInit() as it uses the PMIC wrapper to enable the
// VGP1 regulator.
return Vgp1Enable();
}
} // namespace board_mt8167