"Das U-Boot" Source Tree
at master 141 lines 2.9 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2008 4 * Gururaja Hebbar gururajakr@sanyo.co.in 5 * 6 * reference linux-2.6.20.6/drivers/rtc/rtc-pl031.c 7 */ 8 9#include <command.h> 10#include <dm.h> 11#include <errno.h> 12#include <log.h> 13#include <rtc.h> 14#include <asm/io.h> 15#include <asm/types.h> 16 17/* 18 * Register definitions 19 */ 20#define RTC_DR 0x00 /* Data read register */ 21#define RTC_MR 0x04 /* Match register */ 22#define RTC_LR 0x08 /* Data load register */ 23#define RTC_CR 0x0c /* Control register */ 24#define RTC_IMSC 0x10 /* Interrupt mask and set register */ 25#define RTC_RIS 0x14 /* Raw interrupt status register */ 26#define RTC_MIS 0x18 /* Masked interrupt status register */ 27#define RTC_ICR 0x1c /* Interrupt clear register */ 28 29#define RTC_CR_START (1 << 0) 30 31struct pl031_plat { 32 phys_addr_t base; 33}; 34 35static inline u32 pl031_read_reg(struct udevice *dev, int reg) 36{ 37 struct pl031_plat *pdata = dev_get_plat(dev); 38 39 return readl(pdata->base + reg); 40} 41 42static inline u32 pl031_write_reg(struct udevice *dev, int reg, u32 value) 43{ 44 struct pl031_plat *pdata = dev_get_plat(dev); 45 46 return writel(value, pdata->base + reg); 47} 48 49/* 50 * Probe RTC device 51 */ 52static int pl031_probe(struct udevice *dev) 53{ 54 /* Enable RTC Start in Control register*/ 55 pl031_write_reg(dev, RTC_CR, RTC_CR_START); 56 57 return 0; 58} 59 60/* 61 * Get the current time from the RTC 62 */ 63static int pl031_get(struct udevice *dev, struct rtc_time *tm) 64{ 65 unsigned long tim; 66 67 if (!tm) 68 return -EINVAL; 69 70 tim = pl031_read_reg(dev, RTC_DR); 71 72 rtc_to_tm(tim, tm); 73 74 debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 75 tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, 76 tm->tm_hour, tm->tm_min, tm->tm_sec); 77 78 return 0; 79} 80 81/* 82 * Set the RTC 83 */ 84static int pl031_set(struct udevice *dev, const struct rtc_time *tm) 85{ 86 unsigned long tim; 87 88 if (!tm) 89 return -EINVAL; 90 91 debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 92 tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, 93 tm->tm_hour, tm->tm_min, tm->tm_sec); 94 95 /* Calculate number of seconds this incoming time represents */ 96 tim = rtc_mktime(tm); 97 98 pl031_write_reg(dev, RTC_LR, tim); 99 100 return 0; 101} 102 103/* 104 * Reset the RTC. We set the date back to 1970-01-01. 105 */ 106static int pl031_reset(struct udevice *dev) 107{ 108 pl031_write_reg(dev, RTC_LR, 0); 109 110 return 0; 111} 112 113static const struct rtc_ops pl031_ops = { 114 .get = pl031_get, 115 .set = pl031_set, 116 .reset = pl031_reset, 117}; 118 119static const struct udevice_id pl031_ids[] = { 120 { .compatible = "arm,pl031" }, 121 { } 122}; 123 124static int pl031_of_to_plat(struct udevice *dev) 125{ 126 struct pl031_plat *pdata = dev_get_plat(dev); 127 128 pdata->base = dev_read_addr(dev); 129 130 return 0; 131} 132 133U_BOOT_DRIVER(rtc_pl031) = { 134 .name = "rtc-pl031", 135 .id = UCLASS_RTC, 136 .of_match = pl031_ids, 137 .probe = pl031_probe, 138 .of_to_plat = pl031_of_to_plat, 139 .plat_auto = sizeof(struct pl031_plat), 140 .ops = &pl031_ops, 141};