From patchwork Tue Jan 20 05:16:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 430853 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id D79381402D9 for ; Tue, 20 Jan 2015 16:17:38 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 30B9A4B736; Tue, 20 Jan 2015 06:17:19 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id k+WTmaphBE0b; Tue, 20 Jan 2015 06:17:18 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 354704B739; Tue, 20 Jan 2015 06:16:55 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B5FD24B6A1 for ; Tue, 20 Jan 2015 06:16:36 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cL3kYjVfD8oO for ; Tue, 20 Jan 2015 06:16:36 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ig0-f201.google.com (mail-ig0-f201.google.com [209.85.213.201]) by theia.denx.de (Postfix) with ESMTPS id 5C8ED4B6E8 for ; Tue, 20 Jan 2015 06:16:32 +0100 (CET) Received: by mail-ig0-f201.google.com with SMTP id b16so1266852igk.0 for ; Mon, 19 Jan 2015 21:16:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XhQ9eXfk3tdtqFiKSuigJJxCrwEwquO+k0A3u1v6xdc=; b=TrBKziV0JpSwG2oFg0YK2T70jNAR5VuJ8RtgOpPFLFE416aiOZLn/8qnhjbiJ2icQE IBPhMkFiOx5PSH+ahlAF8llspro1aVm7ATJRBzDP57WFGGWts2+qnp1YqlqooavwgPBa ZK3QX98ccapn2vsBDswMi03Sj3IfWVgNykCbixt48td4JeVIHXi2jeswFWxmn2VfqdQJ kY4eEp5EdEwwtBi1FT1QzVsswJvof0sTSMzzGvic74tQzJ75XvIzjSLidyfJ6aQ3ZyOw owdt0s4FALjEuT4tc2LNN0CSG4O+1YieHcvUmAA+FJhpdWp2Y87+Lcc3makS61Pjs/+I NmfA== X-Gm-Message-State: ALoCoQmTemZm7cVCfB7eBTi9FMbmfdzZFcVT6whr62G3ykINgqGlO8zePji2mc6bhc4l3BcmXSKu X-Received: by 10.42.229.5 with SMTP id jg5mr19926413icb.23.1421730990859; Mon, 19 Jan 2015 21:16:30 -0800 (PST) Received: from corpmail-nozzle1-2.hot.corp.google.com ([100.108.1.103]) by gmr-mx.google.com with ESMTPS id r6si463473yhg.1.2015.01.19.21.16.30 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Jan 2015 21:16:30 -0800 (PST) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by corpmail-nozzle1-2.hot.corp.google.com with ESMTP id G46PnH6H.1; Mon, 19 Jan 2015 21:16:30 -0800 Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 37E8222088D; Mon, 19 Jan 2015 22:16:30 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Mon, 19 Jan 2015 22:16:10 -0700 Message-Id: <1421730977-30077-6-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.2.0.rc0.207.ga3a616c In-Reply-To: <1421730977-30077-1-git-send-email-sjg@chromium.org> References: <1421730977-30077-1-git-send-email-sjg@chromium.org> Cc: Graeme Russ Subject: [U-Boot] [PATCH v3 05/12] x86: rtc: mc146818: Add helpers to read/write CMOS RAM X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de On x86 we use CMOS RAM to read and write some settings. Add basic support for this, including access to registers 128-255. Signed-off-by: Simon Glass --- Changes in v3: - Adjust functions to remain compatible with other RTC drivers Changes in v2: - Adjust the mc146818 driver instead of adding a new cmos.h header drivers/rtc/mc146818.c | 121 +++++++++++++++++++++++++++++-------------------- include/rtc.h | 32 +++++++++++++ 2 files changed, 105 insertions(+), 48 deletions(-) diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index 39e6041..c9d318c 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -27,9 +27,6 @@ /* Set this to 1 to clear the CMOS RAM */ #define CLEAR_CMOS 0 -static uchar rtc_read (uchar reg); -static void rtc_write (uchar reg, uchar val); - #define RTC_PORT_MC146818 CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x70 #define RTC_SECONDS 0x00 #define RTC_SECONDS_ALARM 0x01 @@ -60,24 +57,24 @@ int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, mday, wday, mon, year; /* here check if rtc can be accessed */ - while((rtc_read(RTC_CONFIG_A)&0x80)==0x80); - sec = rtc_read (RTC_SECONDS); - min = rtc_read (RTC_MINUTES); - hour = rtc_read (RTC_HOURS); - mday = rtc_read (RTC_DATE_OF_MONTH); - wday = rtc_read (RTC_DAY_OF_WEEK); - mon = rtc_read (RTC_MONTH); - year = rtc_read (RTC_YEAR); + while ((rtc_read8(RTC_CONFIG_A) & 0x80) == 0x80); + sec = rtc_read8(RTC_SECONDS); + min = rtc_read8(RTC_MINUTES); + hour = rtc_read8(RTC_HOURS); + mday = rtc_read8(RTC_DATE_OF_MONTH); + wday = rtc_read8(RTC_DAY_OF_WEEK); + mon = rtc_read8(RTC_MONTH); + year = rtc_read8(RTC_YEAR); #ifdef RTC_DEBUG printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " "hr: %02x min: %02x sec: %02x\n", year, mon, mday, wday, hour, min, sec ); printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n", - rtc_read (RTC_CONFIG_D) & 0x3F, - rtc_read (RTC_HOURS_ALARM), - rtc_read (RTC_MINUTES_ALARM), - rtc_read (RTC_SECONDS_ALARM) ); + rtc_read8(RTC_CONFIG_D) & 0x3F, + rtc_read8(RTC_HOURS_ALARM), + rtc_read8(RTC_MINUTES_ALARM), + rtc_read8(RTC_SECONDS_ALARM)); #endif tmp->tm_sec = bcd2bin (sec & 0x7F); tmp->tm_min = bcd2bin (min & 0x7F); @@ -108,80 +105,108 @@ int rtc_set (struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif - rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */ + rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */ - rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100)); - rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon)); - rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); - rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); - rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour)); - rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min )); - rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec )); - rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */ + rtc_write8(RTC_YEAR, bin2bcd(tmp->tm_year % 100)); + rtc_write8(RTC_MONTH, bin2bcd(tmp->tm_mon)); + rtc_write8(RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); + rtc_write8(RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); + rtc_write8(RTC_HOURS, bin2bcd(tmp->tm_hour)); + rtc_write8(RTC_MINUTES, bin2bcd(tmp->tm_min)); + rtc_write8(RTC_SECONDS, bin2bcd(tmp->tm_sec)); + rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */ return 0; } void rtc_reset (void) { - rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */ - rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */ - rtc_write(RTC_CONFIG_B,0x00); - rtc_write(RTC_CONFIG_B,0x00); - rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */ + rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */ + rtc_write8(RTC_CONFIG_A, 0x20); /* Normal OP */ + rtc_write8(RTC_CONFIG_B, 0x00); + rtc_write8(RTC_CONFIG_B, 0x00); + rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */ } /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR /* * use direct memory access */ -static uchar rtc_read (uchar reg) +int rtc_read8(int reg) { +#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg); +#else + int ofs = 0; + + if (reg >= 128) { + ofs = 2; + reg -= 128; + } + out8(RTC_PORT_MC146818 + ofs, reg); + + return in8(RTC_PORT_MC146818 + ofs + 1); +#endif } -static void rtc_write (uchar reg, uchar val) +void rtc_write8(int reg, uchar val) { +#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val); -} #else -static uchar rtc_read (uchar reg) + int ofs = 0; + + if (reg >= 128) { + ofs = 2; + reg -= 128; + } + out8(RTC_PORT_MC146818 + ofs, reg); + out8(RTC_PORT_MC146818 + ofs + 1, val); +#endif +} + +u32 rtc_read32(int reg) { - out8(RTC_PORT_MC146818,reg); - return in8(RTC_PORT_MC146818 + 1); + u32 value = 0; + int i; + + for (i = 0; i < sizeof(value); i++) + value |= rtc_read8(reg + i) << (i << 3); + + return value; } -static void rtc_write (uchar reg, uchar val) +void rtc_write32(int reg, u32 value) { - out8(RTC_PORT_MC146818,reg); - out8(RTC_PORT_MC146818+1, val); + int i; + + for (i = 0; i < sizeof(value); i++) + rtc_write8(reg + i, (value >> (i << 3)) & 0xff); } -#endif void rtc_init(void) { #if CLEAR_CMOS int i; - rtc_write(RTC_SECONDS_ALARM, 0); - rtc_write(RTC_MINUTES_ALARM, 0); - rtc_write(RTC_HOURS_ALARM, 0); + rtc_write8(RTC_SECONDS_ALARM, 0); + rtc_write8(RTC_MINUTES_ALARM, 0); + rtc_write8(RTC_HOURS_ALARM, 0); for (i = RTC_CONFIG_A; i < RTC_REG_SIZE; i++) - rtc_write(i, 0); + rtc_write8(i, 0); printf("RTC: zeroing CMOS RAM\n"); #endif /* Setup the real time clock */ - rtc_write(RTC_CONFIG_B, RTC_CONFIG_B_24H); + rtc_write8(RTC_CONFIG_B, RTC_CONFIG_B_24H); /* Setup the frequency it operates at */ - rtc_write(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | + rtc_write8(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | RTC_CONFIG_A_RATE_1024HZ); /* Ensure all reserved bits are 0 in register D */ - rtc_write(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); + rtc_write8(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); /* Clear any pending interrupts */ - rtc_read(RTC_CONFIG_C); + rtc_read8(RTC_CONFIG_C); } #endif diff --git a/include/rtc.h b/include/rtc.h index d11aa8b..54e361e 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -51,6 +51,38 @@ unsigned long mktime (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); /** + * rtc_read8() - Read an 8-bit register + * + * @reg: Register to read + * @return value read + */ +int rtc_read8(int reg); + +/** + * rtc_write8() - Write an 8-bit register + * + * @reg: Register to write + * @value: Value to write + */ +void rtc_write8(int reg, uchar val); + +/** + * rtc_read32() - Read a 32-bit value from the RTC + * + * @reg: Offset to start reading from + * @return value read + */ +u32 rtc_read32(int reg); + +/** + * rtc_write32() - Write a 32-bit value to the RTC + * + * @reg: Register to start writing to + * @value: Value to write + */ +void rtc_write32(int reg, u32 value); + +/** * rtc_init() - Set up the real time clock ready for use */ void rtc_init(void);