Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,21 @@
# SPDX-License-Identifier: GPL-2.0-only
config RESET_STARFIVE_JH71X0
bool
config RESET_STARFIVE_JH7100
bool "StarFive JH7100 Reset Driver"
depends on ARCH_STARFIVE || COMPILE_TEST
select RESET_STARFIVE_JH71X0
default ARCH_STARFIVE
help
This enables the reset controller driver for the StarFive JH7100 SoC.
config RESET_STARFIVE_JH7110
bool "StarFive JH7110 Reset Driver"
depends on CLK_STARFIVE_JH7110_SYS
select AUXILIARY_BUS
select RESET_STARFIVE_JH71X0
default ARCH_STARFIVE
help
This enables the reset controller driver for the StarFive JH7110 SoC.
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Reset driver for the StarFive JH7100 SoC
*
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
*/
#include <linux/platform_device.h>
#include "reset-starfive-jh71x0.h"
#include <dt-bindings/reset/starfive-jh7100.h>
/* register offsets */
#define JH7100_RESET_ASSERT0 0x00
#define JH7100_RESET_ASSERT1 0x04
#define JH7100_RESET_ASSERT2 0x08
#define JH7100_RESET_ASSERT3 0x0c
#define JH7100_RESET_STATUS0 0x10
#define JH7100_RESET_STATUS1 0x14
#define JH7100_RESET_STATUS2 0x18
#define JH7100_RESET_STATUS3 0x1c
/*
* Writing a 1 to the n'th bit of the m'th ASSERT register asserts
* line 32m + n, and writing a 0 deasserts the same line.
* Most reset lines have their status inverted so a 0 bit in the STATUS
* register means the line is asserted and a 1 means it's deasserted. A few
* lines don't though, so store the expected value of the status registers when
* all lines are asserted.
*/
static const u32 jh7100_reset_asserted[4] = {
/* STATUS0 */
BIT(JH7100_RST_U74 % 32) |
BIT(JH7100_RST_VP6_DRESET % 32) |
BIT(JH7100_RST_VP6_BRESET % 32),
/* STATUS1 */
BIT(JH7100_RST_HIFI4_DRESET % 32) |
BIT(JH7100_RST_HIFI4_BRESET % 32),
/* STATUS2 */
BIT(JH7100_RST_E24 % 32),
/* STATUS3 */
0,
};
static int __init jh7100_reset_probe(struct platform_device *pdev)
{
void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
base + JH7100_RESET_ASSERT0,
base + JH7100_RESET_STATUS0,
jh7100_reset_asserted,
JH7100_RSTN_END,
THIS_MODULE);
}
static const struct of_device_id jh7100_reset_dt_ids[] = {
{ .compatible = "starfive,jh7100-reset" },
{ /* sentinel */ }
};
static struct platform_driver jh7100_reset_driver = {
.driver = {
.name = "jh7100-reset",
.of_match_table = jh7100_reset_dt_ids,
.suppress_bind_attrs = true,
},
};
builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Reset driver for the StarFive JH7110 SoC
*
* Copyright (C) 2022 StarFive Technology Co., Ltd.
*/
#include <linux/auxiliary_bus.h>
#include <soc/starfive/reset-starfive-jh71x0.h>
#include "reset-starfive-jh71x0.h"
#include <dt-bindings/reset/starfive,jh7110-crg.h>
struct jh7110_reset_info {
unsigned int nr_resets;
unsigned int assert_offset;
unsigned int status_offset;
};
static const struct jh7110_reset_info jh7110_sys_info = {
.nr_resets = JH7110_SYSRST_END,
.assert_offset = 0x2F8,
.status_offset = 0x308,
};
static const struct jh7110_reset_info jh7110_aon_info = {
.nr_resets = JH7110_AONRST_END,
.assert_offset = 0x38,
.status_offset = 0x3C,
};
static const struct jh7110_reset_info jh7110_stg_info = {
.nr_resets = JH7110_STGRST_END,
.assert_offset = 0x74,
.status_offset = 0x78,
};
static const struct jh7110_reset_info jh7110_isp_info = {
.nr_resets = JH7110_ISPRST_END,
.assert_offset = 0x38,
.status_offset = 0x3C,
};
static const struct jh7110_reset_info jh7110_vout_info = {
.nr_resets = JH7110_VOUTRST_END,
.assert_offset = 0x48,
.status_offset = 0x4C,
};
static int jh7110_reset_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
void __iomem *base = rdev->base;
if (!info || !base)
return -ENODEV;
return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
base + info->assert_offset,
base + info->status_offset,
NULL,
info->nr_resets,
NULL);
}
static const struct auxiliary_device_id jh7110_reset_ids[] = {
{
.name = "clk_starfive_jh7110_sys.rst-sys",
.driver_data = (kernel_ulong_t)&jh7110_sys_info,
},
{
.name = "clk_starfive_jh7110_sys.rst-aon",
.driver_data = (kernel_ulong_t)&jh7110_aon_info,
},
{
.name = "clk_starfive_jh7110_sys.rst-stg",
.driver_data = (kernel_ulong_t)&jh7110_stg_info,
},
{
.name = "clk_starfive_jh7110_sys.rst-isp",
.driver_data = (kernel_ulong_t)&jh7110_isp_info,
},
{
.name = "clk_starfive_jh7110_sys.rst-vo",
.driver_data = (kernel_ulong_t)&jh7110_vout_info,
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
static struct auxiliary_driver jh7110_reset_driver = {
.probe = jh7110_reset_probe,
.id_table = jh7110_reset_ids,
};
module_auxiliary_driver(jh7110_reset_driver);
MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
MODULE_DESCRIPTION("StarFive JH7110 reset driver");
MODULE_LICENSE("GPL");
@@ -0,0 +1,134 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Reset driver for the StarFive JH71X0 SoCs
*
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
*/
#include <linux/bitmap.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/reset-controller.h>
#include <linux/spinlock.h>
#include "reset-starfive-jh71x0.h"
struct jh71x0_reset {
struct reset_controller_dev rcdev;
/* protect registers against concurrent read-modify-write */
spinlock_t lock;
void __iomem *assert;
void __iomem *status;
const u32 *asserted;
};
static inline struct jh71x0_reset *
jh71x0_reset_from(struct reset_controller_dev *rcdev)
{
return container_of(rcdev, struct jh71x0_reset, rcdev);
}
static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
unsigned long offset = id / 32;
u32 mask = BIT(id % 32);
void __iomem *reg_assert = data->assert + offset * sizeof(u32);
void __iomem *reg_status = data->status + offset * sizeof(u32);
u32 done = data->asserted ? data->asserted[offset] & mask : 0;
u32 value;
unsigned long flags;
int ret;
if (!assert)
done ^= mask;
spin_lock_irqsave(&data->lock, flags);
value = readl(reg_assert);
if (assert)
value |= mask;
else
value &= ~mask;
writel(value, reg_assert);
/* if the associated clock is gated, deasserting might otherwise hang forever */
ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
spin_unlock_irqrestore(&data->lock, flags);
return ret;
}
static int jh71x0_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return jh71x0_reset_update(rcdev, id, true);
}
static int jh71x0_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return jh71x0_reset_update(rcdev, id, false);
}
static int jh71x0_reset_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
int ret;
ret = jh71x0_reset_assert(rcdev, id);
if (ret)
return ret;
return jh71x0_reset_deassert(rcdev, id);
}
static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
unsigned long offset = id / 32;
u32 mask = BIT(id % 32);
void __iomem *reg_status = data->status + offset * sizeof(u32);
u32 value = readl(reg_status);
if (!data->asserted)
return !(value & mask);
return !((value ^ data->asserted[offset]) & mask);
}
static const struct reset_control_ops jh71x0_reset_ops = {
.assert = jh71x0_reset_assert,
.deassert = jh71x0_reset_deassert,
.reset = jh71x0_reset_reset,
.status = jh71x0_reset_status,
};
int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
void __iomem *assert, void __iomem *status,
const u32 *asserted, unsigned int nr_resets,
struct module *owner)
{
struct jh71x0_reset *data;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->rcdev.ops = &jh71x0_reset_ops;
data->rcdev.owner = owner;
data->rcdev.nr_resets = nr_resets;
data->rcdev.dev = dev;
data->rcdev.of_node = of_node;
spin_lock_init(&data->lock);
data->assert = assert;
data->status = status;
data->asserted = asserted;
return devm_reset_controller_register(dev, &data->rcdev);
}
EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register);
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
*/
#ifndef __RESET_STARFIVE_JH71X0_H
#define __RESET_STARFIVE_JH71X0_H
int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
void __iomem *assert, void __iomem *status,
const u32 *asserted, unsigned int nr_resets,
struct module *owner);
#endif /* __RESET_STARFIVE_JH71X0_H */