1.1 --- a/conf/landfall-examples/mips-ci20-common.io Tue Nov 14 00:02:42 2023 +0100 1.2 +++ b/conf/landfall-examples/mips-ci20-common.io Thu Nov 16 01:15:40 2023 +0100 1.3 @@ -13,6 +13,7 @@ 1.4 LCD = wrap(hw:match("jz4780-lcd")); 1.5 HDMI = wrap(hw:match("jz4780-hdmi")); 1.6 I2C = wrap(hw:match("jz4780-i2c")); 1.7 + RTC = wrap(hw:match("jz4780-rtc")); 1.8 SSI = wrap(hw:match("jz4780-ssi")); 1.9 } 1.10
2.1 --- a/conf/landfall-examples/mips-jz4780-info.io Tue Nov 14 00:02:42 2023 +0100 2.2 +++ b/conf/landfall-examples/mips-jz4780-info.io Thu Nov 16 01:15:40 2023 +0100 2.3 @@ -10,6 +10,7 @@ 2.4 DMA = wrap(hw:match("jz4780-dma")); 2.5 GPIO = wrap(hw:match("jz4780-gpio")); 2.6 I2C = wrap(hw:match("jz4780-i2c")); 2.7 + RTC = wrap(hw:match("jz4780-rtc")); 2.8 SSI = wrap(hw:match("jz4780-ssi")); 2.9 } 2.10
3.1 --- a/conf/landfall-examples/mips-x1600-info.io Tue Nov 14 00:02:42 2023 +0100 3.2 +++ b/conf/landfall-examples/mips-x1600-info.io Thu Nov 16 01:15:40 2023 +0100 3.3 @@ -10,6 +10,7 @@ 3.4 DMA = wrap(hw:match("x1600-dma")); 3.5 GPIO = wrap(hw:match("x1600-gpio")); 3.6 I2C = wrap(hw:match("x1600-i2c")); 3.7 + RTC = wrap(hw:match("x1600-rtc")); 3.8 SSI = wrap(hw:match("x1600-ssi")); 3.9 } 3.10
4.1 --- a/pkg/devices/Control Tue Nov 14 00:02:42 2023 +0100 4.2 +++ b/pkg/devices/Control Thu Nov 16 01:15:40 2023 +0100 4.3 @@ -40,6 +40,7 @@ 4.4 provides: libdrivers-panel-loader 4.5 provides: libdrivers-panel-qi_lb60 4.6 provides: libdrivers-pwm 4.7 +provides: libdrivers-rtc 4.8 provides: libdrivers-spi 4.9 requires: libc libc_be_l4re libdl l4re_c libio libipc 4.10 Maintainer: paul@boddie.org.uk
5.1 --- a/pkg/devices/lib/Makefile Tue Nov 14 00:02:42 2023 +0100 5.2 +++ b/pkg/devices/lib/Makefile Thu Nov 16 01:15:40 2023 +0100 5.3 @@ -1,7 +1,7 @@ 5.4 PKGDIR ?= .. 5.5 L4DIR ?= $(PKGDIR)/../.. 5.6 5.7 -TARGET := aic common cpm dma gpio hdmi i2c keypad lcd panel pwm spi 5.8 +TARGET := aic common cpm dma gpio hdmi i2c keypad lcd panel pwm rtc spi 5.9 5.10 include $(L4DIR)/mk/subdir.mk 5.11 5.12 @@ -15,4 +15,5 @@ 5.13 lcd: common 5.14 panel: lcd 5.15 pwm: common 5.16 +rtc: common 5.17 spi: cpm dma gpio
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/pkg/devices/lib/rtc/Makefile Thu Nov 16 01:15:40 2023 +0100 6.3 @@ -0,0 +1,8 @@ 6.4 +PKGDIR ?= ../.. 6.5 +L4DIR ?= $(PKGDIR)/../.. 6.6 + 6.7 +TARGET := include src 6.8 + 6.9 +include $(L4DIR)/mk/subdir.mk 6.10 + 6.11 +src: include
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/pkg/devices/lib/rtc/include/Makefile Thu Nov 16 01:15:40 2023 +0100 7.3 @@ -0,0 +1,4 @@ 7.4 +PKGDIR = ../../.. 7.5 +L4DIR ?= $(PKGDIR)/../.. 7.6 + 7.7 +include $(L4DIR)/mk/include.mk
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/pkg/devices/lib/rtc/include/rtc-x1600.h Thu Nov 16 01:15:40 2023 +0100 8.3 @@ -0,0 +1,98 @@ 8.4 +/* 8.5 + * RTC (real-time clock) support for the X1600. 8.6 + * 8.7 + * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 8.8 + * 8.9 + * This program is free software; you can redistribute it and/or 8.10 + * modify it under the terms of the GNU General Public License as 8.11 + * published by the Free Software Foundation; either version 2 of 8.12 + * the License, or (at your option) any later version. 8.13 + * 8.14 + * This program is distributed in the hope that it will be useful, 8.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.17 + * GNU General Public License for more details. 8.18 + * 8.19 + * You should have received a copy of the GNU General Public License 8.20 + * along with this program; if not, write to the Free Software 8.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 8.22 + * Boston, MA 02110-1301, USA 8.23 + */ 8.24 + 8.25 +#pragma once 8.26 + 8.27 +#include <l4/sys/types.h> 8.28 +#include <stdint.h> 8.29 + 8.30 + 8.31 + 8.32 +#ifdef __cplusplus 8.33 + 8.34 +#include <l4/devices/hw_register_block.h> 8.35 + 8.36 +class Rtc_x1600_chip 8.37 +{ 8.38 +protected: 8.39 + Hw::Register_block<32> _regs; 8.40 + 8.41 + /* Utility methods. */ 8.42 + 8.43 + uint32_t read_checked(unsigned reg); 8.44 + void wait(); 8.45 + void write_enable(); 8.46 + 8.47 +public: 8.48 + explicit Rtc_x1600_chip(l4_addr_t addr); 8.49 + 8.50 + void disable(); 8.51 + 8.52 + void enable(); 8.53 + 8.54 + void alarm_disable(); 8.55 + 8.56 + void alarm_enable(); 8.57 + 8.58 + uint32_t get_seconds(); 8.59 + 8.60 + void set_seconds(uint32_t seconds); 8.61 + 8.62 + uint32_t get_alarm_seconds(); 8.63 + 8.64 + void set_alarm_seconds(uint32_t seconds); 8.65 + 8.66 + void set_regulator(uint32_t base, uint32_t adjustment); 8.67 + 8.68 + void power_down(); 8.69 +}; 8.70 + 8.71 +#endif /* __cplusplus */ 8.72 + 8.73 + 8.74 + 8.75 +/* C language interface. */ 8.76 + 8.77 +EXTERN_C_BEGIN 8.78 + 8.79 +void *x1600_rtc_init(l4_addr_t rtc_base); 8.80 + 8.81 +void x1600_rtc_disable(void *rtc); 8.82 + 8.83 +void x1600_rtc_enable(void *rtc); 8.84 + 8.85 +void x1600_rtc_alarm_disable(void *rtc); 8.86 + 8.87 +void x1600_rtc_alarm_enable(void *rtc); 8.88 + 8.89 +uint32_t x1600_rtc_get_seconds(void *rtc); 8.90 + 8.91 +void x1600_rtc_set_seconds(void *rtc, uint32_t seconds); 8.92 + 8.93 +uint32_t x1600_rtc_get_alarm_seconds(void *rtc); 8.94 + 8.95 +void x1600_rtc_set_alarm_seconds(void *rtc, uint32_t seconds); 8.96 + 8.97 +void x1600_rtc_set_regulator(void *rtc, uint32_t base, uint32_t adjustment); 8.98 + 8.99 +void x1600_rtc_power_down(void *rtc); 8.100 + 8.101 +EXTERN_C_END
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/pkg/devices/lib/rtc/src/Makefile Thu Nov 16 01:15:40 2023 +0100 9.3 @@ -0,0 +1,13 @@ 9.4 +PKGDIR ?= ../../.. 9.5 +L4DIR ?= $(PKGDIR)/../.. 9.6 + 9.7 +TARGET = librtc.o.a librtc.o.so 9.8 +PC_FILENAME := libdrivers-rtc 9.9 + 9.10 +SRC_CC := x1600.cc 9.11 + 9.12 +PRIVATE_INCDIR += $(PKGDIR)/lib/rtc/include 9.13 + 9.14 +REQUIRES_LIBS := l4re_c l4re_c-util libdrivers-common 9.15 + 9.16 +include $(L4DIR)/mk/lib.mk
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/pkg/devices/lib/rtc/src/x1600.cc Thu Nov 16 01:15:40 2023 +0100 10.3 @@ -0,0 +1,307 @@ 10.4 +/* 10.5 + * Real-time clock support. 10.6 + * 10.7 + * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 10.8 + * 10.9 + * This program is free software; you can redistribute it and/or 10.10 + * modify it under the terms of the GNU General Public License as 10.11 + * published by the Free Software Foundation; either version 2 of 10.12 + * the License, or (at your option) any later version. 10.13 + * 10.14 + * This program is distributed in the hope that it will be useful, 10.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.17 + * GNU General Public License for more details. 10.18 + * 10.19 + * You should have received a copy of the GNU General Public License 10.20 + * along with this program; if not, write to the Free Software 10.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 10.22 + * Boston, MA 02110-1301, USA 10.23 + */ 10.24 + 10.25 +#include <l4/devices/hw_mmio_register_block.h> 10.26 +#include "rtc-x1600.h" 10.27 + 10.28 + 10.29 + 10.30 +// Register locations. 10.31 + 10.32 +enum Regs : unsigned 10.33 +{ 10.34 + Rtc_control = 0x000, // RTCCR 10.35 + Rtc_seconds = 0x004, // RTCSR 10.36 + Rtc_alarm_seconds = 0x008, // RTCSAR 10.37 + Rtc_regulator = 0x00c, // RTCGR 10.38 + 10.39 + Hibernate_control = 0x020, // HCR 10.40 + Hibernate_wakeup_filter_counter = 0x024, // HWFCR 10.41 + Hibernate_reset_counter = 0x028, // HRCR 10.42 + Hibernate_wakeup_control = 0x02c, // HWCR 10.43 + Hibernate_wakeup_status = 0x030, // HWRSR 10.44 + Hibernate_scratch_pattern = 0x034, // HSPR 10.45 + Hibernate_write_enable_pattern = 0x03c, // WENR 10.46 + Hibernate_wakeup_pin_configure = 0x048, // WKUPPINCR 10.47 +}; 10.48 + 10.49 + // Field definitions. 10.50 + 10.51 +enum Control_bits : unsigned 10.52 +{ 10.53 + Control_write_ready = 0x80, // WRDY 10.54 + Control_1Hz = 0x40, // 1HZ 10.55 + Control_1Hz_irq_enable = 0x20, // 1HZIE 10.56 + Control_alarm = 0x10, // AF 10.57 + Control_alarm_irq_enable = 0x08, // AIE 10.58 + Control_alarm_enable = 0x04, // AE 10.59 + Control_rtc_enable = 0x01, // RTCE 10.60 +}; 10.61 + 10.62 +enum Regulator_bits : unsigned 10.63 +{ 10.64 + Regulator_lock = 0x80000000, // LOCK 10.65 + Regulator_adjust_count_mask = 0x03ff0000, // ADJC 10.66 + Regulator_1Hz_cycle_count_mask = 0x0000ffff, // NC1HZ 10.67 +}; 10.68 + 10.69 +enum Regulator_limits : unsigned 10.70 +{ 10.71 + Regulator_adjust_count_limit = 0x03ff, // ADJC 10.72 + Regulator_1Hz_cycle_count_limit = 0xffff, // NC1HZ 10.73 +}; 10.74 + 10.75 +enum Regulator_shifts : unsigned 10.76 +{ 10.77 + Regulator_adjust_count_shift = 16, // ADJC 10.78 + Regulator_1Hz_cycle_count_shift = 0, // NC1HZ 10.79 +}; 10.80 + 10.81 +enum Hibernate_control_bits : unsigned 10.82 +{ 10.83 + Hibernate_power_down = 0x01, // PD 10.84 +}; 10.85 + 10.86 +enum Hibernate_wakeup_filter_counter_bits : unsigned 10.87 +{ 10.88 + Wakeup_minimum_time_mask = 0xffe0, // HWFCR 10.89 +}; 10.90 + 10.91 +enum Hibernate_reset_counter_bits : unsigned 10.92 +{ 10.93 + Reset_assert_time_mask = 0x7800, // HRCR 10.94 +}; 10.95 + 10.96 +enum Hibernate_wakeup_control_bits : unsigned 10.97 +{ 10.98 + Power_detect_enable_mask = 0xfffffff8, // EPDET 10.99 + Rtc_alarm_wakeup_enable = 0x00000001, // EALM 10.100 +}; 10.101 + 10.102 +enum Hibernate_wakeup_status_bits : unsigned 10.103 +{ 10.104 + Accident_power_down = 0x0100, // APD 10.105 + Hibernate_reset = 0x0020, // HR 10.106 + Pad_pin_reset = 0x0010, // PPR 10.107 + Wakeup_pin_status = 0x0002, // PIN 10.108 + Rtc_alarm_status = 0x0001, // ALM 10.109 +}; 10.110 + 10.111 +enum Hibernate_write_enable_pattern_bits : unsigned 10.112 +{ 10.113 + Write_enable_status = 0x80000000, // WEN 10.114 + Write_enable_pattern_mask = 0x0000ffff, // WENPAT 10.115 + Write_enable_pattern = 0x0000a55a, // WENPAT 10.116 +}; 10.117 + 10.118 +enum Hibernate_wakeup_pin_configure_bits : unsigned 10.119 +{ 10.120 + Rtc_oscillator_test_enable = 0x00080000, // OSC_TE 10.121 + Oscillator_xtclk_rtclk = 0x00040000, // OSC_RETON 10.122 + Oscillator_xtclk_low = 0x00000000, // OSC_RETON 10.123 + Rtc_internal_oscillator_enable = 0x00010000, // OSC_EN 10.124 + Wakeup_pin_extended_press_mask = 0x000000f0, // P_JUD_LEN 10.125 + Wakeup_pin_extended_press_enable = 0x0000000f, // P_RST_LEN 10.126 +}; 10.127 + 10.128 + 10.129 + 10.130 +// Peripheral abstraction. 10.131 + 10.132 +Rtc_x1600_chip::Rtc_x1600_chip(l4_addr_t addr) 10.133 +{ 10.134 + _regs = new Hw::Mmio_register_block<32>(addr); 10.135 +} 10.136 + 10.137 +uint32_t 10.138 +Rtc_x1600_chip::read_checked(unsigned reg) 10.139 +{ 10.140 + uint32_t last, current; 10.141 + 10.142 + wait(); 10.143 + last = _regs[reg]; 10.144 + 10.145 + while (1) 10.146 + { 10.147 + wait(); 10.148 + current = _regs[reg]; 10.149 + 10.150 + if (current == last) 10.151 + return current; 10.152 + else 10.153 + last = current; 10.154 + } 10.155 +} 10.156 + 10.157 +void 10.158 +Rtc_x1600_chip::wait() 10.159 +{ 10.160 + while (!(_regs[Rtc_control] & Control_write_ready)); 10.161 +} 10.162 + 10.163 +void 10.164 +Rtc_x1600_chip::write_enable() 10.165 +{ 10.166 + wait(); 10.167 + _regs[Hibernate_write_enable_pattern] = Write_enable_pattern; 10.168 + 10.169 + while (!(_regs[Hibernate_write_enable_pattern] & Write_enable_status)); 10.170 + 10.171 + wait(); 10.172 +} 10.173 + 10.174 +void 10.175 +Rtc_x1600_chip::disable() 10.176 +{ 10.177 + write_enable(); 10.178 + _regs[Rtc_control] = _regs[Rtc_control] & ~Control_rtc_enable; 10.179 +} 10.180 + 10.181 +void 10.182 +Rtc_x1600_chip::enable() 10.183 +{ 10.184 + write_enable(); 10.185 + _regs[Rtc_control] = _regs[Rtc_control] | Control_rtc_enable; 10.186 +} 10.187 + 10.188 +void 10.189 +Rtc_x1600_chip::alarm_disable() 10.190 +{ 10.191 + write_enable(); 10.192 + _regs[Rtc_control] = _regs[Rtc_control] & ~Control_alarm_enable; 10.193 +} 10.194 + 10.195 +void 10.196 +Rtc_x1600_chip::alarm_enable() 10.197 +{ 10.198 + write_enable(); 10.199 + _regs[Rtc_control] = _regs[Rtc_control] | Control_alarm_enable; 10.200 +} 10.201 + 10.202 +uint32_t 10.203 +Rtc_x1600_chip::get_seconds() 10.204 +{ 10.205 + return read_checked(Rtc_seconds); 10.206 +} 10.207 + 10.208 +void 10.209 +Rtc_x1600_chip::set_seconds(uint32_t seconds) 10.210 +{ 10.211 + write_enable(); 10.212 + _regs[Rtc_seconds] = seconds; 10.213 +} 10.214 + 10.215 +uint32_t 10.216 +Rtc_x1600_chip::get_alarm_seconds() 10.217 +{ 10.218 + return read_checked(Rtc_alarm_seconds); 10.219 +} 10.220 + 10.221 +void 10.222 +Rtc_x1600_chip::set_alarm_seconds(uint32_t seconds) 10.223 +{ 10.224 + write_enable(); 10.225 + _regs[Rtc_alarm_seconds] = seconds; 10.226 +} 10.227 + 10.228 +void 10.229 +Rtc_x1600_chip::set_regulator(uint32_t base, uint32_t adjustment) 10.230 +{ 10.231 + base = base ? base - 1 : 0; 10.232 + adjustment = adjustment ? adjustment - 1 : 0; 10.233 + 10.234 + if (base > Regulator_1Hz_cycle_count_limit) 10.235 + base = Regulator_1Hz_cycle_count_limit; 10.236 + 10.237 + if (adjustment > Regulator_adjust_count_limit) 10.238 + adjustment = Regulator_adjust_count_limit; 10.239 + 10.240 + write_enable(); 10.241 + _regs[Rtc_regulator] = (base << Regulator_1Hz_cycle_count_shift) | 10.242 + (adjustment << Regulator_adjust_count_shift); 10.243 +} 10.244 + 10.245 +void 10.246 +Rtc_x1600_chip::power_down() 10.247 +{ 10.248 + write_enable(); 10.249 + _regs[Hibernate_control] = _regs[Hibernate_control] | Hibernate_power_down; 10.250 +} 10.251 + 10.252 + 10.253 + 10.254 +// C language interface functions. 10.255 + 10.256 +void 10.257 +*x1600_rtc_init(l4_addr_t rtc_base) 10.258 +{ 10.259 + return (void *) new Rtc_x1600_chip(rtc_base); 10.260 +} 10.261 + 10.262 +void x1600_rtc_disable(void *rtc) 10.263 +{ 10.264 + static_cast<Rtc_x1600_chip *>(rtc)->disable(); 10.265 +} 10.266 + 10.267 +void x1600_rtc_enable(void *rtc) 10.268 +{ 10.269 + static_cast<Rtc_x1600_chip *>(rtc)->enable(); 10.270 +} 10.271 + 10.272 +void x1600_rtc_alarm_disable(void *rtc) 10.273 +{ 10.274 + static_cast<Rtc_x1600_chip *>(rtc)->alarm_disable(); 10.275 +} 10.276 + 10.277 +void x1600_rtc_alarm_enable(void *rtc) 10.278 +{ 10.279 + static_cast<Rtc_x1600_chip *>(rtc)->alarm_enable(); 10.280 +} 10.281 + 10.282 +uint32_t x1600_rtc_get_seconds(void *rtc) 10.283 +{ 10.284 + return static_cast<Rtc_x1600_chip *>(rtc)->get_seconds(); 10.285 +} 10.286 + 10.287 +void x1600_rtc_set_seconds(void *rtc, uint32_t seconds) 10.288 +{ 10.289 + static_cast<Rtc_x1600_chip *>(rtc)->set_seconds(seconds); 10.290 +} 10.291 + 10.292 +uint32_t x1600_rtc_get_alarm_seconds(void *rtc) 10.293 +{ 10.294 + return static_cast<Rtc_x1600_chip *>(rtc)->get_alarm_seconds(); 10.295 +} 10.296 + 10.297 +void x1600_rtc_set_alarm_seconds(void *rtc, uint32_t seconds) 10.298 +{ 10.299 + static_cast<Rtc_x1600_chip *>(rtc)->set_alarm_seconds(seconds); 10.300 +} 10.301 + 10.302 +void x1600_rtc_set_regulator(void *rtc, uint32_t base, uint32_t adjustment) 10.303 +{ 10.304 + static_cast<Rtc_x1600_chip *>(rtc)->set_regulator(base, adjustment); 10.305 +} 10.306 + 10.307 +void x1600_rtc_power_down(void *rtc) 10.308 +{ 10.309 + static_cast<Rtc_x1600_chip *>(rtc)->power_down(); 10.310 +}
11.1 --- a/pkg/landfall-examples/hw_info/Makefile Tue Nov 14 00:02:42 2023 +0100 11.2 +++ b/pkg/landfall-examples/hw_info/Makefile Thu Nov 16 01:15:40 2023 +0100 11.3 @@ -7,6 +7,6 @@ 11.4 REQUIRES_LIBS = \ 11.5 libio l4re_c-util libdrivers-aic libdrivers-cpm \ 11.6 libdrivers-dma libdrivers-gpio libdrivers-i2c \ 11.7 - libdrivers-spi libdevice-util 11.8 + libdrivers-rtc libdrivers-spi libdevice-util 11.9 11.10 include $(L4DIR)/mk/prog.mk
12.1 --- a/pkg/landfall-examples/hw_info/common.h Tue Nov 14 00:02:42 2023 +0100 12.2 +++ b/pkg/landfall-examples/hw_info/common.h Thu Nov 16 01:15:40 2023 +0100 12.3 @@ -165,6 +165,28 @@ 12.4 12.5 12.6 12.7 +/* RTC adapter functions. */ 12.8 + 12.9 +void *rtc_init(l4_addr_t start); 12.10 + 12.11 +void rtc_disable(void *rtc); 12.12 + 12.13 +void rtc_enable(void *rtc); 12.14 + 12.15 +uint32_t rtc_get_seconds(void *rtc); 12.16 + 12.17 +void rtc_set_seconds(void *rtc, uint32_t seconds); 12.18 + 12.19 +uint32_t rtc_get_alarm_seconds(void *rtc); 12.20 + 12.21 +void rtc_set_alarm_seconds(void *rtc, uint32_t seconds); 12.22 + 12.23 +void rtc_power_down(void *rtc); 12.24 + 12.25 +void rtc_set_regulator(void *rtc, uint32_t base, uint32_t adjustment); 12.26 + 12.27 + 12.28 + 12.29 /* SPI adapter functions. */ 12.30 12.31 void *spi_init(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, void *cpm); 12.32 @@ -198,7 +220,7 @@ 12.33 12.34 enum memory_regions 12.35 { 12.36 - AIC, CPM, DMA, GPIO, I2C, SSI 12.37 + AIC, CPM, DMA, GPIO, I2C, RTC, SSI 12.38 }; 12.39 12.40
13.1 --- a/pkg/landfall-examples/hw_info/hw_info.c Tue Nov 14 00:02:42 2023 +0100 13.2 +++ b/pkg/landfall-examples/hw_info/hw_info.c Thu Nov 16 01:15:40 2023 +0100 13.3 @@ -1113,6 +1113,20 @@ 13.4 13.5 13.6 13.7 +/* RTC operations. */ 13.8 + 13.9 +static void _rtc_set_seconds(void *rtc, int alarm) 13.10 +{ 13.11 + unsigned int seconds; 13.12 + 13.13 + if (!read_number("Seconds", &seconds)) 13.14 + return; 13.15 + 13.16 + (alarm ? rtc_set_alarm_seconds : rtc_set_seconds)(rtc, seconds); 13.17 +} 13.18 + 13.19 + 13.20 + 13.21 /* SPI operations. */ 13.22 13.23 static void new_spi_channel(void *spi, void *gpio[]) 13.24 @@ -1422,6 +1436,33 @@ 13.25 list_memory_regions(); 13.26 } 13.27 13.28 +static void handle_rtc(void *rtc) 13.29 +{ 13.30 + char *token; 13.31 + 13.32 + if ((token = read_token(NULL)) != NULL) 13.33 + { 13.34 + if (!strcmp(token, "d") || !strcmp(token, "disable")) 13.35 + rtc_disable(rtc); 13.36 + else if (!strcmp(token, "e") || !strcmp(token, "enable")) 13.37 + rtc_enable(rtc); 13.38 + else if (!strcmp(token, "g") || !strcmp(token, "get")) 13.39 + printf("seconds = %d\n", rtc_get_seconds(rtc)); 13.40 + else if (!strcmp(token, "ga") || !strcmp(token, "get-alarm")) 13.41 + printf("seconds = %d\n", rtc_get_alarm_seconds(rtc)); 13.42 + else if (!strcmp(token, "p") || !strcmp(token, "power-down")) 13.43 + rtc_power_down(rtc); 13.44 + else if (!strcmp(token, "s") || !strcmp(token, "set")) 13.45 + _rtc_set_seconds(rtc, 0); 13.46 + else if (!strcmp(token, "sa") || !strcmp(token, "set-alarm")) 13.47 + _rtc_set_seconds(rtc, 1); 13.48 + else 13.49 + printf("rtc disable | enable | get | get-alarm | power-down | set | set-alarm\n"); 13.50 + } 13.51 + else 13.52 + printf("rtc disable | enable | get | get-alarm | power-down | set | set-alarm\n"); 13.53 +} 13.54 + 13.55 static void handle_spi(void *spi, void *gpio[]) 13.56 { 13.57 char *token; 13.58 @@ -1461,9 +1502,10 @@ 13.59 l4_addr_t dma_base = 0, dma_base_end = 0; 13.60 l4_addr_t gpio_base = 0, gpio_base_end = 0; 13.61 l4_addr_t i2c_base = 0, i2c_base_end = 0; 13.62 + l4_addr_t rtc_base = 0, rtc_base_end = 0; 13.63 l4_addr_t ssi_base = 0, ssi_base_end = 0; 13.64 l4_addr_t ssi_phys_base = 0, ssi_phys_base_end = 0; 13.65 - void *aic, *cpm, *dma, *gpio[num_gpio_ports], *i2c, *spi; 13.66 + void *aic, *cpm, *dma, *gpio[num_gpio_ports], *i2c, *rtc, *spi; 13.67 int result = 0; 13.68 unsigned int port; 13.69 13.70 @@ -1534,6 +1576,15 @@ 13.71 13.72 aic = aic_init(aic_phys_base, aic_base, aic_base_end, cpm); 13.73 13.74 + printf("Access RTC...\n"); 13.75 + 13.76 + if ((result = get_memory(io_memory_regions[RTC], &rtc_base, &rtc_base_end)) < 0) 13.77 + return 1; 13.78 + 13.79 + printf("RTC at 0x%lx...0x%lx.\n", rtc_base, rtc_base_end); 13.80 + 13.81 + rtc = rtc_init(rtc_base); 13.82 + 13.83 printf("Access SSI...\n"); 13.84 13.85 if ((result = get_memory_complete(io_memory_regions[SSI], &ssi_base, &ssi_base_end, 13.86 @@ -1546,7 +1597,7 @@ 13.87 13.88 /* Start the interactive session. */ 13.89 13.90 - printf("aic, cpm, dma, gpio, i2c, spi\n"); 13.91 + printf("aic, cpm, dma, gpio, i2c, rtc, spi\n"); 13.92 13.93 while (1) 13.94 { 13.95 @@ -1592,6 +1643,11 @@ 13.96 else if (!strcmp(token, "m") || !strcmp(token, "mem") || !strcmp(token, "memory")) 13.97 handle_memory(); 13.98 13.99 + /* RTC commands. */ 13.100 + 13.101 + else if (!strcmp(token, "r") || !strcmp(token, "rtc")) 13.102 + handle_rtc(rtc); 13.103 + 13.104 /* SPI commands. */ 13.105 13.106 else if (!strcmp(token, "s") || !strcmp(token, "spi"))
14.1 --- a/pkg/landfall-examples/hw_info/jz4780.c Tue Nov 14 00:02:42 2023 +0100 14.2 +++ b/pkg/landfall-examples/hw_info/jz4780.c Thu Nov 16 01:15:40 2023 +0100 14.3 @@ -29,6 +29,10 @@ 14.4 #include <l4/devices/gpio-jz4780.h> 14.5 #include <l4/devices/i2c-jz4780.h> 14.6 14.7 +/* The X1600 RTC functionality is a subset of that in the JZ4780. */ 14.8 + 14.9 +#include <l4/devices/rtc-x1600.h> 14.10 + 14.11 /* GPIO-based SPI can use arbitrary pins, whereas on the CI20 only the secondary 14.12 header provides pins like GPC. */ 14.13 14.14 @@ -331,6 +335,55 @@ 14.15 14.16 14.17 14.18 +/* RTC adapter functions. */ 14.19 + 14.20 +void *rtc_init(l4_addr_t start) 14.21 +{ 14.22 + return x1600_rtc_init(start); 14.23 +} 14.24 + 14.25 +void rtc_disable(void *rtc) 14.26 +{ 14.27 + x1600_rtc_disable(rtc); 14.28 +} 14.29 + 14.30 +void rtc_enable(void *rtc) 14.31 +{ 14.32 + x1600_rtc_enable(rtc); 14.33 +} 14.34 + 14.35 +uint32_t rtc_get_seconds(void *rtc) 14.36 +{ 14.37 + return x1600_rtc_get_seconds(rtc); 14.38 +} 14.39 + 14.40 +void rtc_set_seconds(void *rtc, uint32_t seconds) 14.41 +{ 14.42 + x1600_rtc_set_seconds(rtc, seconds); 14.43 +} 14.44 + 14.45 +uint32_t rtc_get_alarm_seconds(void *rtc) 14.46 +{ 14.47 + return x1600_rtc_get_alarm_seconds(rtc); 14.48 +} 14.49 + 14.50 +void rtc_set_alarm_seconds(void *rtc, uint32_t seconds) 14.51 +{ 14.52 + x1600_rtc_set_alarm_seconds(rtc, seconds); 14.53 +} 14.54 + 14.55 +void rtc_power_down(void *rtc) 14.56 +{ 14.57 + x1600_rtc_power_down(rtc); 14.58 +} 14.59 + 14.60 +void rtc_set_regulator(void *rtc, uint32_t base, uint32_t adjustment) 14.61 +{ 14.62 + x1600_rtc_set_regulator(rtc, base, adjustment); 14.63 +} 14.64 + 14.65 + 14.66 + 14.67 /* SPI adapter functions. */ 14.68 14.69 void *spi_init(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, void *cpm) 14.70 @@ -399,6 +452,7 @@ 14.71 [DMA] = "jz4780-dma", 14.72 [GPIO] = "jz4780-gpio", 14.73 [I2C] = "jz4780-i2c", 14.74 + [RTC] = "jz4780-rtc", 14.75 [SSI] = "jz4780-ssi", 14.76 }; 14.77
15.1 --- a/pkg/landfall-examples/hw_info/x1600.c Tue Nov 14 00:02:42 2023 +0100 15.2 +++ b/pkg/landfall-examples/hw_info/x1600.c Thu Nov 16 01:15:40 2023 +0100 15.3 @@ -24,6 +24,7 @@ 15.4 #include <l4/devices/dma-x1600.h> 15.5 #include <l4/devices/gpio-x1600.h> 15.6 #include <l4/devices/i2c-x1600.h> 15.7 +#include <l4/devices/rtc-x1600.h> 15.8 #include <l4/devices/spi-gpio.h> 15.9 #include <l4/devices/spi-hybrid.h> 15.10 #include <l4/devices/spi-jz4780.h> 15.11 @@ -323,6 +324,55 @@ 15.12 15.13 15.14 15.15 +/* RTC adapter functions. */ 15.16 + 15.17 +void *rtc_init(l4_addr_t start) 15.18 +{ 15.19 + return x1600_rtc_init(start); 15.20 +} 15.21 + 15.22 +void rtc_disable(void *rtc) 15.23 +{ 15.24 + x1600_rtc_disable(rtc); 15.25 +} 15.26 + 15.27 +void rtc_enable(void *rtc) 15.28 +{ 15.29 + x1600_rtc_enable(rtc); 15.30 +} 15.31 + 15.32 +uint32_t rtc_get_seconds(void *rtc) 15.33 +{ 15.34 + return x1600_rtc_get_seconds(rtc); 15.35 +} 15.36 + 15.37 +void rtc_set_seconds(void *rtc, uint32_t seconds) 15.38 +{ 15.39 + x1600_rtc_set_seconds(rtc, seconds); 15.40 +} 15.41 + 15.42 +uint32_t rtc_get_alarm_seconds(void *rtc) 15.43 +{ 15.44 + return x1600_rtc_get_alarm_seconds(rtc); 15.45 +} 15.46 + 15.47 +void rtc_set_alarm_seconds(void *rtc, uint32_t seconds) 15.48 +{ 15.49 + x1600_rtc_set_alarm_seconds(rtc, seconds); 15.50 +} 15.51 + 15.52 +void rtc_power_down(void *rtc) 15.53 +{ 15.54 + x1600_rtc_power_down(rtc); 15.55 +} 15.56 + 15.57 +void rtc_set_regulator(void *rtc, uint32_t base, uint32_t adjustment) 15.58 +{ 15.59 + x1600_rtc_set_regulator(rtc, base, adjustment); 15.60 +} 15.61 + 15.62 + 15.63 + 15.64 /* SPI adapter functions. */ 15.65 15.66 void *spi_init(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, void *cpm) 15.67 @@ -391,6 +441,7 @@ 15.68 [DMA] = "x1600-dma", 15.69 [GPIO] = "x1600-gpio", 15.70 [I2C] = "x1600-i2c", 15.71 + [RTC] = "x1600-rtc", 15.72 [SSI] = "x1600-ssi", 15.73 }; 15.74