blob: 5e28fa55dff6fc72af5652bc0a9be6ed646e7b3c [file] [log] [blame]
// Copyright 2018 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 <lib/mmio/mmio.h>
#include <array>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/platform/bus.h>
#include <ddk/protocol/platform/device.h>
#include <fbl/algorithm.h>
#include <soc/mt8167/mt8167-hw.h>
#include "mt8167.h"
namespace {
constexpr size_t kNumberOfPolarityRegisters = 7;
constexpr uint32_t GetRegister(size_t offset) {
// 1 to invert from Low to High, 0 is either already High or a reserved interrupt
constexpr bool L = true;
constexpr bool H = false;
constexpr bool R = false;
// Start from interrupt 32 (first SPI after 32 PPIs). Interrupt 217 should be low-level triggered,
// despite what the datasheet says.
constexpr std::array<bool, kNumberOfPolarityRegisters* 32> spi_polarities = {
L, L, L, L, R, R, R, R, L, L, L, L, R, R, R, R, // 32 (first interrupt in the line).
L, L, L, L, R, R, R, R, L, L, L, L, R, R, R, R, // 48.
L, L, L, L, R, R, R, R, L, L, L, L, R, R, R, R, // 64.
L, R, L, L, L, L, R, R, R, R, R, R, R, R, R, L, // 80.
H, H, H, H, H, H, H, H, L, L, R, L, L, L, L, L, // 96.
L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, // 112.
L, L, L, L, L, L, L, L, L, H, H, L, H, L, L, L, // 128.
L, L, L, L, H, L, L, L, L, L, L, L, L, L, L, L, // 144.
L, L, L, L, L, H, H, L, L, L, L, L, L, L, L, L, // 160.
L, L, L, L, R, L, L, L, L, L, L, L, L, L, L, L, // 176.
L, R, L, L, L, L, L, L, L, L, R, L, L, L, L, L, // 192.
L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, R, // 208.
R, R, L, L, L, L, L, L, L, L, L, R, L, H, H, H, // 224.
H, L, L, L, R, R, L, H, H, H, H // 240 (first is 240, last is 250).
};
uint32_t temporary_register = 0;
for (size_t j = 0; j < 32; ++j) {
temporary_register |= static_cast<uint32_t>(spi_polarities[offset + j]) << j;
}
return temporary_register;
}
} // namespace
namespace board_mt8167 {
zx_status_t Mt8167::SocInit() {
zx_status_t status;
mmio_buffer_t mmio;
status =
mmio_buffer_init_physical(&mmio, MT8167_SOC_BASE, MT8167_SOC_SIZE,
// Please do not use get_root_resource() in new code. See ZX-1467.
get_root_resource(), ZX_CACHE_POLICY_UNCACHED_DEVICE);
if (status != ZX_OK) {
zxlogf(ERROR, "%s: mmio_buffer_init_physical failed %d ", __FUNCTION__, status);
return status;
}
ddk::MmioBuffer mmio2(mmio);
UpdateRegisters(std::move(mmio2));
return ZX_OK;
}
void Mt8167::UpdateRegisters(ddk::MmioBuffer mmio) {
// Convert Level interrupt polarity in SOC from Low to High as needed by gicv2.
for (size_t i = 0; i < kNumberOfPolarityRegisters; ++i) {
// 32 interrupts per register, one register every 4 bytes.
mmio.Write32(GetRegister(i * 32), MT8167_SOC_INT_POL + i * 4);
}
}
} // namespace board_mt8167