A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

Coldfire: Optimize emac context save/restore in mixer ISR.

Save only once if emac is used in ISR and restore only once per ISR
call if already saved.

Change-Id: I0e40db5d4aab2a8552480f76873f59ff6ccd9977
Reviewed-on: http://gerrit.rockbox.org/176
Tested-by: Michael Sevakis <jethead71@rockbox.org>
Reviewed-by: Michael Sevakis <jethead71@rockbox.org>

+39 -24
+32 -24
firmware/asm/m68k/pcm-mixer.c
··· 23 23 #define MIXER_OPTIMIZED_WRITE_SAMPLES 24 24 static struct emac_context 25 25 { 26 + unsigned long saved; 26 27 unsigned long r[4]; 27 28 } emac_context IBSS_ATTR; 28 29 29 30 /* Save emac context affected in ISR */ 30 31 static FORCE_INLINE void save_emac_context(void) 31 32 { 32 - asm volatile ( 33 - "move.l %%macsr, %%d0 \n" 34 - "move.l %%accext01, %%d1 \n" 35 - "movclr.l %%acc0, %%a0 \n" 36 - "movclr.l %%acc1, %%a1 \n" 37 - "movem.l %%d0-%%d1/%%a0-%%a1, (%0) \n" 38 - : 39 - : "a"(&emac_context) 40 - : "d0", "d1", "a0", "a1"); 33 + /* Save only if not already saved */ 34 + if (emac_context.saved == 0) 35 + { 36 + emac_context.saved = 1; 37 + asm volatile ( 38 + "move.l %%macsr, %%d0 \n" 39 + "move.l %%accext01, %%d1 \n" 40 + "movclr.l %%acc0, %%a0 \n" 41 + "movclr.l %%acc1, %%a1 \n" 42 + "movem.l %%d0-%%d1/%%a0-%%a1, (%0) \n" 43 + "move.l %1, %%macsr \n" 44 + : 45 + : "a"(&emac_context.r), "i"(EMAC_ROUND | EMAC_SATURATE) 46 + : "d0", "d1", "a0", "a1"); 47 + } 41 48 } 42 49 43 50 /* Restore emac context affected in ISR */ 44 51 static FORCE_INLINE void restore_emac_context(void) 45 52 { 46 - asm volatile ( 47 - "movem.l (%0), %%d0-%%d1/%%a0-%%a1 \n" 48 - "move.l %%a1, %%acc1 \n" 49 - "move.l %%a0, %%acc0 \n" 50 - "move.l %%d1, %%accext01 \n" 51 - "move.l %%d0, %%macsr \n" 52 - : 53 - : "a"(&emac_context) 54 - : "d0", "d1", "a0", "a1"); 53 + /* Restore only if saved */ 54 + if (UNLIKELY(emac_context.saved != 0)) 55 + { 56 + asm volatile ( 57 + "movem.l (%0), %%d0-%%d1/%%a0-%%a1 \n" 58 + "move.l %%a1, %%acc1 \n" 59 + "move.l %%a0, %%acc0 \n" 60 + "move.l %%d1, %%accext01 \n" 61 + "move.l %%d0, %%macsr \n" 62 + : 63 + : "a"(&emac_context.r) 64 + : "d0", "d1", "a0", "a1"); 65 + emac_context.saved = 0; 66 + } 55 67 } 56 68 69 + #define mixer_buffer_callback_exit() restore_emac_context() 70 + 57 71 /* Mix channels' samples and apply gain factors */ 58 72 static FORCE_INLINE void mix_samples(void *out, 59 73 const void *src0, ··· 64 78 { 65 79 uint32_t s0, s1, s2, s3; 66 80 save_emac_context(); 67 - coldfire_set_macsr(EMAC_ROUND | EMAC_SATURATE); 68 81 69 82 asm volatile ( 70 83 "move.l (%1)+, %5 \n" ··· 88 101 "=&a"(s0), "=&d"(s1), "=&d"(s2), "=&d"(s3) 89 102 : "r"(src0_amp), "r"(src1_amp), "d"(16) 90 103 ); 91 - 92 - restore_emac_context(); 93 104 } 94 105 95 106 /* Write channel's samples and apply gain factor */ ··· 108 119 /* Channel needs amplitude cut */ 109 120 uint32_t s0, s1, s2, s3; 110 121 save_emac_context(); 111 - coldfire_set_macsr(EMAC_ROUND | EMAC_SATURATE); 112 122 113 123 asm volatile ( 114 124 "move.l (%1)+, %4 \n" ··· 128 138 "=&a"(s0), "=&d"(s1), "=&d"(s2), "=&d"(s3) 129 139 : "r"(amp), "d"(16) 130 140 ); 131 - 132 - restore_emac_context(); 133 141 } 134 142 }
+4
firmware/asm/pcm-mixer.c
··· 109 109 110 110 111 111 #endif /* CPU_* */ 112 + 113 + #ifndef mixer_buffer_callback_exit 114 + #define mixer_buffer_callback_exit() do{}while(0) 115 + #endif
+3
firmware/pcm_mixer.c
··· 232 232 *downmix_buf[downmix_index] = downmix_index ? 0x7fff7fff : 0x80008000; 233 233 #endif 234 234 235 + /* Certain SoC's have to do cleanup */ 236 + mixer_buffer_callback_exit(); 237 + 235 238 return PCM_DMAST_OK; 236 239 } 237 240