-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Add MFD Support for Motorola mc146818 RTC, Counter, and BBRAM #91751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
akanisetti
wants to merge
5
commits into
zephyrproject-rtos:main
Choose a base branch
from
akanisetti:bbram_mc141618
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+588
−113
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
1112f04
drivers: mfd: Enabled motorola,mc146818 MFD
akanisetti ff34ca5
drivers: rtc: Enabled MFD support for RTC mc146818
akanisetti de736cd
drivers: counter: Enables support for MFD in counter
akanisetti bb75220
drivers: bbram: Enables bbram driver for motorola, mc146818
akanisetti bd736c3
dts: x86: Added required modifications to support RTC MFD
akanisetti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,10 @@ | |
status = "okay"; | ||
}; | ||
|
||
&mfd { | ||
status = "okay"; | ||
}; | ||
|
||
&rtc { | ||
status = "okay"; | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Intel SoC BBRAM configuration options | ||
|
||
# Copyright (c) 2025 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config BBRAM_MOTOROLA_MC146818 | ||
bool "BBRAM driver for x86 CMOS/RTC clock's bbram" | ||
default y if !COUNTER | ||
select MFD | ||
depends on DT_HAS_MOTOROLA_MC146818_BBRAM_ENABLED | ||
help | ||
Enable driver for Motorola mc146818 BBRAM. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/* | ||
* Copyright (c) 2025 Intel Corporation. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/* | ||
* Read and Write access to offset ranges 0x2A(42)-0x31(49) and 0xAA(170)-0xB1(177) | ||
* are lockable through BIOS setting. To access the memory in those offsets, | ||
* disable the Lock in BIOS through following steps. | ||
* Intel Advanced Menu -> PCH-IO Configuration -> Security Configuration -> | ||
* RTC Memory Lock -> Disable | ||
*/ | ||
|
||
#define DT_DRV_COMPAT motorola_mc146818_bbram | ||
|
||
#include <zephyr/device.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/init.h> | ||
#include <zephyr/sys/util.h> | ||
#include <zephyr/devicetree.h> | ||
#include <zephyr/drivers/bbram.h> | ||
#include <zephyr/sys/sys_io.h> | ||
#include <zephyr/spinlock.h> | ||
#include <zephyr/drivers/mfd/mc146818.h> | ||
|
||
#define MIN_SIZE 1 /* Minimum size to write */ | ||
#define MIN_OFFSET 0x0E /* Starting offset of memory */ | ||
#define MAX_STD 0x7F /* Last offset of Standard memory bank */ | ||
#define RTC_CENT 0x32 /* Offset for RTC Century Byte */ | ||
|
||
struct bbram_mc146818_config { | ||
const struct device *mfd; | ||
size_t mem_size; | ||
}; | ||
|
||
struct bbram_mc146818_data { | ||
struct k_spinlock lock; | ||
}; | ||
|
||
static int bbram_mc146818_read(const struct device *dev, size_t offset, | ||
size_t size, uint8_t *data) | ||
{ | ||
const struct bbram_mc146818_config *config = dev->config; | ||
struct bbram_mc146818_data *dev_data = dev->data; | ||
|
||
if (size < MIN_SIZE || offset + size > config->mem_size | ||
|| data == NULL) { | ||
return -EFAULT; | ||
} | ||
|
||
offset += MIN_OFFSET; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&dev_data->lock); | ||
|
||
for (size_t i = 0; i < size; i++) { | ||
if (offset < MAX_STD) { | ||
if (offset >= RTC_CENT) { | ||
|
||
/* RTC_CENT byte is used to store Century data for the | ||
* RTC time and date, so skipping read/write operation | ||
* to this byte. | ||
*/ | ||
|
||
*(data + i) = mfd_mc146818_std_read(config->mfd, offset+1); | ||
} else { | ||
*(data + i) = mfd_mc146818_std_read(config->mfd, offset); | ||
} | ||
} else { | ||
*(data + i) = mfd_mc146818_ext_read(config->mfd, offset+1); | ||
} | ||
offset++; | ||
} | ||
|
||
k_spin_unlock(&dev_data->lock, key); | ||
return 0; | ||
} | ||
|
||
static int bbram_mc146818_write(const struct device *dev, size_t offset, | ||
size_t size, const uint8_t *data) | ||
{ | ||
const struct bbram_mc146818_config *config = dev->config; | ||
struct bbram_mc146818_data *dev_data = dev->data; | ||
|
||
if (size < MIN_SIZE || offset + size > config->mem_size | ||
|| data == NULL) { | ||
return -EFAULT; | ||
} | ||
|
||
offset += MIN_OFFSET; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&dev_data->lock); | ||
|
||
for (size_t i = 0; i < size; i++) { | ||
if (offset < MAX_STD) { | ||
if (offset >= RTC_CENT) { | ||
|
||
/* RTC_CENT byte is used to store Century data for the | ||
* RTC time and date, so skipping read/write operation | ||
* to this byte. | ||
*/ | ||
|
||
mfd_mc146818_std_write(config->mfd, offset+1, *(data + i)); | ||
} else { | ||
mfd_mc146818_std_write(config->mfd, offset, *(data + i)); | ||
} | ||
} else { | ||
mfd_mc146818_ext_write(config->mfd, offset+1, *(data + i)); | ||
} | ||
offset++; | ||
} | ||
|
||
k_spin_unlock(&dev_data->lock, key); | ||
return 0; | ||
} | ||
|
||
static int bbram_mc146818_get_size(const struct device *dev, size_t *size) | ||
{ | ||
const struct bbram_mc146818_config *config = dev->config; | ||
|
||
*size = config->mem_size; | ||
|
||
return 0; | ||
} | ||
|
||
static const struct bbram_driver_api bbram_mc146818_api = { | ||
.read = bbram_mc146818_read, | ||
.write = bbram_mc146818_write, | ||
.get_size = bbram_mc146818_get_size, | ||
}; | ||
|
||
static int bbram_mc146818_init(const struct device *dev) | ||
{ | ||
const struct bbram_mc146818_config *config = dev->config; | ||
|
||
if (!device_is_ready(config->mfd)) { | ||
return -ENODEV; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
#define BBRAM_MC146818_DEV_CFG(n) \ | ||
static const struct bbram_mc146818_config bbram_config_##n = { \ | ||
.mfd = DEVICE_DT_GET(DT_INST_PARENT(n)), \ | ||
.mem_size = DT_INST_PROP(n, size), \ | ||
}; \ | ||
static struct bbram_mc146818_data bbram_data_##n; \ | ||
DEVICE_DT_INST_DEFINE(n, &bbram_mc146818_init, NULL, \ | ||
&bbram_data_##n, &bbram_config_##n, \ | ||
POST_KERNEL, \ | ||
UTIL_INC(CONFIG_MFD_MOTOROLA_MC146818_INIT_PRIORITY), \ | ||
&bbram_mc146818_api); \ | ||
|
||
DT_INST_FOREACH_STATUS_OKAY(BBRAM_MC146818_DEV_CFG) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Intel SoC RTC configuration options | ||
|
||
# Copyright (c) 2025 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config MFD_MOTOROLA_MC146818 | ||
bool "MOTOROLA MC146818 multi-function device driver" | ||
default y | ||
depends on DT_HAS_MOTOROLA_MC146818_MFD_ENABLED | ||
help | ||
common code required by bbram and rtc, which will likely be a locking mechanism | ||
so both RTC and BBRAM can set/get regs safely and independently. | ||
|
||
config MFD_MOTOROLA_MC146818_INIT_PRIORITY | ||
int "Init priority of mc146818 MFD" | ||
depends on MFD_MOTOROLA_MC146818 | ||
default 50 | ||
help | ||
Initialization priority for the MOTOROLA MC146818 MFD driver. | ||
It must be greater than RTC, COUNTER and BBRAM driver init priority. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright (c) 2025 Intel Corporation. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#define DT_DRV_COMPAT motorola_mc146818_mfd | ||
|
||
#include <zephyr/kernel.h> | ||
#include <zephyr/device.h> | ||
#include <zephyr/spinlock.h> | ||
#include <zephyr/drivers/mfd/mc146818.h> | ||
#include <zephyr/init.h> | ||
#include <zephyr/sys/util.h> | ||
#include <zephyr/devicetree.h> | ||
#include <zephyr/sys/sys_io.h> | ||
|
||
#define RTC_STD_INDEX (DT_INST_REG_ADDR_BY_IDX(0, 0)) | ||
#define RTC_STD_TARGET (DT_INST_REG_ADDR_BY_IDX(0, 1)) | ||
#define RTC_EXT_INDEX (DT_INST_REG_ADDR_BY_IDX(0, 2)) | ||
#define RTC_EXT_TARGET (DT_INST_REG_ADDR_BY_IDX(0, 3)) | ||
|
||
struct mfd_mc146818_data { | ||
struct k_spinlock lock; | ||
}; | ||
|
||
uint8_t mfd_mc146818_std_read(const struct device *dev, uint8_t offset) | ||
{ | ||
struct mfd_mc146818_data *data = dev->data; | ||
uint8_t value; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&data->lock); | ||
|
||
sys_out8(offset, RTC_STD_INDEX); | ||
value = sys_in8(RTC_STD_TARGET); | ||
|
||
k_spin_unlock(&data->lock, key); | ||
return value; | ||
} | ||
|
||
void mfd_mc146818_std_write(const struct device *dev, uint8_t offset, uint8_t value) | ||
{ | ||
struct mfd_mc146818_data *data = dev->data; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&data->lock); | ||
|
||
sys_out8(offset, RTC_STD_INDEX); | ||
sys_out8(value, RTC_STD_TARGET); | ||
|
||
k_spin_unlock(&data->lock, key); | ||
} | ||
|
||
uint8_t mfd_mc146818_ext_read(const struct device *dev, uint8_t offset) | ||
{ | ||
struct mfd_mc146818_data *data = dev->data; | ||
uint8_t value; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&data->lock); | ||
|
||
sys_out8(offset, RTC_EXT_INDEX); | ||
value = sys_in8(RTC_EXT_TARGET); | ||
|
||
k_spin_unlock(&data->lock, key); | ||
return value; | ||
} | ||
|
||
void mfd_mc146818_ext_write(const struct device *dev, uint8_t offset, uint8_t value) | ||
{ | ||
struct mfd_mc146818_data *data = dev->data; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&data->lock); | ||
|
||
sys_out8(offset, RTC_EXT_INDEX); | ||
sys_out8(value, RTC_EXT_TARGET); | ||
|
||
k_spin_unlock(&data->lock, key); | ||
} | ||
|
||
#define MFD_MC146818_DEFINE(inst) \ | ||
static struct mfd_mc146818_data data##inst; \ | ||
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &data##inst, NULL, \ | ||
POST_KERNEL, \ | ||
CONFIG_MFD_MOTOROLA_MC146818_INIT_PRIORITY, \ | ||
NULL); \ | ||
|
||
DT_INST_FOREACH_STATUS_OKAY(MFD_MC146818_DEFINE) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.