summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWael El-Essawy <welessa@us.ibm.com>2015-10-28 09:58:33 -0500
committerWael Elessawy <welessa@us.ibm.com>2015-11-02 10:27:44 -0600
commitb780668c24b267b1831b411a8f30fa3ae98ba10a (patch)
tree7a96f430587868c3dd5e12af13169fd85b3a52b8
parentccc93c5fdd656234785249a0662a8e8c485963a6 (diff)
downloadtalos-occ-b780668c24b267b1831b411a8f30fa3ae98ba10a.tar.gz
talos-occ-b780668c24b267b1831b411a8f30fa3ae98ba10a.zip
busy_wait based on decrementer values inside interrupts.
Change-Id: Iceba2e502420cd03e173edfa7740c6539e120264 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/21562 Reviewed-by: Wael Elessawy <welessa@us.ibm.com> Tested-by: Wael Elessawy <welessa@us.ibm.com>
-rw-r--r--src/occ_gpe0/apss_util.c34
-rw-r--r--src/occ_gpe0/apss_util.h8
2 files changed, 36 insertions, 6 deletions
diff --git a/src/occ_gpe0/apss_util.c b/src/occ_gpe0/apss_util.c
index 2a78561..04e9879 100644
--- a/src/occ_gpe0/apss_util.c
+++ b/src/occ_gpe0/apss_util.c
@@ -115,17 +115,39 @@ int wait_spi_completion(GpeErrorStruct *error, uint32_t reg, uint8_t timeout)
* End Function Specification
*/
-// result based on busy_wait(1) calibration against pk_sleep(1)
-#define BUSY_LOOP_CONSTANT 71
void busy_wait(uint32_t t_microseconds)
{
int j;
volatile uint32_t i;
-// ppe42_mullw macro works fine, but compiler parameter settings seems broken, use nested loop instead
-// int loop = t * 100; // Assuming loop iteration takes 6 ppe cycles = 0.01 microseconds
- for(j = 0; j < BUSY_LOOP_CONSTANT; j++)
- for(i = 0; i < t_microseconds; i++);
+ uint32_t start_decrementer_value; // The decrementer register value at the beginning
+ uint32_t end_decrementer_value; // The decrementer register value at the end
+ uint32_t current_decrementer_value; // The current decrementer register value
+ uint32_t duration;
+ MFDEC(start_decrementer_value); // get the decrementer register value at the beginning
+ current_decrementer_value = start_decrementer_value;
+
+ // multiply the delay time by the 37.5 MHz external clock frequency.
+ // I believe that the ppe42_mullw macro works fine, but the
+ // compiler parameter settings seems broken.
+ // @todo: This is a temporary fix, use external frequency directive.
+ duration = (t_microseconds << 5)
+ + (t_microseconds << 2)
+ + (t_microseconds)
+ + (t_microseconds >> 1);
+
+ // Calculate the decrementer register value at the end of the busy wait period
+ end_decrementer_value = start_decrementer_value - duration;
+
+ if(start_decrementer_value < end_decrementer_value); // decrementer overflows during the busy wait?
+ {
+ MFDEC(current_decrementer_value);
+ while(current_decrementer_value < end_decrementer_value) // Wait until Decrementer overflows
+ MFDEC(current_decrementer_value);
+ }
+
+ while (current_decrementer_value > end_decrementer_value) // Wait until end_decrementer_value is reached
+ MFDEC(current_decrementer_value);
}
diff --git a/src/occ_gpe0/apss_util.h b/src/occ_gpe0/apss_util.h
index 1f7a76c..1c53cde 100644
--- a/src/occ_gpe0/apss_util.h
+++ b/src/occ_gpe0/apss_util.h
@@ -8,4 +8,12 @@ void apss_set_ffdc(GpeErrorStruct *o_error, uint32_t i_addr, uint32_t i_rc, uint
int wait_spi_completion(GpeErrorStruct *error, uint32_t reg, uint8_t timeout);
+// Read decrementer register
+#define MFDEC(reg_var) \
+asm volatile \
+ ( \
+ " mfdec %[dec_var] \n" \
+ : [dec_var]"=r"(reg_var) \
+ );
+
#endif //_APSS_UTIL_H
OpenPOWER on IntegriCloud