Skip to content

Commit

Permalink
memory: samsung: exynos-srom: Add support for bank configuration
Browse files Browse the repository at this point in the history
Implement handling properties in subnodes and adding child devices to the
system. Child devices will not be added if configuration fails.

Since the driver now does more than suspend-resume support, dependency on
CONFIG_PM is removed.

Signed-off-by: Pavel Fedin <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Pankaj Dubey <[email protected]>
Signed-off-by: Krzysztof Kozlowski <[email protected]>
  • Loading branch information
pfedin authored and krzk committed Apr 18, 2016
1 parent 5901f4c commit 8ac2266
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-exynos/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ menuconfig ARCH_EXYNOS
select COMMON_CLK_SAMSUNG
select EXYNOS_THERMAL
select EXYNOS_PMU
select EXYNOS_SROM if PM
select EXYNOS_SROM
select HAVE_ARM_SCU if SMP
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG
Expand Down
2 changes: 1 addition & 1 deletion drivers/memory/samsung/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ if SAMSUNG_MC

config EXYNOS_SROM
bool "Exynos SROM controller driver" if COMPILE_TEST
depends on (ARM && ARCH_EXYNOS && PM) || (COMPILE_TEST && HAS_IOMEM)
depends on (ARM && ARCH_EXYNOS) || (COMPILE_TEST && HAS_IOMEM)

endif
60 changes: 58 additions & 2 deletions drivers/memory/samsung/exynos-srom.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

Expand Down Expand Up @@ -67,11 +68,50 @@ static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
return rd;
}

static int exynos_srom_configure_bank(struct exynos_srom *srom,
struct device_node *np)
{
u32 bank, width, pmc = 0;
u32 timing[6];
u32 cs, bw;

if (of_property_read_u32(np, "reg", &bank))
return -EINVAL;
if (of_property_read_u32(np, "reg-io-width", &width))
width = 1;
if (of_property_read_bool(np, "samsung,srom-page-mode"))
pmc = 1 << EXYNOS_SROM_BCX__PMC__SHIFT;
if (of_property_read_u32_array(np, "samsung,srom-timing", timing,
ARRAY_SIZE(timing)))
return -EINVAL;

bank *= 4; /* Convert bank into shift/offset */

cs = 1 << EXYNOS_SROM_BW__BYTEENABLE__SHIFT;
if (width == 2)
cs |= 1 << EXYNOS_SROM_BW__DATAWIDTH__SHIFT;

bw = __raw_readl(srom->reg_base + EXYNOS_SROM_BW);
bw = (bw & ~(EXYNOS_SROM_BW__CS_MASK << bank)) | (cs << bank);
__raw_writel(bw, srom->reg_base + EXYNOS_SROM_BW);

__raw_writel(pmc | (timing[0] << EXYNOS_SROM_BCX__TACP__SHIFT) |
(timing[1] << EXYNOS_SROM_BCX__TCAH__SHIFT) |
(timing[2] << EXYNOS_SROM_BCX__TCOH__SHIFT) |
(timing[3] << EXYNOS_SROM_BCX__TACC__SHIFT) |
(timing[4] << EXYNOS_SROM_BCX__TCOS__SHIFT) |
(timing[5] << EXYNOS_SROM_BCX__TACS__SHIFT),
srom->reg_base + EXYNOS_SROM_BC0 + bank);

return 0;
}

static int exynos_srom_probe(struct platform_device *pdev)
{
struct device_node *np;
struct device_node *np, *child;
struct exynos_srom *srom;
struct device *dev = &pdev->dev;
bool bad_bank_config = false;

np = dev->of_node;
if (!np) {
Expand Down Expand Up @@ -100,7 +140,23 @@ static int exynos_srom_probe(struct platform_device *pdev)
return -ENOMEM;
}

return 0;
for_each_child_of_node(np, child) {
if (exynos_srom_configure_bank(srom, child)) {
dev_err(dev,
"Could not decode bank configuration for %s\n",
child->name);
bad_bank_config = true;
}
}

/*
* If any bank failed to configure, we still provide suspend/resume,
* but do not probe child devices
*/
if (bad_bank_config)
return 0;

return of_platform_populate(np, NULL, NULL, dev);
}

static int exynos_srom_remove(struct platform_device *pdev)
Expand Down

0 comments on commit 8ac2266

Please sign in to comment.