1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "hardware/interp.h"
8 #include "hardware/structs/sio.h"
9 #include "hardware/claim.h"
10 
11 check_hw_size(interp_hw_t, SIO_INTERP1_ACCUM0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET);
12 
13 check_hw_layout(sio_hw_t, interp, SIO_INTERP0_ACCUM0_OFFSET);
14 
15 static uint8_t _claimed;
16 
interp_lane_bit(interp_hw_t * interp,uint lane)17 static inline uint interp_lane_bit(interp_hw_t * interp, uint lane) {
18     return (interp_index(interp) << 1u) | lane;
19 }
20 
interp_claim_lane(interp_hw_t * interp,uint lane)21 void interp_claim_lane(interp_hw_t *interp, uint lane) {
22     valid_params_if(HARDWARE_INTERP, lane < 2);
23     hw_claim_or_assert((uint8_t *) &_claimed, interp_lane_bit(interp, lane), "Lane is already claimed");
24 }
25 
interp_claim_lane_mask(interp_hw_t * interp,uint lane_mask)26 void interp_claim_lane_mask(interp_hw_t *interp, uint lane_mask) {
27     valid_params_if(HARDWARE_INTERP, lane_mask && lane_mask <= 0x3);
28     if (lane_mask & 1u) interp_claim_lane(interp, 0);
29     if (lane_mask & 2u) interp_claim_lane(interp, 1);
30 }
31 
interp_unclaim_lane(interp_hw_t * interp,uint lane)32 void interp_unclaim_lane(interp_hw_t *interp, uint lane) {
33     valid_params_if(HARDWARE_INTERP, lane < 2);
34     hw_claim_clear((uint8_t *) &_claimed, interp_lane_bit(interp, lane));
35 }
36 
interp_lane_is_claimed(interp_hw_t * interp,uint lane)37 bool interp_lane_is_claimed(interp_hw_t *interp, uint lane) {
38     valid_params_if(HARDWARE_INTERP, lane < 2);
39     return hw_is_claimed((uint8_t *) &_claimed, interp_lane_bit(interp, lane));
40 }
41 
interp_unclaim_lane_mask(interp_hw_t * interp,uint lane_mask)42 void interp_unclaim_lane_mask(interp_hw_t *interp, uint lane_mask) {
43     valid_params_if(HARDWARE_INTERP, lane_mask <= 0x3);
44     if (lane_mask & 1u) interp_unclaim_lane(interp, 0);
45     if (lane_mask & 2u) interp_unclaim_lane(interp, 1);
46 }
47 
interp_save(interp_hw_t * interp,interp_hw_save_t * saver)48 void interp_save(interp_hw_t *interp, interp_hw_save_t *saver) {
49     saver->accum[0] = interp->accum[0];
50     saver->accum[1] = interp->accum[1];
51     saver->base[0] = interp->base[0];
52     saver->base[1] = interp->base[1];
53     saver->base[2] = interp->base[2];
54     saver->ctrl[0] = interp->ctrl[0];
55     saver->ctrl[1] = interp->ctrl[1];
56 }
57 
interp_restore(interp_hw_t * interp,interp_hw_save_t * saver)58 void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver) {
59     interp->accum[0] = saver->accum[0];
60     interp->accum[1] = saver->accum[1];
61     interp->base[0] = saver->base[0];
62     interp->base[1] = saver->base[1];
63     interp->base[2] = saver->base[2];
64     interp->ctrl[0] = saver->ctrl[0];
65     interp->ctrl[1] = saver->ctrl[1];
66 }
67