You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'armsoc-drivers' into test-merge
ARM: SoC: driver updates for v4.2 Some of these are for drivers/soc, where we're now putting SoC-specific drivers these days. Some are for other driver subsystems where we have received acks from the appropriate maintainers. Some highlights: - simple-mfd: document DT bindings and misc updates - migrate mach-berlin to simple-mfd for clock, pinctrl and reset - memory: support for Tegra132 SoC - memory: introduce tegra EMC driver for scaling memory frequency - misc. updates for ARM CCI and CCN busses Conflicts: arch/arm64/boot/dts/arm/juno-motherboard.dtsi Trivial add/add conflict with our dt branch. Resolution: take both sides. # gpg: Signature made Wed Jun 24 21:32:17 2015 PDT using RSA key ID D3FBC665 # gpg: Good signature from "Kevin Hilman <khilman@deeprootsystems.com>" # gpg: aka "Kevin Hilman <khilman@linaro.org>" # gpg: aka "Kevin Hilman <khilman@kernel.org>" # Conflicts: # arch/arm64/boot/dts/arm/juno-motherboard.dtsi
This commit is contained in:
@@ -33,20 +33,23 @@ directory, with first 8 configurable by user and additional
|
||||
Cycle counter is described by a "type" value 0xff and does
|
||||
not require any other settings.
|
||||
|
||||
The driver also provides a "cpumask" sysfs attribute, which contains
|
||||
a single CPU ID, of the processor which will be used to handle all
|
||||
the CCN PMU events. It is recommended that the user space tools
|
||||
request the events on this processor (if not, the perf_event->cpu value
|
||||
will be overwritten anyway). In case of this processor being offlined,
|
||||
the events are migrated to another one and the attribute is updated.
|
||||
|
||||
Example of perf tool use:
|
||||
|
||||
/ # perf list | grep ccn
|
||||
ccn/cycles/ [Kernel PMU event]
|
||||
<...>
|
||||
ccn/xp_valid_flit/ [Kernel PMU event]
|
||||
ccn/xp_valid_flit,xp=?,port=?,vc=?,dir=?/ [Kernel PMU event]
|
||||
<...>
|
||||
|
||||
/ # perf stat -C 0 -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
|
||||
/ # perf stat -a -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
|
||||
sleep 1
|
||||
|
||||
The driver does not support sampling, therefore "perf record" will
|
||||
not work. Also notice that only single cpu is being selected
|
||||
("-C 0") - this is because perf framework does not support
|
||||
"non-CPU related" counters (yet?) so system-wide session ("-a")
|
||||
would try (and in most cases fail) to set up the same event
|
||||
per each CPU.
|
||||
not work. Per-task (without "-a") perf sessions are not supported.
|
||||
|
||||
@@ -31,8 +31,9 @@ specific to ARM.
|
||||
- compatible
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: must be set to
|
||||
Definition: must contain one of the following:
|
||||
"arm,cci-400"
|
||||
"arm,cci-500"
|
||||
|
||||
- reg
|
||||
Usage: required
|
||||
@@ -99,6 +100,7 @@ specific to ARM.
|
||||
"arm,cci-400-pmu,r1"
|
||||
"arm,cci-400-pmu" - DEPRECATED, permitted only where OS has
|
||||
secure acces to CCI registers
|
||||
"arm,cci-500-pmu,r0"
|
||||
- reg:
|
||||
Usage: required
|
||||
Value type: Integer cells. A register entry, expressed
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
NVIDIA Tegra Memory Controller device tree bindings
|
||||
===================================================
|
||||
|
||||
memory-controller node
|
||||
----------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "nvidia,tegra<chip>-mc"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
@@ -15,9 +18,49 @@ Required properties:
|
||||
This device implements an IOMMU that complies with the generic IOMMU binding.
|
||||
See ../iommu/iommu.txt for details.
|
||||
|
||||
Example:
|
||||
--------
|
||||
emc-timings subnode
|
||||
-------------------
|
||||
|
||||
The node should contain a "emc-timings" subnode for each supported RAM type (see field RAM_CODE in
|
||||
register PMC_STRAPPING_OPT_A).
|
||||
|
||||
Required properties for "emc-timings" nodes :
|
||||
- nvidia,ram-code : Should contain the value of RAM_CODE this timing set is used for.
|
||||
|
||||
timing subnode
|
||||
--------------
|
||||
|
||||
Each "emc-timings" node should contain a subnode for every supported EMC clock rate.
|
||||
|
||||
Required properties for timing nodes :
|
||||
- clock-frequency : Should contain the memory clock rate in Hz.
|
||||
- nvidia,emem-configuration : Values to be written to the EMEM register block. For the Tegra124 SoC
|
||||
(see section "15.6.1 MC Registers" in the TRM), these are the registers whose values need to be
|
||||
specified, according to the board documentation:
|
||||
|
||||
MC_EMEM_ARB_CFG
|
||||
MC_EMEM_ARB_OUTSTANDING_REQ
|
||||
MC_EMEM_ARB_TIMING_RCD
|
||||
MC_EMEM_ARB_TIMING_RP
|
||||
MC_EMEM_ARB_TIMING_RC
|
||||
MC_EMEM_ARB_TIMING_RAS
|
||||
MC_EMEM_ARB_TIMING_FAW
|
||||
MC_EMEM_ARB_TIMING_RRD
|
||||
MC_EMEM_ARB_TIMING_RAP2PRE
|
||||
MC_EMEM_ARB_TIMING_WAP2PRE
|
||||
MC_EMEM_ARB_TIMING_R2R
|
||||
MC_EMEM_ARB_TIMING_W2W
|
||||
MC_EMEM_ARB_TIMING_R2W
|
||||
MC_EMEM_ARB_TIMING_W2R
|
||||
MC_EMEM_ARB_DA_TURNS
|
||||
MC_EMEM_ARB_DA_COVERS
|
||||
MC_EMEM_ARB_MISC0
|
||||
MC_EMEM_ARB_MISC1
|
||||
MC_EMEM_ARB_RING1_THROTTLE
|
||||
|
||||
Example SoC include file:
|
||||
|
||||
/ {
|
||||
mc: memory-controller@0,70019000 {
|
||||
compatible = "nvidia,tegra124-mc";
|
||||
reg = <0x0 0x70019000 0x0 0x1000>;
|
||||
@@ -34,3 +77,40 @@ Example:
|
||||
...
|
||||
iommus = <&mc TEGRA_SWGROUP_SDMMC1A>;
|
||||
};
|
||||
};
|
||||
|
||||
Example board file:
|
||||
|
||||
/ {
|
||||
memory-controller@0,70019000 {
|
||||
emc-timings-3 {
|
||||
nvidia,ram-code = <3>;
|
||||
|
||||
timing-12750000 {
|
||||
clock-frequency = <12750000>;
|
||||
|
||||
nvidia,emem-configuration = <
|
||||
0x40040001 /* MC_EMEM_ARB_CFG */
|
||||
0x8000000a /* MC_EMEM_ARB_OUTSTANDING_REQ */
|
||||
0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
|
||||
0x00000001 /* MC_EMEM_ARB_TIMING_RP */
|
||||
0x00000002 /* MC_EMEM_ARB_TIMING_RC */
|
||||
0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
|
||||
0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
|
||||
0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
|
||||
0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
|
||||
0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
|
||||
0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
|
||||
0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
|
||||
0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
|
||||
0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
|
||||
0x06030203 /* MC_EMEM_ARB_DA_TURNS */
|
||||
0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
|
||||
0x77e30303 /* MC_EMEM_ARB_MISC0 */
|
||||
0x70000f03 /* MC_EMEM_ARB_MISC1 */
|
||||
0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,374 @@
|
||||
NVIDIA Tegra124 SoC EMC (external memory controller)
|
||||
====================================================
|
||||
|
||||
Required properties :
|
||||
- compatible : Should be "nvidia,tegra124-emc".
|
||||
- reg : physical base address and length of the controller's registers.
|
||||
- nvidia,memory-controller : phandle of the MC driver.
|
||||
|
||||
The node should contain a "emc-timings" subnode for each supported RAM type
|
||||
(see field RAM_CODE in register PMC_STRAPPING_OPT_A), with its unit address
|
||||
being its RAM_CODE.
|
||||
|
||||
Required properties for "emc-timings" nodes :
|
||||
- nvidia,ram-code : Should contain the value of RAM_CODE this timing set is
|
||||
used for.
|
||||
|
||||
Each "emc-timings" node should contain a "timing" subnode for every supported
|
||||
EMC clock rate. The "timing" subnodes should have the clock rate in Hz as
|
||||
their unit address.
|
||||
|
||||
Required properties for "timing" nodes :
|
||||
- clock-frequency : Should contain the memory clock rate in Hz.
|
||||
- The following properties contain EMC timing characterization values
|
||||
(specified in the board documentation) :
|
||||
- nvidia,emc-auto-cal-config : EMC_AUTO_CAL_CONFIG
|
||||
- nvidia,emc-auto-cal-config2 : EMC_AUTO_CAL_CONFIG2
|
||||
- nvidia,emc-auto-cal-config3 : EMC_AUTO_CAL_CONFIG3
|
||||
- nvidia,emc-auto-cal-interval : EMC_AUTO_CAL_INTERVAL
|
||||
- nvidia,emc-bgbias-ctl0 : EMC_BGBIAS_CTL0
|
||||
- nvidia,emc-cfg : EMC_CFG
|
||||
- nvidia,emc-cfg-2 : EMC_CFG_2
|
||||
- nvidia,emc-ctt-term-ctrl : EMC_CTT_TERM_CTRL
|
||||
- nvidia,emc-mode-1 : Mode Register 1
|
||||
- nvidia,emc-mode-2 : Mode Register 2
|
||||
- nvidia,emc-mode-4 : Mode Register 4
|
||||
- nvidia,emc-mode-reset : Mode Register 0
|
||||
- nvidia,emc-mrs-wait-cnt : EMC_MRS_WAIT_CNT
|
||||
- nvidia,emc-sel-dpd-ctrl : EMC_SEL_DPD_CTRL
|
||||
- nvidia,emc-xm2dqspadctrl2 : EMC_XM2DQSPADCTRL2
|
||||
- nvidia,emc-zcal-cnt-long : EMC_ZCAL_WAIT_CNT after clock change
|
||||
- nvidia,emc-zcal-interval : EMC_ZCAL_INTERVAL
|
||||
- nvidia,emc-configuration : EMC timing characterization data. These are the
|
||||
registers (see section "15.6.2 EMC Registers" in the TRM) whose values need to
|
||||
be specified, according to the board documentation:
|
||||
|
||||
EMC_RC
|
||||
EMC_RFC
|
||||
EMC_RFC_SLR
|
||||
EMC_RAS
|
||||
EMC_RP
|
||||
EMC_R2W
|
||||
EMC_W2R
|
||||
EMC_R2P
|
||||
EMC_W2P
|
||||
EMC_RD_RCD
|
||||
EMC_WR_RCD
|
||||
EMC_RRD
|
||||
EMC_REXT
|
||||
EMC_WEXT
|
||||
EMC_WDV
|
||||
EMC_WDV_MASK
|
||||
EMC_QUSE
|
||||
EMC_QUSE_WIDTH
|
||||
EMC_IBDLY
|
||||
EMC_EINPUT
|
||||
EMC_EINPUT_DURATION
|
||||
EMC_PUTERM_EXTRA
|
||||
EMC_PUTERM_WIDTH
|
||||
EMC_PUTERM_ADJ
|
||||
EMC_CDB_CNTL_1
|
||||
EMC_CDB_CNTL_2
|
||||
EMC_CDB_CNTL_3
|
||||
EMC_QRST
|
||||
EMC_QSAFE
|
||||
EMC_RDV
|
||||
EMC_RDV_MASK
|
||||
EMC_REFRESH
|
||||
EMC_BURST_REFRESH_NUM
|
||||
EMC_PRE_REFRESH_REQ_CNT
|
||||
EMC_PDEX2WR
|
||||
EMC_PDEX2RD
|
||||
EMC_PCHG2PDEN
|
||||
EMC_ACT2PDEN
|
||||
EMC_AR2PDEN
|
||||
EMC_RW2PDEN
|
||||
EMC_TXSR
|
||||
EMC_TXSRDLL
|
||||
EMC_TCKE
|
||||
EMC_TCKESR
|
||||
EMC_TPD
|
||||
EMC_TFAW
|
||||
EMC_TRPAB
|
||||
EMC_TCLKSTABLE
|
||||
EMC_TCLKSTOP
|
||||
EMC_TREFBW
|
||||
EMC_FBIO_CFG6
|
||||
EMC_ODT_WRITE
|
||||
EMC_ODT_READ
|
||||
EMC_FBIO_CFG5
|
||||
EMC_CFG_DIG_DLL
|
||||
EMC_CFG_DIG_DLL_PERIOD
|
||||
EMC_DLL_XFORM_DQS0
|
||||
EMC_DLL_XFORM_DQS1
|
||||
EMC_DLL_XFORM_DQS2
|
||||
EMC_DLL_XFORM_DQS3
|
||||
EMC_DLL_XFORM_DQS4
|
||||
EMC_DLL_XFORM_DQS5
|
||||
EMC_DLL_XFORM_DQS6
|
||||
EMC_DLL_XFORM_DQS7
|
||||
EMC_DLL_XFORM_DQS8
|
||||
EMC_DLL_XFORM_DQS9
|
||||
EMC_DLL_XFORM_DQS10
|
||||
EMC_DLL_XFORM_DQS11
|
||||
EMC_DLL_XFORM_DQS12
|
||||
EMC_DLL_XFORM_DQS13
|
||||
EMC_DLL_XFORM_DQS14
|
||||
EMC_DLL_XFORM_DQS15
|
||||
EMC_DLL_XFORM_QUSE0
|
||||
EMC_DLL_XFORM_QUSE1
|
||||
EMC_DLL_XFORM_QUSE2
|
||||
EMC_DLL_XFORM_QUSE3
|
||||
EMC_DLL_XFORM_QUSE4
|
||||
EMC_DLL_XFORM_QUSE5
|
||||
EMC_DLL_XFORM_QUSE6
|
||||
EMC_DLL_XFORM_QUSE7
|
||||
EMC_DLL_XFORM_ADDR0
|
||||
EMC_DLL_XFORM_ADDR1
|
||||
EMC_DLL_XFORM_ADDR2
|
||||
EMC_DLL_XFORM_ADDR3
|
||||
EMC_DLL_XFORM_ADDR4
|
||||
EMC_DLL_XFORM_ADDR5
|
||||
EMC_DLL_XFORM_QUSE8
|
||||
EMC_DLL_XFORM_QUSE9
|
||||
EMC_DLL_XFORM_QUSE10
|
||||
EMC_DLL_XFORM_QUSE11
|
||||
EMC_DLL_XFORM_QUSE12
|
||||
EMC_DLL_XFORM_QUSE13
|
||||
EMC_DLL_XFORM_QUSE14
|
||||
EMC_DLL_XFORM_QUSE15
|
||||
EMC_DLI_TRIM_TXDQS0
|
||||
EMC_DLI_TRIM_TXDQS1
|
||||
EMC_DLI_TRIM_TXDQS2
|
||||
EMC_DLI_TRIM_TXDQS3
|
||||
EMC_DLI_TRIM_TXDQS4
|
||||
EMC_DLI_TRIM_TXDQS5
|
||||
EMC_DLI_TRIM_TXDQS6
|
||||
EMC_DLI_TRIM_TXDQS7
|
||||
EMC_DLI_TRIM_TXDQS8
|
||||
EMC_DLI_TRIM_TXDQS9
|
||||
EMC_DLI_TRIM_TXDQS10
|
||||
EMC_DLI_TRIM_TXDQS11
|
||||
EMC_DLI_TRIM_TXDQS12
|
||||
EMC_DLI_TRIM_TXDQS13
|
||||
EMC_DLI_TRIM_TXDQS14
|
||||
EMC_DLI_TRIM_TXDQS15
|
||||
EMC_DLL_XFORM_DQ0
|
||||
EMC_DLL_XFORM_DQ1
|
||||
EMC_DLL_XFORM_DQ2
|
||||
EMC_DLL_XFORM_DQ3
|
||||
EMC_DLL_XFORM_DQ4
|
||||
EMC_DLL_XFORM_DQ5
|
||||
EMC_DLL_XFORM_DQ6
|
||||
EMC_DLL_XFORM_DQ7
|
||||
EMC_XM2CMDPADCTRL
|
||||
EMC_XM2CMDPADCTRL4
|
||||
EMC_XM2CMDPADCTRL5
|
||||
EMC_XM2DQPADCTRL2
|
||||
EMC_XM2DQPADCTRL3
|
||||
EMC_XM2CLKPADCTRL
|
||||
EMC_XM2CLKPADCTRL2
|
||||
EMC_XM2COMPPADCTRL
|
||||
EMC_XM2VTTGENPADCTRL
|
||||
EMC_XM2VTTGENPADCTRL2
|
||||
EMC_XM2VTTGENPADCTRL3
|
||||
EMC_XM2DQSPADCTRL3
|
||||
EMC_XM2DQSPADCTRL4
|
||||
EMC_XM2DQSPADCTRL5
|
||||
EMC_XM2DQSPADCTRL6
|
||||
EMC_DSR_VTTGEN_DRV
|
||||
EMC_TXDSRVTTGEN
|
||||
EMC_FBIO_SPARE
|
||||
EMC_ZCAL_WAIT_CNT
|
||||
EMC_MRS_WAIT_CNT2
|
||||
EMC_CTT
|
||||
EMC_CTT_DURATION
|
||||
EMC_CFG_PIPE
|
||||
EMC_DYN_SELF_REF_CONTROL
|
||||
EMC_QPOP
|
||||
|
||||
Example SoC include file:
|
||||
|
||||
/ {
|
||||
emc@0,7001b000 {
|
||||
compatible = "nvidia,tegra124-emc";
|
||||
reg = <0x0 0x7001b000 0x0 0x1000>;
|
||||
|
||||
nvidia,memory-controller = <&mc>;
|
||||
};
|
||||
};
|
||||
|
||||
Example board file:
|
||||
|
||||
/ {
|
||||
emc@0,7001b000 {
|
||||
emc-timings-3 {
|
||||
nvidia,ram-code = <3>;
|
||||
|
||||
timing-12750000 {
|
||||
clock-frequency = <12750000>;
|
||||
|
||||
nvidia,emc-zcal-cnt-long = <0x00000042>;
|
||||
nvidia,emc-auto-cal-interval = <0x001fffff>;
|
||||
nvidia,emc-ctt-term-ctrl = <0x00000802>;
|
||||
nvidia,emc-cfg = <0x73240000>;
|
||||
nvidia,emc-cfg-2 = <0x000008c5>;
|
||||
nvidia,emc-sel-dpd-ctrl = <0x00040128>;
|
||||
nvidia,emc-bgbias-ctl0 = <0x00000008>;
|
||||
nvidia,emc-auto-cal-config = <0xa1430000>;
|
||||
nvidia,emc-auto-cal-config2 = <0x00000000>;
|
||||
nvidia,emc-auto-cal-config3 = <0x00000000>;
|
||||
nvidia,emc-mode-reset = <0x80001221>;
|
||||
nvidia,emc-mode-1 = <0x80100003>;
|
||||
nvidia,emc-mode-2 = <0x80200008>;
|
||||
nvidia,emc-mode-4 = <0x00000000>;
|
||||
|
||||
nvidia,emc-configuration = <
|
||||
0x00000000 /* EMC_RC */
|
||||
0x00000003 /* EMC_RFC */
|
||||
0x00000000 /* EMC_RFC_SLR */
|
||||
0x00000000 /* EMC_RAS */
|
||||
0x00000000 /* EMC_RP */
|
||||
0x00000004 /* EMC_R2W */
|
||||
0x0000000a /* EMC_W2R */
|
||||
0x00000003 /* EMC_R2P */
|
||||
0x0000000b /* EMC_W2P */
|
||||
0x00000000 /* EMC_RD_RCD */
|
||||
0x00000000 /* EMC_WR_RCD */
|
||||
0x00000003 /* EMC_RRD */
|
||||
0x00000003 /* EMC_REXT */
|
||||
0x00000000 /* EMC_WEXT */
|
||||
0x00000006 /* EMC_WDV */
|
||||
0x00000006 /* EMC_WDV_MASK */
|
||||
0x00000006 /* EMC_QUSE */
|
||||
0x00000002 /* EMC_QUSE_WIDTH */
|
||||
0x00000000 /* EMC_IBDLY */
|
||||
0x00000005 /* EMC_EINPUT */
|
||||
0x00000005 /* EMC_EINPUT_DURATION */
|
||||
0x00010000 /* EMC_PUTERM_EXTRA */
|
||||
0x00000003 /* EMC_PUTERM_WIDTH */
|
||||
0x00000000 /* EMC_PUTERM_ADJ */
|
||||
0x00000000 /* EMC_CDB_CNTL_1 */
|
||||
0x00000000 /* EMC_CDB_CNTL_2 */
|
||||
0x00000000 /* EMC_CDB_CNTL_3 */
|
||||
0x00000004 /* EMC_QRST */
|
||||
0x0000000c /* EMC_QSAFE */
|
||||
0x0000000d /* EMC_RDV */
|
||||
0x0000000f /* EMC_RDV_MASK */
|
||||
0x00000060 /* EMC_REFRESH */
|
||||
0x00000000 /* EMC_BURST_REFRESH_NUM */
|
||||
0x00000018 /* EMC_PRE_REFRESH_REQ_CNT */
|
||||
0x00000002 /* EMC_PDEX2WR */
|
||||
0x00000002 /* EMC_PDEX2RD */
|
||||
0x00000001 /* EMC_PCHG2PDEN */
|
||||
0x00000000 /* EMC_ACT2PDEN */
|
||||
0x00000007 /* EMC_AR2PDEN */
|
||||
0x0000000f /* EMC_RW2PDEN */
|
||||
0x00000005 /* EMC_TXSR */
|
||||
0x00000005 /* EMC_TXSRDLL */
|
||||
0x00000004 /* EMC_TCKE */
|
||||
0x00000005 /* EMC_TCKESR */
|
||||
0x00000004 /* EMC_TPD */
|
||||
0x00000000 /* EMC_TFAW */
|
||||
0x00000000 /* EMC_TRPAB */
|
||||
0x00000005 /* EMC_TCLKSTABLE */
|
||||
0x00000005 /* EMC_TCLKSTOP */
|
||||
0x00000064 /* EMC_TREFBW */
|
||||
0x00000000 /* EMC_FBIO_CFG6 */
|
||||
0x00000000 /* EMC_ODT_WRITE */
|
||||
0x00000000 /* EMC_ODT_READ */
|
||||
0x106aa298 /* EMC_FBIO_CFG5 */
|
||||
0x002c00a0 /* EMC_CFG_DIG_DLL */
|
||||
0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS0 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS1 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS2 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS3 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS4 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS5 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS6 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS7 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS8 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS9 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS10 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS11 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS12 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS13 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS14 */
|
||||
0x00064000 /* EMC_DLL_XFORM_DQS15 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE0 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE1 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE2 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE3 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE4 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE5 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE6 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE7 */
|
||||
0x00000000 /* EMC_DLL_XFORM_ADDR0 */
|
||||
0x00000000 /* EMC_DLL_XFORM_ADDR1 */
|
||||
0x00000000 /* EMC_DLL_XFORM_ADDR2 */
|
||||
0x00000000 /* EMC_DLL_XFORM_ADDR3 */
|
||||
0x00000000 /* EMC_DLL_XFORM_ADDR4 */
|
||||
0x00000000 /* EMC_DLL_XFORM_ADDR5 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE8 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE9 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE10 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE11 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE12 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE13 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE14 */
|
||||
0x00000000 /* EMC_DLL_XFORM_QUSE15 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
|
||||
0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
|
||||
0x000fc000 /* EMC_DLL_XFORM_DQ0 */
|
||||
0x000fc000 /* EMC_DLL_XFORM_DQ1 */
|
||||
0x000fc000 /* EMC_DLL_XFORM_DQ2 */
|
||||
0x000fc000 /* EMC_DLL_XFORM_DQ3 */
|
||||
0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
|
||||
0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
|
||||
0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
|
||||
0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
|
||||
0x10000280 /* EMC_XM2CMDPADCTRL */
|
||||
0x00000000 /* EMC_XM2CMDPADCTRL4 */
|
||||
0x00111111 /* EMC_XM2CMDPADCTRL5 */
|
||||
0x00000000 /* EMC_XM2DQPADCTRL2 */
|
||||
0x00000000 /* EMC_XM2DQPADCTRL3 */
|
||||
0x77ffc081 /* EMC_XM2CLKPADCTRL */
|
||||
0x00000e0e /* EMC_XM2CLKPADCTRL2 */
|
||||
0x81f1f108 /* EMC_XM2COMPPADCTRL */
|
||||
0x07070004 /* EMC_XM2VTTGENPADCTRL */
|
||||
0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
|
||||
0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
|
||||
0x51451400 /* EMC_XM2DQSPADCTRL3 */
|
||||
0x00514514 /* EMC_XM2DQSPADCTRL4 */
|
||||
0x00514514 /* EMC_XM2DQSPADCTRL5 */
|
||||
0x51451400 /* EMC_XM2DQSPADCTRL6 */
|
||||
0x0000003f /* EMC_DSR_VTTGEN_DRV */
|
||||
0x00000007 /* EMC_TXDSRVTTGEN */
|
||||
0x00000000 /* EMC_FBIO_SPARE */
|
||||
0x00000042 /* EMC_ZCAL_WAIT_CNT */
|
||||
0x000e000e /* EMC_MRS_WAIT_CNT2 */
|
||||
0x00000000 /* EMC_CTT */
|
||||
0x00000003 /* EMC_CTT_DURATION */
|
||||
0x0000f2f3 /* EMC_CFG_PIPE */
|
||||
0x800001c5 /* EMC_DYN_SELF_REF_CONTROL */
|
||||
0x0000000a /* EMC_QPOP */
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
Multi-Function Devices (MFD)
|
||||
|
||||
These devices comprise a nexus for heterogeneous hardware blocks containing
|
||||
more than one non-unique yet varying hardware functionality.
|
||||
|
||||
A typical MFD can be:
|
||||
|
||||
- A mixed signal ASIC on an external bus, sometimes a PMIC (Power Management
|
||||
Integrated Circuit) that is manufactured in a lower technology node (rough
|
||||
silicon) that handles analog drivers for things like audio amplifiers, LED
|
||||
drivers, level shifters, PHY (physical interfaces to things like USB or
|
||||
ethernet), regulators etc.
|
||||
|
||||
- A range of memory registers containing "miscellaneous system registers" also
|
||||
known as a system controller "syscon" or any other memory range containing a
|
||||
mix of unrelated hardware devices.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- compatible : "simple-mfd" - this signifies that the operating system should
|
||||
consider all subnodes of the MFD device as separate devices akin to how
|
||||
"simple-bus" inidicates when to see subnodes as children for a simple
|
||||
memory-mapped bus. For more complex devices, when the nexus driver has to
|
||||
probe registers to figure out what child devices exist etc, this should not
|
||||
be used. In the latter case the child devices will be determined by the
|
||||
operating system.
|
||||
|
||||
Example:
|
||||
|
||||
foo@1000 {
|
||||
compatible = "syscon", "simple-mfd";
|
||||
reg = <0x01000 0x1000>;
|
||||
|
||||
led@08.0 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x01>;
|
||||
label = "myled";
|
||||
default-state = "on";
|
||||
};
|
||||
};
|
||||
@@ -10,3 +10,5 @@ Required properties:
|
||||
The second entry gives the physical address and length of the
|
||||
registers indicating the strapping options.
|
||||
|
||||
Optional properties:
|
||||
- nvidia,long-ram-code: If present, the RAM code is long (4 bit). If not, short (2 bit).
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
Allwinnner SoC SRAM controllers
|
||||
-----------------------------------------------------
|
||||
|
||||
The SRAM controller found on most Allwinner devices is represented by
|
||||
a regular node for the SRAM controller itself, with sub-nodes
|
||||
reprensenting the SRAM handled by the SRAM controller.
|
||||
|
||||
Controller Node
|
||||
---------------
|
||||
|
||||
Required properties:
|
||||
- compatible : "allwinner,sun4i-a10-sram-controller"
|
||||
- reg : sram controller register offset + length
|
||||
|
||||
SRAM nodes
|
||||
----------
|
||||
|
||||
Each SRAM is described using the mmio-sram bindings documented in
|
||||
Documentation/devicetree/bindings/misc/sram.txt
|
||||
|
||||
Each SRAM will have SRAM sections that are going to be handled by the
|
||||
SRAM controller as subnodes. These sections are represented following
|
||||
once again the representation described in the mmio-sram binding.
|
||||
|
||||
The valid sections compatible are:
|
||||
- allwinner,sun4i-a10-sram-a3-a4
|
||||
- allwinner,sun4i-a10-sram-d
|
||||
|
||||
Devices using SRAM sections
|
||||
---------------------------
|
||||
|
||||
Some devices need to request to the SRAM controller to map an SRAM for
|
||||
their exclusive use.
|
||||
|
||||
The relationship between such a device and an SRAM section is
|
||||
expressed through the allwinner,sram property, that will take a
|
||||
phandle and an argument.
|
||||
|
||||
This valid values for this argument are:
|
||||
- 0: CPU
|
||||
- 1: Device
|
||||
|
||||
Example
|
||||
-------
|
||||
sram-controller@01c00000 {
|
||||
compatible = "allwinner,sun4i-a10-sram-controller";
|
||||
reg = <0x01c00000 0x30>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
sram_a: sram@00000000 {
|
||||
compatible = "mmio-sram";
|
||||
reg = <0x00000000 0xc000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0x00000000 0xc000>;
|
||||
|
||||
emac_sram: sram-section@8000 {
|
||||
compatible = "allwinner,sun4i-a10-sram-a3-a4";
|
||||
reg = <0x8000 0x4000>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
emac: ethernet@01c0b000 {
|
||||
compatible = "allwinner,sun4i-a10-emac";
|
||||
...
|
||||
|
||||
allwinner,sram = <&emac_sram 1>;
|
||||
};
|
||||
@@ -114,7 +114,7 @@
|
||||
ranges;
|
||||
|
||||
syscon: syscon@10000000 {
|
||||
compatible = "arm,realview-pb1176-syscon", "syscon";
|
||||
compatible = "arm,realview-pb1176-syscon", "syscon", "simple-mfd";
|
||||
reg = <0x10000000 0x1000>;
|
||||
|
||||
led@08.0 {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
sdhci0: sdhci@ab0000 {
|
||||
compatible = "mrvl,pxav3-mmc";
|
||||
reg = <0xab0000 0x200>;
|
||||
clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
|
||||
clocks = <&chip_clk CLKID_SDIO0XIN>, <&chip_clk CLKID_SDIO0>;
|
||||
clock-names = "io", "core";
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
@@ -93,7 +93,7 @@
|
||||
sdhci1: sdhci@ab0800 {
|
||||
compatible = "mrvl,pxav3-mmc";
|
||||
reg = <0xab0800 0x200>;
|
||||
clocks = <&chip CLKID_SDIO1XIN>, <&chip CLKID_SDIO1>;
|
||||
clocks = <&chip_clk CLKID_SDIO1XIN>, <&chip_clk CLKID_SDIO1>;
|
||||
clock-names = "io", "core";
|
||||
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
@@ -103,7 +103,7 @@
|
||||
compatible = "mrvl,pxav3-mmc";
|
||||
reg = <0xab1000 0x200>;
|
||||
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
|
||||
clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_NFC>;
|
||||
clock-names = "io", "core";
|
||||
pinctrl-0 = <&emmc_pmux>;
|
||||
pinctrl-names = "default";
|
||||
@@ -133,13 +133,13 @@
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0xad0600 0x20>;
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
clocks = <&chip CLKID_TWD>;
|
||||
clocks = <&chip_clk CLKID_TWD>;
|
||||
};
|
||||
|
||||
eth1: ethernet@b90000 {
|
||||
compatible = "marvell,pxa168-eth";
|
||||
reg = <0xb90000 0x10000>;
|
||||
clocks = <&chip CLKID_GETH1>;
|
||||
clocks = <&chip_clk CLKID_GETH1>;
|
||||
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
/* set by bootloader */
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
@@ -162,7 +162,7 @@
|
||||
eth0: ethernet@e50000 {
|
||||
compatible = "marvell,pxa168-eth";
|
||||
reg = <0xe50000 0x10000>;
|
||||
clocks = <&chip CLKID_GETH0>;
|
||||
clocks = <&chip_clk CLKID_GETH0>;
|
||||
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
|
||||
/* set by bootloader */
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
@@ -261,7 +261,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c00 0x14>;
|
||||
interrupts = <8>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "okay";
|
||||
};
|
||||
@@ -270,7 +270,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c14 0x14>;
|
||||
interrupts = <9>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "okay";
|
||||
};
|
||||
@@ -279,7 +279,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c28 0x14>;
|
||||
interrupts = <10>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -288,7 +288,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c3c 0x14>;
|
||||
interrupts = <11>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -297,7 +297,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c50 0x14>;
|
||||
interrupts = <12>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -306,7 +306,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c64 0x14>;
|
||||
interrupts = <13>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -315,7 +315,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c78 0x14>;
|
||||
interrupts = <14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -324,7 +324,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c8c 0x14>;
|
||||
interrupts = <15>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -343,7 +343,7 @@
|
||||
compatible = "marvell,berlin2-ahci", "generic-ahci";
|
||||
reg = <0xe90000 0x1000>;
|
||||
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_SATA>;
|
||||
clocks = <&chip_clk CLKID_SATA>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
sata_phy: phy@e900a0 {
|
||||
compatible = "marvell,berlin2-sata-phy";
|
||||
reg = <0xe900a0 0x200>;
|
||||
clocks = <&chip CLKID_SATA>;
|
||||
clocks = <&chip_clk CLKID_SATA>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#phy-cells = <1>;
|
||||
@@ -379,16 +379,28 @@
|
||||
};
|
||||
|
||||
chip: chip-control@ea0000 {
|
||||
compatible = "marvell,berlin2-chip-ctrl";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <2>;
|
||||
compatible = "simple-mfd", "syscon";
|
||||
reg = <0xea0000 0x400>;
|
||||
clocks = <&refclk>;
|
||||
clock-names = "refclk";
|
||||
|
||||
emmc_pmux: emmc-pmux {
|
||||
groups = "G26";
|
||||
function = "emmc";
|
||||
chip_clk: clock {
|
||||
compatible = "marvell,berlin2-clk";
|
||||
#clock-cells = <1>;
|
||||
clocks = <&refclk>;
|
||||
clock-names = "refclk";
|
||||
};
|
||||
|
||||
soc_pinctrl: pin-controller {
|
||||
compatible = "marvell,berlin2-soc-pinctrl";
|
||||
|
||||
emmc_pmux: emmc-pmux {
|
||||
groups = "G26";
|
||||
function = "emmc";
|
||||
};
|
||||
};
|
||||
|
||||
chip_rst: reset {
|
||||
compatible = "marvell,berlin2-reset";
|
||||
#reset-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -470,22 +482,24 @@
|
||||
};
|
||||
|
||||
sysctrl: system-controller@d000 {
|
||||
compatible = "marvell,berlin2-system-ctrl";
|
||||
compatible = "simple-mfd", "syscon";
|
||||
reg = <0xd000 0x100>;
|
||||
|
||||
uart0_pmux: uart0-pmux {
|
||||
groups = "GSM4";
|
||||
function = "uart0";
|
||||
};
|
||||
sys_pinctrl: pin-controller {
|
||||
compatible = "marvell,berlin2-system-pinctrl";
|
||||
uart0_pmux: uart0-pmux {
|
||||
groups = "GSM4";
|
||||
function = "uart0";
|
||||
};
|
||||
|
||||
uart1_pmux: uart1-pmux {
|
||||
groups = "GSM5";
|
||||
function = "uart1";
|
||||
};
|
||||
|
||||
uart2_pmux: uart2-pmux {
|
||||
groups = "GSM3";
|
||||
function = "uart2";
|
||||
uart1_pmux: uart1-pmux {
|
||||
groups = "GSM5";
|
||||
function = "uart1";
|
||||
};
|
||||
uart2_pmux: uart2-pmux {
|
||||
groups = "GSM3";
|
||||
function = "uart2";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
sdhci0: sdhci@ab0000 {
|
||||
compatible = "mrvl,pxav3-mmc";
|
||||
reg = <0xab0000 0x200>;
|
||||
clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
|
||||
clocks = <&chip_clk CLKID_SDIO0XIN>, <&chip_clk CLKID_SDIO0>;
|
||||
clock-names = "io", "core";
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
@@ -105,14 +105,14 @@
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0xad0600 0x20>;
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
clocks = <&chip CLKID_TWD>;
|
||||
clocks = <&chip_clk CLKID_TWD>;
|
||||
};
|
||||
|
||||
usb_phy0: usb-phy@b74000 {
|
||||
compatible = "marvell,berlin2cd-usb-phy";
|
||||
reg = <0xb74000 0x128>;
|
||||
#phy-cells = <0>;
|
||||
resets = <&chip 0x178 23>;
|
||||
resets = <&chip_rst 0x178 23>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -120,14 +120,14 @@
|
||||
compatible = "marvell,berlin2cd-usb-phy";
|
||||
reg = <0xb78000 0x128>;
|
||||
#phy-cells = <0>;
|
||||
resets = <&chip 0x178 24>;
|
||||
resets = <&chip_rst 0x178 24>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
eth1: ethernet@b90000 {
|
||||
compatible = "marvell,pxa168-eth";
|
||||
reg = <0xb90000 0x10000>;
|
||||
clocks = <&chip CLKID_GETH1>;
|
||||
clocks = <&chip_clk CLKID_GETH1>;
|
||||
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
/* set by bootloader */
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
@@ -145,7 +145,7 @@
|
||||
eth0: ethernet@e50000 {
|
||||
compatible = "marvell,pxa168-eth";
|
||||
reg = <0xe50000 0x10000>;
|
||||
clocks = <&chip CLKID_GETH0>;
|
||||
clocks = <&chip_clk CLKID_GETH0>;
|
||||
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
|
||||
/* set by bootloader */
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
@@ -244,7 +244,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c00 0x14>;
|
||||
interrupts = <8>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "okay";
|
||||
};
|
||||
@@ -253,7 +253,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c14 0x14>;
|
||||
interrupts = <9>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "okay";
|
||||
};
|
||||
@@ -262,7 +262,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c28 0x14>;
|
||||
interrupts = <10>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -271,7 +271,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c3c 0x14>;
|
||||
interrupts = <11>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -280,7 +280,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c50 0x14>;
|
||||
interrupts = <12>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -289,7 +289,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c64 0x14>;
|
||||
interrupts = <13>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -298,7 +298,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c78 0x14>;
|
||||
interrupts = <14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -307,7 +307,7 @@
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c8c 0x14>;
|
||||
interrupts = <15>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -323,16 +323,28 @@
|
||||
};
|
||||
|
||||
chip: chip-control@ea0000 {
|
||||
compatible = "marvell,berlin2cd-chip-ctrl";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <2>;
|
||||
compatible = "simple-mfd", "syscon";
|
||||
reg = <0xea0000 0x400>;
|
||||
clocks = <&refclk>;
|
||||
clock-names = "refclk";
|
||||
|
||||
uart0_pmux: uart0-pmux {
|
||||
groups = "G6";
|
||||
function = "uart0";
|
||||
chip_clk: clock {
|
||||
compatible = "marvell,berlin2-clk";
|
||||
#clock-cells = <1>;
|
||||
clocks = <&refclk>;
|
||||
clock-names = "refclk";
|
||||
};
|
||||
|
||||
soc_pinctrl: pin-controller {
|
||||
compatible = "marvell,berlin2cd-soc-pinctrl";
|
||||
|
||||
uart0_pmux: uart0-pmux {
|
||||
groups = "G6";
|
||||
function = "uart0";
|
||||
};
|
||||
};
|
||||
|
||||
chip_rst: reset {
|
||||
compatible = "marvell,berlin2-reset";
|
||||
#reset-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -340,7 +352,7 @@
|
||||
compatible = "chipidea,usb2";
|
||||
reg = <0xed0000 0x200>;
|
||||
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_USB0>;
|
||||
clocks = <&chip_clk CLKID_USB0>;
|
||||
phys = <&usb_phy0>;
|
||||
phy-names = "usb-phy";
|
||||
status = "disabled";
|
||||
@@ -350,7 +362,7 @@
|
||||
compatible = "chipidea,usb2";
|
||||
reg = <0xee0000 0x200>;
|
||||
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_USB1>;
|
||||
clocks = <&chip_clk CLKID_USB1>;
|
||||
phys = <&usb_phy1>;
|
||||
phy-names = "usb-phy";
|
||||
status = "disabled";
|
||||
@@ -417,8 +429,12 @@
|
||||
};
|
||||
|
||||
sysctrl: system-controller@d000 {
|
||||
compatible = "marvell,berlin2cd-system-ctrl";
|
||||
compatible = "simple-mfd", "syscon";
|
||||
reg = <0xd000 0x100>;
|
||||
|
||||
sys_pinctrl: pin-controller {
|
||||
compatible = "marvell,berlin2cd-system-pinctrl";
|
||||
};
|
||||
};
|
||||
|
||||
sic: interrupt-controller@e000 {
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
sdhci0: sdhci@ab0000 {
|
||||
compatible = "mrvl,pxav3-mmc";
|
||||
reg = <0xab0000 0x200>;
|
||||
clocks = <&chip CLKID_SDIO1XIN>;
|
||||
clocks = <&chip_clk CLKID_SDIO1XIN>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -110,7 +110,7 @@
|
||||
sdhci1: sdhci@ab0800 {
|
||||
compatible = "mrvl,pxav3-mmc";
|
||||
reg = <0xab0800 0x200>;
|
||||
clocks = <&chip CLKID_SDIO1XIN>;
|
||||
clocks = <&chip_clk CLKID_SDIO1XIN>;
|
||||
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -119,7 +119,7 @@
|
||||
compatible = "mrvl,pxav3-mmc";
|
||||
reg = <0xab1000 0x200>;
|
||||
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
|
||||
clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_NFC>;
|
||||
clock-names = "io", "core";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -140,7 +140,7 @@
|
||||
local-timer@ad0600 {
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0xad0600 0x20>;
|
||||
clocks = <&chip CLKID_TWD>;
|
||||
clocks = <&chip_clk CLKID_TWD>;
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
};
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
compatible = "marvell,berlin2-usb-phy";
|
||||
reg = <0xa2f400 0x128>;
|
||||
#phy-cells = <0>;
|
||||
resets = <&chip 0x104 14>;
|
||||
resets = <&chip_rst 0x104 14>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
compatible = "chipidea,usb2";
|
||||
reg = <0xa30000 0x10000>;
|
||||
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_USB2>;
|
||||
clocks = <&chip_clk CLKID_USB2>;
|
||||
phys = <&usb_phy2>;
|
||||
phy-names = "usb-phy";
|
||||
status = "disabled";
|
||||
@@ -173,7 +173,7 @@
|
||||
compatible = "marvell,berlin2-usb-phy";
|
||||
reg = <0xb74000 0x128>;
|
||||
#phy-cells = <0>;
|
||||
resets = <&chip 0x104 12>;
|
||||
resets = <&chip_rst 0x104 12>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -181,14 +181,14 @@
|
||||
compatible = "marvell,berlin2-usb-phy";
|
||||
reg = <0xb78000 0x128>;
|
||||
#phy-cells = <0>;
|
||||
resets = <&chip 0x104 13>;
|
||||
resets = <&chip_rst 0x104 13>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
eth0: ethernet@b90000 {
|
||||
compatible = "marvell,pxa168-eth";
|
||||
reg = <0xb90000 0x10000>;
|
||||
clocks = <&chip CLKID_GETH0>;
|
||||
clocks = <&chip_clk CLKID_GETH0>;
|
||||
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
/* set by bootloader */
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
@@ -295,7 +295,7 @@
|
||||
reg = <0x1400 0x100>;
|
||||
interrupt-parent = <&aic>;
|
||||
interrupts = <4>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
pinctrl-0 = <&twsi0_pmux>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
@@ -308,7 +308,7 @@
|
||||
reg = <0x1800 0x100>;
|
||||
interrupt-parent = <&aic>;
|
||||
interrupts = <5>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
pinctrl-0 = <&twsi1_pmux>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
@@ -317,7 +317,7 @@
|
||||
timer0: timer@2c00 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c00 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
interrupts = <8>;
|
||||
};
|
||||
@@ -325,14 +325,14 @@
|
||||
timer1: timer@2c14 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c14 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
};
|
||||
|
||||
timer2: timer@2c28 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c28 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -340,7 +340,7 @@
|
||||
timer3: timer@2c3c {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c3c 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -348,7 +348,7 @@
|
||||
timer4: timer@2c50 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c50 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -356,7 +356,7 @@
|
||||
timer5: timer@2c64 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c64 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -364,7 +364,7 @@
|
||||
timer6: timer@2c78 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c78 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -372,7 +372,7 @@
|
||||
timer7: timer@2c8c {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0x2c8c 0x14>;
|
||||
clocks = <&chip CLKID_CFG>;
|
||||
clocks = <&chip_clk CLKID_CFG>;
|
||||
clock-names = "timer";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -388,21 +388,33 @@
|
||||
};
|
||||
|
||||
chip: chip-control@ea0000 {
|
||||
compatible = "marvell,berlin2q-chip-ctrl";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <2>;
|
||||
compatible = "simple-mfd", "syscon";
|
||||
reg = <0xea0000 0x400>, <0xdd0170 0x10>;
|
||||
clocks = <&refclk>;
|
||||
clock-names = "refclk";
|
||||
|
||||
twsi0_pmux: twsi0-pmux {
|
||||
groups = "G6";
|
||||
function = "twsi0";
|
||||
chip_clk: clock {
|
||||
compatible = "marvell,berlin2q-clk";
|
||||
#clock-cells = <1>;
|
||||
clocks = <&refclk>;
|
||||
clock-names = "refclk";
|
||||
};
|
||||
|
||||
twsi1_pmux: twsi1-pmux {
|
||||
groups = "G7";
|
||||
function = "twsi1";
|
||||
soc_pinctrl: pin-controller {
|
||||
compatible = "marvell,berlin2q-soc-pinctrl";
|
||||
|
||||
twsi0_pmux: twsi0-pmux {
|
||||
groups = "G6";
|
||||
function = "twsi0";
|
||||
};
|
||||
|
||||
twsi1_pmux: twsi1-pmux {
|
||||
groups = "G7";
|
||||
function = "twsi1";
|
||||
};
|
||||
};
|
||||
|
||||
chip_rst: reset {
|
||||
compatible = "marvell,berlin2-reset";
|
||||
#reset-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -410,7 +422,7 @@
|
||||
compatible = "marvell,berlin2q-ahci", "generic-ahci";
|
||||
reg = <0xe90000 0x1000>;
|
||||
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_SATA>;
|
||||
clocks = <&chip_clk CLKID_SATA>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@@ -430,7 +442,7 @@
|
||||
sata_phy: phy@e900a0 {
|
||||
compatible = "marvell,berlin2q-sata-phy";
|
||||
reg = <0xe900a0 0x200>;
|
||||
clocks = <&chip CLKID_SATA>;
|
||||
clocks = <&chip_clk CLKID_SATA>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#phy-cells = <1>;
|
||||
@@ -449,7 +461,7 @@
|
||||
compatible = "chipidea,usb2";
|
||||
reg = <0xed0000 0x10000>;
|
||||
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_USB0>;
|
||||
clocks = <&chip_clk CLKID_USB0>;
|
||||
phys = <&usb_phy0>;
|
||||
phy-names = "usb-phy";
|
||||
status = "disabled";
|
||||
@@ -459,7 +471,7 @@
|
||||
compatible = "chipidea,usb2";
|
||||
reg = <0xee0000 0x10000>;
|
||||
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&chip CLKID_USB1>;
|
||||
clocks = <&chip_clk CLKID_USB1>;
|
||||
phys = <&usb_phy1>;
|
||||
phy-names = "usb-phy";
|
||||
status = "disabled";
|
||||
@@ -554,27 +566,37 @@
|
||||
};
|
||||
|
||||
sysctrl: pin-controller@d000 {
|
||||
compatible = "marvell,berlin2q-system-ctrl";
|
||||
compatible = "simple-mfd", "syscon";
|
||||
reg = <0xd000 0x100>;
|
||||
|
||||
uart0_pmux: uart0-pmux {
|
||||
groups = "GSM12";
|
||||
function = "uart0";
|
||||
sys_pinctrl: pin-controller {
|
||||
compatible = "marvell,berlin2q-system-pinctrl";
|
||||
|
||||
uart0_pmux: uart0-pmux {
|
||||
groups = "GSM12";
|
||||
function = "uart0";
|
||||
};
|
||||
|
||||
uart1_pmux: uart1-pmux {
|
||||
groups = "GSM14";
|
||||
function = "uart1";
|
||||
};
|
||||
|
||||
twsi2_pmux: twsi2-pmux {
|
||||
groups = "GSM13";
|
||||
function = "twsi2";
|
||||
};
|
||||
|
||||
twsi3_pmux: twsi3-pmux {
|
||||
groups = "GSM14";
|
||||
function = "twsi3";
|
||||
};
|
||||
};
|
||||
|
||||
uart1_pmux: uart1-pmux {
|
||||
groups = "GSM14";
|
||||
function = "uart1";
|
||||
};
|
||||
|
||||
twsi2_pmux: twsi2-pmux {
|
||||
groups = "GSM13";
|
||||
function = "twsi2";
|
||||
};
|
||||
|
||||
twsi3_pmux: twsi3-pmux {
|
||||
groups = "GSM14";
|
||||
function = "twsi3";
|
||||
adc: adc {
|
||||
compatible = "marvell,berlin2-adc";
|
||||
interrupts = <12>, <14>;
|
||||
interrupt-names = "adc", "tsen";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
/ {
|
||||
core-module@10000000 {
|
||||
compatible = "arm,core-module-integrator", "syscon";
|
||||
compatible = "arm,core-module-integrator", "syscon", "simple-mfd";
|
||||
reg = <0x10000000 0x200>;
|
||||
|
||||
/* Use core module LED to indicate CPU load */
|
||||
@@ -95,7 +95,7 @@
|
||||
|
||||
syscon {
|
||||
/* Debug registers mapped as syscon */
|
||||
compatible = "syscon";
|
||||
compatible = "syscon", "simple-mfd";
|
||||
reg = <0x1a000000 0x10>;
|
||||
|
||||
led@04.0 {
|
||||
|
||||
@@ -6,6 +6,7 @@ menuconfig ARCH_BERLIN
|
||||
select DW_APB_ICTL
|
||||
select DW_APB_TIMER_OF
|
||||
select GENERIC_IRQ_CHIP
|
||||
select MFD_SYSCON
|
||||
select PINCTRL
|
||||
|
||||
if ARCH_BERLIN
|
||||
|
||||
@@ -138,6 +138,74 @@
|
||||
clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
|
||||
};
|
||||
|
||||
apbregs@010000 {
|
||||
compatible = "syscon", "simple-mfd";
|
||||
reg = <0x010000 0x1000>;
|
||||
|
||||
led@08.0 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x01>;
|
||||
label = "vexpress:0";
|
||||
linux,default-trigger = "heartbeat";
|
||||
default-state = "on";
|
||||
};
|
||||
led@08.1 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x02>;
|
||||
label = "vexpress:1";
|
||||
linux,default-trigger = "mmc0";
|
||||
default-state = "off";
|
||||
};
|
||||
led@08.2 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x04>;
|
||||
label = "vexpress:2";
|
||||
linux,default-trigger = "cpu0";
|
||||
default-state = "off";
|
||||
};
|
||||
led@08.3 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x08>;
|
||||
label = "vexpress:3";
|
||||
linux,default-trigger = "cpu1";
|
||||
default-state = "off";
|
||||
};
|
||||
led@08.4 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x10>;
|
||||
label = "vexpress:4";
|
||||
linux,default-trigger = "cpu2";
|
||||
default-state = "off";
|
||||
};
|
||||
led@08.5 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x20>;
|
||||
label = "vexpress:5";
|
||||
linux,default-trigger = "cpu3";
|
||||
default-state = "off";
|
||||
};
|
||||
led@08.6 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x40>;
|
||||
label = "vexpress:6";
|
||||
default-state = "off";
|
||||
};
|
||||
led@08.7 {
|
||||
compatible = "register-bit-led";
|
||||
offset = <0x08>;
|
||||
mask = <0x80>;
|
||||
label = "vexpress:7";
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
mmci@050000 {
|
||||
compatible = "arm,pl180", "arm,primecell";
|
||||
reg = <0x050000 0x1000>;
|
||||
|
||||
@@ -139,6 +139,12 @@ CONFIG_MMC_ARMMMCI=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SPI=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_SYSCON=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_LEDS_TRIGGER_CPU=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_EFI=y
|
||||
CONFIG_RTC_DRV_XGENE=y
|
||||
|
||||
+24
-7
@@ -7,21 +7,24 @@ menu "Bus devices"
|
||||
config ARM_CCI
|
||||
bool
|
||||
|
||||
config ARM_CCI_PMU
|
||||
bool
|
||||
select ARM_CCI
|
||||
|
||||
config ARM_CCI400_COMMON
|
||||
bool
|
||||
select ARM_CCI
|
||||
|
||||
config ARM_CCI400_PMU
|
||||
bool "ARM CCI400 PMU support"
|
||||
default y
|
||||
depends on ARM || ARM64
|
||||
depends on HW_PERF_EVENTS
|
||||
depends on (ARM && CPU_V7) || ARM64
|
||||
depends on PERF_EVENTS
|
||||
select ARM_CCI400_COMMON
|
||||
select ARM_CCI_PMU
|
||||
help
|
||||
Support for PMU events monitoring on the ARM CCI cache coherent
|
||||
interconnect.
|
||||
|
||||
If unsure, say Y
|
||||
Support for PMU events monitoring on the ARM CCI-400 (cache coherent
|
||||
interconnect). CCI-400 supports counting events related to the
|
||||
connected slave/master interfaces.
|
||||
|
||||
config ARM_CCI400_PORT_CTRL
|
||||
bool
|
||||
@@ -31,6 +34,20 @@ config ARM_CCI400_PORT_CTRL
|
||||
Low level power management driver for CCI400 cache coherent
|
||||
interconnect for ARM platforms.
|
||||
|
||||
config ARM_CCI500_PMU
|
||||
bool "ARM CCI500 PMU support"
|
||||
default y
|
||||
depends on (ARM && CPU_V7) || ARM64
|
||||
depends on PERF_EVENTS
|
||||
select ARM_CCI_PMU
|
||||
help
|
||||
Support for PMU events monitoring on the ARM CCI-500 cache coherent
|
||||
interconnect. CCI-500 provides 8 independent event counters, which
|
||||
can count events pertaining to the slave/master interfaces as well
|
||||
as the internal events to the CCI.
|
||||
|
||||
If unsure, say Y
|
||||
|
||||
config ARM_CCN
|
||||
bool "ARM CCN driver support"
|
||||
depends on ARM || ARM64
|
||||
|
||||
+736
-169
File diff suppressed because it is too large
Load Diff
+214
-56
@@ -166,13 +166,17 @@ struct arm_ccn_dt {
|
||||
|
||||
struct hrtimer hrtimer;
|
||||
|
||||
cpumask_t cpu;
|
||||
struct notifier_block cpu_nb;
|
||||
|
||||
struct pmu pmu;
|
||||
};
|
||||
|
||||
struct arm_ccn {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
unsigned irq_used:1;
|
||||
unsigned int irq;
|
||||
|
||||
unsigned sbas_present:1;
|
||||
unsigned sbsx_present:1;
|
||||
|
||||
@@ -212,7 +216,7 @@ static int arm_ccn_node_to_xp_port(int node)
|
||||
|
||||
static void arm_ccn_pmu_config_set(u64 *config, u32 node_xp, u32 type, u32 port)
|
||||
{
|
||||
*config &= ~((0xff << 0) | (0xff << 8) | (0xff << 24));
|
||||
*config &= ~((0xff << 0) | (0xff << 8) | (0x3 << 24));
|
||||
*config |= (node_xp << 0) | (type << 8) | (port << 24);
|
||||
}
|
||||
|
||||
@@ -336,6 +340,23 @@ static ssize_t arm_ccn_pmu_event_show(struct device *dev,
|
||||
if (event->mask)
|
||||
res += snprintf(buf + res, PAGE_SIZE - res, ",mask=0x%x",
|
||||
event->mask);
|
||||
|
||||
/* Arguments required by an event */
|
||||
switch (event->type) {
|
||||
case CCN_TYPE_CYCLES:
|
||||
break;
|
||||
case CCN_TYPE_XP:
|
||||
res += snprintf(buf + res, PAGE_SIZE - res,
|
||||
",xp=?,port=?,vc=?,dir=?");
|
||||
if (event->event == CCN_EVENT_WATCHPOINT)
|
||||
res += snprintf(buf + res, PAGE_SIZE - res,
|
||||
",cmp_l=?,cmp_h=?,mask=?");
|
||||
break;
|
||||
default:
|
||||
res += snprintf(buf + res, PAGE_SIZE - res, ",node=?");
|
||||
break;
|
||||
}
|
||||
|
||||
res += snprintf(buf + res, PAGE_SIZE - res, "\n");
|
||||
|
||||
return res;
|
||||
@@ -521,6 +542,25 @@ static struct attribute_group arm_ccn_pmu_cmp_mask_attr_group = {
|
||||
.attrs = arm_ccn_pmu_cmp_mask_attrs,
|
||||
};
|
||||
|
||||
static ssize_t arm_ccn_pmu_cpumask_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
|
||||
|
||||
return cpumap_print_to_pagebuf(true, buf, &ccn->dt.cpu);
|
||||
}
|
||||
|
||||
static struct device_attribute arm_ccn_pmu_cpumask_attr =
|
||||
__ATTR(cpumask, S_IRUGO, arm_ccn_pmu_cpumask_show, NULL);
|
||||
|
||||
static struct attribute *arm_ccn_pmu_cpumask_attrs[] = {
|
||||
&arm_ccn_pmu_cpumask_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group arm_ccn_pmu_cpumask_attr_group = {
|
||||
.attrs = arm_ccn_pmu_cpumask_attrs,
|
||||
};
|
||||
|
||||
/*
|
||||
* Default poll period is 10ms, which is way over the top anyway,
|
||||
@@ -542,6 +582,7 @@ static const struct attribute_group *arm_ccn_pmu_attr_groups[] = {
|
||||
&arm_ccn_pmu_events_attr_group,
|
||||
&arm_ccn_pmu_format_attr_group,
|
||||
&arm_ccn_pmu_cmp_mask_attr_group,
|
||||
&arm_ccn_pmu_cpumask_attr_group,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -587,7 +628,65 @@ static int arm_ccn_pmu_type_eq(u32 a, u32 b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void arm_ccn_pmu_event_destroy(struct perf_event *event)
|
||||
static int arm_ccn_pmu_event_alloc(struct perf_event *event)
|
||||
{
|
||||
struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
|
||||
struct hw_perf_event *hw = &event->hw;
|
||||
u32 node_xp, type, event_id;
|
||||
struct arm_ccn_component *source;
|
||||
int bit;
|
||||
|
||||
node_xp = CCN_CONFIG_NODE(event->attr.config);
|
||||
type = CCN_CONFIG_TYPE(event->attr.config);
|
||||
event_id = CCN_CONFIG_EVENT(event->attr.config);
|
||||
|
||||
/* Allocate the cycle counter */
|
||||
if (type == CCN_TYPE_CYCLES) {
|
||||
if (test_and_set_bit(CCN_IDX_PMU_CYCLE_COUNTER,
|
||||
ccn->dt.pmu_counters_mask))
|
||||
return -EAGAIN;
|
||||
|
||||
hw->idx = CCN_IDX_PMU_CYCLE_COUNTER;
|
||||
ccn->dt.pmu_counters[CCN_IDX_PMU_CYCLE_COUNTER].event = event;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate an event counter */
|
||||
hw->idx = arm_ccn_pmu_alloc_bit(ccn->dt.pmu_counters_mask,
|
||||
CCN_NUM_PMU_EVENT_COUNTERS);
|
||||
if (hw->idx < 0) {
|
||||
dev_dbg(ccn->dev, "No more counters available!\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (type == CCN_TYPE_XP)
|
||||
source = &ccn->xp[node_xp];
|
||||
else
|
||||
source = &ccn->node[node_xp];
|
||||
ccn->dt.pmu_counters[hw->idx].source = source;
|
||||
|
||||
/* Allocate an event source or a watchpoint */
|
||||
if (type == CCN_TYPE_XP && event_id == CCN_EVENT_WATCHPOINT)
|
||||
bit = arm_ccn_pmu_alloc_bit(source->xp.dt_cmp_mask,
|
||||
CCN_NUM_XP_WATCHPOINTS);
|
||||
else
|
||||
bit = arm_ccn_pmu_alloc_bit(source->pmu_events_mask,
|
||||
CCN_NUM_PMU_EVENTS);
|
||||
if (bit < 0) {
|
||||
dev_dbg(ccn->dev, "No more event sources/watchpoints on node/XP %d!\n",
|
||||
node_xp);
|
||||
clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
|
||||
return -EAGAIN;
|
||||
}
|
||||
hw->config_base = bit;
|
||||
|
||||
ccn->dt.pmu_counters[hw->idx].event = event;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void arm_ccn_pmu_event_release(struct perf_event *event)
|
||||
{
|
||||
struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
|
||||
struct hw_perf_event *hw = &event->hw;
|
||||
@@ -616,15 +715,14 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
|
||||
struct arm_ccn *ccn;
|
||||
struct hw_perf_event *hw = &event->hw;
|
||||
u32 node_xp, type, event_id;
|
||||
int valid, bit;
|
||||
struct arm_ccn_component *source;
|
||||
int valid;
|
||||
int i;
|
||||
struct perf_event *sibling;
|
||||
|
||||
if (event->attr.type != event->pmu->type)
|
||||
return -ENOENT;
|
||||
|
||||
ccn = pmu_to_arm_ccn(event->pmu);
|
||||
event->destroy = arm_ccn_pmu_event_destroy;
|
||||
|
||||
if (hw->sample_period) {
|
||||
dev_warn(ccn->dev, "Sampling not supported!\n");
|
||||
@@ -642,6 +740,16 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
|
||||
dev_warn(ccn->dev, "Can't provide per-task data!\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
/*
|
||||
* Many perf core operations (eg. events rotation) operate on a
|
||||
* single CPU context. This is obvious for CPU PMUs, where one
|
||||
* expects the same sets of events being observed on all CPUs,
|
||||
* but can lead to issues for off-core PMUs, like CCN, where each
|
||||
* event could be theoretically assigned to a different CPU. To
|
||||
* mitigate this, we enforce CPU assignment to one, selected
|
||||
* processor (the one described in the "cpumask" attribute).
|
||||
*/
|
||||
event->cpu = cpumask_first(&ccn->dt.cpu);
|
||||
|
||||
node_xp = CCN_CONFIG_NODE(event->attr.config);
|
||||
type = CCN_CONFIG_TYPE(event->attr.config);
|
||||
@@ -711,48 +819,20 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
|
||||
node_xp, type, port);
|
||||
}
|
||||
|
||||
/* Allocate the cycle counter */
|
||||
if (type == CCN_TYPE_CYCLES) {
|
||||
if (test_and_set_bit(CCN_IDX_PMU_CYCLE_COUNTER,
|
||||
ccn->dt.pmu_counters_mask))
|
||||
return -EAGAIN;
|
||||
/*
|
||||
* We must NOT create groups containing mixed PMUs, although software
|
||||
* events are acceptable (for example to create a CCN group
|
||||
* periodically read when a hrtimer aka cpu-clock leader triggers).
|
||||
*/
|
||||
if (event->group_leader->pmu != event->pmu &&
|
||||
!is_software_event(event->group_leader))
|
||||
return -EINVAL;
|
||||
|
||||
hw->idx = CCN_IDX_PMU_CYCLE_COUNTER;
|
||||
ccn->dt.pmu_counters[CCN_IDX_PMU_CYCLE_COUNTER].event = event;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate an event counter */
|
||||
hw->idx = arm_ccn_pmu_alloc_bit(ccn->dt.pmu_counters_mask,
|
||||
CCN_NUM_PMU_EVENT_COUNTERS);
|
||||
if (hw->idx < 0) {
|
||||
dev_warn(ccn->dev, "No more counters available!\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (type == CCN_TYPE_XP)
|
||||
source = &ccn->xp[node_xp];
|
||||
else
|
||||
source = &ccn->node[node_xp];
|
||||
ccn->dt.pmu_counters[hw->idx].source = source;
|
||||
|
||||
/* Allocate an event source or a watchpoint */
|
||||
if (type == CCN_TYPE_XP && event_id == CCN_EVENT_WATCHPOINT)
|
||||
bit = arm_ccn_pmu_alloc_bit(source->xp.dt_cmp_mask,
|
||||
CCN_NUM_XP_WATCHPOINTS);
|
||||
else
|
||||
bit = arm_ccn_pmu_alloc_bit(source->pmu_events_mask,
|
||||
CCN_NUM_PMU_EVENTS);
|
||||
if (bit < 0) {
|
||||
dev_warn(ccn->dev, "No more event sources/watchpoints on node/XP %d!\n",
|
||||
node_xp);
|
||||
clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
|
||||
return -EAGAIN;
|
||||
}
|
||||
hw->config_base = bit;
|
||||
|
||||
ccn->dt.pmu_counters[hw->idx].event = event;
|
||||
list_for_each_entry(sibling, &event->group_leader->sibling_list,
|
||||
group_entry)
|
||||
if (sibling->pmu != event->pmu &&
|
||||
!is_software_event(sibling))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -835,9 +915,14 @@ static void arm_ccn_pmu_event_start(struct perf_event *event, int flags)
|
||||
arm_ccn_pmu_read_counter(ccn, hw->idx));
|
||||
hw->state = 0;
|
||||
|
||||
if (!ccn->irq_used)
|
||||
/*
|
||||
* Pin the timer, so that the overflows are handled by the chosen
|
||||
* event->cpu (this is the same one as presented in "cpumask"
|
||||
* attribute).
|
||||
*/
|
||||
if (!ccn->irq)
|
||||
hrtimer_start(&ccn->dt.hrtimer, arm_ccn_pmu_timer_period(),
|
||||
HRTIMER_MODE_REL);
|
||||
HRTIMER_MODE_REL_PINNED);
|
||||
|
||||
/* Set the DT bus input, engaging the counter */
|
||||
arm_ccn_pmu_xp_dt_config(event, 1);
|
||||
@@ -852,7 +937,7 @@ static void arm_ccn_pmu_event_stop(struct perf_event *event, int flags)
|
||||
/* Disable counting, setting the DT bus to pass-through mode */
|
||||
arm_ccn_pmu_xp_dt_config(event, 0);
|
||||
|
||||
if (!ccn->irq_used)
|
||||
if (!ccn->irq)
|
||||
hrtimer_cancel(&ccn->dt.hrtimer);
|
||||
|
||||
/* Let the DT bus drain */
|
||||
@@ -1014,8 +1099,13 @@ static void arm_ccn_pmu_event_config(struct perf_event *event)
|
||||
|
||||
static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)
|
||||
{
|
||||
int err;
|
||||
struct hw_perf_event *hw = &event->hw;
|
||||
|
||||
err = arm_ccn_pmu_event_alloc(event);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
arm_ccn_pmu_event_config(event);
|
||||
|
||||
hw->state = PERF_HES_STOPPED;
|
||||
@@ -1029,6 +1119,8 @@ static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)
|
||||
static void arm_ccn_pmu_event_del(struct perf_event *event, int flags)
|
||||
{
|
||||
arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE);
|
||||
|
||||
arm_ccn_pmu_event_release(event);
|
||||
}
|
||||
|
||||
static void arm_ccn_pmu_event_read(struct perf_event *event)
|
||||
@@ -1079,12 +1171,39 @@ static enum hrtimer_restart arm_ccn_pmu_timer_handler(struct hrtimer *hrtimer)
|
||||
}
|
||||
|
||||
|
||||
static int arm_ccn_pmu_cpu_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *hcpu)
|
||||
{
|
||||
struct arm_ccn_dt *dt = container_of(nb, struct arm_ccn_dt, cpu_nb);
|
||||
struct arm_ccn *ccn = container_of(dt, struct arm_ccn, dt);
|
||||
unsigned int cpu = (long)hcpu; /* for (long) see kernel/cpu.c */
|
||||
unsigned int target;
|
||||
|
||||
switch (action & ~CPU_TASKS_FROZEN) {
|
||||
case CPU_DOWN_PREPARE:
|
||||
if (!cpumask_test_and_clear_cpu(cpu, &dt->cpu))
|
||||
break;
|
||||
target = cpumask_any_but(cpu_online_mask, cpu);
|
||||
if (target < 0)
|
||||
break;
|
||||
perf_pmu_migrate_context(&dt->pmu, cpu, target);
|
||||
cpumask_set_cpu(target, &dt->cpu);
|
||||
WARN_ON(irq_set_affinity(ccn->irq, &dt->cpu) != 0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
|
||||
static DEFINE_IDA(arm_ccn_pmu_ida);
|
||||
|
||||
static int arm_ccn_pmu_init(struct arm_ccn *ccn)
|
||||
{
|
||||
int i;
|
||||
char *name;
|
||||
int err;
|
||||
|
||||
/* Initialize DT subsystem */
|
||||
ccn->dt.base = ccn->base + CCN_REGION_SIZE;
|
||||
@@ -1136,20 +1255,58 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
|
||||
};
|
||||
|
||||
/* No overflow interrupt? Have to use a timer instead. */
|
||||
if (!ccn->irq_used) {
|
||||
if (!ccn->irq) {
|
||||
dev_info(ccn->dev, "No access to interrupts, using timer.\n");
|
||||
hrtimer_init(&ccn->dt.hrtimer, CLOCK_MONOTONIC,
|
||||
HRTIMER_MODE_REL);
|
||||
ccn->dt.hrtimer.function = arm_ccn_pmu_timer_handler;
|
||||
}
|
||||
|
||||
return perf_pmu_register(&ccn->dt.pmu, name, -1);
|
||||
/* Pick one CPU which we will use to collect data from CCN... */
|
||||
cpumask_set_cpu(smp_processor_id(), &ccn->dt.cpu);
|
||||
|
||||
/*
|
||||
* ... and change the selection when it goes offline. Priority is
|
||||
* picked to have a chance to migrate events before perf is notified.
|
||||
*/
|
||||
ccn->dt.cpu_nb.notifier_call = arm_ccn_pmu_cpu_notifier;
|
||||
ccn->dt.cpu_nb.priority = CPU_PRI_PERF + 1,
|
||||
err = register_cpu_notifier(&ccn->dt.cpu_nb);
|
||||
if (err)
|
||||
goto error_cpu_notifier;
|
||||
|
||||
/* Also make sure that the overflow interrupt is handled by this CPU */
|
||||
if (ccn->irq) {
|
||||
err = irq_set_affinity(ccn->irq, &ccn->dt.cpu);
|
||||
if (err) {
|
||||
dev_err(ccn->dev, "Failed to set interrupt affinity!\n");
|
||||
goto error_set_affinity;
|
||||
}
|
||||
}
|
||||
|
||||
err = perf_pmu_register(&ccn->dt.pmu, name, -1);
|
||||
if (err)
|
||||
goto error_pmu_register;
|
||||
|
||||
return 0;
|
||||
|
||||
error_pmu_register:
|
||||
error_set_affinity:
|
||||
unregister_cpu_notifier(&ccn->dt.cpu_nb);
|
||||
error_cpu_notifier:
|
||||
ida_simple_remove(&arm_ccn_pmu_ida, ccn->dt.id);
|
||||
for (i = 0; i < ccn->num_xps; i++)
|
||||
writel(0, ccn->xp[i].base + CCN_XP_DT_CONTROL);
|
||||
writel(0, ccn->dt.base + CCN_DT_PMCR);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void arm_ccn_pmu_cleanup(struct arm_ccn *ccn)
|
||||
{
|
||||
int i;
|
||||
|
||||
irq_set_affinity(ccn->irq, cpu_possible_mask);
|
||||
unregister_cpu_notifier(&ccn->dt.cpu_nb);
|
||||
for (i = 0; i < ccn->num_xps; i++)
|
||||
writel(0, ccn->xp[i].base + CCN_XP_DT_CONTROL);
|
||||
writel(0, ccn->dt.base + CCN_DT_PMCR);
|
||||
@@ -1285,6 +1442,7 @@ static int arm_ccn_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arm_ccn *ccn;
|
||||
struct resource *res;
|
||||
unsigned int irq;
|
||||
int err;
|
||||
|
||||
ccn = devm_kzalloc(&pdev->dev, sizeof(*ccn), GFP_KERNEL);
|
||||
@@ -1309,6 +1467,7 @@ static int arm_ccn_probe(struct platform_device *pdev)
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
irq = res->start;
|
||||
|
||||
/* Check if we can use the interrupt */
|
||||
writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE,
|
||||
@@ -1318,13 +1477,12 @@ static int arm_ccn_probe(struct platform_device *pdev)
|
||||
/* Can set 'disable' bits, so can acknowledge interrupts */
|
||||
writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__ENABLE,
|
||||
ccn->base + CCN_MN_ERRINT_STATUS);
|
||||
err = devm_request_irq(ccn->dev, res->start,
|
||||
arm_ccn_irq_handler, 0, dev_name(ccn->dev),
|
||||
ccn);
|
||||
err = devm_request_irq(ccn->dev, irq, arm_ccn_irq_handler, 0,
|
||||
dev_name(ccn->dev), ccn);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ccn->irq_used = 1;
|
||||
ccn->irq = irq;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
/*
|
||||
@@ -152,13 +153,39 @@ struct mvebu_mbus_state {
|
||||
|
||||
static struct mvebu_mbus_state mbus_state;
|
||||
|
||||
/*
|
||||
* We provide two variants of the mv_mbus_dram_info() function:
|
||||
*
|
||||
* - The normal one, where the described DRAM ranges may overlap with
|
||||
* the I/O windows, but for which the DRAM ranges are guaranteed to
|
||||
* have a power of two size. Such ranges are suitable for the DMA
|
||||
* masters that only DMA between the RAM and the device, which is
|
||||
* actually all devices except the crypto engines.
|
||||
*
|
||||
* - The 'nooverlap' one, where the described DRAM ranges are
|
||||
* guaranteed to not overlap with the I/O windows, but for which the
|
||||
* DRAM ranges will not have power of two sizes. They will only be
|
||||
* aligned on a 64 KB boundary, and have a size multiple of 64
|
||||
* KB. Such ranges are suitable for the DMA masters that DMA between
|
||||
* the crypto SRAM (which is mapped through an I/O window) and a
|
||||
* device. This is the case for the crypto engines.
|
||||
*/
|
||||
|
||||
static struct mbus_dram_target_info mvebu_mbus_dram_info;
|
||||
static struct mbus_dram_target_info mvebu_mbus_dram_info_nooverlap;
|
||||
|
||||
const struct mbus_dram_target_info *mv_mbus_dram_info(void)
|
||||
{
|
||||
return &mvebu_mbus_dram_info;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
|
||||
|
||||
const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(void)
|
||||
{
|
||||
return &mvebu_mbus_dram_info_nooverlap;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mv_mbus_dram_info_nooverlap);
|
||||
|
||||
/* Checks whether the given window has remap capability */
|
||||
static bool mvebu_mbus_window_is_remappable(struct mvebu_mbus_state *mbus,
|
||||
const int win)
|
||||
@@ -576,6 +603,95 @@ static unsigned int armada_xp_mbus_win_remap_offset(int win)
|
||||
return MVEBU_MBUS_NO_REMAP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the memblock information to find the MBus bridge hole in the
|
||||
* physical address space.
|
||||
*/
|
||||
static void __init
|
||||
mvebu_mbus_find_bridge_hole(uint64_t *start, uint64_t *end)
|
||||
{
|
||||
struct memblock_region *r;
|
||||
uint64_t s = 0;
|
||||
|
||||
for_each_memblock(memory, r) {
|
||||
/*
|
||||
* This part of the memory is above 4 GB, so we don't
|
||||
* care for the MBus bridge hole.
|
||||
*/
|
||||
if (r->base >= 0x100000000ULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The MBus bridge hole is at the end of the RAM under
|
||||
* the 4 GB limit.
|
||||
*/
|
||||
if (r->base + r->size > s)
|
||||
s = r->base + r->size;
|
||||
}
|
||||
|
||||
*start = s;
|
||||
*end = 0x100000000ULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function fills in the mvebu_mbus_dram_info_nooverlap data
|
||||
* structure, by looking at the mvebu_mbus_dram_info data, and
|
||||
* removing the parts of it that overlap with I/O windows.
|
||||
*/
|
||||
static void __init
|
||||
mvebu_mbus_setup_cpu_target_nooverlap(struct mvebu_mbus_state *mbus)
|
||||
{
|
||||
uint64_t mbus_bridge_base, mbus_bridge_end;
|
||||
int cs_nooverlap = 0;
|
||||
int i;
|
||||
|
||||
mvebu_mbus_find_bridge_hole(&mbus_bridge_base, &mbus_bridge_end);
|
||||
|
||||
for (i = 0; i < mvebu_mbus_dram_info.num_cs; i++) {
|
||||
struct mbus_dram_window *w;
|
||||
u64 base, size, end;
|
||||
|
||||
w = &mvebu_mbus_dram_info.cs[i];
|
||||
base = w->base;
|
||||
size = w->size;
|
||||
end = base + size;
|
||||
|
||||
/*
|
||||
* The CS is fully enclosed inside the MBus bridge
|
||||
* area, so ignore it.
|
||||
*/
|
||||
if (base >= mbus_bridge_base && end <= mbus_bridge_end)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Beginning of CS overlaps with end of MBus, raise CS
|
||||
* base address, and shrink its size.
|
||||
*/
|
||||
if (base >= mbus_bridge_base && end > mbus_bridge_end) {
|
||||
size -= mbus_bridge_end - base;
|
||||
base = mbus_bridge_end;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of CS overlaps with beginning of MBus, shrink
|
||||
* CS size.
|
||||
*/
|
||||
if (base < mbus_bridge_base && end > mbus_bridge_base)
|
||||
size -= end - mbus_bridge_base;
|
||||
|
||||
w = &mvebu_mbus_dram_info_nooverlap.cs[cs_nooverlap++];
|
||||
w->cs_index = i;
|
||||
w->mbus_attr = 0xf & ~(1 << i);
|
||||
if (mbus->hw_io_coherency)
|
||||
w->mbus_attr |= ATTR_HW_COHERENCY;
|
||||
w->base = base;
|
||||
w->size = size;
|
||||
}
|
||||
|
||||
mvebu_mbus_dram_info_nooverlap.mbus_dram_target_id = TARGET_DDR;
|
||||
mvebu_mbus_dram_info_nooverlap.num_cs = cs_nooverlap;
|
||||
}
|
||||
|
||||
static void __init
|
||||
mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
|
||||
{
|
||||
@@ -964,6 +1080,7 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
|
||||
mvebu_mbus_disable_window(mbus, win);
|
||||
|
||||
mbus->soc->setup_cpu_target(mbus);
|
||||
mvebu_mbus_setup_cpu_target_nooverlap(mbus);
|
||||
|
||||
if (is_coherent)
|
||||
writel(UNIT_SYNC_BARRIER_ALL,
|
||||
|
||||
@@ -502,12 +502,13 @@ static const struct berlin2_gate_data bg2_gates[] __initconst = {
|
||||
|
||||
static void __init berlin2_clock_setup(struct device_node *np)
|
||||
{
|
||||
struct device_node *parent_np = of_get_parent(np);
|
||||
const char *parent_names[9];
|
||||
struct clk *clk;
|
||||
u8 avpll_flags = 0;
|
||||
int n;
|
||||
|
||||
gbase = of_iomap(np, 0);
|
||||
gbase = of_iomap(parent_np, 0);
|
||||
if (!gbase)
|
||||
return;
|
||||
|
||||
@@ -685,7 +686,5 @@ static void __init berlin2_clock_setup(struct device_node *np)
|
||||
bg2_fail:
|
||||
iounmap(gbase);
|
||||
}
|
||||
CLK_OF_DECLARE(berlin2_clock, "marvell,berlin2-chip-ctrl",
|
||||
berlin2_clock_setup);
|
||||
CLK_OF_DECLARE(berlin2cd_clock, "marvell,berlin2cd-chip-ctrl",
|
||||
CLK_OF_DECLARE(berlin2_clk, "marvell,berlin2-clk",
|
||||
berlin2_clock_setup);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user