diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firmware/arm_ffa/bus.c | 2 | ||||
-rw-r--r-- | drivers/memory/emif.c | 65 | ||||
-rw-r--r-- | drivers/soc/mediatek/Kconfig | 9 | ||||
-rw-r--r-- | drivers/soc/mediatek/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-socinfo.c | 191 | ||||
-rw-r--r-- | drivers/soc/renesas/Kconfig | 17 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-rst.c | 1 | ||||
-rw-r--r-- | drivers/soc/renesas/renesas-soc.c | 8 |
8 files changed, 249 insertions, 45 deletions
diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c index 1c7940ba5539..2f557e90f2eb 100644 --- a/drivers/firmware/arm_ffa/bus.c +++ b/drivers/firmware/arm_ffa/bus.c @@ -105,7 +105,7 @@ static struct attribute *ffa_device_attributes_attrs[] = { }; ATTRIBUTE_GROUPS(ffa_device_attributes); -struct bus_type ffa_bus_type = { +const struct bus_type ffa_bus_type = { .name = "arm_ffa", .match = ffa_device_match, .probe = ffa_device_probe, diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c index 434982545be6..8c5ad5c025fa 100644 --- a/drivers/memory/emif.c +++ b/drivers/memory/emif.c @@ -72,7 +72,6 @@ static DEFINE_SPINLOCK(emif_lock); static unsigned long irq_state; static LIST_HEAD(device_list); -#ifdef CONFIG_DEBUG_FS static void do_emif_regdump_show(struct seq_file *s, struct emif_data *emif, struct emif_regs *regs) { @@ -140,31 +139,24 @@ static int emif_mr4_show(struct seq_file *s, void *unused) DEFINE_SHOW_ATTRIBUTE(emif_mr4); -static int __init_or_module emif_debugfs_init(struct emif_data *emif) +static void emif_debugfs_init(struct emif_data *emif) { - emif->debugfs_root = debugfs_create_dir(dev_name(emif->dev), NULL); - debugfs_create_file("regcache_dump", S_IRUGO, emif->debugfs_root, emif, - &emif_regdump_fops); - debugfs_create_file("mr4", S_IRUGO, emif->debugfs_root, emif, - &emif_mr4_fops); - return 0; -} - -static void __exit emif_debugfs_exit(struct emif_data *emif) -{ - debugfs_remove_recursive(emif->debugfs_root); - emif->debugfs_root = NULL; -} -#else -static inline int __init_or_module emif_debugfs_init(struct emif_data *emif) -{ - return 0; + if (IS_ENABLED(CONFIG_DEBUG_FS)) { + emif->debugfs_root = debugfs_create_dir(dev_name(emif->dev), NULL); + debugfs_create_file("regcache_dump", S_IRUGO, emif->debugfs_root, emif, + &emif_regdump_fops); + debugfs_create_file("mr4", S_IRUGO, emif->debugfs_root, emif, + &emif_mr4_fops); + } } -static inline void __exit emif_debugfs_exit(struct emif_data *emif) +static void emif_debugfs_exit(struct emif_data *emif) { + if (IS_ENABLED(CONFIG_DEBUG_FS)) { + debugfs_remove_recursive(emif->debugfs_root); + emif->debugfs_root = NULL; + } } -#endif /* * Get bus width used by EMIF. Note that this may be different from the @@ -679,7 +671,7 @@ static void disable_and_clear_all_interrupts(struct emif_data *emif) clear_all_interrupts(emif); } -static int __init_or_module setup_interrupts(struct emif_data *emif, u32 irq) +static int setup_interrupts(struct emif_data *emif, u32 irq) { u32 interrupts, type; void __iomem *base = emif->base; @@ -710,7 +702,7 @@ static int __init_or_module setup_interrupts(struct emif_data *emif, u32 irq) } -static void __init_or_module emif_onetime_settings(struct emif_data *emif) +static void emif_onetime_settings(struct emif_data *emif) { u32 pwr_mgmt_ctrl, zq, temp_alert_cfg; void __iomem *base = emif->base; @@ -834,8 +826,7 @@ static int is_custom_config_valid(struct emif_custom_configs *cust_cfgs, return valid; } -#if defined(CONFIG_OF) -static void __init_or_module of_get_custom_configs(struct device_node *np_emif, +static void of_get_custom_configs(struct device_node *np_emif, struct emif_data *emif) { struct emif_custom_configs *cust_cfgs = NULL; @@ -884,7 +875,7 @@ static void __init_or_module of_get_custom_configs(struct device_node *np_emif, emif->plat_data->custom_configs = cust_cfgs; } -static void __init_or_module of_get_ddr_info(struct device_node *np_emif, +static void of_get_ddr_info(struct device_node *np_emif, struct device_node *np_ddr, struct ddr_device_info *dev_info) { @@ -918,7 +909,7 @@ static void __init_or_module of_get_ddr_info(struct device_node *np_emif, dev_info->io_width = __fls(io_width) - 1; } -static struct emif_data * __init_or_module of_get_memory_device_details( +static struct emif_data *of_get_memory_device_details( struct device_node *np_emif, struct device *dev) { struct emif_data *emif = NULL; @@ -991,16 +982,7 @@ out: return emif; } -#else - -static struct emif_data * __init_or_module of_get_memory_device_details( - struct device_node *np_emif, struct device *dev) -{ - return NULL; -} -#endif - -static struct emif_data *__init_or_module get_device_details( +static struct emif_data *get_device_details( struct platform_device *pdev) { u32 size; @@ -1104,7 +1086,7 @@ error: return NULL; } -static int __init_or_module emif_probe(struct platform_device *pdev) +static int emif_probe(struct platform_device *pdev) { struct emif_data *emif; int irq, ret; @@ -1159,7 +1141,7 @@ error: return -ENODEV; } -static void __exit emif_remove(struct platform_device *pdev) +static void emif_remove(struct platform_device *pdev) { struct emif_data *emif = platform_get_drvdata(pdev); @@ -1183,7 +1165,8 @@ MODULE_DEVICE_TABLE(of, emif_of_match); #endif static struct platform_driver emif_driver = { - .remove_new = __exit_p(emif_remove), + .probe = emif_probe, + .remove_new = emif_remove, .shutdown = emif_shutdown, .driver = { .name = "emif", @@ -1191,7 +1174,7 @@ static struct platform_driver emif_driver = { }, }; -module_platform_driver_probe(emif_driver, emif_probe); +module_platform_driver(emif_driver); MODULE_DESCRIPTION("TI EMIF SDRAM Controller Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 0810b5b0c688..50c664b65f4d 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -68,4 +68,13 @@ config MTK_SVS chip process corner, temperatures and other factors. Then DVFS driver could apply SVS bank voltage to PMIC/Buck. +config MTK_SOCINFO + tristate "MediaTek SoC Information" + default y + depends on NVMEM_MTK_EFUSE + help + The MediaTek SoC Information (mtk-socinfo) driver provides + information about the SoC to the userspace including the + manufacturer name, marketing name and soc name. + endmenu diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 9d3ce7878c5c..6830512848fd 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_MTK_REGULATOR_COUPLER) += mtk-regulator-coupler.o obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o obj-$(CONFIG_MTK_SVS) += mtk-svs.o +obj-$(CONFIG_MTK_SOCINFO) += mtk-socinfo.o diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c new file mode 100644 index 000000000000..42572e8c1520 --- /dev/null +++ b/drivers/soc/mediatek/mtk-socinfo.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/pm_runtime.h> +#include <linux/nvmem-consumer.h> +#include <linux/device.h> +#include <linux/device/bus.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/string.h> +#include <linux/sys_soc.h> +#include <linux/slab.h> +#include <linux/platform_device.h> + +#define MTK_SOCINFO_ENTRY(_soc_name, _segment_name, _marketing_name, _cell_data1, _cell_data2) {\ + .soc_name = _soc_name, \ + .segment_name = _segment_name, \ + .marketing_name = _marketing_name, \ + .cell_data = {_cell_data1, _cell_data2} \ +} +#define CELL_NOT_USED (0xFFFFFFFF) +#define MAX_CELLS (2) + +struct mtk_socinfo { + struct device *dev; + struct name_data *name_data; + struct socinfo_data *socinfo_data; + struct soc_device *soc_dev; +}; + +struct socinfo_data { + char *soc_name; + char *segment_name; + char *marketing_name; + u32 cell_data[MAX_CELLS]; +}; + +static const char *cell_names[MAX_CELLS] = {"socinfo-data1", "socinfo-data2"}; + +static struct socinfo_data socinfo_data_table[] = { + MTK_SOCINFO_ENTRY("MT8173", "MT8173V/AC", "MT8173", 0x6CA20004, 0x10000000), + MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500", 0x00010043, 0x00000840), + MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500", 0x00010043, 0x00000940), + MTK_SOCINFO_ENTRY("MT8186", "MT8186GV/AZA", "Kompanio 520", 0x81861001, CELL_NOT_USED), + MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528", 0x81862001, CELL_NOT_USED), + MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 830", 0x81880000, 0x00000010), + MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 830", 0x81880000, 0x00000011), + MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820", 0x00001100, 0x00040080), + MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828", 0x00000100, 0x000400C0), + MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200", 0x81950300, CELL_NOT_USED), + MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200", 0x81950304, CELL_NOT_USED), + MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380", 0x81950400, CELL_NOT_USED), + MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED), +}; + +static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop) +{ + struct soc_device_attribute *attrs; + static char machine[30] = {0}; + static const char *soc_manufacturer = "MediaTek"; + + attrs = devm_kzalloc(mtk_socinfop->dev, sizeof(*attrs), GFP_KERNEL); + if (!attrs) + return -ENOMEM; + + snprintf(machine, sizeof(machine), "%s (%s)", mtk_socinfop->socinfo_data->marketing_name, + mtk_socinfop->socinfo_data->soc_name); + attrs->family = soc_manufacturer; + attrs->machine = machine; + + mtk_socinfop->soc_dev = soc_device_register(attrs); + if (IS_ERR(mtk_socinfop->soc_dev)) + return PTR_ERR(mtk_socinfop->soc_dev); + + dev_info(mtk_socinfop->dev, "%s %s SoC detected.\n", soc_manufacturer, attrs->machine); + return 0; +} + +static u32 mtk_socinfo_read_cell(struct device *dev, const char *name) +{ + struct nvmem_device *nvmemp; + struct device_node *np, *nvmem_node = dev->parent->of_node; + u32 offset; + u32 cell_val = CELL_NOT_USED; + + /* should never fail since the nvmem driver registers this child */ + nvmemp = nvmem_device_find(nvmem_node, device_match_of_node); + if (IS_ERR(nvmemp)) + goto out; + + np = of_get_child_by_name(nvmem_node, name); + if (!np) + goto put_device; + + if (of_property_read_u32_index(np, "reg", 0, &offset)) + goto put_node; + + nvmem_device_read(nvmemp, offset, sizeof(cell_val), &cell_val); + +put_node: + of_node_put(np); +put_device: + nvmem_device_put(nvmemp); +out: + return cell_val; +} + +static int mtk_socinfo_get_socinfo_data(struct mtk_socinfo *mtk_socinfop) +{ + unsigned int i, j; + unsigned int num_cell_data = 0; + u32 cell_data[MAX_CELLS] = {0}; + bool match_socinfo; + int match_socinfo_index = -1; + + for (i = 0; i < MAX_CELLS; i++) { + cell_data[i] = mtk_socinfo_read_cell(mtk_socinfop->dev, cell_names[i]); + if (cell_data[i] != CELL_NOT_USED) + num_cell_data++; + else + break; + } + + if (!num_cell_data) + return -ENOENT; + + for (i = 0; i < ARRAY_SIZE(socinfo_data_table); i++) { + match_socinfo = true; + for (j = 0; j < num_cell_data; j++) { + if (cell_data[j] != socinfo_data_table[i].cell_data[j]) { + match_socinfo = false; + break; + } + } + if (match_socinfo) { + mtk_socinfop->socinfo_data = &(socinfo_data_table[i]); + match_socinfo_index = i; + break; + } + } + + return match_socinfo_index >= 0 ? match_socinfo_index : -ENOENT; +} + +static int mtk_socinfo_probe(struct platform_device *pdev) +{ + struct mtk_socinfo *mtk_socinfop; + int ret; + + mtk_socinfop = devm_kzalloc(&pdev->dev, sizeof(*mtk_socinfop), GFP_KERNEL); + if (!mtk_socinfop) + return -ENOMEM; + + mtk_socinfop->dev = &pdev->dev; + + ret = mtk_socinfo_get_socinfo_data(mtk_socinfop); + if (ret < 0) + return dev_err_probe(mtk_socinfop->dev, ret, "Failed to get socinfo data\n"); + + ret = mtk_socinfo_create_socinfo_node(mtk_socinfop); + if (ret) + return dev_err_probe(mtk_socinfop->dev, ret, "Cannot create node\n"); + + platform_set_drvdata(pdev, mtk_socinfop); + return 0; +} + +static void mtk_socinfo_remove(struct platform_device *pdev) +{ + struct mtk_socinfo *mtk_socinfop = platform_get_drvdata(pdev); + + soc_device_unregister(mtk_socinfop->soc_dev); +} + +static struct platform_driver mtk_socinfo = { + .probe = mtk_socinfo_probe, + .remove_new = mtk_socinfo_remove, + .driver = { + .name = "mtk-socinfo", + }, +}; +module_platform_driver(mtk_socinfo); + +MODULE_AUTHOR("William-TW LIN <william-tw.lin@mediatek.com>"); +MODULE_DESCRIPTION("MediaTek socinfo driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 0986672f6375..5deca747fb77 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -34,6 +34,10 @@ config ARCH_RCAR_GEN3 select SYS_SUPPORTS_SH_CMT select SYS_SUPPORTS_SH_TMU +config ARCH_RCAR_GEN4 + bool + select ARCH_RCAR_GEN3 + config ARCH_RMOBILE bool select PM @@ -240,7 +244,7 @@ config ARCH_R8A77961 config ARCH_R8A779F0 bool "ARM64 Platform support for R-Car S4-8" - select ARCH_RCAR_GEN3 + select ARCH_RCAR_GEN4 select SYSC_R8A779F0 help This enables support for the Renesas R-Car S4-8 SoC. @@ -261,18 +265,25 @@ config ARCH_R8A77970 config ARCH_R8A779A0 bool "ARM64 Platform support for R-Car V3U" - select ARCH_RCAR_GEN3 + select ARCH_RCAR_GEN4 select SYSC_R8A779A0 help This enables support for the Renesas R-Car V3U SoC. config ARCH_R8A779G0 bool "ARM64 Platform support for R-Car V4H" - select ARCH_RCAR_GEN3 + select ARCH_RCAR_GEN4 select SYSC_R8A779G0 help This enables support for the Renesas R-Car V4H SoC. +config ARCH_R8A779H0 + bool "ARM64 Platform support for R-Car V4M" + select ARCH_RCAR_GEN4 + select SYSC_R8A779H0 + help + This enables support for the Renesas R-Car V4M SoC. + config ARCH_R8A774C0 bool "ARM64 Platform support for RZ/G2E" select ARCH_RCAR_GEN3 diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index 98fd97da6cd4..7ba02f3a4a4f 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -117,6 +117,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { { .compatible = "renesas,r8a779a0-rst", .data = &rcar_rst_v3u }, { .compatible = "renesas,r8a779f0-rst", .data = &rcar_rst_gen4 }, { .compatible = "renesas,r8a779g0-rst", .data = &rcar_rst_gen4 }, + { .compatible = "renesas,r8a779h0-rst", .data = &rcar_rst_gen4 }, { /* sentinel */ } }; diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index 27eae1a354ab..8f9b8d3736dc 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -270,6 +270,11 @@ static const struct renesas_soc soc_rcar_v4h __initconst __maybe_unused = { .id = 0x5c, }; +static const struct renesas_soc soc_rcar_v4m __initconst __maybe_unused = { + .family = &fam_rcar_gen4, + .id = 0x5d, +}; + static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = { .family = &fam_shmobile, .id = 0x37, @@ -380,6 +385,9 @@ static const struct of_device_id renesas_socs[] __initconst __maybe_unused = { #ifdef CONFIG_ARCH_R8A779G0 { .compatible = "renesas,r8a779g0", .data = &soc_rcar_v4h }, #endif +#ifdef CONFIG_ARCH_R8A779H0 + { .compatible = "renesas,r8a779h0", .data = &soc_rcar_v4m }, +#endif #ifdef CONFIG_ARCH_R9A07G043 #ifdef CONFIG_RISCV { .compatible = "renesas,r9a07g043", .data = &soc_rz_five }, |