diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-24 10:39:22 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-24 10:39:22 -0700 |
| commit | 2e368dd2bbeac6bfd50886371db185b1092067b4 (patch) | |
| tree | c7a1f0e91e48bc13e56684a46b7429fa3d1652eb /drivers/memory | |
| parent | e731f3146ff3bba5424b40140e1a7e6f92e94964 (diff) | |
| parent | 9f7f26930035f557838e215797cb620b563b98ab (diff) | |
| download | linux-2e368dd2bbeac6bfd50886371db185b1092067b4.tar.gz linux-2e368dd2bbeac6bfd50886371db185b1092067b4.tar.bz2 linux-2e368dd2bbeac6bfd50886371db185b1092067b4.zip | |
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC-related driver updates from Olof Johansson:
"Various driver updates for platforms. A bulk of this is smaller fixes
or cleanups, but some of the new material this time around is:
- Support for Nvidia Tegra234 SoC
- Ring accelerator support for TI AM65x
- PRUSS driver for TI platforms
- Renesas support for R-Car V3U SoC
- Reset support for Cortex-M4 processor on i.MX8MQ
There are also new socinfo entries for a handful of different SoCs and
platforms"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (131 commits)
drm/mediatek: reduce clear event
soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
soc: mediatek: cmdq: add jump function
soc: mediatek: cmdq: add write_s_mask value function
soc: mediatek: cmdq: add write_s value function
soc: mediatek: cmdq: add read_s function
soc: mediatek: cmdq: add write_s_mask function
soc: mediatek: cmdq: add write_s function
soc: mediatek: cmdq: add address shift in jump
soc: mediatek: mtk-infracfg: Fix kerneldoc
soc: amlogic: pm-domains: use always-on flag
reset: sti: reset-syscfg: fix struct description warnings
reset: imx7: add the cm4 reset for i.MX8MQ
dt-bindings: reset: imx8mq: add m4 reset
reset: Fix and extend kerneldoc
reset: reset-zynqmp: Added support for Versal platform
dt-bindings: reset: Updated binding for Versal reset driver
reset: imx7: Support module build
soc: fsl: qe: Remove unnessesary check in ucc_set_tdm_rxtx_clk
soc: fsl: qman: convert to use be32_add_cpu()
...
Diffstat (limited to 'drivers/memory')
| -rw-r--r-- | drivers/memory/Kconfig | 52 | ||||
| -rw-r--r-- | drivers/memory/Makefile | 2 | ||||
| -rw-r--r-- | drivers/memory/brcmstb_dpfe.c | 46 | ||||
| -rw-r--r-- | drivers/memory/emif.c | 55 | ||||
| -rw-r--r-- | drivers/memory/fsl-corenet-cf.c | 6 | ||||
| -rw-r--r-- | drivers/memory/mtk-smi.c | 23 | ||||
| -rw-r--r-- | drivers/memory/omap-gpmc.c | 272 | ||||
| -rw-r--r-- | drivers/memory/renesas-rpc-if.c | 4 | ||||
| -rw-r--r-- | drivers/memory/samsung/exynos5422-dmc.c | 108 | ||||
| -rw-r--r-- | drivers/memory/tegra/tegra124-emc.c | 14 | ||||
| -rw-r--r-- | drivers/memory/tegra/tegra124.c | 1 | ||||
| -rw-r--r-- | drivers/memory/tegra/tegra186-emc.c | 10 | ||||
| -rw-r--r-- | drivers/memory/tegra/tegra210-emc-cc-r21021.c | 3 | ||||
| -rw-r--r-- | drivers/memory/tegra/tegra210.c | 2 |
14 files changed, 332 insertions, 266 deletions
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 2c79e95dd486..00e013b14703 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -32,8 +32,9 @@ config ARM_PL172_MPMC config ATMEL_SDRAMC bool "Atmel (Multi-port DDR-)SDRAM Controller" - default y - depends on ARCH_AT91 && OF + default y if ARCH_AT91 + depends on ARCH_AT91 || COMPILE_TEST + depends on OF help This driver is for Atmel SDRAM Controller or Atmel Multi-port DDR-SDRAM Controller available on Atmel AT91SAM9 and SAMA5 SoCs. @@ -42,8 +43,9 @@ config ATMEL_SDRAMC config ATMEL_EBI bool "Atmel EBI driver" - default y - depends on ARCH_AT91 && OF + default y if ARCH_AT91 + depends on ARCH_AT91 || COMPILE_TEST + depends on OF select MFD_SYSCON select MFD_ATMEL_SMC help @@ -52,6 +54,18 @@ config ATMEL_EBI tree is used. This bus supports NANDs, external ethernet controller, SRAMs, ATA devices, etc. +config BRCMSTB_DPFE + bool "Broadcom STB DPFE driver" if COMPILE_TEST + default y if ARCH_BRCMSTB + depends on ARCH_BRCMSTB || COMPILE_TEST + help + This driver provides access to the DPFE interface of Broadcom + STB SoCs. The firmware running on the DCPU inside the DDR PHY can + provide current information about the system's RAM, for instance + the DRAM refresh rate. This can be used as an indirect indicator + for the DRAM's temperature. Slower refresh rate means cooler RAM, + higher refresh rate means hotter RAM. + config BT1_L2_CTL bool "Baikal-T1 CM2 L2-RAM Cache Control Block" depends on MIPS_BAIKAL_T1 || COMPILE_TEST @@ -65,7 +79,8 @@ config BT1_L2_CTL config TI_AEMIF tristate "Texas Instruments AEMIF driver" - depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF + depends on ARCH_DAVINCI || ARCH_KEYSTONE || COMPILE_TEST + depends on OF help This driver is for the AEMIF module available in Texas Instruments SoCs. AEMIF stands for Asynchronous External Memory Interface and @@ -76,7 +91,7 @@ config TI_AEMIF config TI_EMIF tristate "Texas Instruments EMIF driver" - depends on ARCH_OMAP2PLUS + depends on ARCH_OMAP2PLUS || COMPILE_TEST select DDR help This driver is for the EMIF module available in Texas Instruments @@ -88,7 +103,8 @@ config TI_EMIF temperature changes config OMAP_GPMC - bool + bool "Texas Instruments OMAP SoC GPMC driver" if COMPILE_TEST + depends on OF_ADDRESS select GPIOLIB help This driver is for the General Purpose Memory Controller (GPMC) @@ -112,7 +128,8 @@ config OMAP_GPMC_DEBUG config TI_EMIF_SRAM tristate "Texas Instruments EMIF SRAM driver" - depends on (SOC_AM33XX || SOC_AM43XX) && SRAM + depends on SOC_AM33XX || SOC_AM43XX || (ARM && COMPILE_TEST) + depends on SRAM help This driver is for the EMIF module available on Texas Instruments AM33XX and AM43XX SoCs and is required for PM. Certain parts of @@ -122,8 +139,9 @@ config TI_EMIF_SRAM config MVEBU_DEVBUS bool "Marvell EBU Device Bus Controller" - default y - depends on PLAT_ORION && OF + default y if PLAT_ORION + depends on PLAT_ORION || COMPILE_TEST + depends on OF help This driver is for the Device Bus controller available in some Marvell EBU SoCs such as Discovery (mv78xx0), Orion (88f5xxx) and @@ -132,7 +150,7 @@ config MVEBU_DEVBUS config FSL_CORENET_CF tristate "Freescale CoreNet Error Reporting" - depends on FSL_SOC_BOOKE + depends on FSL_SOC_BOOKE || COMPILE_TEST help Say Y for reporting of errors from the Freescale CoreNet Coherency Fabric. Errors reported include accesses to @@ -141,7 +159,7 @@ config FSL_CORENET_CF represents a coherency violation. config FSL_IFC - bool + bool "Freescale IFC driver" if COMPILE_TEST depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST depends on HAS_IOMEM @@ -155,7 +173,7 @@ config JZ4780_NEMC memory devices such as NAND and SRAM. config MTK_SMI - bool + bool "Mediatek SoC Memory Controller driver" if COMPILE_TEST depends on ARCH_MEDIATEK || COMPILE_TEST help This driver is for the Memory Controller module in MediaTek SoCs, @@ -164,7 +182,7 @@ config MTK_SMI config DA8XX_DDRCTL bool "Texas Instruments da8xx DDR2/mDDR driver" - depends on ARCH_DAVINCI_DA8XX + depends on ARCH_DAVINCI_DA8XX || COMPILE_TEST help This driver is for the DDR2/mDDR Memory Controller present on Texas Instruments da8xx SoCs. It's used to tweak various memory @@ -172,16 +190,16 @@ config DA8XX_DDRCTL config PL353_SMC tristate "ARM PL35X Static Memory Controller(SMC) driver" - default y + default y if ARM depends on ARM - depends on ARM_AMBA + depends on ARM_AMBA || COMPILE_TEST help This driver is for the ARM PL351/PL353 Static Memory Controller(SMC) module. config RENESAS_RPCIF tristate "Renesas RPC-IF driver" - depends on ARCH_RENESAS + depends on ARCH_RENESAS || COMPILE_TEST select REGMAP_MMIO help This supports Renesas R-Car Gen3 RPC-IF which provides either SPI diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index b4533ffff2bc..e71cf7b99641 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -10,7 +10,7 @@ endif obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o -obj-$(CONFIG_ARCH_BRCMSTB) += brcmstb_dpfe.o +obj-$(CONFIG_BRCMSTB_DPFE) += brcmstb_dpfe.o obj-$(CONFIG_BT1_L2_CTL) += bt1-l2-ctl.o obj-$(CONFIG_TI_AEMIF) += ti-aemif.o obj-$(CONFIG_TI_EMIF) += emif.o diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c index 60e8633b1175..f43ba69fbb3e 100644 --- a/drivers/memory/brcmstb_dpfe.c +++ b/drivers/memory/brcmstb_dpfe.c @@ -188,11 +188,6 @@ struct brcmstb_dpfe_priv { struct mutex lock; }; -static const char * const error_text[] = { - "Success", "Header code incorrect", "Unknown command or argument", - "Incorrect checksum", "Malformed command", "Timed out", -}; - /* * Forward declaration of our sysfs attribute functions, so we can declare the * attribute data structures early. @@ -307,6 +302,20 @@ static const struct dpfe_api dpfe_api_v3 = { }, }; +static const char *get_error_text(unsigned int i) +{ + static const char * const error_text[] = { + "Success", "Header code incorrect", + "Unknown command or argument", "Incorrect checksum", + "Malformed command", "Timed out", "Unknown error", + }; + + if (unlikely(i >= ARRAY_SIZE(error_text))) + i = ARRAY_SIZE(error_text) - 1; + + return error_text[i]; +} + static bool is_dcpu_enabled(struct brcmstb_dpfe_priv *priv) { u32 val; @@ -445,7 +454,7 @@ static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd, } if (resp != 0) { mutex_unlock(&priv->lock); - return -ETIMEDOUT; + return -ffs(DCPU_RET_ERR_TIMEDOUT); } /* Compute checksum over the message */ @@ -647,8 +656,10 @@ static int brcmstb_dpfe_download_firmware(struct brcmstb_dpfe_priv *priv) return (ret == -ENOENT) ? -EPROBE_DEFER : ret; ret = __verify_firmware(&init, fw); - if (ret) - return -EFAULT; + if (ret) { + ret = -EFAULT; + goto release_fw; + } __disable_dcpu(priv); @@ -667,18 +678,20 @@ static int brcmstb_dpfe_download_firmware(struct brcmstb_dpfe_priv *priv) ret = __write_firmware(priv->dmem, dmem, dmem_size, is_big_endian); if (ret) - return ret; + goto release_fw; ret = __write_firmware(priv->imem, imem, imem_size, is_big_endian); if (ret) - return ret; + goto release_fw; ret = __verify_fw_checksum(&init, priv, header, init.chksum); if (ret) - return ret; + goto release_fw; __enable_dcpu(priv); - return 0; +release_fw: + release_firmware(fw); + return ret; } static ssize_t generic_show(unsigned int command, u32 response[], @@ -691,7 +704,7 @@ static ssize_t generic_show(unsigned int command, u32 response[], ret = __send_command(priv, command, response); if (ret < 0) - return sprintf(buf, "ERROR: %s\n", error_text[-ret]); + return sprintf(buf, "ERROR: %s\n", get_error_text(-ret)); return 0; } @@ -888,11 +901,8 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev) } ret = brcmstb_dpfe_download_firmware(priv); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "Couldn't download firmware -- %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Couldn't download firmware\n"); ret = sysfs_create_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs); if (!ret) diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c index bb6a71d26798..ddb1879f07d3 100644 --- a/drivers/memory/emif.c +++ b/drivers/memory/emif.c @@ -131,16 +131,7 @@ static int emif_regdump_show(struct seq_file *s, void *unused) return 0; } -static int emif_regdump_open(struct inode *inode, struct file *file) -{ - return single_open(file, emif_regdump_show, inode->i_private); -} - -static const struct file_operations emif_regdump_fops = { - .open = emif_regdump_open, - .read = seq_read, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(emif_regdump); static int emif_mr4_show(struct seq_file *s, void *unused) { @@ -150,48 +141,16 @@ static int emif_mr4_show(struct seq_file *s, void *unused) return 0; } -static int emif_mr4_open(struct inode *inode, struct file *file) -{ - return single_open(file, emif_mr4_show, inode->i_private); -} - -static const struct file_operations emif_mr4_fops = { - .open = emif_mr4_open, - .read = seq_read, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(emif_mr4); static int __init_or_module emif_debugfs_init(struct emif_data *emif) { - struct dentry *dentry; - int ret; - - dentry = debugfs_create_dir(dev_name(emif->dev), NULL); - if (!dentry) { - ret = -ENOMEM; - goto err0; - } - emif->debugfs_root = dentry; - - dentry = debugfs_create_file("regcache_dump", S_IRUGO, - emif->debugfs_root, emif, &emif_regdump_fops); - if (!dentry) { - ret = -ENOMEM; - goto err1; - } - - dentry = debugfs_create_file("mr4", S_IRUGO, - emif->debugfs_root, emif, &emif_mr4_fops); - if (!dentry) { - ret = -ENOMEM; - goto err1; - } - + 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; -err1: - debugfs_remove_recursive(emif->debugfs_root); -err0: - return ret; } static void __exit emif_debugfs_exit(struct emif_data *emif) diff --git a/drivers/memory/fsl-corenet-cf.c b/drivers/memory/fsl-corenet-cf.c index 0b0ed72016da..0309bd5a1800 100644 --- a/drivers/memory/fsl-corenet-cf.c +++ b/drivers/memory/fsl-corenet-cf.c @@ -211,10 +211,8 @@ static int ccf_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, ccf); irq = platform_get_irq(pdev, 0); - if (!irq) { - dev_err(&pdev->dev, "%s: no irq\n", __func__); - return -ENXIO; - } + if (irq < 0) + return irq; ret = devm_request_irq(&pdev->dev, irq, ccf_irq, 0, pdev->name, ccf); if (ret) { diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index c21262502581..691e4c344cf8 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -19,6 +19,9 @@ /* mt8173 */ #define SMI_LARB_MMU_EN 0xf00 +/* mt8167 */ +#define MT8167_SMI_LARB_MMU_EN 0xfc0 + /* mt2701 */ #define REG_SMI_SECUR_CON_BASE 0x5c0 @@ -179,6 +182,13 @@ static void mtk_smi_larb_config_port_mt8173(struct device *dev) writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN); } +static void mtk_smi_larb_config_port_mt8167(struct device *dev) +{ + struct mtk_smi_larb *larb = dev_get_drvdata(dev); + + writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN); +} + static void mtk_smi_larb_config_port_gen1(struct device *dev) { struct mtk_smi_larb *larb = dev_get_drvdata(dev); @@ -226,6 +236,11 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = { .config_port = mtk_smi_larb_config_port_mt8173, }; +static const struct mtk_smi_larb_gen mtk_smi_larb_mt8167 = { + /* mt8167 do not need the port in larb */ + .config_port = mtk_smi_larb_config_port_mt8167, +}; + static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = { .port_in_larb = { LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, @@ -255,6 +270,10 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = { static const struct of_device_id mtk_smi_larb_of_ids[] = { { + .compatible = "mediatek,mt8167-smi-larb", + .data = &mtk_smi_larb_mt8167 + }, + { .compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173 }, @@ -419,6 +438,10 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { .data = &mtk_smi_common_gen2, }, { + .compatible = "mediatek,mt8167-smi-common", + .data = &mtk_smi_common_gen2, + }, + { .compatible = "mediatek,mt2701-smi-common", .data = &mtk_smi_common_gen1, }, diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index ca0097664b12..cfa730cfd145 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -33,8 +33,6 @@ #include <linux/platform_data/mtd-nand-omap2.h> -#include <asm/mach-types.h> - #define DEVICE_NAME "omap-gpmc" /* GPMC register offsets */ @@ -245,7 +243,6 @@ static DEFINE_SPINLOCK(gpmc_mem_lock); /* Define chip-selects as reserved by default until probe completes */ static unsigned int gpmc_cs_num = GPMC_CS_NUM; static unsigned int gpmc_nr_waitpins; -static resource_size_t phys_base, mem_size; static unsigned int gpmc_capability; static void __iomem *gpmc_base; @@ -634,14 +631,6 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max return 0; } -#define GPMC_SET_ONE_CD_MAX(reg, st, end, max, field, cd) \ - if (set_gpmc_timing_reg(cs, (reg), (st), (end), (max), \ - t->field, (cd), #field) < 0) \ - return -1 - -#define GPMC_SET_ONE(reg, st, end, field) \ - GPMC_SET_ONE_CD_MAX(reg, st, end, 0, field, GPMC_CD_FCLK) - /** * gpmc_calc_waitmonitoring_divider - calculate proper GPMCFCLKDIVIDER based on WAITMONITORINGTIME * WAITMONITORINGTIME will be _at least_ as long as desired, i.e. @@ -700,12 +689,12 @@ int gpmc_calc_divider(unsigned int sync_clk) int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, const struct gpmc_settings *s) { - int div; + int div, ret; u32 l; div = gpmc_calc_divider(t->sync_clk); if (div < 0) - return div; + return -EINVAL; /* * See if we need to change the divider for waitmonitoringtime. @@ -729,57 +718,114 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, __func__, t->wait_monitoring ); - return -1; + return -ENXIO; } } - GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); - GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off); - GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off); + ret = 0; + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG2, 0, 3, 0, t->cs_on, + GPMC_CD_FCLK, "cs_on"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG2, 8, 12, 0, t->cs_rd_off, + GPMC_CD_FCLK, "cs_rd_off"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG2, 16, 20, 0, t->cs_wr_off, + GPMC_CD_FCLK, "cs_wr_off"); + if (ret) + return -ENXIO; + + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 0, 3, 0, t->adv_on, + GPMC_CD_FCLK, "adv_on"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 8, 12, 0, t->adv_rd_off, + GPMC_CD_FCLK, "adv_rd_off"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 16, 20, 0, t->adv_wr_off, + GPMC_CD_FCLK, "adv_wr_off"); + if (ret) + return -ENXIO; - GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); - GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off); - GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off); if (gpmc_capability & GPMC_HAS_MUX_AAD) { - GPMC_SET_ONE(GPMC_CS_CONFIG3, 4, 6, adv_aad_mux_on); - GPMC_SET_ONE(GPMC_CS_CONFIG3, 24, 26, adv_aad_mux_rd_off); - GPMC_SET_ONE(GPMC_CS_CONFIG3, 28, 30, adv_aad_mux_wr_off); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 4, 6, 0, + t->adv_aad_mux_on, GPMC_CD_FCLK, + "adv_aad_mux_on"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 24, 26, 0, + t->adv_aad_mux_rd_off, GPMC_CD_FCLK, + "adv_aad_mux_rd_off"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 28, 30, 0, + t->adv_aad_mux_wr_off, GPMC_CD_FCLK, + "adv_aad_mux_wr_off"); + if (ret) + return -ENXIO; } - GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); - GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 0, 3, 0, t->oe_on, + GPMC_CD_FCLK, "oe_on"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 8, 12, 0, t->oe_off, + GPMC_CD_FCLK, "oe_off"); if (gpmc_capability & GPMC_HAS_MUX_AAD) { - GPMC_SET_ONE(GPMC_CS_CONFIG4, 4, 6, oe_aad_mux_on); - GPMC_SET_ONE(GPMC_CS_CONFIG4, 13, 15, oe_aad_mux_off); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 4, 6, 0, + t->oe_aad_mux_on, GPMC_CD_FCLK, + "oe_aad_mux_on"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 13, 15, 0, + t->oe_aad_mux_off, GPMC_CD_FCLK, + "oe_aad_mux_off"); + } + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 16, 19, 0, t->we_on, + GPMC_CD_FCLK, "we_on"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 24, 28, 0, t->we_off, + GPMC_CD_FCLK, "we_off"); + if (ret) + return -ENXIO; + + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 0, 4, 0, t->rd_cycle, + GPMC_CD_FCLK, "rd_cycle"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 8, 12, 0, t->wr_cycle, + GPMC_CD_FCLK, "wr_cycle"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 16, 20, 0, t->access, + GPMC_CD_FCLK, "access"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 24, 27, 0, + t->page_burst_access, GPMC_CD_FCLK, + "page_burst_access"); + if (ret) + return -ENXIO; + + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 0, 3, 0, + t->bus_turnaround, GPMC_CD_FCLK, + "bus_turnaround"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 8, 11, 0, + t->cycle2cycle_delay, GPMC_CD_FCLK, + "cycle2cycle_delay"); + if (ret) + return -ENXIO; + + if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) { + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 16, 19, 0, + t->wr_data_mux_bus, GPMC_CD_FCLK, + "wr_data_mux_bus"); + if (ret) + return -ENXIO; + } + if (gpmc_capability & GPMC_HAS_WR_ACCESS) { + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 24, 28, 0, + t->wr_access, GPMC_CD_FCLK, + "wr_access"); + if (ret) + return -ENXIO; } - GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on); - GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off); - - GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle); - GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle); - GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access); - - GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); - - GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround); - GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay); - - if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) - GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); - if (gpmc_capability & GPMC_HAS_WR_ACCESS) - GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); l &= ~0x03; l |= (div - 1); gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); - GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 18, 19, - GPMC_CONFIG1_WAITMONITORINGTIME_MAX, - wait_monitoring, GPMC_CD_CLK); - GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 25, 26, - GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, - clk_activation, GPMC_CD_FCLK); + ret = 0; + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG1, 18, 19, + GPMC_CONFIG1_WAITMONITORINGTIME_MAX, + t->wait_monitoring, GPMC_CD_CLK, + "wait_monitoring"); + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG1, 25, 26, + GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, + t->clk_activation, GPMC_CD_FCLK, + "clk_activation"); + if (ret) + return -ENXIO; #ifdef CONFIG_OMAP_GPMC_DEBUG pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", @@ -870,20 +916,6 @@ static bool gpmc_cs_reserved(int cs) return gpmc->flags & GPMC_CS_RESERVED; } -static void gpmc_cs_set_name(int cs, const char *name) -{ - struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; - - gpmc->name = name; -} - -static const char *gpmc_cs_get_name(int cs) -{ - struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; - - return gpmc->name; -} - static unsigned long gpmc_mem_align(unsigned long size) { int order; @@ -929,56 +961,13 @@ static int gpmc_cs_delete_mem(int cs) return r; } -/** - * gpmc_cs_remap - remaps a chip-select physical base address - * @cs: chip-select to remap - * @base: physical base address to re-map chip-select to - * - * Re-maps a chip-select to a new physical base address specified by - * "base". Returns 0 on success and appropriate negative error code - * on failure. - */ -static int gpmc_cs_remap(int cs, u32 base) -{ - int ret; - u32 old_base, size; - - if (cs > gpmc_cs_num) { - pr_err("%s: requested chip-select is disabled\n", __func__); - return -ENODEV; - } - - /* - * Make sure we ignore any device offsets from the GPMC partition - * allocated for the chip select and that the new base confirms - * to the GPMC 16MB minimum granularity. - */ - base &= ~(SZ_16M - 1); - - gpmc_cs_get_memconf(cs, &old_base, &size); - if (base == old_base) - return 0; - - ret = gpmc_cs_delete_mem(cs); - if (ret < 0) - return ret; - - ret = gpmc_cs_insert_mem(cs, base, size); - if (ret < 0) - return ret; - - ret = gpmc_cs_set_memconf(cs, base, size); - - return ret; -} - int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) { struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; struct resource *res = &gpmc->mem; int r = -1; - if (cs > gpmc_cs_num) { + if (cs >= gpmc_cs_num) { pr_err("%s: requested chip-select is disabled\n", __func__); return -ENODEV; } @@ -1025,8 +1014,7 @@ void gpmc_cs_free(int cs) spin_lock(&gpmc_mem_lock); if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { - printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); - BUG(); + WARN(1, "Trying to free non-reserved GPMC CS%d\n", cs); spin_unlock(&gpmc_mem_lock); return; } @@ -1896,6 +1884,63 @@ static const struct of_device_id gpmc_dt_ids[] = { { } }; +static void gpmc_cs_set_name(int cs, const char *name) +{ + struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; + + gpmc->name = name; +} + +static const char *gpmc_cs_get_name(int cs) +{ + struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; + + return gpmc->name; +} + +/** + * gpmc_cs_remap - remaps a chip-select physical base address + * @cs: chip-select to remap + * @base: physical base address to re-map chip-select to + * + * Re-maps a chip-select to a new physical base address specified by + * "base". Returns 0 on success and appropriate negative error code + * on failure. + */ +static int gpmc_cs_remap(int cs, u32 base) +{ + int ret; + u32 old_base, size; + + if (cs >= gpmc_cs_num) { + pr_err("%s: requested chip-select is disabled\n", __func__); + return -ENODEV; + } + + /* + * Make sure we ignore any device offsets from the GPMC partition + * allocated for the chip select and that the new base confirms + * to the GPMC 16MB minimum granularity. + */ + base &= ~(SZ_16M - 1); + + gpmc_cs_get_memconf(cs, &old_base, &size); + if (base == old_base) + return 0; + + ret = gpmc_cs_delete_mem(cs); + if (ret < 0) + return ret; + + ret = gpmc_cs_insert_mem(cs, base, size); + if (ret < 0) + return ret; + + ret = gpmc_cs_set_memconf(cs, base, size); + + return ret; +} + /** * gpmc_read_settings_dt - read gpmc settings from device-tree * @np: pointer to device-tree node for a gpmc child device @@ -2265,6 +2310,10 @@ static void gpmc_probe_dt_children(struct platform_device *pdev) } } #else +void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) +{ + memset(p, 0, sizeof(*p)); +} static int gpmc_probe_dt(struct platform_device *pdev) { return 0; @@ -2347,12 +2396,9 @@ static int gpmc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpmc); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) + if (!res) return -ENOENT; - phys_base = res->start; - mem_size = resource_size(res); - gpmc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(gpmc_base)) return PTR_ERR(gpmc_base); diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c index 88f51ec8f1d1..f2a33a1af836 100644 --- a/drivers/memory/renesas-rpc-if.c +++ b/drivers/memory/renesas-rpc-if.c @@ -199,10 +199,8 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev) rpc->dirmap = NULL; rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (IS_ERR(rpc->rstc)) - return PTR_ERR(rpc->rstc); - return 0; + return PTR_ERR_OR_ZERO(rpc->rstc); } EXPORT_SYMBOL(rpcif_sw_init); diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c index 714d1f6f077c..c5ee4121a4d2 100644 --- a/drivers/memory/samsung/exynos5422-dmc.c +++ b/drivers/memory/samsung/exynos5422-dmc.c @@ -98,6 +98,8 @@ MODULE_PARM_DESC(irqmode, "Enable IRQ mode (0=off [default], 1=on)"); /** * struct dmc_opp_table - Operating level desciption + * @freq_hz: target frequency in Hz + * @volt_uv: target voltage in uV * * Covers frequency and voltage settings of the DMC operating mode. */ @@ -108,6 +110,41 @@ struct dmc_opp_table { /** * struct exynos5_dmc - main structure describing DMC device + * @dev: DMC device + * @df: devfreq device structure returned by devfreq framework + * @gov_data: configuration of devfreq governor + * @base_drexi0: DREX0 registers mapping + * @base_drexi1: DREX1 registers mapping + * @clk_regmap: regmap for clock controller registers + * @lock: protects curr_rate and frequency/voltage setting section + * @curr_rate: current frequency + * @curr_volt: current voltage + * @opp: OPP table + * @opp_count: number of 'opp' elements + * @timings_arr_size: number of 'timings' elements + * @timing_row: values for timing row register, for each OPP + * @timing_data: values for timing data register, for each OPP + * @timing_power: balues for timing power register, for each OPP + * @timings: DDR memory timings, from device tree + * @min_tck: DDR memory minimum timing values, from device tree + * @bypass_timing_row: value for timing row register for bypass timings + * @bypass_timing_data: value for timing data register for bypass timings + * @bypass_timing_power: value for timing power register for bypass + * timings + * @vdd_mif: Memory interface regulator + * @fout_spll: clock: SPLL + * @fout_bpll: clock: BPLL + * @mout_spll: clock: mux SPLL + * @mout_bpll: clock: mux BPLL + * @mout_mclk_cdrex: clock: mux mclk_cdrex + * @mout_mx_mspll_ccore: clock: mux mx_mspll_ccore + * @counter: devfreq events + * @num_counters: number of 'counter' elements + * @last_overflow_ts: time (in ns) of last overflow of each DREX + * @load: utilization in percents + * @total: total time between devfreq events + * @in_irq_mode: whether running in interrupt mode (true) + * or polling (false) * * The main structure for the Dynamic Memory Controller which covers clocks, * memory regions, HW information, parameters and current operating mode. @@ -119,12 +156,11 @@ struct exynos5_dmc { void __iomem *base_drexi0; void __iomem *base_drexi1; struct regmap *clk_regmap; + /* Protects curr_rate and frequency/voltage setting section */ struct mutex lock; unsigned long curr_rate; unsigned long curr_volt; - unsigned long bypass_rate; struct dmc_opp_table *opp; - struct dmc_opp_table opp_bypass; int opp_count; u32 timings_arr_size; u32 *timing_row; @@ -142,8 +178,6 @@ struct exynos5_dmc { struct clk *mout_bpll; struct clk *mout_mclk_cdrex; struct clk *mout_mx_mspll_ccore; - struct c |
