fw: use proper delay routines, adapt all delays

Because the Pirelli DP-L10 display initialization has very
strict timing requirements, implement compiler version agnostic
delay functions using inline assembly.

As it turned out, our delay routines always were way off:

delay_ms(1000) with GCC 4.8.2 was actually 400ms,
and with GCC 11.2.0 480ms were measured, the latter resulting
in the DP-L10 display not working anymore.

As the new routines now actually wait the time they should,
scale all existing delay times by 0.4 to get the same behavior
as previously with the old GCC version.
steve-m/trx_rebased
Steve Markgraf 2021-10-23 20:31:12 +02:00
parent c731c86b9b
commit 6c6c880a66
17 changed files with 64 additions and 39 deletions

View File

@ -178,7 +178,7 @@ uint16_t twl3025_reg_read(uint8_t reg)
/* A read cycle contains two SPI transfers */
spi_xfer(TWL3025_DEV_IDX, 16, &tx, &rx);
delay_ms(1);
delay_us(400);
spi_xfer(TWL3025_DEV_IDX, 16, &tx, &rx);
rx >>= 6;
@ -192,7 +192,7 @@ uint16_t twl3025_reg_read(uint8_t reg)
static void twl3025_wait_ibic_access(void)
{
/* Wait 6 * 32kHz clock cycles for first IBIC access (187us + 10% = 210us) */
delay_ms(1);
delay_us(400);
}
int twl3025_get_pwon(void)

View File

@ -69,7 +69,7 @@ static void flush_uart(void)
unsigned i;
for (i = 0; i < 500; i++) {
uart_poll(sercomm_uart);
delay_ms(1);
delay_us(400);
}
}

View File

@ -63,7 +63,7 @@ static void flush_uart(void)
unsigned i;
for (i = 0; i < 500; i++) {
uart_poll(sercomm_uart);
delay_ms(1);
delay_us(400);
}
}
@ -83,7 +83,7 @@ static void device_reset(void)
static void device_enter_loader(__unused unsigned char bootrom)
{
flush_uart();
delay_ms(2000);
delay_ms(800);
void (*entry)( void ) = (void (*)(void))0;
entry();
}

View File

