Commit 26efd0f5 authored by Vikram Narayanan's avatar Vikram Narayanan

lcd/ixgbe: Add udelay/msleep support

msleep is just a wrapper around udelay, which is a tight loop. msleep must be
replaced with a real timer in the future
Signed-off-by: Vikram Narayanan's avatarVikram Narayanan <vikram186@gmail.com>
parent bae1379a
......@@ -222,9 +222,6 @@ static inline void force_up_write(void *x)
#undef might_fault
#define might_fault() do { } while(0)
#undef msleep
#define msleep(x) do { } while(0)
/*
* Copy to/from user
*/
......
......@@ -92,7 +92,8 @@ static int boot_main(void)
}
lcd_to_boot_info(ixgbe_ctx)->cptrs[0] = ixgbe_chnl_domain_cptr;
/* for udelay calculatio we need lpj inside LCD */
lcd_to_boot_info(ixgbe_ctx)->cptrs[1].cptr = this_cpu_read(cpu_info.loops_per_jiffy);
/* ---------- RUN! ---------- */
......
......@@ -133,4 +133,57 @@ bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp) { return true; }
struct pglist_data contig_page_data;
/* TODO: Move this to a common header, say arch/x86/include/asm/udelay.h
* As of now, lpj is passed by boot module to LCD. Devise a way to retrieve
* this during vtx container creation so that arch module can handle this
* seamlessly
*/
extern unsigned long loops_per_jiffy;
static void delay_loop(unsigned long loops)
{
asm volatile(
" test %0,%0 \n"
" jz 3f \n"
" jmp 1f \n"
".align 16 \n"
"1: jmp 2f \n"
".align 16 \n"
"2: dec %0 \n"
" jnz 2b \n"
"3: dec %0 \n"
: /* we don't need output */
:"a" (loops)
);
}
void __const_udelay(unsigned long xloops)
{
int d0;
xloops *= 4;
asm("mull %%edx"
:"=d" (xloops), "=&a" (d0)
:"1" (xloops), "0" (loops_per_jiffy * (HZ/4)));
delay_loop(++xloops);
}
/* XXX: Huh? Yeah, a tight loop for msleep is *ugly*. There is
* no way to enable timers inside LCD. Replace this with a real
* timer when such a support is added to LCDs.
*/
void msleep(unsigned int msecs)
{
udelay(msecs * 1000);
}
void __udelay(unsigned long usecs)
{
__const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
}
#endif /* IXGBE_STUB_H */
......@@ -21,6 +21,7 @@ int ixgbe_done = 0;
int ixgbe_init_module(void);
void ixgbe_exit_module(void);
extern int create_async_channel(void);
unsigned long loops_per_jiffy;
/* LOOP ---------------------------------------- */
......@@ -114,7 +115,10 @@ static int __noreturn ixgbe_lcd_init(void)
* Get the ixgbe channel cptr from boot info
*/
ixgbe_register_channel = lcd_get_boot_info()->cptrs[0];
loops_per_jiffy = lcd_get_boot_info()->cptrs[1].cptr;
printk("ixgbe reg channel %lu\n", ixgbe_register_channel.cptr);
printk("ixgbe lpj %lu\n", loops_per_jiffy);
/*
* Initialize ixgbe glue
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment