我按照i.MX 6Dual/6Quad Applications Processor Reference Manual的说明自己做了块板,目前已调试过大多数功能,它们都是OK的。现在我开始调RTC。imx6q上的D9和C9之间的32.768的晶振已正常起振,同时G11脚上的VSNVS_3V0在断电的时候是2.8V,上电的时候是3.0V。
我认为目前的状况表示RTC应该是正确并可以工作的,我使用其它的RTC芯片,都是这个模式。
但现在,在我启动系统后,linux中的系统时间总是从1970年开始。
我再系统中使用hwclock --show命令,系统打印内容如下
root@freescale /$ hwclock --show
Thu Jan 1 00:00:00 1970 0.000000 seconds
我使用hwclock --systohc
root@freescale /$ hwclock --systohc
系统貌似进入死循环。
在内核编译的时候,我选择的RTC驱动是Freescale SNVS Real Time Clock。
在调试中,我进入驱动,增加了下面的打印语句
static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct rtc_drv_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
printk("***************snvs_rtc_read_time is %x\n",rtc_read_lp_counter(ioaddr + SNVS_LPSRTCMR));
rtc_time_to_tm(rtc_read_lp_counter(ioaddr + SNVS_LPSRTCMR), tm);
return 0;
}
打印出的rtc_read_lp_counter(ioaddr + SNVS_LPSRTCMR));总是为0
我接着修改如下
static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct rtc_drv_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
unsigned long time;
int ret;
u32 lp_cr,lp_lr;
u64 old_time_47bit, new_time_47bit;
printk("*****************snvs_rtc_set_time\n");
ret = rtc_tm_to_time(tm, &time);
if (ret != 0)
return ret;
old_time_47bit = (((u64) (__raw_readl(ioaddr + SNVS_LPSRTCMR) &
((0x1 << CNTR_TO_SECS_SH) - 1)) << 32) |
((u64) __raw_readl(ioaddr + SNVS_LPSRTCLR)));
lp_lr = __raw_readl(ioaddr + SNVS_LPLR);
printk("********LPLR is %x\n",lp_lr);
lp_lr = lp_lr | SNVS_LPLR_SRTC_HR;
__raw_writel(lp_lr, ioaddr + SNVS_LPLR);
/* Disable RTC first */
lp_cr = __raw_readl(ioaddr + SNVS_LPCR) & ~SNVS_LPCR_SRTC_ENV;
__raw_writel(lp_cr, ioaddr + SNVS_LPCR);
printk("***************************write en is here\n");
while (__raw_readl(ioaddr + SNVS_LPCR) & SNVS_LPCR_SRTC_ENV)
;
/* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
__raw_writel(time << CNTR_TO_SECS_SH, ioaddr + SNVS_LPSRTCLR);
__raw_writel(time >> (32 - CNTR_TO_SECS_SH), ioaddr + SNVS_LPSRTCMR);
/* Enable RTC again */
__raw_writel(lp_cr | SNVS_LPCR_SRTC_ENV, ioaddr + SNVS_LPCR);
while (!(__raw_readl(ioaddr + SNVS_LPCR) & SNVS_LPCR_SRTC_ENV));
lp_lr = __raw_readl(ioaddr + SNVS_LPLR);
printk("********LPLR is %x\n",lp_lr);
lp_lr = lp_lr | SNVS_LPLR_SRTC_HR;
__raw_writel(lp_lr, ioaddr + SNVS_LPLR);
printk("********************************rtc_write_sync_lp\n");
rtc_write_sync_lp(ioaddr);
printk("**********************is work\n");
new_time_47bit = (((u64) (__raw_readl(ioaddr + SNVS_LPSRTCMR) &
((0x1 << CNTR_TO_SECS_SH) - 1)) << 32) |
((u64) __raw_readl(ioaddr + SNVS_LPSRTCLR)));
time_diff = new_time_47bit - old_time_47bit;
/* signal all waiting threads that time changed */
complete_all(&snvs_completion);
/* allow signalled threads to handle the time change notification */
schedule();
/* reinitialize completion variable */
INIT_COMPLETION(snvs_completion);
return 0;
}
发现程序在
while (__raw_readl(ioaddr + SNVS_LPCR) & SNVS_LPCR_SRTC_ENV)
;
这一行进入死循环。
求大神指教。
|