File indexing completed on 2025-05-11 08:22:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <bspopts.h>
0019
0020 #if IS_AM335X
0021 #include <rtems.h>
0022 #include <bsp.h>
0023 #include <time.h>
0024 #include <libchip/rtc.h>
0025 #include <libcpu/omap3.h>
0026
0027 #define setbit(a,x) (a | (1<<x))
0028 #define bcd(a) ((a & 0x0f)+ (((a & 0xf0) >> 4 )*10))
0029 #define dec(a) (((a / 10) << 4) | (a % 10))
0030 #define WRITE_WAIT_MAX_COUNT 10000
0031
0032 size_t RTC_Count = 1;
0033
0034 static void rtc_write_enable(void);
0035 static void rtc_write_disable(void);
0036 static int rtc_write_wait(void);
0037 static void rtc_clk_init(void);
0038 void rtc_init(int minor);
0039 void print_time(void);
0040 int am335x_rtc_gettime(int minor,rtems_time_of_day *t);
0041 int am335x_rtc_settime(int minor, const rtems_time_of_day *t);
0042 void am335x_rtc_debug(void);
0043
0044
0045
0046
0047 static bool am335x_rtc_probe (int minor)
0048 {
0049 return true;
0050 }
0051
0052
0053
0054
0055 static void rtc_write_enable(void)
0056 {
0057 mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,AM335X_RTC_KICK0_KEY);
0058 mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,AM335X_RTC_KICK1_KEY);
0059 }
0060
0061
0062
0063
0064 static void rtc_write_disable(void)
0065 {
0066
0067 mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,0x11111111);
0068 mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,0x11111111);
0069 }
0070
0071
0072
0073
0074 static int rtc_write_wait(void)
0075 {
0076 int i = WRITE_WAIT_MAX_COUNT;
0077 while((mmio_read(AM335X_RTC_BASE+AM335X_RTC_STATUS_REG) & 0x1) && (i--));
0078
0079 if(i == 0)
0080 return RTEMS_RESOURCE_IN_USE;
0081 else
0082 return RTEMS_SUCCESSFUL;
0083 }
0084
0085
0086
0087
0088
0089 static void rtc_clk_init(void)
0090 {
0091 uint32_t a = 0x0;
0092
0093 a = setbit(a,1);
0094
0095 mmio_write(CM_RTC_BASE+CM_RTC_RTC_CLKCTRL,a);
0096 a = 0x0;
0097
0098
0099 a = setbit(a,9);
0100 a = setbit(a,8);
0101 mmio_write(CM_RTC_BASE+CM_RTC_CLKSTCTRL,a);
0102 }
0103
0104 void rtc_init(int minor)
0105 {
0106 uint32_t a = 0x0;
0107
0108 rtc_clk_init();
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 rtc_write_enable();
0119 a = setbit(a,0);
0120 mmio_write(AM335X_RTC_BASE+AM335X_RTC_SYSCONFIG,a);
0121 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK);
0122 a = setbit(a,6);
0123 mmio_write(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK,a);
0124 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG);
0125 a = setbit(a,0);
0126 mmio_write(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG,a);
0127
0128 rtc_write_disable();
0129 }
0130
0131 int am335x_rtc_gettime(int minor,rtems_time_of_day *t)
0132 {
0133 uint32_t a = 0x0;
0134
0135 if(minor != 0)
0136 return RTEMS_INVALID_NUMBER;
0137
0138 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
0139 t->second = bcd(a);
0140 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
0141 t->minute = bcd(a);
0142 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
0143 t->hour = bcd(a);
0144 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
0145 t->day = bcd(a);
0146 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
0147 t->month = bcd(a);
0148 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
0149 t->year = bcd(a)+2000;
0150 t->ticks=0;
0151 return RTEMS_SUCCESSFUL;
0152 }
0153
0154 int am335x_rtc_settime(int minor,const rtems_time_of_day *t)
0155 {
0156 uint32_t a=0x0;
0157 int rv;
0158
0159 if(minor != 0)
0160 return RTEMS_INVALID_NUMBER;
0161
0162 rtc_write_enable();
0163
0164
0165 a = t->second;
0166 rv=rtc_write_wait();
0167 if(rv != RTEMS_SUCCESSFUL)
0168 return rv;
0169 a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_SECS,dec(a) & 0x7f);
0170
0171 a = t->minute;
0172 rv=rtc_write_wait();
0173 if(rv != RTEMS_SUCCESSFUL)
0174 return rv;
0175 a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MINS,dec(a) & 0x7f);
0176
0177 a = t->hour;
0178 rv=rtc_write_wait();
0179 if(rv != RTEMS_SUCCESSFUL)
0180 return rv;
0181 a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_HOURS,dec(a) & 0x3f);
0182
0183 a = t->day;
0184 rv=rtc_write_wait();
0185 if(rv != RTEMS_SUCCESSFUL)
0186 return rv;
0187 a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_DAYS,dec(a) & 0x3f);
0188
0189 a = t->month;
0190 rv=rtc_write_wait();
0191 if(rv != RTEMS_SUCCESSFUL)
0192 return rv;
0193 a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MONTHS,dec(a) & 0x1f);
0194
0195 a = t->year;
0196 rv=rtc_write_wait();
0197 if(rv != RTEMS_SUCCESSFUL)
0198 return rv;
0199 a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_YEARS,(dec(a)%100) & 0xff);
0200
0201 rtc_write_disable();
0202 return rv;
0203 }
0204
0205 #if BBB_DEBUG
0206 void print_time(void)
0207 {
0208 uint32_t a = 0x0;
0209 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
0210 printk("\n\rSecs %x",a);
0211 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
0212 printk("\n\rMins %x",a);
0213 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
0214 printk("\n\rHours %x",a);
0215 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
0216 printk("\n\rDays %x",a);
0217 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
0218 printk("\n\r Months %x",a);
0219 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
0220 printk("\n\rYears %x",a);
0221 a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_WEEKS);
0222 printk("\n\rWeeks %x",a);
0223 }
0224
0225 void am335x_rtc_debug(void)
0226 {
0227 int i;
0228 rtems_time_of_day t,r;
0229
0230 t.second = 1;
0231 t.minute = 1;
0232 t.hour = 1;
0233 t.day = 7;
0234 t.month = 3;
0235 t. year = 2015;
0236
0237 am335x_rtc_settime(0,&t);
0238 am335x_rtc_gettime(0,&r);
0239
0240 printk("Secs %x",r.second);
0241 printk("Mins %x",r.minute);
0242 printk("Hours %x",r.hour);
0243 printk("Days %x",r.day);
0244 printk("Months %x",r.month);
0245 printk("Years %x",r.year);
0246 }
0247 #endif
0248
0249
0250
0251
0252 rtc_fns am335x_rtc_fns = {
0253 rtc_init,
0254 am335x_rtc_gettime,
0255 am335x_rtc_settime
0256 };
0257
0258
0259
0260
0261
0262 rtc_tbl RTC_Table[] = {
0263 {
0264 "/dev/rtc",
0265 RTC_CUSTOM,
0266 &am335x_rtc_fns,
0267 am335x_rtc_probe,
0268 NULL,
0269 0,
0270 0,
0271 NULL,
0272 NULL
0273 }
0274 };
0275
0276 #endif