| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| |
| <%doc> |
| This file is the "auto-generated DIF library implementation template", which |
| provides implementations of some mandatory DIFs that are similar across all |
| IPs. When rendered, this template implements the DIFs defined in the |
| auto-generated DIF header file (see util/make_new_dif/dif_autogen.inc.tpl). |
| |
| Note, this template requires the following Python objects to be passed: |
| |
| 1. ip: See util/make_new_dif.py for the definition of the `ip` obj. |
| 2. list[irq]: See util/make_new_dif.py for the definition of the `irq` obj. |
| </%doc> |
| |
| <%def name="mmio_region_read32(intr_reg_upper)">mmio_region_read32( |
| ${ip.name_snake}->base_addr, |
| ${ip.name_upper}_INTR_${intr_reg_upper}_REG_OFFSET); |
| </%def> |
| |
| <%def name="mmio_region_write32(intr_reg_upper, value)">mmio_region_write32( |
| ${ip.name_snake}->base_addr, |
| ${ip.name_upper}_INTR_${intr_reg_upper}_REG_OFFSET, |
| ${value}); |
| </%def> |
| |
| // This file is auto-generated. |
| |
| #include "sw/device/lib/dif/dif_${ip.name_snake}.h" |
| |
| #include "${ip.name_snake}_regs.h" // Generated. |
| |
| % if len(irqs) > 0: |
| |
| /** |
| * Get the corresponding interrupt register bit offset. INTR_STATE, |
| * INTR_ENABLE and INTR_TEST registers have the same bit offsets, so this |
| * routine can be reused. |
| */ |
| static bool ${ip.name_snake}_get_irq_bit_index( |
| dif_${ip.name_snake}_irq_t irq, |
| bitfield_bit32_index_t *index_out) { |
| |
| switch (irq) { |
| % for irq in irqs: |
| ## This handles the GPIO IP case where there is a multi-bit interrupt. |
| % if irq.width > 1: |
| % for irq_idx in range(irq.width): |
| case kDif${ip.name_camel}Irq${irq.name_camel}${irq_idx}: |
| *index_out = ${irq_idx}; |
| break; |
| % endfor |
| ## This handles all other IPs. |
| % else: |
| case kDif${ip.name_camel}Irq${irq.name_camel}: |
| *index_out = ${ip.name_upper}_INTR_STATE_${irq.name_upper}_BIT; |
| break; |
| % endif |
| % endfor |
| default: |
| return false; |
| } |
| |
| return true; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_get_state( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| dif_${ip.name_snake}_irq_state_snapshot_t *snapshot) { |
| |
| if (${ip.name_snake} == NULL || snapshot == NULL) { |
| return kDifBadArg; |
| } |
| |
| *snapshot = ${mmio_region_read32("STATE")} |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_is_pending( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| dif_${ip.name_snake}_irq_t irq, |
| bool *is_pending) { |
| |
| if (${ip.name_snake} == NULL || is_pending == NULL) { |
| return kDifBadArg; |
| } |
| |
| bitfield_bit32_index_t index; |
| if (!${ip.name_snake}_get_irq_bit_index(irq, &index)) { |
| return kDifBadArg; |
| } |
| |
| uint32_t intr_state_reg = ${mmio_region_read32("STATE")} |
| *is_pending = bitfield_bit32_read(intr_state_reg, index); |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_acknowledge( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| dif_${ip.name_snake}_irq_t irq) { |
| |
| if (${ip.name_snake} == NULL) { |
| return kDifBadArg; |
| } |
| |
| bitfield_bit32_index_t index; |
| if (!${ip.name_snake}_get_irq_bit_index(irq, &index)) { |
| return kDifBadArg; |
| } |
| |
| // Writing to the register clears the corresponding bits (Write-one clear). |
| uint32_t intr_state_reg = bitfield_bit32_write(0, index, true); |
| ${mmio_region_write32("STATE", "intr_state_reg")} |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_force( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| dif_${ip.name_snake}_irq_t irq) { |
| |
| if (${ip.name_snake} == NULL) { |
| return kDifBadArg; |
| } |
| |
| bitfield_bit32_index_t index; |
| if (!${ip.name_snake}_get_irq_bit_index(irq, &index)) { |
| return kDifBadArg; |
| } |
| |
| uint32_t intr_test_reg = bitfield_bit32_write(0, index, true); |
| ${mmio_region_write32("TEST", "intr_test_reg")} |
| |
| return kDifOk; |
| } |
| |
| % if ip.name_snake != "aon_timer": |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_get_enabled( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| dif_${ip.name_snake}_irq_t irq, |
| dif_toggle_t *state) { |
| |
| if (${ip.name_snake} == NULL || state == NULL) { |
| return kDifBadArg; |
| } |
| |
| bitfield_bit32_index_t index; |
| if (!${ip.name_snake}_get_irq_bit_index(irq, &index)) { |
| return kDifBadArg; |
| } |
| |
| uint32_t intr_enable_reg = ${mmio_region_read32("ENABLE")} |
| bool is_enabled = bitfield_bit32_read(intr_enable_reg, index); |
| *state = is_enabled ? |
| kDifToggleEnabled : kDifToggleDisabled; |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_set_enabled( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| dif_${ip.name_snake}_irq_t irq, |
| dif_toggle_t state) { |
| |
| if (${ip.name_snake} == NULL) { |
| return kDifBadArg; |
| } |
| |
| bitfield_bit32_index_t index; |
| if (!${ip.name_snake}_get_irq_bit_index(irq, &index)) { |
| return kDifBadArg; |
| } |
| |
| uint32_t intr_enable_reg = ${mmio_region_read32("ENABLE")} |
| bool enable_bit = (state == kDifToggleEnabled) ? true : false; |
| intr_enable_reg = bitfield_bit32_write(intr_enable_reg, index, enable_bit); |
| ${mmio_region_write32("ENABLE", "intr_enable_reg")} |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_disable_all( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| dif_${ip.name_snake}_irq_enable_snapshot_t *snapshot) { |
| |
| if (${ip.name_snake} == NULL) { |
| return kDifBadArg; |
| } |
| |
| // Pass the current interrupt state to the caller, if requested. |
| if (snapshot != NULL) { |
| *snapshot = ${mmio_region_read32("ENABLE")} |
| } |
| |
| // Disable all interrupts. |
| ${mmio_region_write32("ENABLE", "0u")} |
| |
| return kDifOk; |
| } |
| |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_${ip.name_snake}_irq_restore_all( |
| const dif_${ip.name_snake}_t *${ip.name_snake}, |
| const dif_${ip.name_snake}_irq_enable_snapshot_t *snapshot) { |
| |
| if (${ip.name_snake} == NULL || snapshot == NULL) { |
| return kDifBadArg; |
| } |
| |
| ${mmio_region_write32("ENABLE", "*snapshot")} |
| |
| return kDifOk; |
| } |
| % endif |
| |
| % endif |