Imbrium Logo

How to use the Real Time Clock (RTC) on the uCdimm


Still an unfinished Document

Thank you very much to Daniel Haensse and others on the uclinux-dev mailing list for helping me getting this to work.

All paths here are relative to linux-2.4.x/

I don't know exactly how to get the internal RTC to function properly. I have done some coding but I still did not understand how to get the RTC into the kernel. Maybe someone could help me, please?! And also, I'm not using cvs so I don't have correct diffs.. Maybe I should, though?!

But anyway, this is what I did:

First, I added the following line in the file arch/m68knommu/config.in:

	if [ "$CONFIG_UCDIMM" = "y" ]; then
		define_bool CONFIG_UCBOOTSTRAP y
		bool '  Use uCbootstrap system calls' CONFIG_UCBOOTSTRAP
+		bool '  Use 128Hz instead of 100Hz timer for 32768kHz' CONFIG_DRAGONBALL_USE_RTC
	fi

There is a typo in the next part:

- bool 'Use 128HZ RTC scheduler instead of 100HZ timer1' CONFIG_DRAGONXBALL_USE_RTC
+ bool 'Use 128HZ RTC scheduler instead of 100HZ timer1' CONFIG_DRAGONBALL_USE_RTC

I added the following to include/asm-m68knommu/param.h:

#ifdef CONFIG_M68VZ328
#ifdef CONFIG_DRAGON2
#define HZ 128
#elif CONFIG_DRAGONBALL_USE_RTC
#define HZ 128
#else
#define HZ 100
#endif
#endif

Then I modified arch/m68knommu/platform/68VZ328/ucdimm/config.c and I don't know if this is all correct:

#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
#define CLOCK_PRE 7

/* sysclock / HZ / TPRER+1
   The PLL frequency is 32768 with a default multiplier of 2024
   which results in a PLL clock of 66.322 MHz, resulting in
   a clock freq of 33.161 MHz */
#define TICKS_PER_JIFFY 41451

static void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
{
#ifdef CONFIG_DRAGONBALL_USE_RTC
        /* Enable RTC in RTC control register (defined in asm/MC68VZ328.h) */
        RTCCTL |= RTCCTL_ENABLE;
        /* Enable 128 Hz interrupt line (defined in asm/MC68VZ328.h) */
        /* SAM5 == 0x2000 or 128Hz / 150.0000Hz interrupt enable */
        RTCIENR |= RTCIENR_SAM5;
        /* SAM_IRQ_NUM = Sampling timer for RTC */
        request_irq(SAM_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
#else
        TCTL = 0; /* disable timer 1 */
        /* set ISR */
        request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
        /* Restart mode, Enable int, Set clock source */
        TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
        TPRER = CLOCK_PRE;
        TCMP = TICKS_PER_JIFFY;
        TCTL |= TCTL_TEN;               /* Enable timer 1 */
#endif
}

static void BSP_tick(void)
{
#ifdef CONFIG_DRAGONBALL_USE_RTC
        RTCISR |= RTCISR_SAM5;
#else
        /* Reset Timer1 */
        TSTAT &= 0;
#endif
}

static unsigned long BSP_gettimeoffset(void)
{
#ifdef CONFIG_DRAGONBALL_USE_RTC
	return 0;
#else
	unsigned long ticks = TCN, offset = 0;

	/* check for pending interrupt */
	if (ticks < (TICKS_PER_JIFFY>>1) && (ISR & (1<<TMR_IRQ_NUM)))
		offset = 1000000/HZ;
	ticks = (ticks * 1000000/HZ) / TICKS_PER_JIFFY;
	return ticks + offset;
#endif
}

Now I did:

	make menuconfig
	[*] Customize Kernel Settings (NEW)
	exit exit save
	Processor type and features  --->
		[*] uCdimm module support
  	[*]   Use uCbootstrap system calls
  	[*]   Use 128Hz instead of 100Hz timer for 32768kHz
	exit exit save
	make dep
	make clean
	make