Topic branch for Samsung soc/drivers update for v4.7:
This moves Samsung SROM controller code from arm/mach-exynos into to separate driver under drivers/memory/samsung. In the future this driver will be re-used on ARM64 Exynos platform. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXIHrcAAoJEME3ZuaGi4PXIfsP/0Fba9eiLkTobPb8B9KhBNzc sQqU3CfYNCQOHTz/1W//JHfFgyOQ67bQjKiMlU5NfXS34l33mafMRLqUhUxpnPZB 3FPkecv0eG/Ojj4XO/aY3GgDSDB0Dpi894D5y2OpbkcYTSADijf1VD4+0WvWsxn0 B9UnZFCbUg2nxbAEDxMuulaDnGi7WhUTaUFYUZVBMZjYaQxDVjVwhNFlixXey8cd 9X0SRnm0quPCnuL/j5UtLQCJQu6vnyM9MqauZQqC9J3Bkd+6LaCIVlObmmoV94O9 pOqllEpSbJ6YD6N3M6DYVMihmJUUj/MTFCuJQg9CJHeb4hWUHZXxDj9w+q0Ps1JI fKE7EhtloN1/31KpQJE7xysG8lyq1tE00v5d270QANyHUq6vYXIQgHU9DVpAorto xkytq/9QClVHm0c40BRVrxIgXyLeSekMtqA9ILpSnhdZepUpt0UIM21x1v5tez9Y S+CQJ3wU+iTA2HfSdFqaZ6bMYLlmqdHaylBtVorMdsLj/ZxKs2syEPgsJcDv1LWm 7pNG8S9d1zIeEB6YXfnUiaSkYvNWEkjn0GOiq+Hs+pPB+6HYoI9SaainAhzi9GAq G42gWyA8v/AupwS0A+V5d97agaMZXxuj/FhMH2xKGhvqdNB5QZVtkNOkO+twAO12 i8bFvqlBUO8vfmYj+J39 =6ukR -----END PGP SIGNATURE----- Merge tag 'samsung-drivers-exynos-srom-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into next/drivers Merge "Samsung soc/drivers update for v4.7" from Krzysztof Kozłowski: This moves Samsung SROM controller code from arm/mach-exynos into to separate driver under drivers/memory/samsung. In the future this driver will be re-used on ARM64 Exynos platform. * tag 'samsung-drivers-exynos-srom-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux: memory: samsung: exynos-srom: Add support for bank configuration ARM: EXYNOS: Remove SROM related register settings from mach-exynos MAINTAINERS: Add maintainers entry for drivers/memory/samsung memory: Add support for Exynos SROM driver dt-bindings: EXYNOS: Add exynos-srom device tree binding ARM: dts: change SROM node compatible from generic to model specific
This commit is contained in:
Коммит
036dae83b9
|
@ -0,0 +1,79 @@
|
|||
SAMSUNG Exynos SoCs SROM Controller driver.
|
||||
|
||||
Required properties:
|
||||
- compatible : Should contain "samsung,exynos4210-srom".
|
||||
|
||||
- reg: offset and length of the register set
|
||||
|
||||
Optional properties:
|
||||
The SROM controller can be used to attach external peripherals. In this case
|
||||
extra properties, describing the bus behind it, should be specified as below:
|
||||
|
||||
- #address-cells: Must be set to 2 to allow device address translation.
|
||||
Address is specified as (bank#, offset).
|
||||
|
||||
- #size-cells: Must be set to 1 to allow device size passing
|
||||
|
||||
- ranges: Must be set up to reflect the memory layout with four integer values
|
||||
per bank:
|
||||
<bank-number> 0 <parent address of bank> <size>
|
||||
|
||||
Sub-nodes:
|
||||
The actual device nodes should be added as subnodes to the SROMc node. These
|
||||
subnodes, in addition to regular device specification, should contain the following
|
||||
properties, describing configuration of the relevant SROM bank:
|
||||
|
||||
Required properties:
|
||||
- reg: bank number, base address (relative to start of the bank) and size of
|
||||
the memory mapped for the device. Note that base address will be
|
||||
typically 0 as this is the start of the bank.
|
||||
|
||||
- samsung,srom-timing : array of 6 integers, specifying bank timings in the
|
||||
following order: Tacp, Tcah, Tcoh, Tacc, Tcos, Tacs.
|
||||
Each value is specified in cycles and has the following
|
||||
meaning and valid range:
|
||||
Tacp : Page mode access cycle at Page mode (0 - 15)
|
||||
Tcah : Address holding time after CSn (0 - 15)
|
||||
Tcoh : Chip selection hold on OEn (0 - 15)
|
||||
Tacc : Access cycle (0 - 31, the actual time is N + 1)
|
||||
Tcos : Chip selection set-up before OEn (0 - 15)
|
||||
Tacs : Address set-up before CSn (0 - 15)
|
||||
|
||||
Optional properties:
|
||||
- reg-io-width : data width in bytes (1 or 2). If omitted, default of 1 is used.
|
||||
|
||||
- samsung,srom-page-mode : if page mode is set, 4 data page mode will be configured,
|
||||
else normal (1 data) page mode will be set.
|
||||
|
||||
Example: basic definition, no banks are configured
|
||||
memory-controller@12570000 {
|
||||
compatible = "samsung,exynos4210-srom";
|
||||
reg = <0x12570000 0x14>;
|
||||
};
|
||||
|
||||
Example: SROMc with SMSC911x ethernet chip on bank 3
|
||||
memory-controller@12570000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0 0x04000000 0x20000 // Bank0
|
||||
1 0 0x05000000 0x20000 // Bank1
|
||||
2 0 0x06000000 0x20000 // Bank2
|
||||
3 0 0x07000000 0x20000>; // Bank3
|
||||
|
||||
compatible = "samsung,exynos4210-srom";
|
||||
reg = <0x12570000 0x14>;
|
||||
|
||||
ethernet@3,0 {
|
||||
compatible = "smsc,lan9115";
|
||||
reg = <3 0 0x10000>; // Bank 3, offset = 0
|
||||
phy-mode = "mii";
|
||||
interrupt-parent = <&gpx0>;
|
||||
interrupts = <5 8>;
|
||||
reg-io-width = <2>;
|
||||
smsc,irq-push-pull;
|
||||
smsc,force-internal-phy;
|
||||
|
||||
samsung,srom-page-mode;
|
||||
samsung,srom-timing = <9 12 1 9 1 1>;
|
||||
};
|
||||
};
|
|
@ -1545,6 +1545,7 @@ F: arch/arm/mach-s5p*/
|
|||
F: arch/arm/mach-exynos*/
|
||||
F: drivers/*/*s3c2410*
|
||||
F: drivers/*/*/*s3c2410*
|
||||
F: drivers/memory/samsung/*
|
||||
F: drivers/soc/samsung/*
|
||||
F: drivers/spi/spi-s3c*
|
||||
F: sound/soc/samsung/*
|
||||
|
|
|
@ -77,8 +77,8 @@
|
|||
reg = <0x10000000 0x100>;
|
||||
};
|
||||
|
||||
sromc@12570000 {
|
||||
compatible = "samsung,exynos-srom";
|
||||
memory-controller@12570000 {
|
||||
compatible = "samsung,exynos4210-srom";
|
||||
reg = <0x12570000 0x14>;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
reg = <0x10000000 0x100>;
|
||||
};
|
||||
|
||||
sromc@12250000 {
|
||||
compatible = "samsung,exynos-srom";
|
||||
memory-controller@12250000 {
|
||||
compatible = "samsung,exynos4210-srom";
|
||||
reg = <0x12250000 0x14>;
|
||||
};
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
smsc,irq-push-pull;
|
||||
smsc,force-internal-phy;
|
||||
|
||||
samsung,srom-page-mode = <1>;
|
||||
samsung,srom-page-mode;
|
||||
samsung,srom-timing = <9 12 1 9 1 1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -102,8 +102,8 @@
|
|||
reg = <0x10000000 0x100>;
|
||||
};
|
||||
|
||||
sromc: sromc@12250000 {
|
||||
compatible = "samsung,exynos-srom";
|
||||
sromc: memory-controller@12250000 {
|
||||
compatible = "samsung,exynos4210-srom";
|
||||
reg = <0x12250000 0x14>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
@ -18,6 +18,7 @@ menuconfig ARCH_EXYNOS
|
|||
select COMMON_CLK_SAMSUNG
|
||||
select EXYNOS_THERMAL
|
||||
select EXYNOS_PMU
|
||||
select EXYNOS_SROM
|
||||
select HAVE_ARM_SCU if SMP
|
||||
select HAVE_S3C2410_I2C if I2C
|
||||
select HAVE_S3C2410_WATCHDOG if WATCHDOG
|
||||
|
@ -26,11 +27,13 @@ menuconfig ARCH_EXYNOS
|
|||
select PINCTRL_EXYNOS
|
||||
select PM_GENERIC_DOMAINS if PM
|
||||
select S5P_DEV_MFC
|
||||
select SAMSUNG_MC
|
||||
select SOC_SAMSUNG
|
||||
select SRAM
|
||||
select THERMAL
|
||||
select THERMAL_OF
|
||||
select MFD_SYSCON
|
||||
select MEMORY
|
||||
select CLKSRC_EXYNOS_MCT
|
||||
select POWER_RESET
|
||||
select POWER_RESET_SYSCON
|
||||
|
|
|
@ -31,11 +31,6 @@
|
|||
|
||||
static struct map_desc exynos4_iodesc[] __initdata = {
|
||||
{
|
||||
.virtual = (unsigned long)S5P_VA_SROMC,
|
||||
.pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = (unsigned long)S5P_VA_CMU,
|
||||
.pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
|
||||
.length = SZ_128K,
|
||||
|
@ -58,15 +53,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct map_desc exynos5_iodesc[] __initdata = {
|
||||
{
|
||||
.virtual = (unsigned long)S5P_VA_SROMC,
|
||||
.pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device exynos_cpuidle = {
|
||||
.name = "exynos_cpuidle",
|
||||
#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
|
||||
|
@ -138,9 +124,6 @@ static void __init exynos_map_io(void)
|
|||
{
|
||||
if (soc_is_exynos4())
|
||||
iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
|
||||
|
||||
if (soc_is_exynos5())
|
||||
iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
|
||||
}
|
||||
|
||||
static void __init exynos_init_io(void)
|
||||
|
|
|
@ -25,7 +25,4 @@
|
|||
|
||||
#define EXYNOS4_PA_COREPERI 0x10500000
|
||||
|
||||
#define EXYNOS4_PA_SROMC 0x12570000
|
||||
#define EXYNOS5_PA_SROMC 0x12250000
|
||||
|
||||
#endif /* __ASM_ARCH_MAP_H */
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* S5P SROMC register definitions
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_SAMSUNG_REGS_SROM_H
|
||||
#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__
|
||||
|
||||
#include <mach/map.h>
|
||||
|
||||
#define S5P_SROMREG(x) (S5P_VA_SROMC + (x))
|
||||
|
||||
#define S5P_SROM_BW S5P_SROMREG(0x0)
|
||||
#define S5P_SROM_BC0 S5P_SROMREG(0x4)
|
||||
#define S5P_SROM_BC1 S5P_SROMREG(0x8)
|
||||
#define S5P_SROM_BC2 S5P_SROMREG(0xc)
|
||||
#define S5P_SROM_BC3 S5P_SROMREG(0x10)
|
||||
#define S5P_SROM_BC4 S5P_SROMREG(0x14)
|
||||
#define S5P_SROM_BC5 S5P_SROMREG(0x18)
|
||||
|
||||
/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
|
||||
|
||||
#define S5P_SROM_BW__DATAWIDTH__SHIFT 0
|
||||
#define S5P_SROM_BW__ADDRMODE__SHIFT 1
|
||||
#define S5P_SROM_BW__WAITENABLE__SHIFT 2
|
||||
#define S5P_SROM_BW__BYTEENABLE__SHIFT 3
|
||||
|
||||
#define S5P_SROM_BW__CS_MASK 0xf
|
||||
|
||||
#define S5P_SROM_BW__NCS0__SHIFT 0
|
||||
#define S5P_SROM_BW__NCS1__SHIFT 4
|
||||
#define S5P_SROM_BW__NCS2__SHIFT 8
|
||||
#define S5P_SROM_BW__NCS3__SHIFT 12
|
||||
#define S5P_SROM_BW__NCS4__SHIFT 16
|
||||
#define S5P_SROM_BW__NCS5__SHIFT 20
|
||||
|
||||
/* applies to same to BCS0 - BCS3 */
|
||||
|
||||
#define S5P_SROM_BCX__PMC__SHIFT 0
|
||||
#define S5P_SROM_BCX__TACP__SHIFT 4
|
||||
#define S5P_SROM_BCX__TCAH__SHIFT 8
|
||||
#define S5P_SROM_BCX__TCOH__SHIFT 12
|
||||
#define S5P_SROM_BCX__TACC__SHIFT 16
|
||||
#define S5P_SROM_BCX__TCOS__SHIFT 24
|
||||
#define S5P_SROM_BCX__TACS__SHIFT 28
|
||||
|
||||
#endif /* __PLAT_SAMSUNG_REGS_SROM_H */
|
|
@ -34,10 +34,11 @@
|
|||
#include <asm/smp_scu.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
|
||||
#include <plat/pm-common.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "regs-srom.h"
|
||||
|
||||
#define REG_TABLE_END (-1U)
|
||||
|
||||
|
@ -53,15 +54,6 @@ struct exynos_wkup_irq {
|
|||
u32 mask;
|
||||
};
|
||||
|
||||
static struct sleep_save exynos_core_save[] = {
|
||||
/* SROM side */
|
||||
SAVE_ITEM(S5P_SROM_BW),
|
||||
SAVE_ITEM(S5P_SROM_BC0),
|
||||
SAVE_ITEM(S5P_SROM_BC1),
|
||||
SAVE_ITEM(S5P_SROM_BC2),
|
||||
SAVE_ITEM(S5P_SROM_BC3),
|
||||
};
|
||||
|
||||
struct exynos_pm_data {
|
||||
const struct exynos_wkup_irq *wkup_irq;
|
||||
unsigned int wake_disable_mask;
|
||||
|
@ -343,8 +335,6 @@ static void exynos_pm_prepare(void)
|
|||
/* Set wake-up mask registers */
|
||||
exynos_pm_set_wakeup_mask();
|
||||
|
||||
s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
|
||||
|
||||
exynos_pm_enter_sleep_mode();
|
||||
|
||||
/* ensure at least INFORM0 has the resume address */
|
||||
|
@ -375,8 +365,6 @@ static void exynos5420_pm_prepare(void)
|
|||
/* Set wake-up mask registers */
|
||||
exynos_pm_set_wakeup_mask();
|
||||
|
||||
s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
|
||||
|
||||
exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
|
||||
/*
|
||||
* The cpu state needs to be saved and restored so that the
|
||||
|
@ -467,8 +455,6 @@ static void exynos_pm_resume(void)
|
|||
/* For release retention */
|
||||
exynos_pm_release_retention();
|
||||
|
||||
s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
|
||||
|
||||
if (cpuid == ARM_CPU_PART_CORTEX_A9)
|
||||
scu_enable(S5P_VA_SCU);
|
||||
|
||||
|
@ -535,8 +521,6 @@ static void exynos5420_pm_resume(void)
|
|||
|
||||
pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
|
||||
|
||||
s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
|
||||
|
||||
early_wakeup:
|
||||
|
||||
tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
|
||||
#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
|
||||
#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
|
||||
|
||||
#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
|
||||
#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
|
||||
|
|
|
@ -122,6 +122,7 @@ config MTK_SMI
|
|||
mainly help enable/disable iommu and control the power domain and
|
||||
clocks for each local arbiter.
|
||||
|
||||
source "drivers/memory/samsung/Kconfig"
|
||||
source "drivers/memory/tegra/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
@ -17,4 +17,5 @@ obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
|
|||
obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
|
||||
obj-$(CONFIG_MTK_SMI) += mtk-smi.o
|
||||
|
||||
obj-$(CONFIG_SAMSUNG_MC) += samsung/
|
||||
obj-$(CONFIG_TEGRA_MC) += tegra/
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
config SAMSUNG_MC
|
||||
bool "Samsung Exynos Memory Controller support" if COMPILE_TEST
|
||||
help
|
||||
Support for the Memory Controller (MC) devices found on
|
||||
Samsung Exynos SoCs.
|
||||
|
||||
if SAMSUNG_MC
|
||||
|
||||
config EXYNOS_SROM
|
||||
bool "Exynos SROM controller driver" if COMPILE_TEST
|
||||
depends on (ARM && ARCH_EXYNOS) || (COMPILE_TEST && HAS_IOMEM)
|
||||
|
||||
endif
|
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_EXYNOS_SROM) += exynos-srom.o
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com/
|
||||
*
|
||||
* EXYNOS - SROM Controller support
|
||||
* Author: Pankaj Dubey <pankaj.dubey@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#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>
|
||||
|
||||
#include "exynos-srom.h"
|
||||
|
||||
static const unsigned long exynos_srom_offsets[] = {
|
||||
/* SROM side */
|
||||
EXYNOS_SROM_BW,
|
||||
EXYNOS_SROM_BC0,
|
||||
EXYNOS_SROM_BC1,
|
||||
EXYNOS_SROM_BC2,
|
||||
EXYNOS_SROM_BC3,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct exynos_srom_reg_dump: register dump of SROM Controller registers.
|
||||
* @offset: srom register offset from the controller base address.
|
||||
* @value: the value of register under the offset.
|
||||
*/
|
||||
struct exynos_srom_reg_dump {
|
||||
u32 offset;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct exynos_srom: platform data for exynos srom controller driver.
|
||||
* @dev: platform device pointer
|
||||
* @reg_base: srom base address
|
||||
* @reg_offset: exynos_srom_reg_dump pointer to hold offset and its value.
|
||||
*/
|
||||
struct exynos_srom {
|
||||
struct device *dev;
|
||||
void __iomem *reg_base;
|
||||
struct exynos_srom_reg_dump *reg_offset;
|
||||
};
|
||||
|
||||
static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
|
||||
const unsigned long *rdump,
|
||||
unsigned long nr_rdump)
|
||||
{
|
||||
struct exynos_srom_reg_dump *rd;
|
||||
unsigned int i;
|
||||
|
||||
rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
|
||||
if (!rd)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < nr_rdump; ++i)
|
||||
rd[i].offset = rdump[i];
|
||||
|
||||
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, *child;
|
||||
struct exynos_srom *srom;
|
||||
struct device *dev = &pdev->dev;
|
||||
bool bad_bank_config = false;
|
||||
|
||||
np = dev->of_node;
|
||||
if (!np) {
|
||||
dev_err(&pdev->dev, "could not find device info\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
srom = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct exynos_srom), GFP_KERNEL);
|
||||
if (!srom)
|
||||
return -ENOMEM;
|
||||
|
||||
srom->dev = dev;
|
||||
srom->reg_base = of_iomap(np, 0);
|
||||
if (!srom->reg_base) {
|
||||
dev_err(&pdev->dev, "iomap of exynos srom controller failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, srom);
|
||||
|
||||
srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
|
||||
sizeof(exynos_srom_offsets));
|
||||
if (!srom->reg_offset) {
|
||||
iounmap(srom->reg_base);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct exynos_srom *srom = platform_get_drvdata(pdev);
|
||||
|
||||
kfree(srom->reg_offset);
|
||||
iounmap(srom->reg_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void exynos_srom_save(void __iomem *base,
|
||||
struct exynos_srom_reg_dump *rd,
|
||||
unsigned int num_regs)
|
||||
{
|
||||
for (; num_regs > 0; --num_regs, ++rd)
|
||||
rd->value = readl(base + rd->offset);
|
||||
}
|
||||
|
||||
static void exynos_srom_restore(void __iomem *base,
|
||||
const struct exynos_srom_reg_dump *rd,
|
||||
unsigned int num_regs)
|
||||
{
|
||||
for (; num_regs > 0; --num_regs, ++rd)
|
||||
writel(rd->value, base + rd->offset);
|
||||
}
|
||||
|
||||
static int exynos_srom_suspend(struct device *dev)
|
||||
{
|
||||
struct exynos_srom *srom = dev_get_drvdata(dev);
|
||||
|
||||
exynos_srom_save(srom->reg_base, srom->reg_offset,
|
||||
ARRAY_SIZE(exynos_srom_offsets));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos_srom_resume(struct device *dev)
|
||||
{
|
||||
struct exynos_srom *srom = dev_get_drvdata(dev);
|
||||
|
||||
exynos_srom_restore(srom->reg_base, srom->reg_offset,
|
||||
ARRAY_SIZE(exynos_srom_offsets));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct of_device_id of_exynos_srom_ids[] = {
|
||||
{
|
||||
.compatible = "samsung,exynos4210-srom",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_exynos_srom_ids);
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume);
|
||||
|
||||
static struct platform_driver exynos_srom_driver = {
|
||||
.probe = exynos_srom_probe,
|
||||
.remove = exynos_srom_remove,
|
||||
.driver = {
|
||||
.name = "exynos-srom",
|
||||
.of_match_table = of_exynos_srom_ids,
|
||||
.pm = &exynos_srom_pm_ops,
|
||||
},
|
||||
};
|
||||
module_platform_driver(exynos_srom_driver);
|
||||
|
||||
MODULE_AUTHOR("Pankaj Dubey <pankaj.dubey@samsung.com>");
|
||||
MODULE_DESCRIPTION("Exynos SROM Controller Driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* Exynos SROMC register definitions
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __EXYNOS_SROM_H
|
||||
#define __EXYNOS_SROM_H __FILE__
|
||||
|
||||
#define EXYNOS_SROMREG(x) (x)
|
||||
|
||||
#define EXYNOS_SROM_BW EXYNOS_SROMREG(0x0)
|
||||
#define EXYNOS_SROM_BC0 EXYNOS_SROMREG(0x4)
|
||||
#define EXYNOS_SROM_BC1 EXYNOS_SROMREG(0x8)
|
||||
#define EXYNOS_SROM_BC2 EXYNOS_SROMREG(0xc)
|
||||
#define EXYNOS_SROM_BC3 EXYNOS_SROMREG(0x10)
|
||||
#define EXYNOS_SROM_BC4 EXYNOS_SROMREG(0x14)
|
||||
#define EXYNOS_SROM_BC5 EXYNOS_SROMREG(0x18)
|
||||
|
||||
/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
|
||||
|
||||
#define EXYNOS_SROM_BW__DATAWIDTH__SHIFT 0
|
||||
#define EXYNOS_SROM_BW__ADDRMODE__SHIFT 1
|
||||
#define EXYNOS_SROM_BW__WAITENABLE__SHIFT 2
|
||||
#define EXYNOS_SROM_BW__BYTEENABLE__SHIFT 3
|
||||
|
||||
#define EXYNOS_SROM_BW__CS_MASK 0xf
|
||||
|
||||
#define EXYNOS_SROM_BW__NCS0__SHIFT 0
|
||||
#define EXYNOS_SROM_BW__NCS1__SHIFT 4
|
||||
#define EXYNOS_SROM_BW__NCS2__SHIFT 8
|
||||
#define EXYNOS_SROM_BW__NCS3__SHIFT 12
|
||||
#define EXYNOS_SROM_BW__NCS4__SHIFT 16
|
||||
#define EXYNOS_SROM_BW__NCS5__SHIFT 20
|
||||
|
||||
/* applies to same to BCS0 - BCS3 */
|
||||
|
||||
#define EXYNOS_SROM_BCX__PMC__SHIFT 0
|
||||
#define EXYNOS_SROM_BCX__TACP__SHIFT 4
|
||||
#define EXYNOS_SROM_BCX__TCAH__SHIFT 8
|
||||
#define EXYNOS_SROM_BCX__TCOH__SHIFT 12
|
||||
#define EXYNOS_SROM_BCX__TACC__SHIFT 16
|
||||
#define EXYNOS_SROM_BCX__TCOS__SHIFT 24
|
||||
#define EXYNOS_SROM_BCX__TACS__SHIFT 28
|
||||
|
||||
#endif /* __EXYNOS_SROM_H */
|
Загрузка…
Ссылка в новой задаче