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