This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Writing to RTC results in 10-15 frames loss in dm368 during encoding

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;
}