summaryrefslogtreecommitdiff
path: root/drivers/memory
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/atmel-ebi.c35
-rw-r--r--drivers/memory/emif.c31
-rw-r--r--drivers/memory/mtk-smi.c6
-rw-r--r--drivers/memory/omap-gpmc.c24
-rw-r--r--drivers/memory/pl172.c58
-rw-r--r--drivers/memory/pl353-smc.c57
-rw-r--r--drivers/memory/renesas-rpc-if.c2
-rw-r--r--drivers/memory/samsung/exynos5422-dmc.c90
-rw-r--r--drivers/memory/stm32-fmc2-ebi.c23
-rw-r--r--drivers/memory/tegra/mc.c11
-rw-r--r--drivers/memory/tegra/tegra124-emc.c7
-rw-r--r--drivers/memory/tegra/tegra186-emc.c5
-rw-r--r--drivers/memory/tegra/tegra20-emc.c7
-rw-r--r--drivers/memory/tegra/tegra210-emc-cc-r21021.c429
-rw-r--r--drivers/memory/tegra/tegra30-emc.c7
-rw-r--r--drivers/memory/ti-aemif.c74
16 files changed, 225 insertions, 641 deletions
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index e8bb5f37f5cb..8db970da9af9 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -6,6 +6,7 @@
* Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
*/
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
@@ -517,7 +518,7 @@ static int atmel_ebi_dev_disable(struct atmel_ebi *ebi, struct device_node *np)
static int atmel_ebi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct device_node *child, *np = dev->of_node, *smc_np;
+ struct device_node *np = dev->of_node;
struct atmel_ebi *ebi;
int ret, reg_cells;
struct clk *clk;
@@ -541,30 +542,24 @@ static int atmel_ebi_probe(struct platform_device *pdev)
ebi->clk = clk;
- smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0);
+ struct device_node *smc_np __free(device_node) =
+ of_parse_phandle(dev->of_node, "atmel,smc", 0);
ebi->smc.regmap = syscon_node_to_regmap(smc_np);
- if (IS_ERR(ebi->smc.regmap)) {
- ret = PTR_ERR(ebi->smc.regmap);
- goto put_node;
- }
+ if (IS_ERR(ebi->smc.regmap))
+ return PTR_ERR(ebi->smc.regmap);
ebi->smc.layout = atmel_hsmc_get_reg_layout(smc_np);
- if (IS_ERR(ebi->smc.layout)) {
- ret = PTR_ERR(ebi->smc.layout);
- goto put_node;
- }
+ if (IS_ERR(ebi->smc.layout))
+ return PTR_ERR(ebi->smc.layout);
ebi->smc.clk = of_clk_get(smc_np, 0);
if (IS_ERR(ebi->smc.clk)) {
- if (PTR_ERR(ebi->smc.clk) != -ENOENT) {
- ret = PTR_ERR(ebi->smc.clk);
- goto put_node;
- }
+ if (PTR_ERR(ebi->smc.clk) != -ENOENT)
+ return PTR_ERR(ebi->smc.clk);
ebi->smc.clk = NULL;
}
- of_node_put(smc_np);
ret = clk_prepare_enable(ebi->smc.clk);
if (ret)
return ret;
@@ -597,7 +592,7 @@ static int atmel_ebi_probe(struct platform_device *pdev)
reg_cells += val;
- for_each_available_child_of_node(np, child) {
+ for_each_available_child_of_node_scoped(np, child) {
if (!of_property_present(child, "reg"))
continue;
@@ -607,18 +602,12 @@ static int atmel_ebi_probe(struct platform_device *pdev)
child);
ret = atmel_ebi_dev_disable(ebi, child);
- if (ret) {
- of_node_put(child);
+ if (ret)
return ret;
- }
}
}
return of_platform_populate(np, NULL, NULL, dev);
-
-put_node:
- of_node_put(smc_np);
- return ret;
}
static __maybe_unused int atmel_ebi_resume(struct device *dev)
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 8c5ad5c025fa..99eb7d1baa5f 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -7,6 +7,7 @@
* Aneesh V <aneesh@ti.com>
* Santosh Shilimkar <santosh.shilimkar@ti.com>
*/
+#include <linux/cleanup.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
@@ -57,7 +58,6 @@ struct emif_data {
u8 temperature_level;
u8 lpmode;
struct list_head node;
- unsigned long irq_state;
void __iomem *base;
struct device *dev;
struct emif_regs *regs_cache[EMIF_MAX_NUM_FREQUENCIES];
@@ -69,7 +69,6 @@ struct emif_data {
static struct emif_data *emif1;
static DEFINE_SPINLOCK(emif_lock);
-static unsigned long irq_state;
static LIST_HEAD(device_list);
static void do_emif_regdump_show(struct seq_file *s, struct emif_data *emif,
@@ -523,18 +522,18 @@ out:
static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif)
{
u32 old_temp_level;
- irqreturn_t ret = IRQ_HANDLED;
+ irqreturn_t ret;
struct emif_custom_configs *custom_configs;
- spin_lock_irqsave(&emif_lock, irq_state);
+ guard(spinlock_irqsave)(&emif_lock);
old_temp_level = emif->temperature_level;
get_temperature_level(emif);
if (unlikely(emif->temperature_level == old_temp_level)) {
- goto out;
+ return IRQ_HANDLED;
} else if (!emif->curr_regs) {
dev_err(emif->dev, "temperature alert before registers are calculated, not de-rating timings\n");
- goto out;
+ return IRQ_HANDLED;
}
custom_configs = emif->plat_data->custom_configs;
@@ -554,8 +553,7 @@ static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif)
* from thread context
*/
emif->temperature_level = SDRAM_TEMP_VERY_HIGH_SHUTDOWN;
- ret = IRQ_WAKE_THREAD;
- goto out;
+ return IRQ_WAKE_THREAD;
}
}
@@ -571,10 +569,9 @@ static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif)
/* Temperature is going up - handle immediately */
setup_temperature_sensitive_regs(emif, emif->curr_regs);
do_freq_update();
+ ret = IRQ_HANDLED;
}
-out:
- spin_unlock_irqrestore(&emif_lock, irq_state);
return ret;
}
@@ -617,6 +614,7 @@ static irqreturn_t emif_interrupt_handler(int irq, void *dev_id)
static irqreturn_t emif_threaded_isr(int irq, void *dev_id)
{
struct emif_data *emif = dev_id;
+ unsigned long irq_state;
if (emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) {
dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n");
@@ -864,7 +862,7 @@ static void of_get_custom_configs(struct device_node *np_emif,
be32_to_cpup(poll_intvl);
}
- if (of_find_property(np_emif, "extended-temp-part", &len))
+ if (of_property_read_bool(np_emif, "extended-temp-part"))
cust_cfgs->mask |= EMIF_CUSTOM_CONFIG_EXTENDED_TEMP_PART;
if (!is_custom_config_valid(cust_cfgs, emif->dev)) {
@@ -880,13 +878,9 @@ static void of_get_ddr_info(struct device_node *np_emif,
struct ddr_device_info *dev_info)
{
u32 density = 0, io_width = 0;
- int len;
- if (of_find_property(np_emif, "cs1-used", &len))
- dev_info->cs1_used = true;
-
- if (of_find_property(np_emif, "cal-resistor-per-cs", &len))
- dev_info->cal_resistors_per_cs = true;
+ dev_info->cs1_used = of_property_read_bool(np_emif, "cs1-used");
+ dev_info->cal_resistors_per_cs = of_property_read_bool(np_emif, "cal-resistor-per-cs");
if (of_device_is_compatible(np_ddr, "jedec,lpddr2-s4"))
dev_info->type = DDR_TYPE_LPDDR2_S4;
@@ -916,7 +910,6 @@ static struct emif_data *of_get_memory_device_details(
struct ddr_device_info *dev_info = NULL;
struct emif_platform_data *pd = NULL;
struct device_node *np_ddr;
- int len;
np_ddr = of_parse_phandle(np_emif, "device-handle", 0);
if (!np_ddr)
@@ -944,7 +937,7 @@ static struct emif_data *of_get_memory_device_details(
of_property_read_u32(np_emif, "phy-type", &pd->phy_type);
- if (of_find_property(np_emif, "hw-caps-ll-interface", &len))
+ if (of_property_read_bool(np_emif, "hw-caps-ll-interface"))
pd->hw_caps |= EMIF_HW_CAPS_LL_INTERFACE;
of_get_ddr_info(np_emif, np_ddr, dev_info);
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index fbe52ecc0eca..2bc034dff691 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -771,13 +771,9 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
if (IS_ERR(common->smi_ao_base))
return PTR_ERR(common->smi_ao_base);
- common->clk_async = devm_clk_get(dev, "async");
+ common->clk_async = devm_clk_get_enabled(dev, "async");
if (IS_ERR(common->clk_async))
return PTR_ERR(common->clk_async);
-
- ret = clk_prepare_enable(common->clk_async);
- if (ret)
- return ret;
} else {
common->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(common->base))
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 80d038884207..c8a0d82f9c27 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -9,6 +9,7 @@
* Copyright (C) 2009 Texas Instruments
* Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
*/
+#include <linux/cleanup.h>
#include <linux/cpu_pm.h>
#include <linux/irq.h>
#include <linux/kernel.h>
@@ -989,18 +990,18 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
if (size > (1 << GPMC_SECTION_SHIFT))
return -ENOMEM;
- spin_lock(&gpmc_mem_lock);
- if (gpmc_cs_reserved(cs)) {
- r = -EBUSY;
- goto out;
- }
+ guard(spinlock)(&gpmc_mem_lock);
+
+ if (gpmc_cs_reserved(cs))
+ return -EBUSY;
+
if (gpmc_cs_mem_enabled(cs))
r = adjust_resource(res, res->start & ~(size - 1), size);
if (r < 0)
r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0,
size, NULL, NULL);
if (r < 0)
- goto out;
+ return r;
/* Disable CS while changing base address and size mask */
gpmc_cs_disable_mem(cs);
@@ -1008,16 +1009,15 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
r = gpmc_cs_set_memconf(cs, res->start, resource_size(res));
if (r < 0) {
release_resource(res);
- goto out;
+ return r;
}
/* Enable CS */
gpmc_cs_enable_mem(cs);
*base = res->start;
gpmc_cs_set_reserved(cs, 1);
-out:
- spin_unlock(&gpmc_mem_lock);
- return r;
+
+ return 0;
}
EXPORT_SYMBOL(gpmc_cs_request);
@@ -1026,10 +1026,9 @@ void gpmc_cs_free(int cs)
struct gpmc_cs_data *gpmc;
struct resource *res;
- spin_lock(&gpmc_mem_lock);
+ guard(spinlock)(&gpmc_mem_lock);
if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
WARN(1, "Trying to free non-reserved GPMC CS%d\n", cs);
- spin_unlock(&gpmc_mem_lock);
return;
}
gpmc = &gpmc_cs[cs];
@@ -1039,7 +1038,6 @@ void gpmc_cs_free(int cs)
if (res->flags)
release_resource(res);
gpmc_cs_set_reserved(cs, 0);
- spin_unlock(&gpmc_mem_lock);
}
EXPORT_SYMBOL(gpmc_cs_free);
diff --git a/drivers/memory/pl172.c b/drivers/memory/pl172.c
index 9eb8cc7de494..be7ba599cccf 100644
--- a/drivers/memory/pl172.c
+++ b/drivers/memory/pl172.c
@@ -187,6 +187,13 @@ static int pl172_parse_cs_config(struct amba_device *adev,
return -EINVAL;
}
+static void pl172_amba_release_regions(void *data)
+{
+ struct amba_device *adev = data;
+
+ amba_release_regions(adev);
+}
+
static const char * const pl172_revisions[] = {"r1", "r2", "r2p3", "r2p4"};
static const char * const pl175_revisions[] = {"r1"};
static const char * const pl176_revisions[] = {"r0"};
@@ -216,38 +223,30 @@ static int pl172_probe(struct amba_device *adev, const struct amba_id *id)
if (!pl172)
return -ENOMEM;
- pl172->clk = devm_clk_get(dev, "mpmcclk");
- if (IS_ERR(pl172->clk)) {
- dev_err(dev, "no mpmcclk provided clock\n");
- return PTR_ERR(pl172->clk);
- }
-
- ret = clk_prepare_enable(pl172->clk);
- if (ret) {
- dev_err(dev, "unable to mpmcclk enable clock\n");
- return ret;
- }
+ pl172->clk = devm_clk_get_enabled(dev, "mpmcclk");
+ if (IS_ERR(pl172->clk))
+ return dev_err_probe(dev, PTR_ERR(pl172->clk),
+ "no mpmcclk provided clock\n");
pl172->rate = clk_get_rate(pl172->clk) / MSEC_PER_SEC;
- if (!pl172->rate) {
- dev_err(dev, "unable to get mpmcclk clock rate\n");
- ret = -EINVAL;
- goto err_clk_enable;
- }
+ if (!pl172->rate)
+ return dev_err_probe(dev, -EINVAL,
+ "unable to get mpmcclk clock rate\n");
ret = amba_request_regions(adev, NULL);
if (ret) {
dev_err(dev, "unable to request AMBA regions\n");
- goto err_clk_enable;
+ return ret;
}
+ ret = devm_add_action_or_reset(dev, pl172_amba_release_regions, adev);
+ if (ret)
+ return ret;
+
pl172->base = devm_ioremap(dev, adev->res.start,
resource_size(&adev->res));
- if (!pl172->base) {
- dev_err(dev, "ioremap failed\n");
- ret = -ENOMEM;
- goto err_no_ioremap;
- }
+ if (!pl172->base)
+ return dev_err_probe(dev, -ENOMEM, "ioremap failed\n");
amba_set_drvdata(adev, pl172);
@@ -265,20 +264,6 @@ static int pl172_probe(struct amba_device *adev, const struct amba_id *id)
}
return 0;
-
-err_no_ioremap:
- amba_release_regions(adev);
-err_clk_enable:
- clk_disable_unprepare(pl172->clk);
- return ret;
-}
-
-static void pl172_remove(struct amba_device *adev)
-{
- struct pl172_data *pl172 = amba_get_drvdata(adev);
-
- clk_disable_unprepare(pl172->clk);
- amba_release_regions(adev);
}
static const struct amba_id pl172_ids[] = {
@@ -306,7 +291,6 @@ static struct amba_driver pl172_driver = {
.name = "memory-pl172",
},
.probe = pl172_probe,
- .remove = pl172_remove,
.id_table = pl172_ids,
};
module_amba_driver(pl172_driver);
diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c
index 56e51737c81f..28a8cc56003c 100644
--- a/drivers/memory/pl353-smc.c
+++ b/drivers/memory/pl353-smc.c
@@ -74,73 +74,39 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
struct device_node *of_node = adev->dev.of_node;
const struct of_device_id *match = NULL;
struct pl353_smc_data *pl353_smc;
- struct device_node *child;
- int err;
pl353_smc = devm_kzalloc(&adev->dev, sizeof(*pl353_smc), GFP_KERNEL);
if (!pl353_smc)
return -ENOMEM;
- pl353_smc->aclk = devm_clk_get(&adev->dev, "apb_pclk");
- if (IS_ERR(pl353_smc->aclk)) {
- dev_err(&adev->dev, "aclk clock not found.\n");
- return PTR_ERR(pl353_smc->aclk);
- }
-
- pl353_smc->memclk = devm_clk_get(&adev->dev, "memclk");
- if (IS_ERR(pl353_smc->memclk)) {
- dev_err(&adev->dev, "memclk clock not found.\n");
- return PTR_ERR(pl353_smc->memclk);
- }
+ pl353_smc->aclk = devm_clk_get_enabled(&adev->dev, "apb_pclk");
+ if (IS_ERR(pl353_smc->aclk))
+ return dev_err_probe(&adev->dev, PTR_ERR(pl353_smc->aclk),
+ "aclk clock not found.\n");
- err = clk_prepare_enable(pl353_smc->aclk);
- if (err) {
- dev_err(&adev->dev, "Unable to enable AXI clock.\n");
- return err;
- }
-
- err = clk_prepare_enable(pl353_smc->memclk);
- if (err) {
- dev_err(&adev->dev, "Unable to enable memory clock.\n");
- goto disable_axi_clk;
- }
+ pl353_smc->memclk = devm_clk_get_enabled(&adev->dev, "memclk");
+ if (IS_ERR(pl353_smc->memclk))
+ return dev_err_probe(&adev->dev, PTR_ERR(pl353_smc->memclk),
+ "memclk clock not found.\n");
amba_set_drvdata(adev, pl353_smc);
/* Find compatible children. Only a single child is supported */
- for_each_available_child_of_node(of_node, child) {
+ for_each_available_child_of_node_scoped(of_node, child) {
match = of_match_node(pl353_smc_supported_children, child);
if (!match) {
dev_warn(&adev->dev, "unsupported child node\n");
continue;
}
+ of_platform_device_create(child, NULL, &adev->dev);
break;
}
if (!match) {
- err = -ENODEV;
dev_err(&adev->dev, "no matching children\n");
- goto disable_mem_clk;
+ return -ENODEV;
}
- of_platform_device_create(child, NULL, &adev->dev);
- of_node_put(child);
-
return 0;
-
-disable_mem_clk:
- clk_disable_unprepare(pl353_smc->memclk);
-disable_axi_clk:
- clk_disable_unprepare(pl353_smc->aclk);
-
- return err;
-}
-
-static void pl353_smc_remove(struct amba_device *adev)
-{
- struct pl353_smc_data *pl353_smc = amba_get_drvdata(adev);
-
- clk_disable_unprepare(pl353_smc->memclk);
- clk_disable_unprepare(pl353_smc->aclk);
}
static const struct amba_id pl353_ids[] = {
@@ -159,7 +125,6 @@ static struct amba_driver pl353_smc_driver = {
},
.id_table = pl353_ids,
.probe = pl353_smc_probe,
- .remove = pl353_smc_remove,
};
module_amba_driver(pl353_smc_driver);
diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
index 3167826b236a..7fbd36fa1a1b 100644
--- a/drivers/memory/renesas-rpc-if.c
+++ b/drivers/memory/renesas-rpc-if.c
@@ -367,7 +367,7 @@ int rpcif_hw_init(struct device *dev, bool hyperflash)
regmap_update_bits(rpc->regmap, RPCIF_CMNCR,
RPCIF_CMNCR_MOIIO(3) | RPCIF_CMNCR_IOFV(3) |
RPCIF_CMNCR_BSZ(3),
- RPCIF_CMNCR_MOIIO(1) | RPCIF_CMNCR_IOFV(2) |
+ RPCIF_CMNCR_MOIIO(1) | RPCIF_CMNCR_IOFV(3) |
RPCIF_CMNCR_BSZ(hyperflash ? 1 : 0));
else
regmap_update_bits(rpc->regmap, RPCIF_CMNCR,
diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c
index da7ecd921c72..7d80322754fa 100644
--- a/drivers/memory/samsung/exynos5422-dmc.c
+++ b/drivers/memory/samsung/exynos5422-dmc.c
@@ -4,6 +4,7 @@
* Author: Lukasz Luba <l.luba@partner.samsung.com>
*/
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/devfreq.h>
#include <linux/devfreq-event.h>
@@ -339,19 +340,20 @@ static int exynos5_switch_timing_regs(struct exynos5_dmc *dmc, bool set)
static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
struct devfreq_dev_profile *profile)
{
+ struct device *dev = dmc->dev;
int i, ret;
int idx;
unsigned long freq;
- ret = devm_pm_opp_of_add_table(dmc->dev);
+ ret = devm_pm_opp_of_add_table(dev);
if (ret < 0) {
- dev_err(dmc->dev, "Failed to get OPP table\n");
+ dev_err(dev, "Failed to get OPP table\n");
return ret;
}
- dmc->opp_count = dev_pm_opp_get_opp_count(dmc->dev);
+ dmc->opp_count = dev_pm_opp_get_opp_count(dev);
- dmc->opp = devm_kmalloc_array(dmc->dev, dmc->opp_count,
+ dmc->opp = devm_kmalloc_array(dev, dmc->opp_count,
sizeof(struct dmc_opp_table), GFP_KERNEL);
if (!dmc->opp)
return -ENOMEM;
@@ -360,7 +362,7 @@ static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
for (i = 0, freq = ULONG_MAX; i < dmc->opp_count; i++, freq--) {
struct dev_pm_opp *opp;
- opp = dev_pm_opp_find_freq_floor(dmc->dev, &freq);
+ opp = dev_pm_opp_find_freq_floor(dev, &freq);
if (IS_ERR(opp))
return PTR_ERR(opp);
@@ -1175,51 +1177,44 @@ static int create_timings_aligned(struct exynos5_dmc *dmc, u32 *reg_timing_row,
static int of_get_dram_timings(struct exynos5_dmc *dmc)
{
int ret = 0;
+ struct device *dev = dmc->dev;
int idx;
- struct device_node *np_ddr;
u32 freq_mhz, clk_period_ps;
- np_ddr = of_parse_phandle(dmc->dev->of_node, "device-handle", 0);
+ struct device_node *np_ddr __free(device_node) =
+ of_parse_phandle(dev->of_node, "device-handle", 0);
if (!np_ddr) {
- dev_warn(dmc->dev, "could not find 'device-handle' in DT\n");
+ dev_warn(dev, "could not find 'device-handle' in DT\n");
return -EINVAL;
}
- dmc->timing_row = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
+ dmc->timing_row = devm_kmalloc_array(dev, TIMING_COUNT,
sizeof(u32), GFP_KERNEL);
- if (!dmc->timing_row) {
- ret = -ENOMEM;
- goto put_node;
- }
+ if (!dmc->timing_row)
+ return -ENOMEM;
- dmc->timing_data = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
+ dmc->timing_data = devm_kmalloc_array(dev, TIMING_COUNT,
sizeof(u32), GFP_KERNEL);
- if (!dmc->timing_data) {
- ret = -ENOMEM;
- goto put_node;
- }
+ if (!dmc->timing_data)
+ return -ENOMEM;
- dmc->timing_power = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
+ dmc->timing_power = devm_kmalloc_array(dev, TIMING_COUNT,
sizeof(u32), GFP_KERNEL);
- if (!dmc->timing_power) {
- ret = -ENOMEM;
- goto put_node;
- }
+ if (!dmc->timing_power)
+ return -ENOMEM;
- dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dmc->dev,
+ dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dev,
DDR_TYPE_LPDDR3,
&dmc->timings_arr_size);
if (!dmc->timings) {
- dev_warn(dmc->dev, "could not get timings from DT\n");
- ret = -EINVAL;
- goto put_node;
+ dev_warn(dev, "could not get timings from DT\n");
+ return -EINVAL;
}
- dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dmc->dev);
+ dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dev);
if (!dmc->min_tck) {
- dev_warn(dmc->dev, "could not get tck from DT\n");
- ret = -EINVAL;
- goto put_node;
+ dev_warn(dev, "could not get tck from DT\n");
+ return -EINVAL;
}
/* Sorted array of OPPs with frequency ascending */
@@ -1239,8 +1234,6 @@ static int of_get_dram_timings(struct exynos5_dmc *dmc)
dmc->bypass_timing_data = dmc->timing_data[idx - 1];
dmc->bypass_timing_power = dmc->timing_power[idx - 1];
-put_node:
- of_node_put(np_ddr);
return ret;
}
@@ -1254,34 +1247,34 @@ put_node:
static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc)
{
int ret;
+ struct device *dev = dmc->dev;
unsigned long target_volt = 0;
unsigned long target_rate = 0;
unsigned int tmp;
- dmc->fout_spll = devm_clk_get(dmc->dev, "fout_spll");
+ dmc->fout_spll = devm_clk_get(dev, "fout_spll");
if (IS_ERR(dmc->fout_spll))
return PTR_ERR(dmc->fout_spll);
- dmc->fout_bpll = devm_clk_get(dmc->dev, "fout_bpll");
+ dmc->fout_bpll = devm_clk_get(dev, "fout_bpll");
if (IS_ERR(dmc->fout_bpll))
return PTR_ERR(dmc->fout_bpll);
- dmc->mout_mclk_cdrex = devm_clk_get(dmc->dev, "mout_mclk_cdrex");
+ dmc->mout_mclk_cdrex = devm_clk_get(dev, "mout_mclk_cdrex");
if (IS_ERR(dmc->mout_mclk_cdrex))
return PTR_ERR(dmc->mout_mclk_cdrex);
- dmc->mout_bpll = devm_clk_get(dmc->dev, "mout_bpll");
+ dmc->mout_bpll = devm_clk_get(dev, "mout_bpll");
if (IS_ERR(dmc->mout_bpll))
return PTR_ERR(dmc->mout_bpll);
- dmc->mout_mx_mspll_ccore = devm_clk_get(dmc->dev,
- "mout_mx_mspll_ccore");
+ dmc->mout_mx_mspll_ccore = devm_clk_get(dev, "mout_mx_mspll_ccore");
if (IS_ERR(dmc->mout_mx_mspll_ccore))
return PTR_ERR(dmc->mout_mx_mspll_ccore);
- dmc->mout_spll = devm_clk_get(dmc->dev, "ff_dout_spll2");
+ dmc->mout_spll = devm_clk_get(dev, "ff_dout_spll2");
if (IS_ERR(dmc->mout_spll)) {
- dmc->mout_spll = devm_clk_get(dmc->dev, "mout_sclk_spll");
+ dmc->mout_spll = devm_clk_get(dev, "mout_sclk_spll");
if (IS_ERR(dmc->mout_spll))
return PTR_ERR(dmc->mout_spll);
}
@@ -1329,38 +1322,37 @@ static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc)
*/
static int exynos5_performance_counters_init(struct exynos5_dmc *dmc)
{
+ struct device *dev = dmc->dev;
int ret, i;
- dmc->num_counters = devfreq_event_get_edev_count(dmc->dev,
- "devfreq-events");
+ dmc->num_counters = devfreq_event_get_edev_count(dev, "devfreq-events");
if (dmc->num_counters < 0) {
- dev_err(dmc->dev, "could not get devfreq-event counters\n");
+ dev_err(dev, "could not get devfreq-event counters\n");
return dmc->num_counters;
}
- dmc->counter = devm_kcalloc(dmc->dev, dmc->num_counters,
+ dmc->counter = devm_kcalloc(dev, dmc->num_counters,
sizeof(*dmc->counter), GFP_KERNEL);
if (!dmc->counter)
return -ENOMEM;
for (i = 0; i < dmc->num_counters; i++) {
dmc->counter[i] =
- devfreq_event_get_edev_by_phandle(dmc->dev,
- "devfreq-events", i);
+ devfreq_event_get_edev_by_phandle(dev, "devfreq-events", i);
if (IS_ERR_OR_NULL(dmc->counter[i]))
return -EPROBE_DEFER;
}
ret = exynos5_counters_enable_edev(dmc);
if (ret < 0) {
- dev_err(dmc->dev, "could not enable event counter\n");
+ dev_err(dev, "could not enable event counter\n");
return ret;
}
ret = exynos5_counters_set_event(dmc);
if (ret < 0) {
exynos5_counters_disable_edev(dmc);
- dev_err(dmc->dev, "could not set event counter\n");
+ dev_err(dev, "could not set event counter\n");
return ret;
}
diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c
index 1c63eeacd071..566c225f71c0 100644
--- a/drivers/memory/stm32-fmc2-ebi.c
+++ b/drivers/memory/stm32-fmc2-ebi.c
@@ -1573,29 +1573,22 @@ static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,
static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi)
{
struct device *dev = ebi->dev;
- struct device_node *child;
bool child_found = false;
u32 bank;
int ret;
- for_each_available_child_of_node(dev->of_node, child) {
+ for_each_available_child_of_node_scoped(dev->of_node, child) {
ret = of_property_read_u32(child, "reg", &bank);
- if (ret) {
- dev_err(dev, "could not retrieve reg property: %d\n",
- ret);
- of_node_put(child);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "could not retrieve reg property\n");
if (bank >= FMC2_MAX_BANKS) {
dev_err(dev, "invalid reg value: %d\n", bank);
- of_node_put(child);
return -EINVAL;
}
if (ebi->bank_assigned & BIT(bank)) {
dev_err(dev, "bank already assigned: %d\n", bank);
- of_node_put(child);
return -EINVAL;
}
@@ -1603,19 +1596,15 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi)
ret = ebi->data->check_rif(ebi, bank + 1);
if (ret) {
dev_err(dev, "bank access failed: %d\n", bank);
- of_node_put(child);
return ret;
}
}
if (bank < FMC2_MAX_EBI_CE) {
ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank);
- if (ret) {
- dev_err(dev, "setup chip select %d failed: %d\n",
- bank, ret);
- of_node_put(child);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "setup chip select %d failed\n", bank);
}
ebi->bank_assigned |= BIT(bank);
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 224b488794e5..bd5b58f1fd42 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -450,7 +450,6 @@ static int load_one_timing(struct tegra_mc *mc,
static int load_timings(struct tegra_mc *mc, struct device_node *node)
{
- struct device_node *child;
struct tegra_mc_timing *timing;
int child_count = of_get_child_count(node);
int i = 0, err;
@@ -462,14 +461,12 @@ static int load_timings(struct tegra_mc *mc, struct device_node *node)
mc->num_timings = child_count;
- for_each_child_of_node(node, child) {
+ for_each_child_of_node_scoped(node, child) {
timing = &mc->timings[i++];
err = load_one_timing(mc, timing, child);
- if (err) {
- of_node_put(child);
+ if (err)
return err;
- }
}
return 0;
@@ -477,7 +474,6 @@ static int load_timings(struct tegra_mc *mc, struct device_node *node)
static int tegra_mc_setup_timings(struct tegra_mc *mc)
{
- struct device_node *node;
u32 ram_code, node_ram_code;
int err;
@@ -485,14 +481,13 @@ static int tegra_mc_setup_timings(struct tegra_mc *mc)
mc->num_timings = 0;
- for_each_child_of_node(mc->dev->of_node, node) {
+ for_each_child_of_node_scoped(mc->dev->of_node, node) {
err = of_property_read_u32(node, "nvidia,ram-code",
&node_ram_code);
if (err || (node_ram_code != ram_code))
continue;
err = load_timings(mc, node);
- of_node_put(node);
if (err)
return err;
break;
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 47c0c19e13fd..03f1daa2d132 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -992,7 +992,6 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
struct device_node *node)
{
int child_count = of_get_child_count(node);
- struct device_node *child;
struct emc_timing *timing;
unsigned int i = 0;
int err;
@@ -1004,14 +1003,12 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
emc->num_timings = child_count;
- for_each_child_of_node(node, child) {
+ for_each_child_of_node_scoped(node, child) {
timing = &emc->timings[i++];
err = load_one_timing_from_dt(emc, timing, child);
- if (err) {
- of_node_put(child);
+ if (err)
return err;
- }
}
sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings,
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index 57d9ae12fcfe..33d67d251719 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -35,11 +35,6 @@ struct tegra186_emc {
struct icc_provider provider;
};
-static inline struct tegra186_emc *to_tegra186_emc(struct icc_provider *provider)
-{
- return container_of(provider, struct tegra186_emc, provider);
-}
-
/*
* debugfs interface
*
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 97cf59523b0b..7193f848d17e 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -410,7 +410,6 @@ static int cmp_timings(const void *_a, const void *_b)
static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
struct device_node *node)
{
- struct device_node *child;
struct emc_timing *timing;
int child_count;
int err;
@@ -428,15 +427,13 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
timing = emc->timings;
- for_each_child_of_node(node, child) {
+ for_each_child_of_node_scoped(node, child) {
if (of_node_name_eq(child, "lpddr2"))
continue;
err = load_one_timing_from_dt(emc, timing++, child);
- if (err) {
- of_node_put(child);
+ if (err)
return err;
- }
emc->num_timings++;
}
diff --git a/drivers/memory/tegra/tegra210-emc-cc-r21021.c b/drivers/memory/tegra/tegra210-emc-cc-r21021.c
index 4cb608c71ead..a30a646ec468 100644
--- a/drivers/memory/tegra/tegra210-emc-cc-r21021.c
+++ b/drivers/memory/tegra/tegra210-emc-cc-r21021.c
@@ -75,29 +75,29 @@ enum {
* The division portion of the average operation.
*/
#define __AVERAGE_PTFV(dev) \
- ({ next->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] = \
- next->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] / \
+ ({ next->ptfv_list[(dev)] = \
+ next->ptfv_list[(dev)] / \
next->ptfv_list[PTFV_DVFS_SAMPLES_INDEX]; })
/*
* Convert val to fixed point and add it to the temporary average.
*/
#define __INCREMENT_PTFV(dev, val) \
- ({ next->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] += \
+ ({ next->ptfv_list[(dev)] += \
((val) * MOVAVG_PRECISION_FACTOR); })
/*
* Convert a moving average back to integral form and return the value.
*/
#define __MOVAVG_AC(timing, dev) \
- ((timing)->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] / \
+ ((timing)->ptfv_list[(dev)] / \
MOVAVG_PRECISION_FACTOR)
/* Weighted update. */
#define __WEIGHTED_UPDATE_PTFV(dev, nval) \
do { \
int w = PTFV_MOVAVG_WEIGHT_INDEX; \
- int dqs = PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX; \
+ int dqs = (dev); \
\
next->ptfv_list[dqs] = \
((nval * MOVAVG_PRECISION_FACTOR) + \
@@ -105,315 +105,91 @@ enum {
next->ptfv_list[w])) / \
(next->ptfv_list[w] + 1); \
\
- emc_dbg(emc, EMA_UPDATES, "%s: (s=%lu) EMA: %u\n", \
+ emc_dbg(emc, EMA_UPDATES, "%s: (s=%u) EMA: %u\n", \
__stringify(dev), nval, next->ptfv_list[dqs]); \
} while (0)
/* Access a particular average. */
#define __MOVAVG(timing, dev) \
- ((timing)->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX])
+ ((timing)->ptfv_list[(dev)])
-static u32 update_clock_tree_delay(struct tegra210_emc *emc, int type)
+static bool tegra210_emc_compare_update_delay(struct tegra210_emc_timing *timing,
+ u32 measured, u32 idx)
{
- bool periodic_training_update = type == PERIODIC_TRAINING_UPDATE;
- struct tegra210_emc_timing *last = emc->last;
- struct tegra210_emc_timing *next = emc->next;
- u32 last_timing_rate_mhz = last->rate / 1000;
- u32 next_timing_rate_mhz = next->rate / 1000;
- bool dvfs_update = type == DVFS_UPDATE;
- s32 tdel = 0, tmdel = 0, adel = 0;
- bool dvfs_pt1 = type == DVFS_PT1;
- unsigned long cval = 0;
- u32 temp[2][2], value;
- unsigned int i;
-
- /*
- * Dev0 MSB.
- */
- if (dvfs_pt1 || periodic_training_update) {
- value = tegra210_emc_mrr_read(emc, 2, 19);
-
- for (i = 0; i < emc->num_channels; i++) {
- temp[i][0] = (value & 0x00ff) << 8;
- temp[i][1] = (value & 0xff00) << 0;
- value >>= 16;
- }
-
- /*
- * Dev0 LSB.
- */
- value = tegra210_emc_mrr_read(emc, 2, 18);
-
- for (i = 0; i < emc->num_channels; i++) {
- temp[i][0] |= (value & 0x00ff) >> 0;
- temp[i][1] |= (value & 0xff00) >> 8;
- value >>= 16;
- }
- }
-
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[0][0];
- }
+ u32 *curr = &timing->current_dram_clktree[idx];
+ u32 rate_mhz = timing->rate / 1000;
+ u32 tmdel;
- if (dvfs_pt1)
- __INCREMENT_PTFV(C0D0U0, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C0D0U0);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C0D0U0, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C0D0U0] -
- __MOVAVG_AC(next, C0D0U0);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C0D0U0] =
- __MOVAVG_AC(next, C0D0U0);
- }
+ tmdel = abs(*curr - measured);
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[0][1];
+ if (tmdel * 128 * rate_mhz / 1000000 > timing->tree_margin) {
+ *curr = measured;
+ return true;
}
- if (dvfs_pt1)
- __INCREMENT_PTFV(C0D0U1, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C0D0U1);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C0D0U1, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C0D0U1] -
- __MOVAVG_AC(next, C0D0U1);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C0D0U1] =
- __MOVAVG_AC(next, C0D0U1);
- }
-
- if (emc->num_channels > 1) {
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[1][0];
- }
-
- if (dvfs_pt1)
- __INCREMENT_PTFV(C1D0U0, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C1D0U0);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C1D0U0, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C1D0U0] -
- __MOVAVG_AC(next, C1D0U0);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C1D0U0] =
- __MOVAVG_AC(next, C1D0U0);
- }
-
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[1][1];
- }
-
- if (dvfs_pt1)
- __INCREMENT_PTFV(C1D0U1, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C1D0U1);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C1D0U1, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C1D0U1] -
- __MOVAVG_AC(next, C1D0U1);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C1D0U1] =
- __MOVAVG_AC(next, C1D0U1);
- }
- }
-
- if (emc->num_devices < 2)
- goto done;
-
- /*
- * Dev1 MSB.
- */
- if (dvfs_pt1 || periodic_training_update) {
- value = tegra210_emc_mrr_read(emc, 1, 19);
+ return false;
+}
- for (i = 0; i < emc->num_channels; i++) {
- temp[i][0] = (value & 0x00ff) << 8;
- temp[i][1] = (value & 0xff00) << 0;
- value >>= 16;
- }
+static void tegra210_emc_get_clktree_delay(struct tegra210_emc *emc,
+ u32 delay[DRAM_CLKTREE_NUM])
+{
+ struct tegra210_emc_timing *curr = emc->last;
+ u32 rate_mhz = curr->rate / 1000;
+ u32 msb, lsb, dqsosc, delay_us;
+ unsigned int c, d, idx;
+ unsigned long clocks;
- /*
- * Dev1 LSB.
- */
- value = tegra210_emc_mrr_read(emc, 1, 18);
+ clocks = tegra210_emc_actual_osc_clocks(curr->run_clocks);
+ delay_us = 2 + (clocks / rate_mhz);
- for (i = 0; i < emc->num_channels; i++) {
- temp[i][0] |= (value & 0x00ff) >> 0;
- temp[i][1] |= (value & 0xff00) >> 8;
- value >>= 16;
- }
- }
+ tegra210_emc_start_periodic_compensation(emc);
+ udelay(delay_us);
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[0][0];
- }
+ for (d = 0; d < emc->num_devices; d++) {
+ /* Read DQSOSC from MRR18/19 */
+ msb = tegra210_emc_mrr_read(emc, 2 - d, 19);
+ lsb = tegra210_emc_mrr_read(emc, 2 - d, 18);
- if (dvfs_pt1)
- __INCREMENT_PTFV(C0D1U0, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C0D1U0);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C0D1U0, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C0D1U0] -
- __MOVAVG_AC(next, C0D1U0);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C0D1U0] =
- __MOVAVG_AC(next, C0D1U0);
- }
+ for (c = 0; c < emc->num_channels; c++) {
+ /* C[c]D[d]U[0] */
+ idx = c * 4 + d * 2;
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[0][1];
- }
+ dqsosc = (msb & 0x00ff) << 8;
+ dqsosc |= (lsb & 0x00ff) >> 0;
- if (dvfs_pt1)
- __INCREMENT_PTFV(C0D1U1, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C0D1U1);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C0D1U1, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C0D1U1] -
- __MOVAVG_AC(next, C0D1U1);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C0D1U1] =
- __MOVAVG_AC(next, C0D1U1);
- }
+ /* Check for unpopulated channels */
+ if (dqsosc)
+ delay[idx] = (clocks * 1000000) /
+ (rate_mhz * 2 * dqsosc);
- if (emc->num_channels > 1) {
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[1][0];
- }
+ /* C[c]D[d]U[1] */
+ idx++;
- if (dvfs_pt1)
- __INCREMENT_PTFV(C1D1U0, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C1D1U0);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C1D1U0, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C1D1U0] -
- __MOVAVG_AC(next, C1D1U0);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C1D1U0] =
- __MOVAVG_AC(next, C1D1U0);
- }
+ dqsosc = (msb & 0xff00) << 0;
+ dqsosc |= (lsb & 0xff00) >> 8;
- if (dvfs_pt1 || periodic_training_update) {
- cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
- cval *= 1000000;
- cval /= last_timing_rate_mhz * 2 * temp[1][1];
- }
+ /* Check for unpopulated channels */
+ if (dqsosc)
+ delay[idx] = (clocks * 1000000) /
+ (rate_mhz * 2 * dqsosc);
- if (dvfs_pt1)
- __INCREMENT_PTFV(C1D1U1, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C1D1U1);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C1D1U1, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C1D1U1] -
- __MOVAVG_AC(next, C1D1U1);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
-
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C1D1U1] =
- __MOVAVG_AC(next, C1D1U1);
+ msb >>= 16;
+ lsb >>= 16;
}
}
-
-done:
- return adel;
}
-static u32 periodic_compensation_handler(struct tegra210_emc *emc, u32 type,
- struct tegra210_emc_timing *last,
- struct tegra210_emc_timing *next)
+static bool periodic_compensation_handler(struct tegra210_emc *emc, u32 type,
+ struct tegra210_emc_timing *last,
+ struct tegra210_emc_timing *next)
{
#define __COPY_EMA(nt, lt, dev) \
({ __MOVAVG(nt, dev) = __MOVAVG(lt, dev) * \
(nt)->ptfv_list[PTFV_DVFS_SAMPLES_INDEX]; })
- u32 i, adel = 0, samples = next->ptfv_list[PTFV_DVFS_SAMPLES_INDEX];
- u32 delay;
-
- delay = tegra210_emc_actual_osc_clocks(last->run_clocks);
- delay *= 1000;
- delay = 2 + (delay / last->rate);
+ u32 i, samples = next->ptfv_list[PTFV_DVFS_SAMPLES_INDEX];
+ u32 delay[DRAM_CLKTREE_NUM], idx;
+ bool over = false;
if (!next->periodic_training)
return 0;
@@ -427,57 +203,46 @@ static u32 periodic_compensation_handler(struct tegra210_emc *emc, u32 type,
* calibration then we can reuse the previous
* frequencies EMA data.
*/
- __COPY_EMA(next, last, C0D0U0);
- __COPY_EMA(next, last, C0D0U1);
- __COPY_EMA(next, last, C1D0U0);
- __COPY_EMA(next, last, C1D0U1);
- __COPY_EMA(next, last, C0D1U0);
- __COPY_EMA(next, last, C0D1U1);
- __COPY_EMA(next, last, C1D1U0);
- __COPY_EMA(next, last, C1D1U1);
+ for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++)
+ __COPY_EMA(next, last, idx);
} else {
/* Reset the EMA.*/
- __MOVAVG(next, C0D0U0) = 0;
- __MOVAVG(next, C0D0U1) = 0;
- __MOVAVG(next, C1D0U0) = 0;
- __MOVAVG(next, C1D0U1) = 0;
- __MOVAVG(next, C0D1U0) = 0;
- __MOVAVG(next, C0D1U1) = 0;
- __MOVAVG(next, C1D1U0) = 0;
- __MOVAVG(next, C1D1U1) = 0;
+ for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++)
+ __MOVAVG(next, idx) = 0;
for (i = 0; i < samples; i++) {
- tegra210_emc_start_periodic_compensation(emc);
- udelay(delay);
+ /* Generate next sample of data. */
+ tegra210_emc_get_clktree_delay(emc, delay);
- /*
- * Generate next sample of data.
- */
- adel = update_clock_tree_delay(emc, DVFS_PT1);
+ for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++)
+ __INCREMENT_PTFV(idx, delay[idx]);
}
}
- /*
- * Seems like it should be part of the
- * 'if (last_timing->periodic_training)' conditional
- * since is already done for the else clause.
- */
- adel = update_clock_tree_delay(emc, DVFS_UPDATE);
+ for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++) {
+ /* Do the division part of the moving average */
+ __AVERAGE_PTFV(idx);
+ over |= tegra210_emc_compare_update_delay(next,
+ __MOVAVG_AC(next, idx), idx);
+ }
}
if (type == PERIODIC_TRAINING_SEQUENCE) {
- tegra210_emc_start_periodic_compensation(emc);
- udelay(delay);
+ tegra210_emc_get_clktree_delay(emc, delay);
- adel = update_clock_tree_delay(emc, PERIODIC_TRAINING_UPDATE);
+ for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++) {
+ __WEIGHTED_UPDATE_PTFV(idx, delay[idx]);
+ over |= tegra210_emc_compare_update_delay(next,
+ __MOVAVG_AC(next, idx), idx);
+ }
}
- return adel;
+ return over;
}
static u32 tegra210_emc_r21021_periodic_compensation(struct tegra210_emc *emc)
{
- u32 emc_cfg, emc_cfg_o, emc_cfg_update, del, value;
+ u32 emc_cfg, emc_cfg_o, emc_cfg_update, value;
static const u32 list[] = {
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0,
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1,
@@ -492,7 +257,6 @@ static u32 tegra210_emc_r21021_periodic_compensation(struct tegra210_emc *emc)
};
struct tegra210_emc_timing *last = emc->last;
unsigned int items = ARRAY_SIZE(list), i;
- unsigned long delay;
if (last->periodic_training) {
emc_dbg(emc, PER_TRAIN, "Periodic training starting\n");
@@ -530,30 +294,18 @@ static u32 tegra210_emc_r21021_periodic_compensation(struct tegra210_emc *emc)
/*
* 2. osc kick off - this assumes training and dvfs have set
* correct MR23.
- */
- tegra210_emc_start_periodic_compensation(emc);
-
- /*
+ *
* 3. Let dram capture its clock tree delays.
- */
- delay = tegra210_emc_actual_osc_clocks(last->run_clocks);
- delay *= 1000;
- delay /= last->rate + 1;
- udelay(delay);
-
- /*
+ *
* 4. Check delta wrt previous values (save value if margin
* exceeds what is set in table).
*/
- del = periodic_compensation_handler(emc,
- PERIODIC_TRAINING_SEQUENCE,
- last, last);
-
+ if (periodic_compensation_handler(emc, PERIODIC_TRAINING_SEQUENCE,
+ last, last)) {
/*
* 5. Apply compensation w.r.t. trained values (if clock tree
* has drifted more than the set margin).
*/
- if (last->tree_margin < ((del * 128 * (last->rate / 1000)) / 1000000)) {
for (i = 0; i < items; i++) {
value = tegra210_emc_compensate(last, list[i]);
emc_dbg(emc, EMA_WRITES, "0x%08x <= 0x%08x\n",
@@ -734,16 +486,7 @@ static void tegra210_emc_r21021_set_clock(struct tegra210_emc *emc, u32 clksrc)
EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_MASK,
0);
- tegra210_emc_start_periodic_compensation(emc);
-
- delay = 1000 * tegra210_emc_actual_osc_clocks(last->run_clocks);
- udelay((delay / last->rate) + 2);
-
- value = periodic_compensation_handler(emc, DVFS_SEQUENCE, fake,
- next);
- value = (value * 128 * next->rate / 1000) / 1000000;
-
- if (next->periodic_training && value > next->tree_margin)
+ if (periodic_compensation_handler(emc, DVFS_SEQUENCE, fake, next))
compensate_trimmer_applicable = true;
}
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index d7b0a23c2d7d..921dce1b8bc6 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -979,7 +979,6 @@ static int emc_check_mc_timings(struct tegra_emc *emc)
static int emc_load_timings_from_dt(struct tegra_emc *emc,
struct device_node *node)
{
- struct device_node *child;
struct emc_timing *timing;
int child_count;
int err;
@@ -998,12 +997,10 @@ static int emc_load_timings_from_dt(struct tegra_emc *emc,
emc->num_timings = child_count;
timing = emc->timings;
- for_each_child_of_node(node, child) {
+ for_each_child_of_node_scoped(node, child) {
err = load_one_timing_from_dt(emc, timing++, child);
- if (err) {
- of_node_put(child);
+ if (err)
return err;
- }
}
sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings,
diff --git a/drivers/memory/ti-aemif.c b/drivers/memory/ti-aemif.c
index e192db9e0e4b..d54dc3cfff73 100644
--- a/drivers/memory/ti-aemif.c
+++ b/drivers/memory/ti-aemif.c
@@ -17,7 +17,6 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
-#include <linux/platform_data/ti-aemif.h>
#define TA_SHIFT 2
#define RHOLD_SHIFT 4
@@ -330,42 +329,27 @@ static int aemif_probe(struct platform_device *pdev)
int ret = -ENODEV;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct device_node *child_np;
struct aemif_device *aemif;
- struct aemif_platform_data *pdata;
- struct of_dev_auxdata *dev_lookup;
aemif = devm_kzalloc(dev, sizeof(*aemif), GFP_KERNEL);
if (!aemif)
return -ENOMEM;
- pdata = dev_get_platdata(&pdev->dev);
- dev_lookup = pdata ? pdata->dev_lookup : NULL;
-
platform_set_drvdata(pdev, aemif);
- aemif->clk = devm_clk_get(dev, NULL);
- if (IS_ERR(aemif->clk)) {
- dev_err(dev, "cannot get clock 'aemif'\n");
- return PTR_ERR(aemif->clk);
- }
-
- ret = clk_prepare_enable(aemif->clk);
- if (ret)
- return ret;
+ aemif->clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(aemif->clk))
+ return dev_err_probe(dev, PTR_ERR(aemif->clk),
+ "cannot get clock 'aemif'\n");
aemif->clk_rate = clk_get_rate(aemif->clk) / MSEC_PER_SEC;
if (np && of_device_is_compatible(np, "ti,da850-aemif"))
aemif->cs_offset = 2;
- else if (pdata)
- aemif->cs_offset = pdata->cs_offset;
aemif->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(aemif->base)) {
- ret = PTR_ERR(aemif->base);
- goto error;
- }
+ if (IS_ERR(aemif->base))
+ return PTR_ERR(aemif->base);
if (np) {
/*
@@ -374,17 +358,10 @@ static int aemif_probe(struct platform_device *pdev)
* functions iterate over these nodes and update the cs data
* array.
*/
- for_each_available_child_of_node(np, child_np) {
+ for_each_available_child_of_node_scoped(np, child_np) {
ret = of_aemif_parse_abus_config(pdev, child_np);
- if (ret < 0) {
- of_node_put(child_np);
- goto error;
- }
- }
- } else if (pdata && pdata->num_abus_data > 0) {
- for (i = 0; i < pdata->num_abus_data; i++, aemif->num_cs++) {
- aemif->cs_data[i].cs = pdata->abus_data[i].cs;
- aemif_get_hw_params(pdev, i);
+ if (ret < 0)
+ return ret;
}
}
@@ -393,7 +370,7 @@ static int aemif_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(dev, "Error configuring chip select %d\n",
aemif->cs_data[i].cs);
- goto error;
+ return ret;
}
}
@@ -402,41 +379,18 @@ static int aemif_probe(struct platform_device *pdev)
* child will be probed after the AEMIF timing parameters are set.
*/
if (np) {
- for_each_available_child_of_node(np, child_np) {
- ret = of_platform_populate(child_np, NULL,
- dev_lookup, dev);
- if (ret < 0) {
- of_node_put(child_np);
- goto error;
- }
- }
- } else if (pdata) {
- for (i = 0; i < pdata->num_sub_devices; i++) {
- pdata->sub_devices[i].dev.parent = dev;
- ret = platform_device_register(&pdata->sub_devices[i]);
- if (ret) {
- dev_warn(dev, "Error register sub device %s\n",
- pdata->sub_devices[i].name);
- }
+ for_each_available_child_of_node_scoped(np, child_np) {
+ ret = of_platform_populate(child_np, NULL, NULL, dev);
+ if (ret < 0)
+ return ret;
}
}
return 0;
-error:
- clk_disable_unprepare(aemif->clk);
- return ret;
-}
-
-static void aemif_remove(struct platform_device *pdev)
-{
- struct aemif_device *aemif = platform_get_drvdata(pdev);
-
- clk_disable_unprepare(aemif->clk);
}
static struct platform_driver aemif_driver = {
.probe = aemif_probe,
- .remove_new = aemif_remove,
.driver = {
.name = "ti-aemif",
.of_match_table = of_match_ptr(aemif_of_match),