Skip to content

Commit c4d4ff9

Browse files
committed
drivers: bbram: Enable bbram driver for MC146818
Enable bbram driver for MC146818 on RPL-s platform as a child of RTC MC146818 Signed-off-by: Anisetti Avinash Krishna <anisetti.avinash.krishna@intel.com>
1 parent 8fd5a7d commit c4d4ff9

File tree

7 files changed

+234
-0
lines changed

7 files changed

+234
-0
lines changed

boards/intel/rpl/intel_rpl_s_crb.dts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@
2424
aliases {
2525
watchdog0 = &tco_wdt;
2626
rtc = &rtc;
27+
bbram = &bbram;
2728
};
2829
};

drivers/bbram/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ zephyr_library_sources_ifdef(CONFIG_BBRAM_MICROCHIP_MCP7940N_EMUL bbram_microchi
1818
zephyr_library_sources_ifdef(CONFIG_BBRAM_XEC bbram_xec.c)
1919
zephyr_library_sources_ifdef(CONFIG_BBRAM_STM32 bbram_stm32.c)
2020
zephyr_library_sources_ifdef(CONFIG_BBRAM_RTS5912 bbram_rts5912.c)
21+
zephyr_library_sources_ifdef(CONFIG_BBRAM_MOTOROLA_MC146818 bbram_mc146818.c)

drivers/bbram/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,6 @@ source "drivers/bbram/Kconfig.stm32"
4444

4545
source "drivers/bbram/Kconfig.rts5912"
4646

47+
source "drivers/bbram/Kconfig.mc146818"
48+
4749
endif # BBRAM

drivers/bbram/Kconfig.mc146818

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Intel SoC BBRAM configuration options
2+
3+
# Copyright (c) 2025 Intel Corporation
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config BBRAM_MOTOROLA_MC146818
7+
bool "BBRAM driver for x86 CMOS/RTC clock's bbram"
8+
default y
9+
depends on RTC_MOTOROLA_MC146818
10+
depends on DT_HAS_MOTOROLA_MC146818_BBRAM_ENABLED
11+
help
12+
Enable driver for Motorola mc146818 BBRAM.

drivers/bbram/bbram_mc146818.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/*
2+
* Copyright (c) 2025 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* Read and Write access to offset ranges 0x2A(42)-0x31(49) and 0xAA(170)-0xB1(177)
9+
* are lockable through BIOS setting. To access the memory in those offsets,
10+
* disable the Lock in BIOS through following steps.
11+
* Intel Advanced Menu -> PCH-IO Configuration -> Security Configuration ->
12+
* RTC Memory Lock -> Disable
13+
*/
14+
15+
#define DT_DRV_COMPAT motorola_mc146818_bbram
16+
17+
#include <zephyr/device.h>
18+
#include <zephyr/kernel.h>
19+
#include <zephyr/init.h>
20+
#include <zephyr/sys/util.h>
21+
#include <zephyr/devicetree.h>
22+
#include <zephyr/drivers/bbram.h>
23+
#include <zephyr/sys/sys_io.h>
24+
#include <zephyr/spinlock.h>
25+
#include <zephyr/drivers/rtc/mc146818.h>
26+
27+
#define MIN_SIZE 1 /* Minimum size to write */
28+
#define MIN_OFFSET 0x0E /* Starting offset of memory */
29+
#define MAX_STD 0x7F /* Last offset of Standard memory bank */
30+
#define RTC_CENT 0x32 /* Offset for RTC Century Byte */
31+
32+
struct bbram_mc146818_config {
33+
const struct device *parent;
34+
io_port_t std_index;
35+
io_port_t std_target;
36+
io_port_t ext_index;
37+
io_port_t ext_target;
38+
size_t mem_size;
39+
};
40+
41+
struct bbram_mc146818_data {
42+
struct k_spinlock *lock;
43+
};
44+
45+
static uint8_t std_reg_read(const struct bbram_mc146818_config *cfg, int reg)
46+
{
47+
48+
sys_out8(reg, cfg->std_index);
49+
return sys_in8(cfg->std_target);
50+
}
51+
52+
static uint8_t ext_reg_read(const struct bbram_mc146818_config *cfg, int reg)
53+
{
54+
55+
sys_out8(reg, cfg->ext_index);
56+
return sys_in8(cfg->ext_target);
57+
}
58+
59+
static void std_reg_write(const struct bbram_mc146818_config *cfg, uint8_t value, int reg)
60+
{
61+
sys_out8(reg, cfg->std_index);
62+
sys_out8(value, cfg->std_target);
63+
}
64+
65+
static void ext_reg_write(const struct bbram_mc146818_config *cfg, uint8_t value, int reg)
66+
{
67+
sys_out8(reg, cfg->ext_index);
68+
sys_out8(value, cfg->ext_target);
69+
}
70+
71+
static int bbram_mc146818_read(const struct device *dev, size_t offset,
72+
size_t size, uint8_t *data)
73+
{
74+
const struct bbram_mc146818_config *config = dev->config;
75+
struct bbram_mc146818_data *dev_data = dev->data;
76+
77+
if (size < MIN_SIZE || offset + size > config->mem_size
78+
|| data == NULL) {
79+
return -EFAULT;
80+
}
81+
82+
offset += MIN_OFFSET;
83+
84+
k_spinlock_key_t key = k_spin_lock(dev_data->lock);
85+
86+
for (size_t i = 0; i < size; i++) {
87+
if (offset < MAX_STD) {
88+
if (offset >= RTC_CENT) {
89+
90+
/* RTC_CENT byte is used to store Century data for the
91+
* RTC time and date, so skipping read/write operation
92+
* to this byte.
93+
*/
94+
95+
*(data + i) = std_reg_read(config, offset+1);
96+
} else {
97+
*(data + i) = std_reg_read(config, offset);
98+
}
99+
} else {
100+
*(data + i) = ext_reg_read(config, offset+1);
101+
}
102+
offset++;
103+
}
104+
105+
k_spin_unlock(dev_data->lock, key);
106+
return 0;
107+
}
108+
109+
static int bbram_mc146818_write(const struct device *dev, size_t offset,
110+
size_t size, const uint8_t *data)
111+
{
112+
const struct bbram_mc146818_config *config = dev->config;
113+
struct bbram_mc146818_data *dev_data = dev->data;
114+
115+
if (size < MIN_SIZE || offset + size > config->mem_size
116+
|| data == NULL) {
117+
return -EFAULT;
118+
}
119+
120+
offset += MIN_OFFSET;
121+
122+
k_spinlock_key_t key = k_spin_lock(dev_data->lock);
123+
124+
for (size_t i = 0; i < size; i++) {
125+
if (offset < MAX_STD) {
126+
if (offset >= RTC_CENT) {
127+
128+
/* RTC_CENT byte is used to store Century data for the
129+
* RTC time and date, so skipping read/write operation
130+
* to this byte.
131+
*/
132+
133+
std_reg_write(config, *(data + i), offset+1);
134+
} else {
135+
std_reg_write(config, *(data + i), offset);
136+
}
137+
} else {
138+
ext_reg_write(config, *(data + i), offset+1);
139+
}
140+
offset++;
141+
}
142+
143+
k_spin_unlock(dev_data->lock, key);
144+
return 0;
145+
}
146+
147+
static int bbram_mc146818_get_size(const struct device *dev, size_t *size)
148+
{
149+
const struct bbram_mc146818_config *config = dev->config;
150+
151+
*size = config->mem_size;
152+
153+
return 0;
154+
}
155+
156+
static const struct bbram_driver_api bbram_mc146818_api = {
157+
.read = bbram_mc146818_read,
158+
.write = bbram_mc146818_write,
159+
.get_size = bbram_mc146818_get_size,
160+
};
161+
162+
static int bbram_mc146818_init(const struct device *dev)
163+
{
164+
const struct bbram_mc146818_config *config = dev->config;
165+
struct bbram_mc146818_data *dev_data = dev->data;
166+
struct rtc_mc146818_data *parent_data = config->parent->data;
167+
168+
if (!device_is_ready(config->parent)) {
169+
return -ENODEV;
170+
}
171+
172+
dev_data->lock = &parent_data->lock;
173+
return 0;
174+
}
175+
176+
#define BBRAM_MC146818_DEV_CFG(n) \
177+
static const struct bbram_mc146818_config bbram_config_##n = { \
178+
.parent = DEVICE_DT_GET(DT_INST_PARENT(n)), \
179+
.std_index = DT_REG_ADDR_BY_IDX(DT_INST_PARENT(n), 0), \
180+
.std_target = DT_REG_ADDR_BY_IDX(DT_INST_PARENT(n), 1), \
181+
.ext_index = DT_INST_REG_ADDR_BY_IDX(n, 0), \
182+
.ext_target = DT_INST_REG_ADDR_BY_IDX(n, 1), \
183+
.mem_size = DT_INST_PROP(n, size), \
184+
}; \
185+
static struct bbram_mc146818_data bbram_data_##n; \
186+
DEVICE_DT_INST_DEFINE(n, &bbram_mc146818_init, NULL, \
187+
&bbram_data_##n, &bbram_config_##n, \
188+
POST_KERNEL, \
189+
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
190+
&bbram_mc146818_api); \
191+
192+
DT_INST_FOREACH_STATUS_OKAY(BBRAM_MC146818_DEV_CFG)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright (c) 2025, Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
description: Motorola MC146818 compatible Real Timer Clock Battery Backed RAM
6+
7+
compatible: "motorola,mc146818-bbram"
8+
9+
include: base.yaml
10+
11+
properties:
12+
reg:
13+
required: true
14+
size:
15+
type: int
16+
required: true
17+
description: Memory capacity in bytes.

dts/x86/intel/raptor_lake_s.dtsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,15 @@
549549
interrupts = <8 IRQ_TYPE_LOWEST_EDGE_RISING 3>;
550550
interrupt-parent = <&intc>;
551551
alarms-count = <1>;
552+
#address-cells = <1>;
553+
#size-cells = <1>;
554+
555+
bbram: bbram@72 {
556+
compatible = "motorola,mc146818-bbram";
557+
reg = <0x72 0x01 0x73 0x01>;
558+
size = <241>;
559+
status = "okay";
560+
};
552561

553562
status = "okay";
554563
};

0 commit comments

Comments
 (0)