diff options
Diffstat (limited to 'drivers/memory')
-rw-r--r-- | drivers/memory/omap-gpmc.c | 122 | ||||
-rw-r--r-- | drivers/memory/renesas-rpc-if.c | 22 | ||||
-rw-r--r-- | drivers/memory/tegra/mc.c | 25 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra186-emc.c | 15 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra20-emc.c | 15 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra210-emc-core.c | 15 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra234.c | 165 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra30-emc.c | 15 |
8 files changed, 318 insertions, 76 deletions
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 2351f2708da2..57d9f91fe89b 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -134,6 +134,7 @@ #define GPMC_CONFIG_DEV_SIZE 0x00000002 #define GPMC_CONFIG_DEV_TYPE 0x00000003 +#define GPMC_CONFIG_WAITPINPOLARITY(pin) (BIT(pin) << 8) #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) #define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29) @@ -229,6 +230,12 @@ struct omap3_gpmc_regs { struct gpmc_cs_config cs_context[GPMC_CS_NUM]; }; +struct gpmc_waitpin { + u32 pin; + u32 polarity; + struct gpio_desc *desc; +}; + struct gpmc_device { struct device *dev; int irq; @@ -236,6 +243,7 @@ struct gpmc_device { struct gpio_chip gpio_chip; struct notifier_block nb; struct omap3_gpmc_regs context; + struct gpmc_waitpin *waitpins; int nirqs; unsigned int is_suspended:1; struct resource *data; @@ -1035,6 +1043,62 @@ void gpmc_cs_free(int cs) } EXPORT_SYMBOL(gpmc_cs_free); +static bool gpmc_is_valid_waitpin(u32 waitpin) +{ + return waitpin < gpmc_nr_waitpins; +} + +static int gpmc_alloc_waitpin(struct gpmc_device *gpmc, + struct gpmc_settings *p) +{ + int ret; + struct gpmc_waitpin *waitpin; + struct gpio_desc *waitpin_desc; + + if (!gpmc_is_valid_waitpin(p->wait_pin)) + return -EINVAL; + + waitpin = &gpmc->waitpins[p->wait_pin]; + + if (!waitpin->desc) { + /* Reserve the GPIO for wait pin usage. + * GPIO polarity doesn't matter here. Wait pin polarity + * is set in GPMC_CONFIG register. + */ + waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip, + p->wait_pin, "WAITPIN", + GPIO_ACTIVE_HIGH, + GPIOD_IN); + + ret = PTR_ERR(waitpin_desc); + if (IS_ERR(waitpin_desc) && ret != -EBUSY) + return ret; + + /* New wait pin */ + waitpin->desc = waitpin_desc; + waitpin->pin = p->wait_pin; + waitpin->polarity = p->wait_pin_polarity; + } else { + /* Shared wait pin */ + if (p->wait_pin_polarity != waitpin->polarity || + p->wait_pin != waitpin->pin) { + dev_err(gpmc->dev, + "shared-wait-pin: invalid configuration\n"); + return -EINVAL; + } + dev_info(gpmc->dev, "shared wait-pin: %d\n", waitpin->pin); + } + + return 0; +} + +static void gpmc_free_waitpin(struct gpmc_device *gpmc, + int wait_pin) +{ + if (gpmc_is_valid_waitpin(wait_pin)) + gpiochip_free_own_desc(gpmc->waitpins[wait_pin].desc); +} + /** * gpmc_configure - write request to configure gpmc * @cmd: command type @@ -1886,6 +1950,17 @@ int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); + if (p->wait_pin_polarity != GPMC_WAITPINPOLARITY_INVALID) { + config1 = gpmc_read_reg(GPMC_CONFIG); + + if (p->wait_pin_polarity == GPMC_WAITPINPOLARITY_ACTIVE_LOW) + config1 &= ~GPMC_CONFIG_WAITPINPOLARITY(p->wait_pin); + else if (p->wait_pin_polarity == GPMC_WAITPINPOLARITY_ACTIVE_HIGH) + config1 |= GPMC_CONFIG_WAITPINPOLARITY(p->wait_pin); + + gpmc_write_reg(GPMC_CONFIG, config1); + } + return 0; } @@ -1975,7 +2050,25 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) __func__); } + p->wait_pin = GPMC_WAITPIN_INVALID; + p->wait_pin_polarity = GPMC_WAITPINPOLARITY_INVALID; + if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) { + if (!gpmc_is_valid_waitpin(p->wait_pin)) { + pr_err("%s: Invalid wait-pin (%d)\n", __func__, p->wait_pin); + p->wait_pin = GPMC_WAITPIN_INVALID; + } + + if (!of_property_read_u32(np, "ti,wait-pin-polarity", + &p->wait_pin_polarity)) { + if (p->wait_pin_polarity != GPMC_WAITPINPOLARITY_ACTIVE_HIGH && + p->wait_pin_polarity != GPMC_WAITPINPOLARITY_ACTIVE_LOW) { + pr_err("%s: Invalid wait-pin-polarity (%d)\n", + __func__, p->wait_pin_polarity); + p->wait_pin_polarity = GPMC_WAITPINPOLARITY_INVALID; + } + } + p->wait_on_read = of_property_read_bool(np, "gpmc,wait-on-read"); p->wait_on_write = of_property_read_bool(np, @@ -2080,7 +2173,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, const char *name; int ret, cs; u32 val; - struct gpio_desc *waitpin_desc = NULL; struct gpmc_device *gpmc = platform_get_drvdata(pdev); if (of_property_read_u32(child, "reg", &cs) < 0) { @@ -2208,17 +2300,9 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, /* Reserve wait pin if it is required and valid */ if (gpmc_s.wait_on_read || gpmc_s.wait_on_write) { - unsigned int wait_pin = gpmc_s.wait_pin; - - waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip, - wait_pin, "WAITPIN", - GPIO_ACTIVE_HIGH, - GPIOD_IN); - if (IS_ERR(waitpin_desc)) { - dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin); - ret = PTR_ERR(waitpin_desc); + ret = gpmc_alloc_waitpin(gpmc, &gpmc_s); + if (ret < 0) goto err; - } } gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings"); @@ -2260,7 +2344,7 @@ err_child_fail: ret = -ENODEV; err_cs: - gpiochip_free_own_desc(waitpin_desc); + gpmc_free_waitpin(gpmc, gpmc_s.wait_pin); err: gpmc_cs_free(cs); @@ -2489,7 +2573,7 @@ static int omap_gpmc_context_notifier(struct notifier_block *nb, static int gpmc_probe(struct platform_device *pdev) { - int rc; + int rc, i; u32 l; struct resource *res; struct gpmc_device *gpmc; @@ -2545,6 +2629,15 @@ static int gpmc_probe(struct platform_device *pdev) gpmc_nr_waitpins = GPMC_NR_WAITPINS; } + gpmc->waitpins = devm_kzalloc(&pdev->dev, + gpmc_nr_waitpins * sizeof(struct gpmc_waitpin), + GFP_KERNEL); + if (!gpmc->waitpins) + return -ENOMEM; + + for (i = 0; i < gpmc_nr_waitpins; i++) + gpmc->waitpins[i].pin = GPMC_WAITPIN_INVALID; + pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); @@ -2598,9 +2691,12 @@ gpio_init_failed: static int gpmc_remove(struct platform_device *pdev) { + int i; struct gpmc_device *gpmc = platform_get_drvdata(pdev); cpu_pm_unregister_notifier(&gpmc->nb); + for (i = 0; i < gpmc_nr_waitpins; i++) + gpmc_free_waitpin(gpmc, i); gpmc_free_irq(gpmc); gpmc_mem_exit(); pm_runtime_put_sync(&pdev->dev); diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c index 4316988d791a..09cd4318a83d 100644 --- a/drivers/memory/renesas-rpc-if.c +++ b/drivers/memory/renesas-rpc-if.c @@ -136,7 +136,8 @@ #define RPCIF_PHYCNT_DDRCAL BIT(19) #define RPCIF_PHYCNT_HS BIT(18) #define RPCIF_PHYCNT_CKSEL(v) (((v) & 0x3) << 16) /* valid only for RZ/G2L */ -#define RPCIF_PHYCNT_STRTIM(v) (((v) & 0x7) << 15) /* valid for R-Car and RZ/G2{E,H,M,N} */ +#define RPCIF_PHYCNT_STRTIM(v) (((v) & 0x7) << 15 | ((v) & 0x8) << 24) /* valid for R-Car and RZ/G2{E,H,M,N} */ + #define RPCIF_PHYCNT_WBUF2 BIT(4) #define RPCIF_PHYCNT_WBUF BIT(2) #define RPCIF_PHYCNT_PHYMEM(v) (((v) & 0x3) << 0) @@ -317,9 +318,15 @@ int rpcif_hw_init(struct rpcif *rpc, bool hyperflash) regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_PHYMEM_MASK, RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0)); + /* DMA Transfer is not supported */ + regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_HS, 0); + if (rpc->type == RPCIF_RCAR_GEN3) regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_STRTIM(7), RPCIF_PHYCNT_STRTIM(7)); + else if (rpc->type == RPCIF_RCAR_GEN4) + regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, + RPCIF_PHYCNT_STRTIM(15), RPCIF_PHYCNT_STRTIM(15)); regmap_update_bits(rpc->regmap, RPCIF_PHYOFFSET1, RPCIF_PHYOFFSET1_DDRTMG(3), RPCIF_PHYOFFSET1_DDRTMG(3)); @@ -330,17 +337,17 @@ int rpcif_hw_init(struct rpcif *rpc, bool hyperflash) regmap_update_bits(rpc->regmap, RPCIF_PHYINT, RPCIF_PHYINT_WPVAL, 0); - if (rpc->type == RPCIF_RCAR_GEN3) - regmap_update_bits(rpc->regmap, RPCIF_CMNCR, - RPCIF_CMNCR_MOIIO(3) | RPCIF_CMNCR_BSZ(3), - RPCIF_CMNCR_MOIIO(3) | - RPCIF_CMNCR_BSZ(hyperflash ? 1 : 0)); - else + if (rpc->type == RPCIF_RZ_G2L) 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_BSZ(hyperflash ? 1 : 0)); + else + regmap_update_bits(rpc->regmap, RPCIF_CMNCR, + RPCIF_CMNCR_MOIIO(3) | RPCIF_CMNCR_BSZ(3), + RPCIF_CMNCR_MOIIO(3) | + RPCIF_CMNCR_BSZ(hyperflash ? 1 : 0)); /* Set RCF after BSZ update */ regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF); @@ -715,6 +722,7 @@ static int rpcif_remove(struct platform_device *pdev) static const struct of_device_id rpcif_of_match[] = { { .compatible = "renesas,rcar-gen3-rpc-if", .data = (void *)RPCIF_RCAR_GEN3 }, + { .compatible = "renesas,rcar-gen4-rpc-if", .data = (void *)RPCIF_RCAR_GEN4 }, { .compatible = "renesas,rzg2l-rpc-if", .data = (void *)RPCIF_RZ_G2L }, {}, }; diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index 2f7a58a9df1a..592907546ee6 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c @@ -107,6 +107,31 @@ int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev) } EXPORT_SYMBOL_GPL(tegra_mc_probe_device); +int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, + phys_addr_t *base, u64 *size) +{ + u32 offset; + + if (id < 1 || id >= mc->soc->num_carveouts) + return -EINVAL; + + if (id < 6) + offset = 0xc0c + 0x50 * (id - 1); + else + offset = 0x2004 + 0x50 * (id - 6); + + *base = mc_ch_readl(mc, MC_BROADCAST_CHANNEL, offset + 0x0); +#ifdef CONFIG_PHYS_ADDR_T_64BIT + *base |= (phys_addr_t)mc_ch_readl(mc, MC_BROADCAST_CHANNEL, offset + 0x4) << 32; +#endif + + if (size) + *size = mc_ch_readl(mc, MC_BROADCAST_CHANNEL, offset + 0x8) << 17; + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_mc_get_carveout_info); + static int tegra_mc_block_dma_common(struct tegra_mc *mc, const struct tegra_mc_reset *rst) { diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c index 54b47ca33483..26e763bde92a 100644 --- a/drivers/memory/tegra/tegra186-emc.c +++ b/drivers/memory/tegra/tegra186-emc.c @@ -84,20 +84,7 @@ static int tegra186_emc_debug_available_rates_show(struct seq_file *s, return 0; } - -static int tegra186_emc_debug_available_rates_open(struct inode *inode, - struct file *file) -{ - return single_open(file, tegra186_emc_debug_available_rates_show, - inode->i_private); -} - -static const struct file_operations tegra186_emc_debug_available_rates_fops = { - .open = tegra186_emc_debug_available_rates_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(tegra186_emc_debug_available_rates); static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate) { diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index 25ba3c5e4ad6..bd4e37b6552d 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -841,20 +841,7 @@ static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data) return 0; } - -static int tegra_emc_debug_available_rates_open(struct inode *inode, - struct file *file) -{ - return single_open(file, tegra_emc_debug_available_rates_show, - inode->i_private); -} - -static const struct file_operations tegra_emc_debug_available_rates_fops = { - .open = tegra_emc_debug_available_rates_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(tegra_emc_debug_available_rates); static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) { diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c index cbe1a7723514..ae5f982f861b 100644 --- a/drivers/memory/tegra/tegra210-emc-core.c +++ b/drivers/memory/tegra/tegra210-emc-core.c @@ -1621,20 +1621,7 @@ static int tegra210_emc_debug_available_rates_show(struct seq_file *s, return 0; } - -static int tegra210_emc_debug_available_rates_open(struct inode *inode, - struct file *file) -{ - return single_open(file, tegra210_emc_debug_available_rates_show, - inode->i_private); -} - -static const struct file_operations tegra210_emc_debug_available_rates_fops = { - .open = tegra210_emc_debug_available_rates_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(tegra210_emc_debug_available_rates); static int tegra210_emc_debug_min_rate_get(void *data, u64 *rate) { diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c index a9e8fd99730f..02dcc5748bba 100644 --- a/drivers/memory/tegra/tegra234.c +++ b/drivers/memory/tegra/tegra234.c @@ -170,6 +170,166 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { .security = 0x504, }, }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0RDA, + .name = "dla0rda", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x5f0, + .security = 0x5f4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0FALRDB, + .name = "dla0falrdb", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x5f8, + .security = 0x5fc, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0WRA, + .name = "dla0wra", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x600, + .security = 0x604, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0RDB, + .name = "dla0rdb", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x160, + .security = 0x164, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0RDA1, + .name = "dla0rda1", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x748, + .security = 0x74c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0FALWRB, + .name = "dla0falwrb", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x608, + .security = 0x60c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0RDB1, + .name = "dla0rdb1", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x168, + .security = 0x16c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA0WRB, + .name = "dla0wrb", + .sid = TEGRA234_SID_NVDLA0, + .regs = { + .sid = { + .override = 0x170, + .security = 0x174, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1RDA, + .name = "dla0rda", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x610, + .security = 0x614, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1FALRDB, + .name = "dla0falrdb", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x618, + .security = 0x61c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1WRA, + .name = "dla0wra", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x620, + .security = 0x624, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1RDB, + .name = "dla0rdb", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x178, + .security = 0x17c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1RDA1, + .name = "dla0rda1", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x750, + .security = 0x754, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1FALWRB, + .name = "dla0falwrb", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x628, + .security = 0x62c, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1RDB1, + .name = "dla0rdb1", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x370, + .security = 0x374, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_DLA1WRB, + .name = "dla0wrb", + .sid = TEGRA234_SID_NVDLA1, + .regs = { + .sid = { + .override = 0x378, + .security = 0x37c, + }, + }, }, }; @@ -187,4 +347,9 @@ const struct tegra_mc_soc tegra234_mc_soc = { .ops = &tegra186_mc_ops, .ch_intmask = 0x0000ff00, .global_intstatus_channel_shift = 8, + /* + * Additionally, there are lite carveouts but those are not currently + * supported. + */ + .num_carveouts = 32, }; diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index 9ba2a9e5316b..77706e9bc543 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -1359,20 +1359,7 @@ static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data) return 0; } - -static int tegra_emc_debug_available_rates_open(struct inode *inode, - struct file *file) -{ - return single_open(file, tegra_emc_debug_available_rates_show, - inode->i_private); -} - -static const struct file_operations tegra_emc_debug_available_rates_fops = { - .open = tegra_emc_debug_available_rates_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(tegra_emc_debug_available_rates); static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) { |