Commit 08b8f3c4 authored by Anisetti Avinash Krishna's avatar Anisetti Avinash Krishna Committed by Henrik Brix Andersen
Browse files

drivers: bbram: Enables bbram driver for motorola, mc146818

Enables bbram driver for motorola, mc146818 under its MFD
to access the RAM of the RTC.

Signed-off-by: default avatarAnisetti Avinash Krishna <anisetti.avinash.krishna@intel.com>
parent 2b1b3f09
Loading
Loading
Loading
Loading
+1 −0
Changes for drivers/bbram/CMakeLists.txt: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -18,3 +18,4 @@ zephyr_library_sources_ifdef(CONFIG_BBRAM_MICROCHIP_MCP7940N_EMUL bbram_microchi
zephyr_library_sources_ifdef(CONFIG_BBRAM_XEC bbram_xec.c)
zephyr_library_sources_ifdef(CONFIG_BBRAM_STM32 bbram_stm32.c)
zephyr_library_sources_ifdef(CONFIG_BBRAM_RTS5912 bbram_rts5912.c)
zephyr_library_sources_ifdef(CONFIG_BBRAM_MOTOROLA_MC146818 bbram_mc146818.c)
+2 −0
Changes for drivers/bbram/Kconfig: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -44,4 +44,6 @@ source "drivers/bbram/Kconfig.stm32"

source "drivers/bbram/Kconfig.rts5912"

source "drivers/bbram/Kconfig.mc146818"

endif # BBRAM
+12 −0
Changes for drivers/bbram/Kconfig.mc146818: 12 added lines, 0 removed lines.
Original line number Diff line number Diff line
# 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.
+155 −0
Changes for drivers/bbram/bbram_mc146818.c: 155 added lines, 0 removed lines.
Original line number Diff line number Diff line
/*
 * 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 DEVICE_API(bbram, 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)
+17 −0
Changes for dts/bindings/memory-controllers/motorola,mc146818-bbram.yaml: 17 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Copyright (c) 2025, Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

description: Motorola MC146818 compatible Real Timer Clock Battery Backed RAM

compatible: "motorola,mc146818-bbram"

include: base.yaml

on-bus: mc146818-mfd

properties:
  size:
    type: int
    required: true
    description: Memory capacity in bytes.