xref: /openbmc/linux/arch/powerpc/platforms/ps3/time.c (revision 7b6a09f3)
1f58a9d17SGeoff Levand /*
2f58a9d17SGeoff Levand  *  PS3 time and rtc routines.
3f58a9d17SGeoff Levand  *
4f58a9d17SGeoff Levand  *  Copyright (C) 2006 Sony Computer Entertainment Inc.
5f58a9d17SGeoff Levand  *  Copyright 2006 Sony Corp.
6f58a9d17SGeoff Levand  *
7f58a9d17SGeoff Levand  *  This program is free software; you can redistribute it and/or modify
8f58a9d17SGeoff Levand  *  it under the terms of the GNU General Public License as published by
9f58a9d17SGeoff Levand  *  the Free Software Foundation; version 2 of the License.
10f58a9d17SGeoff Levand  *
11f58a9d17SGeoff Levand  *  This program is distributed in the hope that it will be useful,
12f58a9d17SGeoff Levand  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13f58a9d17SGeoff Levand  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14f58a9d17SGeoff Levand  *  GNU General Public License for more details.
15f58a9d17SGeoff Levand  *
16f58a9d17SGeoff Levand  *  You should have received a copy of the GNU General Public License
17f58a9d17SGeoff Levand  *  along with this program; if not, write to the Free Software
18f58a9d17SGeoff Levand  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19f58a9d17SGeoff Levand  */
20f58a9d17SGeoff Levand 
21f58a9d17SGeoff Levand #include <linux/kernel.h>
220b5f037aSGeert Uytterhoeven #include <linux/platform_device.h>
23f58a9d17SGeoff Levand 
247b6a09f3SGeert Uytterhoeven #include <asm/firmware.h>
25f58a9d17SGeoff Levand #include <asm/rtc.h>
26f58a9d17SGeoff Levand #include <asm/lv1call.h>
27f58a9d17SGeoff Levand #include <asm/ps3.h>
28f58a9d17SGeoff Levand 
29f58a9d17SGeoff Levand #include "platform.h"
30f58a9d17SGeoff Levand 
31f58a9d17SGeoff Levand #define dump_tm(_a) _dump_tm(_a, __func__, __LINE__)
32f58a9d17SGeoff Levand static void _dump_tm(const struct rtc_time *tm, const char* func, int line)
33f58a9d17SGeoff Levand {
34f58a9d17SGeoff Levand 	pr_debug("%s:%d tm_sec  %d\n", func, line, tm->tm_sec);
35f58a9d17SGeoff Levand 	pr_debug("%s:%d tm_min  %d\n", func, line, tm->tm_min);
36f58a9d17SGeoff Levand 	pr_debug("%s:%d tm_hour %d\n", func, line, tm->tm_hour);
37f58a9d17SGeoff Levand 	pr_debug("%s:%d tm_mday %d\n", func, line, tm->tm_mday);
38f58a9d17SGeoff Levand 	pr_debug("%s:%d tm_mon  %d\n", func, line, tm->tm_mon);
39f58a9d17SGeoff Levand 	pr_debug("%s:%d tm_year %d\n", func, line, tm->tm_year);
40f58a9d17SGeoff Levand 	pr_debug("%s:%d tm_wday %d\n", func, line, tm->tm_wday);
41f58a9d17SGeoff Levand }
42f58a9d17SGeoff Levand 
43f58a9d17SGeoff Levand #define dump_time(_a) _dump_time(_a, __func__, __LINE__)
44848cfdc5SGeoff Levand static void __maybe_unused _dump_time(int time, const char *func,
45f58a9d17SGeoff Levand 	int line)
46f58a9d17SGeoff Levand {
47f58a9d17SGeoff Levand 	struct rtc_time tm;
48f58a9d17SGeoff Levand 
49f58a9d17SGeoff Levand 	to_tm(time, &tm);
50f58a9d17SGeoff Levand 
51f58a9d17SGeoff Levand 	pr_debug("%s:%d time    %d\n", func, line, time);
52f58a9d17SGeoff Levand 	_dump_tm(&tm, func, line);
53f58a9d17SGeoff Levand }
54f58a9d17SGeoff Levand 
55f58a9d17SGeoff Levand void __init ps3_calibrate_decr(void)
56f58a9d17SGeoff Levand {
57f58a9d17SGeoff Levand 	int result;
58f58a9d17SGeoff Levand 	u64 tmp;
59f58a9d17SGeoff Levand 
60f58a9d17SGeoff Levand 	result = ps3_repository_read_be_tb_freq(0, &tmp);
61f58a9d17SGeoff Levand 	BUG_ON(result);
62f58a9d17SGeoff Levand 
63f58a9d17SGeoff Levand 	ppc_tb_freq = tmp;
64f58a9d17SGeoff Levand 	ppc_proc_freq = ppc_tb_freq * 40;
65f58a9d17SGeoff Levand }
66f58a9d17SGeoff Levand 
67f58a9d17SGeoff Levand static u64 read_rtc(void)
68f58a9d17SGeoff Levand {
69f58a9d17SGeoff Levand 	int result;
70f58a9d17SGeoff Levand 	u64 rtc_val;
71f58a9d17SGeoff Levand 	u64 tb_val;
72f58a9d17SGeoff Levand 
73f58a9d17SGeoff Levand 	result = lv1_get_rtc(&rtc_val, &tb_val);
74f58a9d17SGeoff Levand 	BUG_ON(result);
75f58a9d17SGeoff Levand 
76f58a9d17SGeoff Levand 	return rtc_val;
77f58a9d17SGeoff Levand }
78f58a9d17SGeoff Levand 
79f58a9d17SGeoff Levand unsigned long __init ps3_get_boot_time(void)
80f58a9d17SGeoff Levand {
81d7b98e3dSGeoff Levand 	return read_rtc() + ps3_os_area_get_rtc_diff();
82f58a9d17SGeoff Levand }
830b5f037aSGeert Uytterhoeven 
840b5f037aSGeert Uytterhoeven static int __init ps3_rtc_init(void)
850b5f037aSGeert Uytterhoeven {
860b5f037aSGeert Uytterhoeven 	struct platform_device *pdev;
870b5f037aSGeert Uytterhoeven 
887b6a09f3SGeert Uytterhoeven 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
897b6a09f3SGeert Uytterhoeven 		return -ENODEV;
907b6a09f3SGeert Uytterhoeven 
910b5f037aSGeert Uytterhoeven 	pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
920b5f037aSGeert Uytterhoeven 	if (IS_ERR(pdev))
930b5f037aSGeert Uytterhoeven 		return PTR_ERR(pdev);
940b5f037aSGeert Uytterhoeven 
950b5f037aSGeert Uytterhoeven 	return 0;
960b5f037aSGeert Uytterhoeven }
970b5f037aSGeert Uytterhoeven 
980b5f037aSGeert Uytterhoeven module_init(ps3_rtc_init);
99