Hi,
Writing to RTC results in 10-15 frames loss in dm368 using appro sdk 2.6 during single encoding in h264 at 720@P25.
You can test it by using the cmd line "hwclock -w ". This command results in loss of frames during encoding.
I had a look at the driver of rtc "ti-davinci/drivers/rtc/rtc-davinci-dm365.c". The Interrupts are disabled during the write/read from rtc and there is also a busy wait during write/read to rtc . Please have a look at source code below from the linux drivers for reference.
Is there any way we can avoid this by fixing in the drivers ?.
We have to update the rtc every 8hrs depends on the drift between system clock and the rtc. It is not nice to loose 10 frames every 8 hrs.
#define rtcif_read(addr) __raw_readl( \
(unsigned int *)((u32)dm365_rtc_base + (u32)(addr)))
#define rtcif_write(val, addr) __raw_writel(val, \
(unsigned int *)((u32)dm365_rtc_base + (u32)(addr)))
static DEFINE_SPINLOCK(dm365_rtc_lock);
static void __iomem *dm365_rtc_base;
static resource_size_t dm365_rtc_pbase;
static size_t dm365_rtc_base_size;
static int dm365_rtc_irq;
/* platform_bus isn't hotpluggable, so for static linkage it'd be safe
* to get rid of probe() and remove() code ... too bad the driver struct
* remembers probe(), that's about 25% of the runtime footprint!!
*/
#ifndef MODULE
#undef __devexit
#undef __devexit_p
#define __devexit __exit
#define __devexit_p __exit_p
#endif
void rtcss_wait_busy(void)
{
unsigned int count = 0;
while ((rtcif_read(DM365_RTCIF_DMA_CMD_REG)
& DM365_RTCIF_DMA_CMD_BUSY) != 0)
{
if(count++>20000)
{
break;
}
}
if(count>20000)
printk("rtc wait time out !!!!!\r\n");
}
static int rtcss_write_rtc(unsigned long val, u8 addr)
{
unsigned int cmd;
// while (rtcif_read(DM365_RTCIF_DMA_CMD_REG) & DM365_RTCIF_DMA_CMD_BUSY);
rtcss_wait_busy();
rtcif_write(DM365_RTCIF_INT_ENA_RTCSS_INTENA |
DM365_RTCIF_INT_ENA_RTCIF_INTENA, DM365_RTCIF_INT_FLG_REG);
cmd = DM365_RTCIF_DMA_CMD_BYTEENA0_LSB | addr;
rtcif_write(cmd, DM365_RTCIF_DMA_CMD_REG);
rtcif_write(val, DM365_RTCIF_DMA_DATA0_REG);
// while (rtcif_read(DM365_RTCIF_DMA_CMD_REG) & DM365_RTCIF_DMA_CMD_BUSY);
rtcss_wait_busy();
return rtcif_read(DM365_RTCIF_INT_FLG_REG);
}
static int dm365_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
u16 days;
u8 new_cctrl;
unsigned long flags;
if (convert2days(&days, tm) < 0)
return -EINVAL;
spin_lock_irqsave(&dm365_rtc_lock, flags);
while (rtcss_read_rtc(RTCSS_RTC_CCTRL_REG) & RTCSS_RTC_CCTRL_CALBUSY) ;
rtcss_write_rtc(BIN2BCD(tm->tm_sec), RTCSS_RTC_SEC_REG);
while (rtcss_read_rtc(RTCSS_RTC_CCTRL_REG) & RTCSS_RTC_CCTRL_CALBUSY) ;
rtcss_write_rtc(BIN2BCD(tm->tm_min), RTCSS_RTC_MIN_REG);
while (rtcss_read_rtc(RTCSS_RTC_CCTRL_REG) & RTCSS_RTC_CCTRL_CALBUSY) ;
rtcss_write_rtc(BIN2BCD(tm->tm_hour), RTCSS_RTC_HOUR_REG);
while (rtcss_read_rtc(RTCSS_RTC_CCTRL_REG) & RTCSS_RTC_CCTRL_CALBUSY) ;
rtcss_write_rtc(days & 0xFF, RTCSS_RTC_DAY0_REG);
while (rtcss_read_rtc(RTCSS_RTC_CCTRL_REG) & RTCSS_RTC_CCTRL_CALBUSY) ;
rtcss_write_rtc((days & 0xFF00) >> 8, RTCSS_RTC_DAY1_REG);
new_cctrl = rtcss_read_rtc(RTCSS_RTC_CCTRL_REG);
new_cctrl |= RTCSS_RTC_CCTRL_CAEN;
rtcss_write_rtc(new_cctrl, RTCSS_RTC_CCTRL_REG);
spin_unlock_irqrestore(&dm365_rtc_lock, flags);
return 0;
}