1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/debug.h>
6 #include <ddk/device.h>
7 #include <ddk/platform-defs.h>
8 #include <ddk/protocol/platform/bus.h>
9 #include <ddk/protocol/platform/device.h>
10
11 #include <ddktl/mmio.h>
12
13 #include <fbl/algorithm.h>
14
15 #include <soc/mt8167/mt8167-hw.h>
16
17 #include "mt8167.h"
18
19 namespace board_mt8167 {
20
SocInit()21 zx_status_t Mt8167::SocInit() {
22 zx_status_t status;
23 mmio_buffer_t mmio;
24 status = mmio_buffer_init_physical(&mmio, MT8167_SOC_BASE, MT8167_SOC_SIZE,
25 get_root_resource(), ZX_CACHE_POLICY_UNCACHED_DEVICE);
26 if (status != ZX_OK) {
27 zxlogf(ERROR, "%s: mmio_buffer_init_physical failed %d \n", __FUNCTION__, status);
28 return status;
29 }
30 ddk::MmioBuffer mmio2(mmio);
31
32 // 1 to invert from Low to High, 0 is either already High or a reserved interrupt
33 static constexpr bool L = 1;
34 static constexpr bool H = 0;
35 static constexpr bool R = 0;
36
37 static const bool spi_polarities[] = {
38 L, L, L, L, R, R, R, R, L, L, L, L, R, R, R, R, // 32 (first interrupt in the line).
39 L, L, L, L, R, R, R, R, L, L, L, L, R, R, R, R, // 48.
40 L, L, L, L, R, R, R, R, L, L, L, L, R, R, R, R, // 64.
41 L, R, L, L, L, L, R, R, R, R, R, R, R, R, R, L, // 80.
42 H, H, H, H, H, H, H, H, L, L, R, L, L, L, L, L, // 96.
43 L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, // 112.
44 L, L, L, L, L, L, L, L, L, H, H, L, H, L, L, L, // 128.
45 L, L, L, L, H, L, L, L, L, L, L, L, L, L, L, L, // 144.
46 L, L, L, L, L, H, H, L, L, L, L, L, L, L, L, L, // 160.
47 L, L, L, L, R, L, L, L, L, L, L, L, L, L, L, L, // 176.
48 L, R, L, L, L, L, L, L, L, L, R, L, L, L, L, L, // 192.
49 L, L, L, L, L, L, L, L, L, H, L, L, L, L, L, R, // 208.
50 R, R, L, L, L, L, L, L, L, L, L, R, L, H, H, H, // 224.
51 H, L, L, L, R, R, L, H, H, H, H // 240 (first is 240, last is 250).
52 };
53
54 // Start from interrupt 32 (first SPI after 32 PPIs)
55 // Convert Level interrupt polarity in SOC from Low to High as needed by gicv2.
56 for (size_t i = 0; i < fbl::count_of(spi_polarities); ++i) {
57 // 32 interrupts per register, one register every 4 bytes.
58 mmio2.ModifyBit<uint32_t>(spi_polarities[i], i % 32, MT8167_SOC_INT_POL + i / 32 * 4);
59 }
60 return ZX_OK;
61 }
62
63 } // namespace board_mt8167
64