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,35 @@
# SPDX-License-Identifier: GPL-2.0
config SAMSUNG_MC
bool "Samsung Exynos Memory Controller support" if COMPILE_TEST
help
Support for the Memory Controller (MC) devices found on
Samsung Exynos SoCs.
if SAMSUNG_MC
config EXYNOS5422_DMC
tristate "Exynos5422 Dynamic Memory Controller driver"
depends on ARCH_EXYNOS || (COMPILE_TEST && HAS_IOMEM)
select DDR
depends on DEVFREQ_GOV_SIMPLE_ONDEMAND
depends on (PM_DEVFREQ && PM_DEVFREQ_EVENT)
help
This adds driver for Samsung Exynos5422 SoC DMC (Dynamic Memory
Controller). The driver provides support for Dynamic Voltage and
Frequency Scaling in DMC and DRAM. It also supports changing timings
of DRAM running with different frequency. The timings are calculated
based on DT memory information.
If unsure, say Y on devices with Samsung Exynos SoCs.
config EXYNOS_SROM
bool "Exynos SROM controller driver" if COMPILE_TEST
depends on (ARM && ARCH_EXYNOS) || (COMPILE_TEST && HAS_IOMEM)
help
This adds driver for Samsung Exynos SoC SROM controller. The driver
in basic operation mode only saves and restores SROM registers
during suspend. If however appropriate device tree configuration
is provided, the driver enables support for external memory
or external devices.
If unsure, say Y on devices with Samsung Exynos SoCs.
endif
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_EXYNOS5422_DMC) += exynos5422-dmc.o
obj-$(CONFIG_EXYNOS_SROM) += exynos-srom.o
@@ -0,0 +1,210 @@
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2015 Samsung Electronics Co., Ltd.
// http://www.samsung.com/
//
// Exynos - SROM Controller support
// Author: Pankaj Dubey <pankaj.dubey@samsung.com>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "exynos-srom.h"
static const unsigned long exynos_srom_offsets[] = {
/* SROM side */
EXYNOS_SROM_BW,
EXYNOS_SROM_BC0,
EXYNOS_SROM_BC1,
EXYNOS_SROM_BC2,
EXYNOS_SROM_BC3,
};
/**
* struct exynos_srom_reg_dump: register dump of SROM Controller registers.
* @offset: srom register offset from the controller base address.
* @value: the value of register under the offset.
*/
struct exynos_srom_reg_dump {
u32 offset;
u32 value;
};
/**
* struct exynos_srom: platform data for exynos srom controller driver.
* @dev: platform device pointer
* @reg_base: srom base address
* @reg_offset: exynos_srom_reg_dump pointer to hold offset and its value.
*/
struct exynos_srom {
struct device *dev;
void __iomem *reg_base;
struct exynos_srom_reg_dump *reg_offset;
};
static struct exynos_srom_reg_dump *
exynos_srom_alloc_reg_dump(const unsigned long *rdump,
unsigned long nr_rdump)
{
struct exynos_srom_reg_dump *rd;
unsigned int i;
rd = kzalloc_objs(*rd, nr_rdump);
if (!rd)
return NULL;
for (i = 0; i < nr_rdump; ++i)
rd[i].offset = rdump[i];
return rd;
}
static int exynos_srom_configure_bank(struct exynos_srom *srom,
struct device_node *np)
{
u32 bank, width, pmc = 0;
u32 timing[6];
u32 cs, bw;
if (of_property_read_u32(np, "reg", &bank))
return -EINVAL;
if (of_property_read_u32(np, "reg-io-width", &width))
width = 1;
if (of_property_read_bool(np, "samsung,srom-page-mode"))
pmc = 1 << EXYNOS_SROM_BCX__PMC__SHIFT;
if (of_property_read_u32_array(np, "samsung,srom-timing", timing,
ARRAY_SIZE(timing)))
return -EINVAL;
bank *= 4; /* Convert bank into shift/offset */
cs = 1 << EXYNOS_SROM_BW__BYTEENABLE__SHIFT;
if (width == 2)
cs |= 1 << EXYNOS_SROM_BW__DATAWIDTH__SHIFT;
bw = readl_relaxed(srom->reg_base + EXYNOS_SROM_BW);
bw = (bw & ~(EXYNOS_SROM_BW__CS_MASK << bank)) | (cs << bank);
writel_relaxed(bw, srom->reg_base + EXYNOS_SROM_BW);
writel_relaxed(pmc | (timing[0] << EXYNOS_SROM_BCX__TACP__SHIFT) |
(timing[1] << EXYNOS_SROM_BCX__TCAH__SHIFT) |
(timing[2] << EXYNOS_SROM_BCX__TCOH__SHIFT) |
(timing[3] << EXYNOS_SROM_BCX__TACC__SHIFT) |
(timing[4] << EXYNOS_SROM_BCX__TCOS__SHIFT) |
(timing[5] << EXYNOS_SROM_BCX__TACS__SHIFT),
srom->reg_base + EXYNOS_SROM_BC0 + bank);
return 0;
}
static int exynos_srom_probe(struct platform_device *pdev)
{
struct device_node *np, *child;
struct exynos_srom *srom;
struct device *dev = &pdev->dev;
bool bad_bank_config = false;
np = dev->of_node;
if (!np) {
dev_err(&pdev->dev, "could not find device info\n");
return -EINVAL;
}
srom = devm_kzalloc(&pdev->dev,
sizeof(struct exynos_srom), GFP_KERNEL);
if (!srom)
return -ENOMEM;
srom->dev = dev;
srom->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(srom->reg_base)) {
dev_err(&pdev->dev, "iomap of exynos srom controller failed\n");
return PTR_ERR(srom->reg_base);
}
platform_set_drvdata(pdev, srom);
srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
ARRAY_SIZE(exynos_srom_offsets));
if (!srom->reg_offset)
return -ENOMEM;
for_each_child_of_node(np, child) {
if (exynos_srom_configure_bank(srom, child)) {
dev_err(dev,
"Could not decode bank configuration for %pOFn\n",
child);
bad_bank_config = true;
}
}
/*
* If any bank failed to configure, we still provide suspend/resume,
* but do not probe child devices
*/
if (bad_bank_config)
return 0;
return of_platform_populate(np, NULL, NULL, dev);
}
#ifdef CONFIG_PM_SLEEP
static void exynos_srom_save(void __iomem *base,
struct exynos_srom_reg_dump *rd,
unsigned int num_regs)
{
for (; num_regs > 0; --num_regs, ++rd)
rd->value = readl(base + rd->offset);
}
static void exynos_srom_restore(void __iomem *base,
const struct exynos_srom_reg_dump *rd,
unsigned int num_regs)
{
for (; num_regs > 0; --num_regs, ++rd)
writel(rd->value, base + rd->offset);
}
static int exynos_srom_suspend(struct device *dev)
{
struct exynos_srom *srom = dev_get_drvdata(dev);
exynos_srom_save(srom->reg_base, srom->reg_offset,
ARRAY_SIZE(exynos_srom_offsets));
return 0;
}
static int exynos_srom_resume(struct device *dev)
{
struct exynos_srom *srom = dev_get_drvdata(dev);
exynos_srom_restore(srom->reg_base, srom->reg_offset,
ARRAY_SIZE(exynos_srom_offsets));
return 0;
}
#endif
static const struct of_device_id of_exynos_srom_ids[] = {
{
.compatible = "samsung,exynos4210-srom",
},
{},
};
static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume);
static struct platform_driver exynos_srom_driver = {
.probe = exynos_srom_probe,
.driver = {
.name = "exynos-srom",
.of_match_table = of_exynos_srom_ids,
.pm = &exynos_srom_pm_ops,
.suppress_bind_attrs = true,
},
};
builtin_platform_driver(exynos_srom_driver);
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Exynos SROMC register definitions
*/
#ifndef __EXYNOS_SROM_H
#define __EXYNOS_SROM_H __FILE__
#define EXYNOS_SROMREG(x) (x)
#define EXYNOS_SROM_BW EXYNOS_SROMREG(0x0)
#define EXYNOS_SROM_BC0 EXYNOS_SROMREG(0x4)
#define EXYNOS_SROM_BC1 EXYNOS_SROMREG(0x8)
#define EXYNOS_SROM_BC2 EXYNOS_SROMREG(0xc)
#define EXYNOS_SROM_BC3 EXYNOS_SROMREG(0x10)
#define EXYNOS_SROM_BC4 EXYNOS_SROMREG(0x14)
#define EXYNOS_SROM_BC5 EXYNOS_SROMREG(0x18)
/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
#define EXYNOS_SROM_BW__DATAWIDTH__SHIFT 0
#define EXYNOS_SROM_BW__ADDRMODE__SHIFT 1
#define EXYNOS_SROM_BW__WAITENABLE__SHIFT 2
#define EXYNOS_SROM_BW__BYTEENABLE__SHIFT 3
#define EXYNOS_SROM_BW__CS_MASK 0xf
#define EXYNOS_SROM_BW__NCS0__SHIFT 0
#define EXYNOS_SROM_BW__NCS1__SHIFT 4
#define EXYNOS_SROM_BW__NCS2__SHIFT 8
#define EXYNOS_SROM_BW__NCS3__SHIFT 12
#define EXYNOS_SROM_BW__NCS4__SHIFT 16
#define EXYNOS_SROM_BW__NCS5__SHIFT 20
/* applies to same to BCS0 - BCS3 */
#define EXYNOS_SROM_BCX__PMC__SHIFT 0
#define EXYNOS_SROM_BCX__TACP__SHIFT 4
#define EXYNOS_SROM_BCX__TCAH__SHIFT 8
#define EXYNOS_SROM_BCX__TCOH__SHIFT 12
#define EXYNOS_SROM_BCX__TACC__SHIFT 16
#define EXYNOS_SROM_BCX__TCOS__SHIFT 24
#define EXYNOS_SROM_BCX__TACS__SHIFT 28
#endif /* __EXYNOS_SROM_H */
File diff suppressed because it is too large Load Diff