Software APIs
soc_proxy_gpios.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
7 #include "sw/device/lib/dif/dif_soc_proxy.h"
8 #include "sw/device/lib/runtime/irq.h"
11 #include "sw/device/lib/testing/test_framework/status.h"
12 
13 #include "hw/top_darjeeling/sw/autogen/top_darjeeling.h"
14 
15 OTTF_DEFINE_TEST_CONFIG();
16 
17 bool test_main(void) {
18  dif_pinmux_t pinmux;
19  dif_rv_plic_t rv_plic;
20  dif_soc_proxy_t soc_proxy;
21  CHECK_DIF_OK(dif_pinmux_init(
22  mmio_region_from_addr(TOP_DARJEELING_PINMUX_AON_BASE_ADDR), &pinmux));
23  CHECK_DIF_OK(dif_rv_plic_init(
24  mmio_region_from_addr(TOP_DARJEELING_RV_PLIC_BASE_ADDR), &rv_plic));
25  CHECK_DIF_OK(dif_soc_proxy_init(
26  mmio_region_from_addr(TOP_DARJEELING_SOC_PROXY_CORE_BASE_ADDR),
27  &soc_proxy));
28 
29  // Enable external IRQs in Ibex.
30  irq_external_ctrl(true);
31 
32  // Enable IRQ0 in SoC Proxy and PLIC.
33  const dif_soc_proxy_irq_t soc_proxy_irq = 0;
34  const dif_rv_plic_irq_id_t rv_plic_irq =
35  kTopDarjeelingPlicIrqIdSocProxyExternal0;
36  const dif_rv_plic_target_t rv_plic_target = kTopDarjeelingPlicTargetIbex0;
37  CHECK_DIF_OK(dif_soc_proxy_irq_set_enabled(&soc_proxy, soc_proxy_irq,
39  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(&rv_plic, rv_plic_irq, 1));
40  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(&rv_plic, rv_plic_irq,
41  rv_plic_target, kDifToggleEnabled));
42 
43  // Map muxable SoC GPIs in pinmux.
44  top_darjeeling_pinmux_peripheral_in_t peripheral_in[] = {
45  kTopDarjeelingPinmuxPeripheralInSocProxySocGpi12,
46  kTopDarjeelingPinmuxPeripheralInSocProxySocGpi13,
47  kTopDarjeelingPinmuxPeripheralInSocProxySocGpi14,
48  kTopDarjeelingPinmuxPeripheralInSocProxySocGpi15,
49  };
50  top_darjeeling_pinmux_insel_t insel[] = {
51  kTopDarjeelingPinmuxInselMio4,
52  kTopDarjeelingPinmuxInselMio5,
53  kTopDarjeelingPinmuxInselMio6,
54  kTopDarjeelingPinmuxInselMio7,
55  };
56  static_assert(ARRAYSIZE(peripheral_in) == ARRAYSIZE(insel),
57  "Illegal pinmux input configuration arrays!");
58  for (size_t i = 0; i < ARRAYSIZE(peripheral_in); i++) {
59  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux, peripheral_in[i], insel[i]));
60  }
61  LOG_INFO("Muxable SoC GPIs mapped.");
62 
63  // Wait for interrupt through which DV signals the switch to muxable GPOs.
64  unsigned try_num = 0;
65  while (true) {
66  if (try_num > 10) {
67  LOG_ERROR("Exceeded allowed number of unexpected IRQs!");
68  return false;
69  }
70 
72  bool soc_proxy_irq_pending, rv_plic_irq_pending;
73  CHECK_DIF_OK(dif_soc_proxy_irq_is_pending(&soc_proxy, soc_proxy_irq,
74  &soc_proxy_irq_pending));
75  CHECK_DIF_OK(dif_rv_plic_irq_is_pending(&rv_plic, rv_plic_irq,
76  &rv_plic_irq_pending));
77  if (soc_proxy_irq_pending && rv_plic_irq_pending) {
78  break;
79  }
80 
81  try_num++;
82  }
83 
84  // Acknowledge and complete IRQ.
85  CHECK_DIF_OK(dif_soc_proxy_irq_acknowledge(&soc_proxy, soc_proxy_irq));
86  CHECK_DIF_OK(dif_rv_plic_irq_complete(&rv_plic, rv_plic_target, rv_plic_irq));
87 
88  // Disable IRQ in PLIC and SoC Proxy.
89  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(&rv_plic, rv_plic_irq,
90  rv_plic_target, kDifToggleDisabled));
91  CHECK_DIF_OK(dif_soc_proxy_irq_set_enabled(&soc_proxy, soc_proxy_irq,
93 
94  // Disable external IRQs in Ibex.
95  irq_external_ctrl(false);
96 
97  // Map muxable SoC GPOs in pinmux.
98  top_darjeeling_pinmux_mio_out_t mio_out[] = {
99  kTopDarjeelingPinmuxMioOutMio4,
100  kTopDarjeelingPinmuxMioOutMio5,
101  kTopDarjeelingPinmuxMioOutMio6,
102  kTopDarjeelingPinmuxMioOutMio7,
103  };
104  top_darjeeling_pinmux_outsel_t outsel[] = {
105  kTopDarjeelingPinmuxOutselSocProxySocGpo12,
106  kTopDarjeelingPinmuxOutselSocProxySocGpo13,
107  kTopDarjeelingPinmuxOutselSocProxySocGpo14,
108  kTopDarjeelingPinmuxOutselSocProxySocGpo15,
109  };
110  static_assert(ARRAYSIZE(mio_out) == ARRAYSIZE(outsel),
111  "Illegal pinmux output configuration arrays!");
112  for (size_t i = 0; i < ARRAYSIZE(mio_out); i++) {
113  CHECK_DIF_OK(dif_pinmux_output_select(&pinmux, mio_out[i], outsel[i]));
114  }
115  LOG_INFO("Muxable SoC GPOs mapped.");
116 
117  return true;
118 }