@ -108,7 +108,7 @@ static void wait_key_release(void)
{
/* wait for key release */
while (key_state == PRESSED) {
delay_ms(10);
delay_ms(4);
keypad_poll();
}
}
@ -323,7 +323,7 @@ int main(void)
while (1) {
for (i = 0; i < 50; i++) {
keypad_poll();
delay_ms(10);
delay_ms(4);
osmo_timers_update();
handle_key_code();
}

View File

@ -285,7 +285,7 @@ void do_sim_test(void)
printf(" Result: ");
myHexdump(buffer,12);
delay_ms(5000);
delay_ms(2000);
calypso_sim_powerdown();

View File

@ -409,8 +409,8 @@ int main(void)
osmo_timers_update();
intro();
delay_ms(5000);
fb_clear_fancy(20);
delay_ms(2000);
fb_clear_fancy(8);
fb_setfg(FB_COLOR_BLACK);
fb_setbg(FB_COLOR_WHITE);

View File

@ -49,7 +49,7 @@ void pll_init(void)
writew(PLL_RST, MTK_PLL_PLL);
writew(0, MTK_PLL_PLL);
delay_ms(1);
delay_us(400);
/* Turn on PLL for MCU, DSP and USB */
writew(PLL_MPLLSEL_PLL | PLL_DPLLSEL | PLL_UPLLSEL, MTK_PLL_PLL);
@ -87,9 +87,9 @@ void memory_init(void)
for (i = 0; i < 5; ++i) {
/* Setup five single bits, one by one for DRAM init */
writel((1 << (24 + i)) | (0x400013), MTK_EMI_CONN);
delay_ms(1);
delay_us(400);
writel(0x400013, MTK_EMI_CONN);
delay_ms(1);
delay_us(400);
}
#if 0
@ -109,9 +109,9 @@ void memory_init(void)
for (i = 0; i < 5; ++i) {
/* Setup five single bits, one by one for DRAM init */
writel((1 << (24 + i)) | (0x500013), MTK_EMI_CONN);
delay_ms(1);
delay_us(400);
writel(0x500013, MTK_EMI_CONN);
delay_ms(1);
delay_us(400);
}
#endif

View File

@ -186,13 +186,13 @@ static void dsp_pre_boot(const struct dsp_section *bootcode)
writew(BL_STATUS_NA, BL_CMD_STATUS);
} else
delay_ms(10);
delay_ms(4);
dputs("Releasing DSP from Reset\n");
calypso_reset_set(RESET_DSP, 0);
/* Wait 10 us */
delay_ms(100);
delay_ms(40);
dsp_bl_wait_ready();
}
@ -650,7 +650,7 @@ static void _dsp_dump_range(uint32_t addr, uint32_t size, int mode)
while (bs--) {
/* FIXME workaround: small delay to prevent overflowing
* the sercomm buffer */
delay_ms(2);
delay_us(800);
if ((addr&15)==0)
printf("%05lx : ", addr);
printf("%04hx%c", *api++, ((addr&15)==15)?'\n':' ');

View File

@ -86,7 +86,7 @@ void calypso_sim_regdump(void)
#ifdef DEBUG
unsigned int regVal;
#define SIM_DEBUG_OUTPUTDELAY 200
#define SIM_DEBUG_OUTPUTDELAY 80
puts("\n\n\n");
puts("====================== CALYPSO SIM REGISTER DUMP =====================\n");

View File

@ -121,7 +121,7 @@ int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din)
break;
}
/* FIXME: calibrate how much delay we really need (seven 13MHz cycles) */
delay_ms(1);
delay_us(400);
if (din) {
tmp = readw(SPI_REG(REG_RX_MSB)) << 16;

View File

@ -291,7 +291,7 @@ void tpu_wait_idle(void)
{
dputs("Waiting for TPU Idle ");
/* Wait until TPU is doing something */
delay_us(3);
delay_us(1);
/* Wait until TPU is idle */
while (readw(TPU_REG(TPU_CTRL)) & TPU_CTRL_IDLE)
dputchar('.');

View File

@ -99,7 +99,7 @@ static void fb_s6b33b1x_send_cmdlist(const struct s6b33b1x_cmdlist *p)
static void fb_spca_write(uint16_t addr, uint16_t val)
{
writew(addr, nCS4_ADDR);
delay_ms(1);
delay_us(100);
writew(val , nCS4_ADDR | 2);
}
@ -109,15 +109,15 @@ static void fb_spca_init(void)
/* Initialize Sunplus SPCA552E Media Controller for bypass mode */
fb_spca_write(0x7e, 0x00); /* internal register access */
delay_ms(10);
delay_ms(4);
fb_spca_write(0x7a, 0x00); /* keep CPU in reset state */
delay_ms(10);
delay_ms(4);
fb_spca_write(0x7f, 0x00); /* select main page */
delay_ms(5);
delay_ms(2);
fb_spca_write(0x72, 0x07); /* don't reshape timing, 16 bit mode */
fb_spca_write(0x14, 0x03);
fb_spca_write(0x7f, 0x00); /* select main page */
delay_ms(5);
delay_ms(2);
fb_spca_write(0x06, 0xff);
fb_spca_write(0x7f, 0x09);
fb_spca_write(0x19, 0x08); /* backlight: 0x08 is on, 0x0c is off */

View File

@ -128,9 +128,9 @@ static void
fb_ssd1783_init(void){
printf("%s: initializing LCD.\n",__FUNCTION__);
calypso_reset_set(RESET_EXT, 0);
delay_ms(5);
delay_ms(2);
uwire_init();
delay_ms(5);
delay_ms(2);
fb_ssd1783_send_cmdlist(ssd1783_initdata);
}

View File

@ -126,9 +126,9 @@ static void
fb_ssd1963_init(void){
printf("%s: initializing LCD.\n",__FUNCTION__);
calypso_reset_set(RESET_EXT, 0);
delay_ms(5);
delay_ms(2);
uwire_init();
delay_ms(5);
delay_ms(2);
fb_ssd1963_send_cmdlist(ssd1963_initdata);
}

View File

@ -73,9 +73,9 @@ static void
fb_td014_init(void) {
printf("%s: initializing LCD.\n",__FUNCTION__);
calypso_reset_set(RESET_EXT, 0);
delay_ms(5);
delay_ms(2);
uwire_init();
delay_ms(5);
delay_ms(2);
fb_td014_send_cmdlist(td014_initdata);
}

View File

@ -147,7 +147,7 @@
/* 1 = SIM card insertion/extraction */
#define SIM_OPERATION_DELAY 100 /* Time between operations like reset, vcc apply ect... */
#define SIM_OPERATION_DELAY 40 /* Time between operations like reset, vcc apply etc... */
void calypso_sim_regdump(void); /* Display Register dump */

View File

@ -1,16 +1,41 @@
#include <delay.h>
/* FIXME: We need properly calibrated delay loops at some point! */
#define CALYPSO_CLK 52000000
#define CYCLES_PER_LOOP 4
#define COUNTS_PER_MS (CALYPSO_CLK / CYCLES_PER_LOOP) / 1000
#define COUNTS_PER_US COUNTS_PER_MS/1000
void delay_us(unsigned int us)
{
volatile unsigned int i;
unsigned int counts = COUNTS_PER_US * us;
for (i= 0; i < us*4; i++) { i; }
asm volatile
(
"mov r3, %[counts]\n\t"
"usloop:\n\t"
"subs r3, #1\n\t"
"bne usloop\n\t"
: /* we have no output, list empty */
: [counts] "r" (counts)
/* r3 and flags are clobbered */
: "r3", "cc"
);
}
void delay_ms(unsigned int ms)
{
volatile unsigned int i;
for (i= 0; i < ms*1300; i++) { i; }
unsigned int counts = COUNTS_PER_MS;
while (ms--) {
asm volatile
(
"mov r3, %[counts]\n\t"
"msloop:\n\t"
"subs r3, #1\n\t"
"bne msloop\n\t"
: /* we have no output, list empty */
: [counts] "r" (counts)
/* r3 and flags are clobbered */
: "r3", "cc"
);
}
}