Commit 48c1c40a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm-soc-drivers-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull ARM SoC driver updates from Arnd Bergmann:
 "There are a couple of subsystems maintained by other people that merge
  their drivers through the SoC tree, those changes include:

   - The SCMI firmware framework gains support for sensor notifications
     and for controlling voltage domains.

   - A large update for the Tegra memory controller driver, integrating
     it better with the interconnect framework

   - The memory controller subsystem gains support for Mediatek MT8192

   - The reset controller framework gains support for sharing pulsed
     resets

  For Soc specific drivers in drivers/soc, the main changes are

   - The Allwinner/sunxi MBUS gets a rework for the way it handles
     dma_map_ops and offsets between physical and dma address spaces.

   - An errata fix plus some cleanups for Freescale Layerscape SoCs

   - A cleanup for renesas drivers regarding MMIO accesses.

   - New SoC specific drivers for Mediatek MT8192 and MT8183 power
     domains

   - New SoC specific drivers for Aspeed AST2600 LPC bus control and SoC
     identification.

   - Core Power Domain support for Qualcomm MSM8916, MSM8939, SDM660 and
     SDX55.

   - A rework of the TI AM33xx 'genpd' power domain support to use
     information from DT instead of platform data

   - Support for TI AM64x SoCs

   - Allow building some Amlogic drivers as modules instead of built-in

  Finally, there are numerous cleanups and smaller bug fixes for
  Mediatek, Tegra, Samsung, Qualcomm, TI OMAP, Amlogic, Rockchips,
  Renesas, and Xilinx SoCs"

* tag 'arm-soc-drivers-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (222 commits)
  soc: mediatek: mmsys: Specify HAS_IOMEM dependency for MTK_MMSYS
  firmware: xilinx: Properly align function parameter
  firmware: xilinx: Add a blank line after function declaration
  firmware: xilinx: Remove additional newline
  firmware: xilinx: Fix kernel-doc warnings
  firmware: xlnx-zynqmp: fix compilation warning
  soc: xilinx: vcu: add missing register NUM_CORE
  soc: xilinx: vcu: use vcu-settings syscon registers
  dt-bindings: soc: xlnx: extract xlnx, vcu-settings to separate binding
  soc: xilinx: vcu: drop useless success message
  clk: samsung: mark PM functions as __maybe_unused
  soc: samsung: exynos-chipid: initialize later - with arch_initcall
  soc: samsung: exynos-chipid: order list of SoCs by name
  memory: jz4780_nemc: Fix potential NULL dereference in jz4780_nemc_probe()
  memory: ti-emif-sram: only build for ARMv7
  memory: tegra30: Support interconnect framework
  memory: tegra20: Support hardware versioning and clean up OPP table initialization
  dt-bindings: memory: tegra20-emc: Document opp-supported-hw property
  soc: rockchip: io-domain: Fix error return code in rockchip_iodomain_probe()
  reset-controller: ti: force the write operation when assert or deassert
  ...
parents 9805529e 1dcdee6e
......@@ -2948,7 +2948,7 @@
mtdset= [ARM]
ARM/S3C2412 JIVE boot control
See arch/arm/mach-s3c2412/mach-jive.c
See arch/arm/mach-s3c/mach-jive.c
mtouchusb.raw_coordinates=
[HW] Make the MicroTouch USB driver use raw coordinates
......
......@@ -29,7 +29,7 @@ GPIOLIB
The following functions now either have a `s3c_` specific variant
or are merged into gpiolib. See the definitions in
arch/arm/plat-samsung/include/plat/gpio-cfg.h:
arch/arm/mach-s3c/gpio-cfg.h:
- s3c2410_gpio_setpin() gpio_set_value() or gpio_direction_output()
- s3c2410_gpio_getpin() gpio_get_value() or gpio_direction_input()
......@@ -86,7 +86,7 @@ between the calls.
Headers
-------
See arch/arm/mach-s3c24xx/include/mach/regs-gpio.h for the list
See arch/arm/mach-s3c/regs-gpio-s3c24xx.h for the list
of GPIO pins, and the configuration values for them. This
is included by using #include <mach/regs-gpio.h>
......
......@@ -18,7 +18,7 @@ Introduction
versions.
The S3C2416 and S3C2450 devices are very similar and S3C2450 support is
included under the arch/arm/mach-s3c2416 directory. Note, while core
included under the arch/arm/mach-s3c directory. Note, while core
support for these SoCs is in, work on some of the extra peripherals
and extra interrupts is still ongoing.
......@@ -37,19 +37,11 @@ Configuration
Layout
------
The core support files are located in the platform code contained in
arch/arm/plat-s3c24xx with headers in include/asm-arm/plat-s3c24xx.
This directory should be kept to items shared between the platform
code (arch/arm/plat-s3c24xx) and the arch/arm/mach-s3c24* code.
The core support files, register, kernel and paltform data are located in the
platform code contained in arch/arm/mach-s3c with headers in
arch/arm/mach-s3c/include
Each cpu has a directory with the support files for it, and the
machines that carry the device. For example S3C2410 is contained
in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
Register, kernel and platform data definitions are held in the
arch/arm/mach-s3c2410 directory./include/mach
arch/arm/plat-s3c24xx:
arch/arm/mach-s3c:
Files in here are either common to all the s3c24xx family,
or are common to only some of them with names to indicate this
......@@ -134,7 +126,7 @@ Adding New Machines
should keep this in mind before altering items outside of their own
machine files.
Machine definitions should be kept in linux/arch/arm/mach-s3c2410,
Machine definitions should be kept in arch/arm/mach-s3c,
and there are a number of examples that can be looked at.
Read the kernel patch submission policies as well as the
......@@ -293,7 +285,7 @@ Platform Data
}
Note, since the code is marked as __init, it should not be
exported outside arch/arm/mach-s3c2410/, or exported to
exported outside arch/arm/mach-s3c/, or exported to
modules via EXPORT_SYMBOL() and related functions.
......
......@@ -36,7 +36,7 @@ Board Support
-------------
The driver attaches to a platform device, which will need to be
added by the board specific support file in linux/arch/arm/mach-s3c2410,
added by the board specific support file in arch/arm/mach-s3c,
such as mach-bast.c or mach-smdk2410.c
The platform device's platform_data field is only needed if the
......@@ -51,9 +51,9 @@ Board Support
Platform Data
-------------
See arch/arm/mach-s3c2410/include/mach/usb-control.h for the
See include/linux/platform_data/usb-ohci-s3c2410.h for the
descriptions of the platform device data. An implementation
can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c .
can be found in arch/arm/mach-s3c/simtec-usb.c .
The `struct s3c2410_hcd_info` contains a pair of functions
that get called to enable over-current detection, and to
......
......@@ -37,5 +37,4 @@ implementation to configure pins as necessary.
The s3c_gpio_cfgpin() and s3c_gpio_setpull() provide the means for a
driver or machine to change gpio configuration.
See arch/arm/plat-samsung/include/plat/gpio-cfg.h for more information
on these functions.
See arch/arm/mach-s3c/gpio-cfg.h for more information on these functions.
......@@ -23,6 +23,7 @@ properties:
enum:
- qcom,sc7180-llcc
- qcom,sdm845-llcc
- qcom,sm8150-llcc
reg:
items:
......
......@@ -18,8 +18,30 @@ clock-names. See ../../clock/clock-bindings.txt for details.
../../reset/reset.txt for details.
- reset-names: Must include the following entries:
- actmon
- operating-points-v2: See ../bindings/opp/opp.txt for details.
- interconnects: Should contain entries for memory clients sitting on
MC->EMC memory interconnect path.
- interconnect-names: Should include name of the interconnect path for each
interconnect entry. Consult TRM documentation for
information about available memory clients, see MEMORY
CONTROLLER section.
For each opp entry in 'operating-points-v2' table:
- opp-supported-hw: bitfield indicating SoC speedo ID mask
- opp-peak-kBps: peak bandwidth of the memory channel
Example:
dfs_opp_table: opp-table {
compatible = "operating-points-v2";
opp@12750000 {
opp-hz = /bits/ 64 <12750000>;
opp-supported-hw = <0x000F>;
opp-peak-kBps = <51000>;
};
...
};
actmon@6000c800 {
compatible = "nvidia,tegra124-actmon";
reg = <0x0 0x6000c800 0x0 0x400>;
......@@ -29,4 +51,7 @@ Example:
clock-names = "actmon", "emc";
resets = <&tegra_car 119>;
reset-names = "actmon";
operating-points-v2 = <&dfs_opp_table>;
interconnects = <&mc TEGRA124_MC_MPCORER &emc>;
interconnect-names = "cpu";
};
......@@ -20,6 +20,10 @@ Required properties:
- reset-names: Must include the following entries:
- host1x
Each host1x client module having to perform DMA through the Memory Controller
should have the interconnect endpoints set to the Memory Client and External
Memory respectively.
The host1x top-level node defines a number of children, each representing one
of the following host1x client modules:
......@@ -36,6 +40,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries:
- mpe
Optional properties:
- interconnects: Must contain entry for the MPE memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
- vi: video input
Required properties:
......@@ -113,6 +123,12 @@ of the following host1x client modules:
Required properties:
- remote-endpoint: phandle to vi port 'endpoint' node.
Optional properties:
- interconnects: Must contain entry for the VI memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
- epp: encoder pre-processor
Required properties:
......@@ -126,6 +142,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries:
- epp
Optional properties:
- interconnects: Must contain entry for the EPP memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
- isp: image signal processor
Required properties:
......@@ -139,6 +161,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries:
- isp
Optional properties:
- interconnects: Must contain entry for the ISP memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
- gr2d: 2D graphics engine
Required properties:
......@@ -152,6 +180,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries:
- 2d
Optional properties:
- interconnects: Must contain entry for the GR2D memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
- gr3d: 3D graphics engine
Required properties:
......@@ -170,6 +204,12 @@ of the following host1x client modules:
- 3d
- 3d2 (Only required on SoCs with two 3D clocks)
Optional properties:
- interconnects: Must contain entry for the GR3D memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
- dc: display controller
Required properties:
......@@ -197,6 +237,10 @@ of the following host1x client modules:
- nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
- nvidia,edid: supplies a binary EDID blob
- nvidia,panel: phandle of a display panel
- interconnects: Must contain entry for the DC memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
- hdmi: High Definition Multimedia Interface
......@@ -345,6 +389,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries:
- vic
Optional properties:
- interconnects: Must contain entry for the VIC memory clients.
- interconnect-names: Must include name of the interconnect path for each
interconnect entry. Consult TRM documentation for information about
available memory clients, see MEMORY CONTROLLER section.
Example:
/ {
......@@ -498,6 +548,15 @@ Example:
resets = <&tegra_car 27>;
reset-names = "dc";
interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
<&mc TEGRA20_MC_DISPLAY0B &emc>,
<&mc TEGRA20_MC_DISPLAY0C &emc>,
<&mc TEGRA20_MC_DISPLAYHC &emc>;
interconnect-names = "wina",
"winb",
"winc",
"cursor";
rgb {
status = "disabled";
};
......@@ -513,6 +572,15 @@ Example:
resets = <&tegra_car 26>;
reset-names = "dc";
interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
<&mc TEGRA20_MC_DISPLAY0BB &emc>,
<&mc TEGRA20_MC_DISPLAY0CB &emc>,
<&mc TEGRA20_MC_DISPLAYHCB &emc>;
interconnect-names = "wina",
"winb",
"winc",
"cursor";
rgb {
status = "disabled";
};
......
SMI (Smart Multimedia Interface) Common
The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
Mediatek SMI have two generations of HW architecture, here is the list
which generation the SoCs use:
generation 1: mt2701 and mt7623.
generation 2: mt2712, mt6779, mt8167, mt8173 and mt8183.
There's slight differences between the two SMI, for generation 2, the
register which control the iommu port is at each larb's register base. But
for generation 1, the register is at smi ao base(smi always on register
base). Besides that, the smi async clock should be prepared and enabled for
SMI generation 1 to transform the smi clock into emi clock domain, but that is
not needed for SMI generation 2.
Required properties:
- compatible : must be one of :
"mediatek,mt2701-smi-common"
"mediatek,mt2712-smi-common"
"mediatek,mt6779-smi-common"
"mediatek,mt7623-smi-common", "mediatek,mt2701-smi-common"
"mediatek,mt8167-smi-common"
"mediatek,mt8173-smi-common"
"mediatek,mt8183-smi-common"
- reg : the register and size of the SMI block.
- power-domains : a phandle to the power domain of this local arbiter.
- clocks : Must contain an entry for each entry in clock-names.
- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries
for generation 2 smi HW as follows:
- "apb" : Advanced Peripheral Bus clock, It's the clock for setting
the register.
- "smi" : It's the clock for transfer data and command.
They may be the same if both source clocks are the same.
- "async" : asynchronous clock, it help transform the smi clock into the emi
clock domain, this clock is only needed by generation 1 smi HW.
and these 2 option clocks for generation 2 smi HW:
- "gals0": the path0 clock of GALS(Global Async Local Sync).
- "gals1": the path1 clock of GALS(Global Async Local Sync).
Here is the list which has this GALS: mt6779 and mt8183.
Example:
smi_common: smi@14022000 {
compatible = "mediatek,mt8173-smi-common";
reg = <0 0x14022000 0 0x1000>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_SMI_COMMON>,
<&mmsys CLK_MM_SMI_COMMON>;
clock-names = "apb", "smi";
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (c) 2020 MediaTek Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/mediatek,smi-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: SMI (Smart Multimedia Interface) Common
maintainers:
- Yong Wu <yong.wu@mediatek.com>
description: |
The hardware block diagram please check bindings/iommu/mediatek,iommu.yaml
MediaTek SMI have two generations of HW architecture, here is the list
which generation the SoCs use:
generation 1: mt2701 and mt7623.
generation 2: mt2712, mt6779, mt8167, mt8173, mt8183 and mt8192.
There's slight differences between the two SMI, for generation 2, the
register which control the iommu port is at each larb's register base. But
for generation 1, the register is at smi ao base(smi always on register
base). Besides that, the smi async clock should be prepared and enabled for
SMI generation 1 to transform the smi clock into emi clock domain, but that is
not needed for SMI generation 2.
properties:
compatible:
oneOf:
- enum:
- mediatek,mt2701-smi-common
- mediatek,mt2712-smi-common
- mediatek,mt6779-smi-common
- mediatek,mt8167-smi-common
- mediatek,mt8173-smi-common
- mediatek,mt8183-smi-common
- mediatek,mt8192-smi-common
- description: for mt7623
items:
- const: mediatek,mt7623-smi-common
- const: mediatek,mt2701-smi-common
reg:
maxItems: 1
power-domains:
maxItems: 1
clocks:
description: |
apb and smi are mandatory. the async is only for generation 1 smi HW.
gals(global async local sync) also is optional, see below.
minItems: 2
maxItems: 4
items:
- description: apb is Advanced Peripheral Bus clock, It's the clock for
setting the register.
- description: smi is the clock for transfer data and command.
- description: async is asynchronous clock, it help transform the smi
clock into the emi clock domain.
- description: gals0 is the path0 clock of gals.
- description: gals1 is the path1 clock of gals.
clock-names:
minItems: 2
maxItems: 4
required:
- compatible
- reg
- power-domains
- clocks
- clock-names
allOf:
- if: # only for gen1 HW
properties:
compatible:
contains:
enum:
- mediatek,mt2701-smi-common
then:
properties:
clock:
items:
minItems: 3
maxItems: 3
clock-names:
items:
- const: apb
- const: smi
- const: async
- if: # for gen2 HW that have gals
properties:
compatible:
enum:
- mediatek,mt6779-smi-common
- mediatek,mt8183-smi-common
- mediatek,mt8192-smi-common
then:
properties:
clock:
items:
minItems: 4
maxItems: 4
clock-names:
items:
- const: apb
- const: smi
- const: gals0
- const: gals1
else: # for gen2 HW that don't have gals
properties:
clock:
items:
minItems: 2
maxItems: 2
clock-names:
items:
- const: apb
- const: smi
additionalProperties: false
examples:
- |+
#include <dt-bindings/clock/mt8173-clk.h>
#include <dt-bindings/power/mt8173-power.h>
smi_common: smi@14022000 {
compatible = "mediatek,mt8173-smi-common";
reg = <0x14022000 0x1000>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_SMI_COMMON>,
<&mmsys CLK_MM_SMI_COMMON>;
clock-names = "apb", "smi";
};
SMI (Smart Multimedia Interface) Local Arbiter
The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
Required properties:
- compatible : must be one of :
"mediatek,mt2701-smi-larb"
"mediatek,mt2712-smi-larb"
"mediatek,mt6779-smi-larb"
"mediatek,mt7623-smi-larb", "mediatek,mt2701-smi-larb"
"mediatek,mt8167-smi-larb"
"mediatek,mt8173-smi-larb"
"mediatek,mt8183-smi-larb"
- reg : the register and size of this local arbiter.
- mediatek,smi : a phandle to the smi_common node.
- power-domains : a phandle to the power domain of this local arbiter.
- clocks : Must contain an entry for each entry in clock-names.
- clock-names: must contain 2 entries, as follows:
- "apb" : Advanced Peripheral Bus clock, It's the clock for setting
the register.
- "smi" : It's the clock for transfer data and command.
and this optional clock name:
- "gals": the clock for GALS(Global Async Local Sync).
Here is the list which has this GALS: mt8183.
Required property for mt2701, mt2712, mt6779, mt7623 and mt8167:
- mediatek,larb-id :the hardware id of this larb.
Example:
larb1: larb@16010000 {
compatible = "mediatek,mt8173-smi-larb";
reg = <0 0x16010000 0 0x1000>;
mediatek,smi = <&smi_common>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
clocks = <&vdecsys CLK_VDEC_CKEN>,
<&vdecsys CLK_VDEC_LARB_CKEN>;
clock-names = "apb", "smi";
};
Example for mt2701:
larb0: larb@14010000 {
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x14010000 0 0x1000>;
mediatek,smi = <&smi_common>;
mediatek,larb-id = <0>;
clocks = <&mmsys CLK_MM_SMI_LARB0>,
<&mmsys CLK_MM_SMI_LARB0>;
clock-names = "apb", "smi";
power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (c) 2020 MediaTek Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/mediatek,smi-larb.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: SMI (Smart Multimedia Interface) Local Arbiter
maintainers:
- Yong Wu <yong.wu@mediatek.com>
description: |
The hardware block diagram please check bindings/iommu/mediatek,iommu.yaml
properties:
compatible:
oneOf:
- enum:
- mediatek,mt2701-smi-larb
- mediatek,mt2712-smi-larb
- mediatek,mt6779-smi-larb
- mediatek,mt8167-smi-larb
- mediatek,mt8173-smi-larb
- mediatek,mt8183-smi-larb
- mediatek,mt8192-smi-larb
- description: for mt7623
items:
- const: mediatek,mt7623-smi-larb
- const: mediatek,mt2701-smi-larb
reg:
maxItems: 1
clocks:
description: |
apb and smi are mandatory. gals(global async local sync) is optional.
minItems: 2
maxItems: 3
items:
- description: apb is Advanced Peripheral Bus clock, It's the clock for
setting the register.
- description: smi is the clock for transfer data and command.
- description: the clock for gals.
clock-names:
minItems: 2
maxItems: 3
power-domains:
maxItems: 1
mediatek,smi:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: a phandle to the smi_common node.
mediatek,larb-id:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 31
description: the hardware id of this larb. It's only required when this
hardward id is not consecutive from its M4U point of view.
required:
- compatible
- reg
- clocks
- clock-names
- power-domains
allOf:
- if: # HW has gals
properties:
compatible:
enum:
- mediatek,mt8183-smi-larb
then:
properties:
clock:
items:
minItems: 3
maxItems: 3
clock-names:
items:
- const: apb
- const: smi
- const: gals
else:
properties:
clock:
items:
minItems: 2
maxItems: 2
clock-names:
items:
- const: apb
- const: smi
- if:
properties:
compatible:
contains:
enum:
- mediatek,mt2701-smi-larb
- mediatek,mt2712-smi-larb
- mediatek,mt6779-smi-larb
- mediatek,mt8167-smi-larb
- mediatek,mt8192-smi-larb
then:
required:
- mediatek,larb-id
additionalProperties: false
examples:
- |+
#include <dt-bindings/clock/mt8173-clk.h>
#include <dt-bindings/power/mt8173-power.h>
larb1: larb@16010000 {
compatible = "mediatek,mt8173-smi-larb";
reg = <0x16010000 0x1000>;
mediatek,smi = <&smi_common>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
clocks = <&vdecsys CLK_VDEC_CKEN>,
<&vdecsys CLK_VDEC_LARB_CKEN>;
clock-names = "apb", "smi";
};
......@@ -29,11 +29,23 @@ properties:
items:
- const: emc
"#interconnect-cells":
const: 0
nvidia,memory-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description:
phandle of the memory controller node
core-supply:
description:
Phandle of voltage regulator of the SoC "core" power domain.
operating-points-v2:
description:
Should contain freqs and voltages and opp-supported-hw property, which
is a bitfield indicating SoC speedo ID mask.
patternProperties:
"^emc-timings-[0-9]+$":
type: object
......@@ -327,6 +339,8 @@ required:
- clocks
- clock-names
- nvidia,memory-controller
- "#interconnect-cells"
- operating-points-v2
additionalProperties: false
......@@ -345,6 +359,7 @@ examples:
#iommu-cells = <1>;
#reset-cells = <1>;
#interconnect-cells = <1>;
};
external-memory-controller@7001b000 {
......@@ -354,6 +369,10 @@ examples:
clock-names = "emc";
nvidia,memory-controller = <&mc>;
operating-points-v2 = <&dvfs_opp_table>;
core-supply = <&vdd_core>;
#interconnect-cells = <0>;
emc-timings-0 {
nvidia,ram-code = <3>;
......
......@@ -40,6 +40,9 @@ properties:
"#iommu-cells":
const: 1
"#interconnect-cells":
const: 1
patternProperties:
"^emc-timings-[0-9]+$":
type: object
......@@ -104,6 +107,7 @@ required:
- clock-names
- "#reset-cells"
- "#iommu-cells"
- "#interconnect-cells"
additionalProperties: false
......@@ -119,6 +123,7 @@ examples:
#iommu-cells = <1>;
#reset-cells = <1>;
#interconnect-cells = <1>;
emc-timings-3 {
nvidia,ram-code = <3>;
......
......@@ -12,18 +12,44 @@ Properties:
irrespective of ram-code configuration.
- interrupts : Should contain EMC General interrupt.
- clocks : Should contain EMC clock.
- nvidia,memory-controller : Phandle of the Memory Controller node.
- #interconnect-cells : Should be 0.
- operating-points-v2: See ../bindings/opp/opp.txt for details.
For each opp entry in 'operating-points-v2' table:
- opp-supported-hw: One bitfield indicating SoC process ID mask
A bitwise AND is performed against this value and if any bit
matches, the OPP gets enabled.
Optional properties:
- core-supply: Phandle of voltage regulator of the SoC "core" power domain.
Child device nodes describe the memory settings for different configurations and clock rates.
Example:
opp_table: opp-table {
compatible = "operating-points-v2";
opp@36000000 {
opp-microvolt = <950000 950000 1300000>;
opp-hz = /bits/ 64 <36000000>;
};
...
};
memory-controller@7000f400 {
#address-cells = < 1 >;
#size-cells = < 0 >;
#interconnect-cells = <0>;
compatible = "nvidia,tegra20-emc";
reg = <0x7000f4000 0x200>;
reg = <0x7000f400 0x400>;
interrupts = <0 78 0x04>;
clocks = <&tegra_car TEGRA20_CLK_EMC>;
nvidia,memory-controller = <&mc>;
core-supply = <&core_vdd_reg>;
operating-points-v2 = <&opp_table>;
}
......
......@@ -16,6 +16,8 @@ Required properties:
IOMMU specifier needed to encode an address. GART supports only a single
address space that is shared by all devices, therefore no additional
information needed for the address encoding.
- #interconnect-cells : Should be 1. This cell represents memory client.
The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.
Example:
mc: memory-controller@7000f000 {
......@@ -27,6 +29,7 @@ Example:
interrupts = <GIC_SPI 77 0x04>;
#reset-cells = <1>;
#iommu-cells = <0>;
#interconnect-cells = <1>;
};
video-codec@6001a000 {
......
......@@ -31,11 +31,23 @@ properties:
interrupts:
maxItems: 1
"#interconnect-cells":
const: 0
nvidia,memory-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle of the Memory Controller node.
core-supply:
description:
Phandle of voltage regulator of the SoC "core" power domain.
operating-points-v2:
description:
Should contain freqs and voltages and opp-supported-hw property, which
is a bitfield indicating SoC speedo ID mask.
patternProperties:
"^emc-timings-[0-9]+$":
type: object
......@@ -214,6 +226,8 @@ required:
- interrupts
- clocks
- nvidia,memory-controller
- "#interconnect-cells"
- operating-points-v2
additionalProperties: false
......@@ -226,6 +240,10 @@ examples:
clocks = <&tegra_car 57>;
nvidia,memory-controller = <&mc>;
operating-points-v2 = <&dvfs_opp_table>;
core-supply = <&vdd_core>;
#interconnect-cells = <0>;
emc-timings-1 {
nvidia,ram-code = <1>;
......
......@@ -57,6 +57,9 @@ properties:
"#iommu-cells":
const: 1
"#interconnect-cells":
const: 1
patternProperties:
"^emc-timings-[0-9]+$":
type: object
......@@ -120,6 +123,7 @@ required:
- clock-names
- "#reset-cells"
- "#iommu-cells"
- "#interconnect-cells"
additionalProperties: false
......@@ -135,6 +139,7 @@ examples:
#iommu-cells = <1>;
#reset-cells = <1>;
#interconnect-cells = <1>;
emc-timings-1 {
nvidia,ram-code = <1>;
......
......@@ -46,6 +46,7 @@ Required properties
- compatible: One of:
"aspeed,ast2400-lpc", "simple-mfd"
"aspeed,ast2500-lpc", "simple-mfd"
"aspeed,ast2600-lpc", "simple-mfd"
- reg: contains the physical address and length values of the Aspeed
LPC memory region.
......@@ -64,6 +65,7 @@ BMC Node
- compatible: One of:
"aspeed,ast2400-lpc-bmc"
"aspeed,ast2500-lpc-bmc"
"aspeed,ast2600-lpc-bmc"
- reg: contains the physical address and length values of the
H8S/2168-compatible LPC controller memory region
......@@ -74,6 +76,7 @@ Host Node
- compatible: One of:
"aspeed,ast2400-lpc-host", "simple-mfd", "syscon"
"aspeed,ast2500-lpc-host", "simple-mfd", "syscon"
"aspeed,ast2600-lpc-host", "simple-mfd", "syscon"
- reg: contains the address and length values of the host-related
register space for the Aspeed LPC controller
......@@ -128,6 +131,7 @@ Required properties:
- compatible: One of:
"aspeed,ast2400-lpc-ctrl";
"aspeed,ast2500-lpc-ctrl";
"aspeed,ast2600-lpc-ctrl";
- reg: contains offset/length values of the host interface controller
memory regions
......@@ -168,6 +172,7 @@ Required properties:
- compatible: One of:
"aspeed,ast2400-lhc";
"aspeed,ast2500-lhc";
"aspeed,ast2600-lhc";
- reg: contains offset/length values of the LHC memory regions. In the
AST2400 and AST2500 there are two regions.
......@@ -187,7 +192,8 @@ state of the LPC bus. Some systems may chose to modify this configuration.
Required properties:
- compatible: "aspeed,ast2500-lpc-reset" or
- compatible: "aspeed,ast2600-lpc-reset" or
"aspeed,ast2500-lpc-reset"
"aspeed,ast2400-lpc-reset"
- reg: offset and length of the IP in the LHC memory region
- #reset-controller indicates the number of reset cells expected
......
......@@ -20,3 +20,29 @@ syscon: syscon@1e6e2000 {
#clock-cells = <1>;
#reset-cells = <1>;
};
Silicon ID
-----------------
Families have unique hardware silicon identifiers within the SoC.
Required properties:
- compatible: "aspeed,silicon-id" or:
"aspeed,ast2400-silicon-id" or
"aspeed,ast2500-silicon-id" or
"aspeed,ast2600-silicon-id"
- reg: offset and length of the silicon id information
optionally, a second offset and length describes the unique chip id
The reg should be the unique silicon id register, and
not backwards compatible one in eg. the 2600.
Example:
silicon-id@7c {
compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id";
reg = <0x7c 0x4 0x150 0x8>;
};
......@@ -16,12 +16,16 @@ description:
properties:
compatible:
enum:
- qcom,msm8916-rpmpd
- qcom,msm8939-rpmpd
- qcom,msm8976-rpmpd
- qcom,msm8996-rpmpd
- qcom,msm8998-rpmpd
- qcom,qcs404-rpmpd
- qcom,sdm660-rpmpd
- qcom,sc7180-rpmhpd
- qcom,sdm845-rpmhpd
- qcom,sdx55-rpmhpd
- qcom,sm8150-rpmhpd
- qcom,sm8250-rpmhpd
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# # Copyright 2020 MediaTek Inc.
%YAML 1.2
---
$id: "http://devicetree.org/schemas/soc/mediatek/devapc.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: MediaTek Device Access Permission Control driver
description: |
MediaTek bus fabric provides TrustZone security support and data
protection to prevent slaves from being accessed by unexpected masters.
The security violation is logged and sent to the processor for further
analysis and countermeasures.
maintainers:
- Neal Liu <neal.liu@mediatek.com>
properties:
compatible:
enum:
- mediatek,mt6779-devapc
reg:
description: The base address of devapc register bank
maxItems: 1
interrupts:
description: A single interrupt specifier
maxItems: 1
clocks:
description: Contains module clock source and clock names
maxItems: 1
clock-names:
description: Names of the clocks list in clocks property
maxItems: 1
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/mt6779-clk.h>
devapc: devapc@10207000 {
compatible = "mediatek,mt6779-devapc";
reg = <0x10207000 0x1000>;
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_LOW>;
clocks = <&infracfg_ao CLK_INFRA_DEVICE_APC>;
clock-names = "devapc-infra-clock";
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/xilinx/xlnx,vcu-settings.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Xilinx VCU Settings
maintainers:
- Michael Tretter <kernel@pengutronix.de>
description: |
The Xilinx VCU Settings provides information about the configuration of the
video codec unit.
properties:
compatible:
items:
- const: xlnx,vcu-settings
- const: syscon
reg:
maxItems: 1
required:
- compatible
- reg
examples:
- |
xlnx_vcu: vcu@a0041000 {
compatible = "xlnx,vcu-settings", "syscon";
reg = <0x0 0xa0041000 0x0 0x1000>;
};
......@@ -12,10 +12,7 @@ Required properties:
- compatible: shall be one of:
"xlnx,vcu"
"xlnx,vcu-logicoreip-1.0"
- reg, reg-names: There are two sets of registers need to provide.
1. vcu slcr
2. Logicore
reg-names should contain name for the each register sequence.
- reg : The base offset and size of the VCU_PL_SLCR register space.
- clocks: phandle for aclk and pll_ref clocksource
- clock-names: The identification string, "aclk", is always required for
the axi clock. "pll_ref" is required for pll.
......@@ -23,9 +20,7 @@ Example:
xlnx_vcu: vcu@a0040000 {
compatible = "xlnx,vcu-logicoreip-1.0";
reg = <0x0 0xa0040000 0x0 0x1000>,
<0x0 0xa0041000 0x0 0x1000>;
reg-names = "vcu_slcr", "logicore";
reg = <0x0 0xa0040000 0x0 0x1000>;
clocks = <&si570_1>, <&clkc 71>;
clock-names = "pll_ref", "aclk";
};
......@@ -34,7 +34,7 @@ These resources should be specified in that order, as the ordering of the
two address regions is important (the driver expects these to be address
and then data).
An example from arch/arm/mach-s3c2410/mach-bast.c is::
An example from arch/arm/mach-s3c/mach-bast.c is::
static struct resource bast_dm9k_resource[] = {
[0] = {
......
......@@ -2074,7 +2074,7 @@ M: Matthias Brugger <matthias.bgg@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
W: https://mtk.bcnfs.org/
W: https://mtk.wiki.kernel.org/
C: irc://chat.freenode.net/linux-mediatek
F: arch/arm/boot/dts/mt6*
F: arch/arm/boot/dts/mt7*
......@@ -11429,6 +11429,7 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git
F: Documentation/devicetree/bindings/memory-controllers/
F: drivers/memory/
F: include/dt-bindings/memory/
MEMORY FREQUENCY SCALING DRIVERS FOR NVIDIA TEGRA
M: Dmitry Osipenko <digetx@gmail.com>
......
......@@ -192,6 +192,11 @@ p2a: p2a-control@2c {
status = "disabled";
};
silicon-id@7c {
compatible = "aspeed,ast2400-silicon-id", "aspeed,silicon-id";
reg = <0x7c 0x4>;
};
pinctrl: pinctrl@80 {
reg = <0x80 0x18>, <0xa0 0x10>;
compatible = "aspeed,ast2400-pinctrl";
......
......@@ -239,6 +239,11 @@ p2a: p2a-control@2c {
status = "disabled";
};
silicon-id@7c {
compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id";
reg = <0x7c 0x4 0x150 0x8>;
};
pinctrl: pinctrl@80 {
compatible = "aspeed,ast2500-pinctrl";
reg = <0x80 0x18>, <0xa0 0x10>;
......
......@@ -317,6 +317,11 @@ pinctrl: pinctrl {
compatible = "aspeed,ast2600-pinctrl";
};
silicon-id@14 {
compatible = "aspeed,ast2600-silicon-id", "aspeed,silicon-id";
reg = <0x14 0x4 0x5b0 0x8>;
};
smp-memram@180 {
compatible = "aspeed,ast2600-smpmem";
reg = <0x180 0x40>;
......
......@@ -8,7 +8,7 @@
*/
#include <linux/io.h>
#include <linux/of.h>
#include <linux/dma-mapping.h>
#include <linux/dma-map-ops.h>
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
......
......@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-map-ops.h>
#include <linux/io.h>
#include <asm/irq.h>
......
......@@ -627,6 +627,9 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
{
struct clk_hw_omap *clk;
if (!oh)
return NULL;
if (oh->clkdm) {
return oh->clkdm;
} else if (oh->_clk) {
......@@ -3677,6 +3680,9 @@ static void __init omap_hwmod_setup_earlycon_flags(void)
*/
static int __init omap_hwmod_setup_all(void)
{
if (!inited)
return 0;
_ensure_mpu_hwmod_is_setup(NULL);
omap_hwmod_for_each(_init, NULL);
......
......@@ -580,6 +580,8 @@ static void pdata_quirks_check(struct pdata_init *quirks)
void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
{
struct device_node *np;
/*
* We still need this for omap2420 and omap3 PM to work, others are
* using drivers/misc/sram.c already.
......@@ -591,6 +593,15 @@ void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
if (of_machine_is_compatible("ti,omap3"))
omap3_mcbsp_init();
pdata_quirks_check(auxdata_quirks);
/* Populate always-on PRCM in l4_wkup to probe l4_wkup */
np = of_find_node_by_name(NULL, "prcm");
if (!np)
np = of_find_node_by_name(NULL, "prm");
if (np)
of_platform_populate(np, omap_dt_match_table,
omap_auxdata_lookup, NULL);
of_platform_populate(NULL, omap_dt_match_table,
omap_auxdata_lookup, NULL);
pdata_quirks_check(pdata_quirks);
......
......@@ -12,7 +12,7 @@
#include <linux/io.h>
#include <linux/async.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dma-map-ops.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/sh_clk.h>
......
......@@ -11,7 +11,8 @@
#include <linux/pci_ids.h>
#include <linux/export.h>
#include <linux/list.h>
#include <linux/dma-direct.h>
#include <linux/dma-map-ops.h>
#include <linux/swiotlb.h>
#include <asm/iommu.h>
#define STA2X11_SWIOTLB_SIZE (4*1024*1024)
......
......@@ -853,8 +853,12 @@ static int sysc_ioremap(struct sysc *ddata)
*/
static int sysc_map_and_check_registers(struct sysc *ddata)
{
struct device_node *np = ddata->dev->of_node;
int error;
if (!of_get_property(np, "reg", NULL))
return 0;
error = sysc_parse_and_check_child_range(ddata);
if (error)
return error;
......@@ -1222,10 +1226,10 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
ddata->enabled = false;
err_allow_idle:
reset_control_assert(ddata->rsts);
sysc_clkdm_allow_idle(ddata);
reset_control_assert(ddata->rsts);
return error;
}
......@@ -1379,6 +1383,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
SYSC_QUIRK_CLKDM_NOAUTO),
SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff,
SYSC_QUIRK_CLKDM_NOAUTO),
SYSC_QUIRK("gpmc", 0, 0, 0x10, 0x14, 0x00000060, 0xffffffff,
SYSC_QUIRK_GPMC_DEBUG),
SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff,
SYSC_QUIRK_OPT_CLKS_NEEDED),
SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
......@@ -1814,6 +1820,14 @@ static void sysc_init_module_quirks(struct sysc *ddata)
return;
}
#ifdef CONFIG_OMAP_GPMC_DEBUG
if (ddata->cfg.quirks & SYSC_QUIRK_GPMC_DEBUG) {
ddata->cfg.quirks |= SYSC_QUIRK_NO_RESET_ON_INIT;
return;
}
#endif
if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) {
ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c;
ddata->post_reset_quirk = sysc_post_reset_quirk_i2c;
......@@ -1945,6 +1959,7 @@ static int sysc_reset(struct sysc *ddata)
*/
static int sysc_init_module(struct sysc *ddata)
{
bool rstctrl_deasserted = false;
int error = 0;
error = sysc_clockdomain_init(ddata);
......@@ -1969,6 +1984,7 @@ static int sysc_init_module(struct sysc *ddata)
error = reset_control_deassert(ddata->rsts);
if (error)
goto err_main_clocks;
rstctrl_deasserted = true;
}
ddata->revision = sysc_read_revision(ddata);
......@@ -1978,13 +1994,13 @@ static int sysc_init_module(struct sysc *ddata)
if (ddata->legacy_mode) {
error = sysc_legacy_init(ddata);
if (error)
goto err_reset;
goto err_main_clocks;
}
if (!ddata->legacy_mode) {
error = sysc_enable_module(ddata->dev);
if (error)
goto err_reset;
goto err_main_clocks;
}
error = sysc_reset(ddata);
......@@ -1994,10 +2010,6 @@ static int sysc_init_module(struct sysc *ddata)
if (error && !ddata->legacy_mode)
sysc_disable_module(ddata->dev);
err_reset:
if (error && !(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
err_main_clocks:
if (error)
sysc_disable_main_clocks(ddata);
......@@ -2008,6 +2020,10 @@ static int sysc_init_module(struct sysc *ddata)
sysc_clkdm_allow_idle(ddata);
}
if (error && rstctrl_deasserted &&
!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
return error;
}
......@@ -2909,6 +2925,9 @@ static int sysc_probe(struct platform_device *pdev)
if (!ddata)
return -ENOMEM;
ddata->offsets[SYSC_REVISION] = -ENODEV;
ddata->offsets[SYSC_SYSCONFIG] = -ENODEV;
ddata->offsets[SYSC_SYSSTATUS] = -ENODEV;
ddata->dev = &pdev->dev;
platform_set_drvdata(pdev, ddata);
......@@ -2975,9 +2994,6 @@ static int sysc_probe(struct platform_device *pdev)
}
/* Balance use counts as PM runtime should have enabled these all */
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
if (!(ddata->cfg.quirks &
(SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) {
sysc_disable_main_clocks(ddata);
......@@ -2985,6 +3001,9 @@ static int sysc_probe(struct platform_device *pdev)
sysc_clkdm_allow_idle(ddata);
}
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
sysc_show_registers(ddata);
ddata->dev->type = &sysc_device_type;
......
......@@ -19,6 +19,16 @@ config EXYNOS_AUDSS_CLK_CON
on some Exynos SoC variants. Choose M or Y here if you want to
use audio devices such as I2S, PCM, etc.
config EXYNOS_CLKOUT
tristate "Samsung Exynos clock output driver"
depends on COMMON_CLK_SAMSUNG
default y if ARCH_EXYNOS
help
Support for the clock output (XCLKOUT) present on some of Exynos SoC
variants. Usually the XCLKOUT is used to monitor the status of the
certains clocks from SoC, but it could also be tied to other devices
as an input clock.
# For S3C24XX platforms, select following symbols:
config S3C2410_COMMON_CLK
bool "Samsung S3C2410 clock controller support" if COMPILE_TEST
......
......@@ -15,7 +15,7 @@ obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o
obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o
obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
......
......@@ -9,10 +9,13 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#define EXYNOS_CLKOUT_NR_CLKS 1
#define EXYNOS_CLKOUT_PARENTS 32
......@@ -28,41 +31,103 @@ struct exynos_clkout {
struct clk_mux mux;
spinlock_t slock;
void __iomem *reg;
struct device_node *np;
u32 pmu_debug_save;
struct clk_hw_onecell_data data;
};
static struct exynos_clkout *clkout;
struct exynos_clkout_variant {
u32 mux_mask;
};
static int exynos_clkout_suspend(void)
{
clkout->pmu_debug_save = readl(clkout->reg + EXYNOS_PMU_DEBUG_REG);
static const struct exynos_clkout_variant exynos_clkout_exynos4 = {
.mux_mask = EXYNOS4_CLKOUT_MUX_MASK,
};
return 0;
}
static const struct exynos_clkout_variant exynos_clkout_exynos5 = {
.mux_mask = EXYNOS5_CLKOUT_MUX_MASK,
};
static void exynos_clkout_resume(void)
static const struct of_device_id exynos_clkout_ids[] = {
{
.compatible = "samsung,exynos3250-pmu",
.data = &exynos_clkout_exynos4,
}, {
.compatible = "samsung,exynos4210-pmu",
.data = &exynos_clkout_exynos4,
}, {
.compatible = "samsung,exynos4412-pmu",
.data = &exynos_clkout_exynos4,
}, {
.compatible = "samsung,exynos5250-pmu",
.data = &exynos_clkout_exynos5,
}, {
.compatible = "samsung,exynos5410-pmu",
.data = &exynos_clkout_exynos5,
}, {
.compatible = "samsung,exynos5420-pmu",
.data = &exynos_clkout_exynos5,
}, {
.compatible = "samsung,exynos5433-pmu",
.data = &exynos_clkout_exynos5,
}, { }
};
MODULE_DEVICE_TABLE(of, exynos_clkout_ids);
/*
* Device will be instantiated as child of PMU device without its own
* device node. Therefore match compatibles against parent.
*/
static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask)
{
writel(clkout->pmu_debug_save, clkout->reg + EXYNOS_PMU_DEBUG_REG);
}
const struct exynos_clkout_variant *variant;
const struct of_device_id *match;
static struct syscore_ops exynos_clkout_syscore_ops = {
.suspend = exynos_clkout_suspend,
.resume = exynos_clkout_resume,
};
if (!dev->parent) {
dev_err(dev, "not instantiated from MFD\n");
return -EINVAL;
}
match = of_match_device(exynos_clkout_ids, dev->parent);
if (!match) {
dev_err(dev, "cannot match parent device\n");
return -EINVAL;
}
variant = match->data;
static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
*mux_mask = variant->mux_mask;
return 0;
}
static int exynos_clkout_probe(struct platform_device *pdev)
{
const char *parent_names[EXYNOS_CLKOUT_PARENTS];
struct clk *parents[EXYNOS_CLKOUT_PARENTS];
int parent_count;
int ret;
int i;
struct exynos_clkout *clkout;
int parent_count, ret, i;
u32 mux_mask;
clkout = kzalloc(struct_size(clkout, data.hws, EXYNOS_CLKOUT_NR_CLKS),
GFP_KERNEL);
clkout = devm_kzalloc(&pdev->dev,
struct_size(clkout, data.hws, EXYNOS_CLKOUT_NR_CLKS),
GFP_KERNEL);
if (!clkout)
return;
return -ENOMEM;
ret = exynos_clkout_match_parent_dev(&pdev->dev, &mux_mask);
if (ret)
return ret;
clkout->np = pdev->dev.of_node;
if (!clkout->np) {
/*
* pdev->dev.parent was checked by exynos_clkout_match_parent_dev()
* so it is not NULL.
*/
clkout->np = pdev->dev.parent->of_node;
}
platform_set_drvdata(pdev, clkout);
spin_lock_init(&clkout->slock);
......@@ -71,7 +136,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
char name[] = "clkoutXX";
snprintf(name, sizeof(name), "clkout%d", i);
parents[i] = of_clk_get_by_name(node, name);
parents[i] = of_clk_get_by_name(clkout->np, name);
if (IS_ERR(parents[i])) {
parent_names[i] = "none";
continue;
......@@ -82,11 +147,13 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
}
if (!parent_count)
goto free_clkout;
return -EINVAL;
clkout->reg = of_iomap(node, 0);
if (!clkout->reg)
clkout->reg = of_iomap(clkout->np, 0);
if (!clkout->reg) {
ret = -ENODEV;
goto clks_put;
}
clkout->gate.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
clkout->gate.bit_idx = EXYNOS_CLKOUT_DISABLE_SHIFT;
......@@ -103,17 +170,17 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
&clk_mux_ops, NULL, NULL, &clkout->gate.hw,
&clk_gate_ops, CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT);
if (IS_ERR(clkout->data.hws[0]))
if (IS_ERR(clkout->data.hws[0])) {
ret = PTR_ERR(clkout->data.hws[0]);
goto err_unmap;
}
clkout->data.num = EXYNOS_CLKOUT_NR_CLKS;
ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, &clkout->data);
ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data);
if (ret)
goto err_clk_unreg;
register_syscore_ops(&exynos_clkout_syscore_ops);
return;
return 0;
err_clk_unreg:
clk_hw_unregister(clkout->data.hws[0]);
......@@ -123,38 +190,56 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i)
if (!IS_ERR(parents[i]))
clk_put(parents[i]);
free_clkout:
kfree(clkout);
pr_err("%s: failed to register clkout clock\n", __func__);
dev_err(&pdev->dev, "failed to register clkout clock\n");
return ret;
}
/*
* We use CLK_OF_DECLARE_DRIVER initialization method to avoid setting
* the OF_POPULATED flag on the pmu device tree node, so later the
* Exynos PMU platform device can be properly probed with PMU driver.
*/
static int exynos_clkout_remove(struct platform_device *pdev)
{
struct exynos_clkout *clkout = platform_get_drvdata(pdev);
of_clk_del_provider(clkout->np);
clk_hw_unregister(clkout->data.hws[0]);
iounmap(clkout->reg);
return 0;
}
static void __init exynos4_clkout_init(struct device_node *node)
static int __maybe_unused exynos_clkout_suspend(struct device *dev)
{
exynos_clkout_init(node, EXYNOS4_CLKOUT_MUX_MASK);
struct exynos_clkout *clkout = dev_get_drvdata(dev);
clkout->pmu_debug_save = readl(clkout->reg + EXYNOS_PMU_DEBUG_REG);
return 0;
}
CLK_OF_DECLARE_DRIVER(exynos4210_clkout, "samsung,exynos4210-pmu",
exynos4_clkout_init);
CLK_OF_DECLARE_DRIVER(exynos4412_clkout, "samsung,exynos4412-pmu",
exynos4_clkout_init);
CLK_OF_DECLARE_DRIVER(exynos3250_clkout, "samsung,exynos3250-pmu",
exynos4_clkout_init);
static void __init exynos5_clkout_init(struct device_node *node)
static int __maybe_unused exynos_clkout_resume(struct device *dev)
{
exynos_clkout_init(node, EXYNOS5_CLKOUT_MUX_MASK);
struct exynos_clkout *clkout = dev_get_drvdata(dev);
writel(clkout->pmu_debug_save, clkout->reg + EXYNOS_PMU_DEBUG_REG);
return 0;
}
CLK_OF_DECLARE_DRIVER(exynos5250_clkout, "samsung,exynos5250-pmu",
exynos5_clkout_init);
CLK_OF_DECLARE_DRIVER(exynos5410_clkout, "samsung,exynos5410-pmu",
exynos5_clkout_init);
CLK_OF_DECLARE_DRIVER(exynos5420_clkout, "samsung,exynos5420-pmu",
exynos5_clkout_init);
CLK_OF_DECLARE_DRIVER(exynos5433_clkout, "samsung,exynos5433-pmu",
exynos5_clkout_init);
static SIMPLE_DEV_PM_OPS(exynos_clkout_pm_ops, exynos_clkout_suspend,
exynos_clkout_resume);
static struct platform_driver exynos_clkout_driver = {
.driver = {
.name = "exynos-clkout",
.of_match_table = exynos_clkout_ids,
.pm = &exynos_clkout_pm_ops,
},
.probe = exynos_clkout_probe,
.remove = exynos_clkout_remove,
};
module_platform_driver(exynos_clkout_driver);
MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
MODULE_DESCRIPTION("Samsung Exynos clock output driver");
MODULE_LICENSE("GPL");
......@@ -266,6 +266,8 @@ static const char *enable_init_clks[] = {
"dpll_ddr_m2_ck",
"dpll_mpu_m2_ck",
"l3_gclk",
/* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */
"l3-clkctrl:00bc:0",
"l4hs_gclk",
"l4fw_gclk",
"l4ls_gclk",
......
......@@ -155,8 +155,7 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int part_id)
static const struct of_device_id compatible_machine_match[] = {
{ .compatible = "arm,vexpress,v2p-ca15_a7" },
{ .compatible = "samsung,exynos5420" },
{ .compatible = "samsung,exynos5800" },
{ .compatible = "google,peach" },
{},
};
......
......@@ -1474,17 +1474,17 @@ int scmi_notification_init(struct scmi_handle *handle)
ni->gid = gid;
ni->handle = handle;
ni->registered_protocols = devm_kcalloc(handle->dev, SCMI_MAX_PROTO,
sizeof(char *), GFP_KERNEL);
if (!ni->registered_protocols)
goto err;
ni->notify_wq = alloc_workqueue(dev_name(handle->dev),
WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
0);
if (!ni->notify_wq)
goto err;
ni->registered_protocols = devm_kcalloc(handle->dev, SCMI_MAX_PROTO,
sizeof(char *), GFP_KERNEL);
if (!ni->registered_protocols)
goto err;
mutex_init(&ni->pending_mtx);
hash_init(ni->pending_events_handlers);
......
This diff is collapsed.
......@@ -60,22 +60,40 @@ static void imx_dsp_handle_rx(struct mbox_client *c, void *msg)
}
}
static int imx_dsp_probe(struct platform_device *pdev)
struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *dsp_ipc, int idx)
{
struct device *dev = &pdev->dev;
struct imx_dsp_ipc *dsp_ipc;
struct imx_dsp_chan *dsp_chan;
if (idx >= DSP_MU_CHAN_NUM)
return ERR_PTR(-EINVAL);
dsp_chan = &dsp_ipc->chans[idx];
dsp_chan->ch = mbox_request_channel_byname(&dsp_chan->cl, dsp_chan->name);
return dsp_chan->ch;
}
EXPORT_SYMBOL(imx_dsp_request_channel);
void imx_dsp_free_channel(struct imx_dsp_ipc *dsp_ipc, int idx)
{
struct imx_dsp_chan *dsp_chan;
if (idx >= DSP_MU_CHAN_NUM)
return;
dsp_chan = &dsp_ipc->chans[idx];
mbox_free_channel(dsp_chan->ch);
}
EXPORT_SYMBOL(imx_dsp_free_channel);
static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc)
{
struct device *dev = dsp_ipc->dev;
struct imx_dsp_chan *dsp_chan;
struct mbox_client *cl;
char *chan_name;
int ret;
int i, j;
device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL);
if (!dsp_ipc)
return -ENOMEM;
for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
if (i < 2)
chan_name = kasprintf(GFP_KERNEL, "txdb%d", i);
......@@ -86,6 +104,7 @@ static int imx_dsp_probe(struct platform_device *pdev)
return -ENOMEM;
dsp_chan = &dsp_ipc->chans[i];
dsp_chan->name = chan_name;
cl = &dsp_chan->cl;
cl->dev = dev;
cl->tx_block = false;
......@@ -104,27 +123,43 @@ static int imx_dsp_probe(struct platform_device *pdev)
}
dev_dbg(dev, "request mbox chan %s\n", chan_name);
/* chan_name is not used anymore by framework */
kfree(chan_name);
}
dsp_ipc->dev = dev;
dev_set_drvdata(dev, dsp_ipc);
dev_info(dev, "NXP i.MX DSP IPC initialized\n");
return 0;
out:
kfree(chan_name);
for (j = 0; j < i; j++) {
dsp_chan = &dsp_ipc->chans[j];
mbox_free_channel(dsp_chan->ch);
kfree(dsp_chan->name);
}
return ret;
}
static int imx_dsp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct imx_dsp_ipc *dsp_ipc;
int ret;
device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL);
if (!dsp_ipc)
return -ENOMEM;
dsp_ipc->dev = dev;
dev_set_drvdata(dev, dsp_ipc);
ret = imx_dsp_setup_channels(dsp_ipc);
if (ret < 0)
return ret;
dev_info(dev, "NXP i.MX DSP IPC initialized\n");
return 0;
}
static int imx_dsp_remove(struct platform_device *pdev)
{
struct imx_dsp_chan *dsp_chan;
......@@ -136,6 +171,7 @@ static int imx_dsp_remove(struct platform_device *pdev)
for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
dsp_chan = &dsp_ipc->chans[i];
mbox_free_channel(dsp_chan->ch);
kfree(dsp_chan->name);
}
return 0;
......
......@@ -160,12 +160,18 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
{ "mipi0-pwm0", IMX_SC_R_MIPI_0_PWM_0, 1, false, 0 },
{ "mipi0-i2c", IMX_SC_R_MIPI_0_I2C_0, 2, true, 0 },
{ "mipi1", IMX_SC_R_MIPI_1, 1, false, 0 },
{ "mipi1-pwm0", IMX_SC_R_MIPI_1_PWM_0, 1, false, 0 },
{ "mipi1-i2c", IMX_SC_R_MIPI_1_I2C_0, 2, true, 0 },
/* LVDS SS */
{ "lvds0", IMX_SC_R_LVDS_0, 1, false, 0 },
{ "lvds1", IMX_SC_R_LVDS_1, 1, false, 0 },
/* DC SS */
{ "dc0", IMX_SC_R_DC_0, 1, false, 0 },
{ "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, true, 0 },
{ "dc0-video", IMX_SC_R_DC_0_VIDEO0, 2, true, 0 },
/* CM40 SS */
{ "cm40-i2c", IMX_SC_R_M4_0_I2C, 1, false, 0 },
......@@ -180,6 +186,12 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
{ "cm41-pid", IMX_SC_R_M4_1_PID0, 5, true, 0},
{ "cm41-mu-a1", IMX_SC_R_M4_1_MU_1A, 1, false, 0},
{ "cm41-lpuart", IMX_SC_R_M4_1_UART, 1, false, 0},
/* IMAGE SS */
{ "img-jpegdec-mp", IMX_SC_R_MJPEG_DEC_MP, 1, false, 0 },
{ "img-jpegdec-s0", IMX_SC_R_MJPEG_DEC_S0, 4, true, 0 },
{ "img-jpegenc-mp", IMX_SC_R_MJPEG_ENC_MP, 1, false, 0 },
{ "img-jpegenc-s0", IMX_SC_R_MJPEG_ENC_S0, 4, true, 0 },
};
static const struct imx_sc_pd_soc imx8qxp_scu_pd = {
......
......@@ -3,8 +3,9 @@
# Amlogic Secure Monitor driver
#
config MESON_SM
bool
default ARCH_MESON
tristate "Amlogic Secure Monitor driver"
depends on ARCH_MESON || COMPILE_TEST
default y
depends on ARM64_4K_PAGES
help
Say y here to enable the Amlogic secure monitor driver
......@@ -331,3 +331,4 @@ static struct platform_driver meson_sm_driver = {
},
};
module_platform_driver_probe(meson_sm_driver, meson_sm_probe);
MODULE_LICENSE("GPL v2");
......@@ -412,16 +412,12 @@ static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
goto out;
}
len = strlen(ppath) + strlen(name) + 1;
len = snprintf(pathbuf, pathlen, "%s%s/", ppath, name);
if (len >= pathlen) {
err = -EINVAL;
goto out;
}
strncpy(pathbuf, ppath, pathlen);
strncat(pathbuf, name, strlen(name));
strcat(pathbuf, "/");
err = bpmp_populate_debugfs_inband(bpmp, dentry,
pathbuf);
if (err < 0)
......
This diff is collapsed.
......@@ -49,7 +49,6 @@
#define TI_SCI_MSG_RM_RING_RECONFIG 0x1102
#define TI_SCI_MSG_RM_RING_RESET 0x1103
#define TI_SCI_MSG_RM_RING_CFG 0x1110
#define TI_SCI_MSG_RM_RING_GET_CFG 0x1111
/* PSI-L requests */
#define TI_SCI_MSG_RM_PSIL_PAIR 0x1280
......@@ -574,8 +573,10 @@ struct ti_sci_msg_req_get_resource_range {
/**
* struct ti_sci_msg_resp_get_resource_range - Response to resource get range.
* @hdr: Generic Header
* @range_start: Start index of the resource range.
* @range_num: Number of resources in the range.
* @range_start: Start index of the first resource range.
* @range_num: Number of resources in the first range.
* @range_start_sec: Start index of the second resource range.
* @range_num_sec: Number of resources in the second range.
*
* Response to request TI_SCI_MSG_GET_RESOURCE_RANGE.
*/
......@@ -583,6 +584,8 @@ struct ti_sci_msg_resp_get_resource_range {
struct ti_sci_msg_hdr hdr;
u16 range_start;
u16 range_num;
u16 range_start_sec;
u16 range_num_sec;
} __packed;
/**
......@@ -656,6 +659,8 @@ struct ti_sci_msg_req_manage_irq {
* 3 - Valid bit for @tisci_msg_rm_ring_cfg_req mode
* 4 - Valid bit for @tisci_msg_rm_ring_cfg_req size
* 5 - Valid bit for @tisci_msg_rm_ring_cfg_req order_id
* 6 - Valid bit for @tisci_msg_rm_ring_cfg_req virtid
* 7 - Valid bit for @tisci_msg_rm_ring_cfg_req ASEL
* @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
* @index: ring index to be configured.
* @addr_lo: 32 LSBs of ring base address to be programmed into the ring's
......@@ -669,6 +674,9 @@ struct ti_sci_msg_req_manage_irq {
* the formula (log2(size_bytes) - 2), where size_bytes cannot be
* greater than 256.
* @order_id: Specifies the ring's bus order ID.
* @virtid: Ring virt ID value
* @asel: Ring ASEL (address select) value to be set into the ASEL field of the
* ring's RING_BA_HI register.
*/
struct ti_sci_msg_rm_ring_cfg_req {
struct ti_sci_msg_hdr hdr;
......@@ -681,49 +689,8 @@ struct ti_sci_msg_rm_ring_cfg_req {
u8 mode;
u8 size;
u8 order_id;
} __packed;
/**
* struct ti_sci_msg_rm_ring_get_cfg_req - Get RA ring's configuration
*
* Gets the configuration of the non-real-time register fields of a ring. The
* host, or a supervisor of the host, who owns the ring must be the requesting
* host. The values of the non-real-time registers are returned in
* @ti_sci_msg_rm_ring_get_cfg_resp.
*
* @hdr: Generic Header
* @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
* @index: ring index.
*/
struct ti_sci_msg_rm_ring_get_cfg_req {
struct ti_sci_msg_hdr hdr;
u16 nav_id;
u16 index;
} __packed;
/**
* struct ti_sci_msg_rm_ring_get_cfg_resp - Ring get configuration response
*
* Response received by host processor after RM has handled
* @ti_sci_msg_rm_ring_get_cfg_req. The response contains the ring's
* non-real-time register values.
*
* @hdr: Generic Header
* @addr_lo: Ring 32 LSBs of base address
* @addr_hi: Ring 16 MSBs of base address.
* @count: Ring number of elements.
* @mode: Ring mode.
* @size: encoded Ring element size
* @order_id: ing order ID.
*/
struct ti_sci_msg_rm_ring_get_cfg_resp {
struct ti_sci_msg_hdr hdr;
u32 addr_lo;
u32 addr_hi;
u32 count;
u8 mode;
u8 size;
u8 order_id;
u16 virtid;
u8 asel;
} __packed;
/**
......@@ -910,6 +877,8 @@ struct rm_ti_sci_msg_udmap_rx_flow_opt_cfg {
* 12 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_credit_count
* 13 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::fdepth
* 14 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_burst_size
* 15 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_tdtype
* 16 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::extended_ch_type
*
* @nav_id: SoC device ID of Navigator Subsystem where tx channel is located
*
......@@ -973,6 +942,15 @@ struct rm_ti_sci_msg_udmap_rx_flow_opt_cfg {
*
* @tx_burst_size: UDMAP transmit channel burst size configuration to be
* programmed into the tx_burst_size field of the TCHAN_TCFG register.
*
* @tx_tdtype: UDMAP transmit channel teardown type configuration to be
* programmed into the tdtype field of the TCHAN_TCFG register:
* 0 - Return immediately
* 1 - Wait for completion message from remote peer
*
* @extended_ch_type: Valid for BCDMA.
* 0 - the channel is split tx channel (tchan)
* 1 - the channel is block copy channel (bchan)
*/
struct ti_sci_msg_rm_udmap_tx_ch_cfg_req {
struct ti_sci_msg_hdr hdr;
......@@ -994,6 +972,8 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg_req {
u16 fdepth;
u8 tx_sched_priority;
u8 tx_burst_size;
u8 tx_tdtype;
u8 extended_ch_type;
} __packed;
/**
......
......@@ -615,13 +615,13 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_data);
/**
* zynqmp_pm_set_sd_tapdelay() - Set tap delay for the SD device
*
* @node_id Node ID of the device
* @type Type of tap delay to set (input/output)
* @value Value to set fot the tap delay
* @node_id: Node ID of the device
* @type: Type of tap delay to set (input/output)
* @value: Value to set fot the tap delay
*
* This function sets input/output tap delay for the SD device.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value)
{
......@@ -633,12 +633,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
/**
* zynqmp_pm_sd_dll_reset() - Reset DLL logic
*
* @node_id Node ID of the device
* @type Reset type
* @node_id: Node ID of the device
* @type: Reset type
*
* This function resets DLL logic for the SD device.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
{
......@@ -649,12 +649,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
/**
* zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs)
* @index GGS register index
* @value Register value to be written
* @index: GGS register index
* @value: Register value to be written
*
* This function writes value to GGS register.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_write_ggs(u32 index, u32 value)
{
......@@ -665,12 +665,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);
/**
* zynqmp_pm_write_ggs() - PM API for reading global general storage (ggs)
* @index GGS register index
* @value Register value to be written
* @index: GGS register index
* @value: Register value to be written
*
* This function returns GGS register value.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_read_ggs(u32 index, u32 *value)
{
......@@ -682,12 +682,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs);
/**
* zynqmp_pm_write_pggs() - PM API for writing persistent global general
* storage (pggs)
* @index PGGS register index
* @value Register value to be written
* @index: PGGS register index
* @value: Register value to be written
*
* This function writes value to PGGS register.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_write_pggs(u32 index, u32 value)
{
......@@ -699,12 +699,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
/**
* zynqmp_pm_write_pggs() - PM API for reading persistent global general
* storage (pggs)
* @index PGGS register index
* @value Register value to be written
* @index: PGGS register index
* @value: Register value to be written
*
* This function returns PGGS register value.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_read_pggs(u32 index, u32 *value)
{
......@@ -715,12 +715,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);
/**
* zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status
* @value Status value to be written
* @value: Status value to be written
*
* This function sets healthy bit value to indicate boot health status
* to firmware.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_set_boot_health_status(u32 value)
{
......@@ -815,10 +815,10 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status);
* zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
* master has initialized its own power management
*
* Return: Returns status, either success or error+reason
*
* This API function is to be used for notify the power management controller
* about the completed power management initialization.
*
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_init_finalize(void)
{
......
......@@ -829,8 +829,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
mtk_crtc->cmdq_client =
cmdq_mbox_create(mtk_crtc->mmsys_dev,
drm_crtc_index(&mtk_crtc->base),
2000);
drm_crtc_index(&mtk_crtc->base));
if (IS_ERR(mtk_crtc->cmdq_client)) {
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
drm_crtc_index(&mtk_crtc->base));
......
......@@ -7,6 +7,7 @@
#define MTK_DRM_DDP_COMP_H
#include <linux/io.h>
#include <linux/soc/mediatek/mtk-mmsys.h>
struct device;
struct device_node;
......@@ -35,39 +36,6 @@ enum mtk_ddp_comp_type {
MTK_DDP_COMP_TYPE_MAX,
};
enum mtk_ddp_comp_id {
DDP_COMPONENT_AAL0,
DDP_COMPONENT_AAL1,
DDP_COMPONENT_BLS,
DDP_COMPONENT_CCORR,
DDP_COMPONENT_COLOR0,
DDP_COMPONENT_COLOR1,
DDP_COMPONENT_DITHER,
DDP_COMPONENT_DPI0,
DDP_COMPONENT_DPI1,
DDP_COMPONENT_DSI0,
DDP_COMPONENT_DSI1,
DDP_COMPONENT_DSI2,
DDP_COMPONENT_DSI3,
DDP_COMPONENT_GAMMA,
DDP_COMPONENT_OD0,
DDP_COMPONENT_OD1,
DDP_COMPONENT_OVL0,
DDP_COMPONENT_OVL_2L0,
DDP_COMPONENT_OVL_2L1,
DDP_COMPONENT_OVL1,
DDP_COMPONENT_PWM0,
DDP_COMPONENT_PWM1,
DDP_COMPONENT_PWM2,
DDP_COMPONENT_RDMA0,
DDP_COMPONENT_RDMA1,
DDP_COMPONENT_RDMA2,
DDP_COMPONENT_UFOE,
DDP_COMPONENT_WDMA0,
DDP_COMPONENT_WDMA1,
DDP_COMPONENT_ID_MAX,
};
struct mtk_ddp_comp;
struct cmdq_pkt;
struct mtk_ddp_comp_funcs {
......
......@@ -805,25 +805,6 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
ret = of_dma_configure(drm->dev, dev->of_node, true);
if (ret)
return ret;
} else {
/*
* If we don't have the interconnect property, most likely
* because of an old DT, we need to set the DMA offset by hand
* on our device since the RAM mapping is at 0 for the DMA bus,
* unlike the CPU.
*
* XXX(hch): this has no business in a driver and needs to move
* to the device tree.
*
* If we have two subsequent calls to dma_direct_set_offset
* returns -EINVAL. Unfortunately, this happens when we have two
* backends in the system, and will result in the driver
* reporting an error while it has been setup properly before.
* Ignore EINVAL, but it should really be removed eventually.
*/
ret = dma_direct_set_offset(drm->dev, PHYS_OFFSET, 0, SZ_4G);
if (ret && ret != -EINVAL)
return ret;
}
backend->engine.node = dev->of_node;
......
......@@ -30,7 +30,7 @@ static inline u64 __pow10(u8 x)
static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
{
s8 scale = sensor->scale;
int scale = sensor->scale;
u64 f;
switch (sensor->type) {
......
......@@ -167,33 +167,6 @@ static int sun4i_csi_probe(struct platform_device *pdev)
if (!csi->traits)
return -EINVAL;
/*
* On Allwinner SoCs, some high memory bandwidth devices do DMA
* directly over the memory bus (called MBUS), instead of the
* system bus. The memory bus has a different addressing scheme
* without the DRAM starting offset.
*
* In some cases this can be described by an interconnect in
* the device tree. In other cases where the hardware is not
* fully understood and the interconnect is left out of the
* device tree, fall back to a default offset.
*/
if (of_find_property(csi->dev->of_node, "interconnects", NULL)) {
ret = of_dma_configure(csi->dev, csi->dev->of_node, true);
if (ret)
return ret;
} else {
/*
* XXX(hch): this has no business in a driver and needs to move
* to the device tree.
*/
#ifdef PHYS_PFN_OFFSET
ret = dma_direct_set_offset(csi->dev, PHYS_OFFSET, 0, SZ_4G);
if (ret)
return ret;
#endif
}
csi->mdev.dev = csi->dev;
strscpy(csi->mdev.model, "Allwinner Video Capture Device",
sizeof(csi->mdev.model));
......
......@@ -881,14 +881,6 @@ static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev,
return 0;
}
/*
* PHYS_OFFSET isn't available on all architectures. In order to
* accommodate for COMPILE_TEST, let's define it to something dumb.
*/
#if defined(CONFIG_COMPILE_TEST) && !defined(PHYS_OFFSET)
#define PHYS_OFFSET 0
#endif
static int sun6i_csi_probe(struct platform_device *pdev)
{
struct sun6i_csi_dev *sdev;
......@@ -899,15 +891,6 @@ static int sun6i_csi_probe(struct platform_device *pdev)
return -ENOMEM;
sdev->dev = &pdev->dev;
/*
* The DMA bus has the memory mapped at 0.
*
* XXX(hch): this has no business in a driver and needs to move
* to the device tree.
*/
ret = dma_direct_set_offset(sdev->dev, PHYS_OFFSET, 0, SZ_4G);
if (ret)
return ret;
ret = sun6i_csi_resource_request(sdev, pdev);
if (ret)
......
......@@ -825,10 +825,6 @@ static int deinterlace_probe(struct platform_device *pdev)
return ret;
}
ret = of_dma_configure(dev->dev, dev->dev->of_node, true);
if (ret)
return ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dev->base))
......
......@@ -128,7 +128,7 @@ config OMAP_GPMC_DEBUG
config TI_EMIF_SRAM
tristate "Texas Instruments EMIF SRAM driver"
depends on SOC_AM33XX || SOC_AM43XX || (ARM && COMPILE_TEST)
depends on SOC_AM33XX || SOC_AM43XX || (ARM && CPU_V7 && COMPILE_TEST)
depends on SRAM
help
This driver is for the EMIF module available on Texas Instruments
......@@ -191,8 +191,8 @@ config DA8XX_DDRCTL
config PL353_SMC
tristate "ARM PL35X Static Memory Controller(SMC) driver"
default y if ARM
depends on ARM
depends on ARM_AMBA || COMPILE_TEST
depends on ARM || COMPILE_TEST
depends on ARM_AMBA
help
This driver is for the ARM PL351/PL353 Static Memory
Controller(SMC) module.
......
......@@ -291,6 +291,8 @@ static int jz4780_nemc_probe(struct platform_device *pdev)
nemc->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
/*
* The driver currently only uses the registers up to offset
......@@ -304,9 +306,9 @@ static int jz4780_nemc_probe(struct platform_device *pdev)
}
nemc->base = devm_ioremap(dev, res->start, NEMC_REG_LEN);
if (IS_ERR(nemc->base)) {
if (!nemc->base) {
dev_err(dev, "failed to get I/O memory\n");
return PTR_ERR(nemc->base);
return -ENOMEM;
}
writel(0, nemc->base + NEMC_NFCSR);
......
......@@ -268,6 +268,10 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
/* IPU0 | IPU1 | CCU */
};
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
.config_port = mtk_smi_larb_config_port_gen2_general,
};
static const struct of_device_id mtk_smi_larb_of_ids[] = {
{
.compatible = "mediatek,mt8167-smi-larb",
......@@ -293,6 +297,10 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
.compatible = "mediatek,mt8183-smi-larb",
.data = &mtk_smi_larb_mt8183
},
{
.compatible = "mediatek,mt8192-smi-larb",
.data = &mtk_smi_larb_mt8192
},
{}
};
......@@ -432,6 +440,13 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
F_MMU1_LARB(7),
};
static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
.gen = MTK_SMI_GEN2,
.has_gals = true,
.bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
F_MMU1_LARB(6),
};
static const struct of_device_id mtk_smi_common_of_ids[] = {
{
.compatible = "mediatek,mt8173-smi-common",
......@@ -457,6 +472,10 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
.compatible = "mediatek,mt8183-smi-common",
.data = &mtk_smi_common_mt8183,
},
{
.compatible = "mediatek,mt8192-smi-common",
.data = &mtk_smi_common_mt8192,
},
{}
};
......
......@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
......@@ -204,18 +203,6 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
}
EXPORT_SYMBOL(rpcif_sw_init);
void rpcif_enable_rpm(struct rpcif *rpc)
{
pm_runtime_enable(rpc->dev);
}
EXPORT_SYMBOL(rpcif_enable_rpm);
void rpcif_disable_rpm(struct rpcif *rpc)
{
pm_runtime_put_sync(rpc->dev);
}
EXPORT_SYMBOL(rpcif_disable_rpm);
void rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
{
u32 dummy;
......@@ -508,7 +495,8 @@ int rpcif_manual_xfer(struct rpcif *rpc)
return ret;
err_out:
ret = reset_control_reset(rpc->rstc);
if (reset_control_reset(rpc->rstc))
dev_err(rpc->dev, "Failed to reset HW\n");
rpcif_hw_init(rpc, rpc->bus_size == 2);
goto exit;
}
......@@ -560,9 +548,11 @@ static int rpcif_probe(struct platform_device *pdev)
} else if (of_device_is_compatible(flash, "cfi-flash")) {
name = "rpc-if-hyperflash";
} else {
of_node_put(flash);
dev_warn(&pdev->dev, "unknown flash type\n");
return -ENODEV;
}
of_node_put(flash);
vdev = platform_device_alloc(name, pdev->id);
if (!vdev)
......
......@@ -3,14 +3,17 @@ config TEGRA_MC
bool "NVIDIA Tegra Memory Controller support"
default y
depends on ARCH_TEGRA
select INTERCONNECT
help
This driver supports the Memory Controller (MC) hardware found on
NVIDIA Tegra SoCs.
config TEGRA20_EMC
bool "NVIDIA Tegra20 External Memory Controller driver"
tristate "NVIDIA Tegra20 External Memory Controller driver"
default y
depends on ARCH_TEGRA_2x_SOC
depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select PM_DEVFREQ
help
This driver is for the External Memory Controller (EMC) found on
Tegra20 chips. The EMC controls the external DRAM on the board.
......@@ -18,9 +21,10 @@ config TEGRA20_EMC
external memory.
config TEGRA30_EMC
bool "NVIDIA Tegra30 External Memory Controller driver"
tristate "NVIDIA Tegra30 External Memory Controller driver"
default y
depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
select PM_OPP
help
This driver is for the External Memory Controller (EMC) found on
Tegra30 chips. The EMC controls the external DRAM on the board.
......
......@@ -6,6 +6,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
......@@ -42,6 +43,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
static void tegra_mc_devm_action_put_device(void *data)
{
struct tegra_mc *mc = data;
put_device(mc->dev);
}
/**
* devm_tegra_memory_controller_get() - get Tegra Memory Controller handle
* @dev: device pointer for the consumer device
*
* This function will search for the Memory Controller node in a device-tree
* and retrieve the Memory Controller handle.
*
* Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
*/
struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev)
{
struct platform_device *pdev;
struct device_node *np;
struct tegra_mc *mc;
int err;
np = of_parse_phandle(dev->of_node, "nvidia,memory-controller", 0);
if (!np)
return ERR_PTR(-ENOENT);
pdev = of_find_device_by_node(np);
of_node_put(np);
if (!pdev)
return ERR_PTR(-ENODEV);
mc = platform_get_drvdata(pdev);
if (!mc) {
put_device(&pdev->dev);
return ERR_PTR(-EPROBE_DEFER);
}
err = devm_add_action(dev, tegra_mc_devm_action_put_device, mc);
if (err) {
put_device(mc->dev);
return ERR_PTR(err);
}
return mc;
}
EXPORT_SYMBOL_GPL(devm_tegra_memory_controller_get);
static int tegra_mc_block_dma_common(struct tegra_mc *mc,
const struct tegra_mc_reset *rst)
{
......@@ -298,6 +347,7 @@ int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
return 0;
}
EXPORT_SYMBOL_GPL(tegra_mc_write_emem_configuration);
unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
{
......@@ -309,6 +359,7 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
return dram_count;
}
EXPORT_SYMBOL_GPL(tegra_mc_get_emem_device_count);
static int load_one_timing(struct tegra_mc *mc,
struct tegra_mc_timing *timing,
......@@ -591,6 +642,101 @@ static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
return IRQ_HANDLED;
}
/*
* Memory Controller (MC) has few Memory Clients that are issuing memory
* bandwidth allocation requests to the MC interconnect provider. The MC
* provider aggregates the requests and then sends the aggregated request
* up to the External Memory Controller (EMC) interconnect provider which
* re-configures hardware interface to External Memory (EMEM) in accordance
* to the required bandwidth. Each MC interconnect node represents an
* individual Memory Client.
*
* Memory interconnect topology:
*
* +----+
* +--------+ | |
* | TEXSRD +--->+ |
* +--------+ | |
* | | +-----+ +------+
* ... | MC +--->+ EMC +--->+ EMEM |
* | | +-----+ +------+
* +--------+ | |
* | DISP.. +--->+ |
* +--------+ | |
* +----+
*/
static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
{
struct icc_node *node;
unsigned int i;
int err;
/* older device-trees don't have interconnect properties */
if (!device_property_present(mc->dev, "#interconnect-cells") ||
!mc->soc->icc_ops)
return 0;
mc->provider.dev = mc->dev;
mc->provider.data = &mc->provider;
mc->provider.set = mc->soc->icc_ops->set;
mc->provider.aggregate = mc->soc->icc_ops->aggregate;
mc->provider.xlate_extended = mc->soc->icc_ops->xlate_extended;
err = icc_provider_add(&mc->provider);
if (err)
return err;
/* create Memory Controller node */
node = icc_node_create(TEGRA_ICC_MC);
if (IS_ERR(node)) {
err = PTR_ERR(node);
goto del_provider;
}
node->name = "Memory Controller";
icc_node_add(node, &mc->provider);
/* link Memory Controller to External Memory Controller */
err = icc_link_create(node, TEGRA_ICC_EMC);
if (err)
goto remove_nodes;
for (i = 0; i < mc->soc->num_clients; i++) {
/* create MC client node */
node = icc_node_create(mc->soc->clients[i].id);
if (IS_ERR(node)) {
err = PTR_ERR(node);
goto remove_nodes;
}
node->name = mc->soc->clients[i].name;
icc_node_add(node, &mc->provider);
/* link Memory Client to Memory Controller */
err = icc_link_create(node, TEGRA_ICC_MC);
if (err)
goto remove_nodes;
}
/*
* MC driver is registered too early, so early that generic driver
* syncing doesn't work for the MC. But it doesn't really matter
* since syncing works for the EMC drivers, hence we can sync the
* MC driver by ourselves and then EMC will complete syncing of
* the whole ICC state.
*/
icc_sync_state(mc->dev);
return 0;
remove_nodes:
icc_nodes_remove(&mc->provider);
del_provider:
icc_provider_del(&mc->provider);
return err;
}
static int tegra_mc_probe(struct platform_device *pdev)
{
struct resource *res;
......@@ -659,10 +805,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
}
mc->irq = platform_get_irq(pdev, 0);
if (mc->irq < 0) {
dev_err(&pdev->dev, "interrupt not specified\n");
if (mc->irq < 0)
return mc->irq;
}
WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n");
......@@ -681,6 +825,11 @@ static int tegra_mc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to register reset controller: %d\n",
err);
err = tegra_mc_interconnect_setup(mc);
if (err < 0)
dev_err(&pdev->dev, "failed to initialize interconnect: %d\n",
err);
if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU) && mc->soc->smmu) {
mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc);
if (IS_ERR(mc->smmu)) {
......
......@@ -78,6 +78,20 @@
#define MC_TIMING_UPDATE BIT(0)
static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
{
val = val * percents;
do_div(val, 100);
return min_t(u64, val, U32_MAX);
}
static inline struct tegra_mc *
icc_provider_to_tegra_mc(struct icc_provider *provider)
{
return container_of(provider, struct tegra_mc, provider);
}
static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
{
return readl_relaxed(mc->regs + offset);
......@@ -115,4 +129,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
extern const struct tegra_mc_soc tegra210_mc_soc;
#endif
/*
* These IDs are for internal use of Tegra ICC drivers. The ID numbers are
* chosen such that they don't conflict with the device-tree ICC node IDs.
*/
#define TEGRA_ICC_MC 1000
#define TEGRA_ICC_EMC 1001
#define TEGRA_ICC_EMEM 1002
#endif /* MEMORY_TEGRA_MC_H */
......@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra114_mc_clients[] = {
.id = 0x00,
.name = "ptcr",
.swgroup = TEGRA_SWGROUP_PTC,
.la = {
.reg = 0x34c,
.shift = 0,
.mask = 0xff,
.def = 0x0,
},
}, {
.id = 0x01,
.name = "display0a",
......
......@@ -1177,10 +1177,8 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc)
static int tegra_emc_probe(struct platform_device *pdev)
{
struct platform_device *mc;
struct device_node *np;
struct tegra_emc *emc;
struct resource *res;
u32 ram_code;
int err;
......@@ -1190,25 +1188,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
emc->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
emc->regs = devm_ioremap_resource(&pdev->dev, res);
emc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(emc->regs))
return PTR_ERR(emc->regs);
np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
if (!np) {
dev_err(&pdev->dev, "could not get memory controller\n");
return -ENOENT;
}
mc = of_find_device_by_node(np);
of_node_put(np);
if (!mc)
return -ENOENT;
emc->mc = platform_get_drvdata(mc);
if (!emc->mc)
return -EPROBE_DEFER;
emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
if (IS_ERR(emc->mc))
return PTR_ERR(emc->mc);
ram_code = tegra_read_ram_code();
......
......@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra124_mc_clients[] = {
.id = 0x00,
.name = "ptcr",
.swgroup = TEGRA_SWGROUP_PTC,
.la = {
.reg = 0x34c,
.shift = 0,
.mask = 0xff,
.def = 0x0,
},
}, {
.id = 0x01,
.name = "display0a",
......
This diff is collapsed.
......@@ -3,6 +3,10 @@
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <dt-bindings/memory/tegra20-mc.h>
#include "mc.h"
......@@ -280,6 +284,78 @@ static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
.reset_status = tegra20_mc_reset_status,
};
static int tegra20_mc_icc_set(struct icc_node *src, struct icc_node *dst)
{
/*
* It should be possible to tune arbitration knobs here, but the
* default values are known to work well on all devices. Hence
* nothing to do here so far.
*/
return 0;
}
static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
{
/*
* ISO clients need to reserve extra bandwidth up-front because
* there could be high bandwidth pressure during initial filling
* of the client's FIFO buffers. Secondly, we need to take into
* account impurities of the memory subsystem.
*/
if (tag & TEGRA_MC_ICC_TAG_ISO)
peak_bw = tegra_mc_scale_percents(peak_bw, 300);
*agg_avg += avg_bw;
*agg_peak = max(*agg_peak, peak_bw);
return 0;
}
static struct icc_node_data *
tegra20_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
{
struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
unsigned int i, idx = spec->args[0];
struct icc_node_data *ndata;
struct icc_node *node;
list_for_each_entry(node, &mc->provider.nodes, node_list) {
if (node->id != idx)
continue;
ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
if (!ndata)
return ERR_PTR(-ENOMEM);
ndata->node = node;
/* these clients are isochronous by default */
if (strstarts(node->name, "display") ||
strstarts(node->name, "vi"))
ndata->tag = TEGRA_MC_ICC_TAG_ISO;
else
ndata->tag = TEGRA_MC_ICC_TAG_DEFAULT;
return ndata;
}
for (i = 0; i < mc->soc->num_clients; i++) {
if (mc->soc->clients[i].id == idx)
return ERR_PTR(-EPROBE_DEFER);
}
dev_err(mc->dev, "invalid ICC client ID %u\n", idx);
return ERR_PTR(-EINVAL);
}
static const struct tegra_mc_icc_ops tegra20_mc_icc_ops = {
.xlate_extended = tegra20_mc_of_icc_xlate_extended,
.aggregate = tegra20_mc_icc_aggreate,
.set = tegra20_mc_icc_set,
};
const struct tegra_mc_soc tegra20_mc_soc = {
.clients = tegra20_mc_clients,
.num_clients = ARRAY_SIZE(tegra20_mc_clients),
......@@ -290,4 +366,5 @@ const struct tegra_mc_soc tegra20_mc_soc = {
.reset_ops = &tegra20_mc_reset_ops,
.resets = tegra20_mc_resets,
.num_resets = ARRAY_SIZE(tegra20_mc_resets),
.icc_ops = &tegra20_mc_icc_ops,
};
......@@ -1828,7 +1828,6 @@ static int tegra210_emc_probe(struct platform_device *pdev)
{
struct thermal_cooling_device *cd;
unsigned long current_rate;
struct platform_device *mc;
struct tegra210_emc *emc;
struct device_node *np;
unsigned int i;
......@@ -1846,35 +1845,19 @@ static int tegra210_emc_probe(struct platform_device *pdev)
spin_lock_init(&emc->lock);
emc->dev = &pdev->dev;
np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
if (!np) {
dev_err(&pdev->dev, "could not get memory controller\n");
return -ENOENT;
}
mc = of_find_device_by_node(np);
of_node_put(np);
if (!mc)
return -ENOENT;
emc->mc = platform_get_drvdata(mc);
if (!emc->mc) {
put_device(&mc->dev);
return -EPROBE_DEFER;
}
emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
if (IS_ERR(emc->mc))
return PTR_ERR(emc->mc);
emc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(emc->regs)) {
err = PTR_ERR(emc->regs);
goto put_mc;
}
if (IS_ERR(emc->regs))
return PTR_ERR(emc->regs);
for (i = 0; i < 2; i++) {
emc->channel[i] = devm_platform_ioremap_resource(pdev, 1 + i);
if (IS_ERR(emc->channel[i])) {
err = PTR_ERR(emc->channel[i]);
goto put_mc;
}
if (IS_ERR(emc->channel[i]))
return PTR_ERR(emc->channel[i]);
}
tegra210_emc_detect(emc);
......@@ -1884,7 +1867,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
err = of_reserved_mem_device_init_by_name(emc->dev, np, "nominal");
if (err < 0) {
dev_err(emc->dev, "failed to get nominal EMC table: %d\n", err);
goto put_mc;
return err;
}
err = of_reserved_mem_device_init_by_name(emc->dev, np, "derated");
......@@ -2015,8 +1998,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
tegra210_clk_emc_detach(emc->clk);
release:
of_reserved_mem_device_release(emc->dev);
put_mc:
put_device(emc->mc->dev);
return err;
}
......@@ -2027,7 +2009,6 @@ static int tegra210_emc_remove(struct platform_device *pdev)
debugfs_remove_recursive(emc->debugfs.root);
tegra210_clk_emc_detach(emc->clk);
of_reserved_mem_device_release(emc->dev);
put_device(emc->mc->dev);
return 0;
}
......
......@@ -24,7 +24,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2e8,
.shift = 0,
.mask = 0xff,
.def = 0xc2,
.def = 0x1e,
},
}, {
.id = 0x02,
......@@ -38,7 +38,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f4,
.shift = 0,
.mask = 0xff,
.def = 0xc6,
.def = 0x1e,
},
}, {
.id = 0x03,
......@@ -52,7 +52,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2e8,
.shift = 16,
.mask = 0xff,
.def = 0x50,
.def = 0x1e,
},
}, {
.id = 0x04,
......@@ -66,7 +66,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f4,
.shift = 16,
.mask = 0xff,
.def = 0x50,
.def = 0x1e,
},
}, {
.id = 0x05,
......@@ -80,7 +80,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2ec,
.shift = 0,
.mask = 0xff,
.def = 0x50,
.def = 0x1e,
},
}, {
.id = 0x06,
......@@ -94,7 +94,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f8,
.shift = 0,
.mask = 0xff,
.def = 0x50,
.def = 0x1e,
},
}, {
.id = 0x0e,
......@@ -108,7 +108,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2e0,
.shift = 0,
.mask = 0xff,
.def = 0x13,
.def = 0x2e,
},
}, {
.id = 0x0f,
......@@ -136,7 +136,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f0,
.shift = 0,
.mask = 0xff,
.def = 0x50,
.def = 0x1e,
},
}, {
.id = 0x11,
......@@ -150,7 +150,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2fc,
.shift = 0,
.mask = 0xff,
.def = 0x50,
.def = 0x1e,
},
}, {
.id = 0x15,
......@@ -380,7 +380,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x350,
.shift = 16,
.mask = 0xff,
.def = 0x65,
.def = 0x80,
},
}, {
.id = 0x44,
......@@ -620,7 +620,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f0,
.shift = 16,
.mask = 0xff,
.def = 0x50,
.def = 0x1e,
},
}, {
.id = 0x60,
......@@ -648,7 +648,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x3bc,
.shift = 0,
.mask = 0xff,
.def = 0x49,
.def = 0x5a,
},
}, {
.id = 0x62,
......@@ -676,7 +676,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x3c4,
.shift = 0,
.mask = 0xff,
.def = 0x49,
.def = 0x5a,
},
}, {
.id = 0x64,
......@@ -897,7 +897,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.bit = 1,
},
.la = {
.reg = 0xb98,
.reg = 0x3e0,
.shift = 16,
.mask = 0xff,
.def = 0x80,
......@@ -956,7 +956,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x3ec,
.shift = 16,
.mask = 0xff,
.def = 0xff,
.def = 0x80,
},
}, {
.id = 0x86,
......@@ -1020,35 +1020,45 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
};
static const struct tegra_smmu_swgroup tegra210_swgroups[] = {
{ .name = "dc", .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 },
{ .name = "dcb", .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 },
{ .name = "afi", .swgroup = TEGRA_SWGROUP_AFI, .reg = 0x238 },
{ .name = "avpc", .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c },
{ .name = "hda", .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 },
{ .name = "dc", .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 },
{ .name = "dcb", .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 },
{ .name = "hc", .swgroup = TEGRA_SWGROUP_HC, .reg = 0x250 },
{ .name = "hda", .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 },
{ .name = "isp2", .swgroup = TEGRA_SWGROUP_ISP2, .reg = 0x258 },
{ .name = "nvenc", .swgroup = TEGRA_SWGROUP_NVENC, .reg = 0x264 },
{ .name = "nv", .swgroup = TEGRA_SWGROUP_NV, .reg = 0x268 },
{ .name = "nv2", .swgroup = TEGRA_SWGROUP_NV2, .reg = 0x26c },
{ .name = "ppcs", .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 },
{ .name = "sata", .swgroup = TEGRA_SWGROUP_SATA, .reg = 0x274 },
{ .name = "isp2", .swgroup = TEGRA_SWGROUP_ISP2, .reg = 0x258 },
{ .name = "vi", .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 },
{ .name = "vic", .swgroup = TEGRA_SWGROUP_VIC, .reg = 0x284 },
{ .name = "xusb_host", .swgroup = TEGRA_SWGROUP_XUSB_HOST, .reg = 0x288 },
{ .name = "xusb_dev", .swgroup = TEGRA_SWGROUP_XUSB_DEV, .reg = 0x28c },
{ .name = "isp2b", .swgroup = TEGRA_SWGROUP_ISP2B, .reg = 0xaa4 },
{ .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 },
{ .name = "a9avp", .swgroup = TEGRA_SWGROUP_A9AVP, .reg = 0x290 },
{ .name = "gpu", .swgroup = TEGRA_SWGROUP_GPU, .reg = 0xaac },
{ .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 },
{ .name = "ppcs1", .swgroup = TEGRA_SWGROUP_PPCS1, .reg = 0x298 },
{ .name = "dc1", .swgroup = TEGRA_SWGROUP_DC1, .reg = 0xa88 },
{ .name = "sdmmc1a", .swgroup = TEGRA_SWGROUP_SDMMC1A, .reg = 0xa94 },
{ .name = "sdmmc2a", .swgroup = TEGRA_SWGROUP_SDMMC2A, .reg = 0xa98 },
{ .name = "sdmmc3a", .swgroup = TEGRA_SWGROUP_SDMMC3A, .reg = 0xa9c },
{ .name = "sdmmc4a", .swgroup = TEGRA_SWGROUP_SDMMC4A, .reg = 0xaa0 },
{ .name = "vic", .swgroup = TEGRA_SWGROUP_VIC, .reg = 0x284 },
{ .name = "vi", .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 },
{ .name = "isp2b", .swgroup = TEGRA_SWGROUP_ISP2B, .reg = 0xaa4 },
{ .name = "gpu", .swgroup = TEGRA_SWGROUP_GPU, .reg = 0xaac },
{ .name = "ppcs2", .swgroup = TEGRA_SWGROUP_PPCS2, .reg = 0xab0 },
{ .name = "nvdec", .swgroup = TEGRA_SWGROUP_NVDEC, .reg = 0xab4 },
{ .name = "ape", .swgroup = TEGRA_SWGROUP_APE, .reg = 0xab8 },
{ .name = "nvjpg", .swgroup = TEGRA_SWGROUP_NVJPG, .reg = 0xac0 },
{ .name = "se", .swgroup = TEGRA_SWGROUP_SE, .reg = 0xabc },
{ .name = "nvjpg", .swgroup = TEGRA_SWGROUP_NVJPG, .reg = 0xac0 },
{ .name = "hc1", .swgroup = TEGRA_SWGROUP_HC1, .reg = 0xac4 },
{ .name = "se1", .swgroup = TEGRA_SWGROUP_SE1, .reg = 0xac8 },
{ .name = "axiap", .swgroup = TEGRA_SWGROUP_AXIAP, .reg = 0xacc },
{ .name = "etr", .swgroup = TEGRA_SWGROUP_ETR, .reg = 0xad0 },
{ .name = "tsecb", .swgroup = TEGRA_SWGROUP_TSECB, .reg = 0xad4 },
{ .name = "tsec1", .swgroup = TEGRA_SWGROUP_TSEC1, .reg = 0xad8 },
{ .name = "tsecb1", .swgroup = TEGRA_SWGROUP_TSECB1, .reg = 0xadc },
{ .name = "nvdec1", .swgroup = TEGRA_SWGROUP_NVDEC1, .reg = 0xae0 },
};
static const unsigned int tegra210_group_display[] = {
......
This diff is collapsed.
This diff is collapsed.
......@@ -258,6 +258,7 @@ config OMAP_CF
config AT91_CF
tristate "AT91 CompactFlash Controller"
depends on PCI
depends on OF
depends on PCMCIA && ARCH_AT91
help
Say Y here to support the CompactFlash controller on AT91 chips.
......
......@@ -13,7 +13,6 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/platform_data/atmel.h>
#include <linux/io.h>
#include <linux/sizes.h>
#include <linux/mfd/syscon.h>
......@@ -35,6 +34,17 @@
#define CF_IO_PHYS (1 << 23)
#define CF_MEM_PHYS (0x017ff800)
struct at91_cf_data {
int irq_pin; /* I/O IRQ */
int det_pin; /* Card detect */
int vcc_pin; /* power switching */
int rst_pin; /* card reset */
u8 chipselect; /* EBI Chip Select number */
u8 flags;
#define AT91_CF_TRUE_IDE 0x01
#define AT91_IDE_SWAP_A0_A2 0x02
};
struct regmap *mc;
/*--------------------------------------------------------------------------*/
......@@ -209,16 +219,18 @@ static struct pccard_operations at91_cf_ops = {
/*--------------------------------------------------------------------------*/
#if defined(CONFIG_OF)
static const struct of_device_id at91_cf_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-cf" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, at91_cf_dt_ids);
static int at91_cf_dt_init(struct platform_device *pdev)
static int at91_cf_probe(struct platform_device *pdev)
{
struct at91_cf_data *board;
struct at91_cf_socket *cf;
struct at91_cf_data *board;
struct resource *io;
int status;
board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL);
if (!board)
......@@ -229,33 +241,9 @@ static int at91_cf_dt_init(struct platform_device *pdev)
board->vcc_pin = of_get_gpio(pdev->dev.of_node, 2);
board->rst_pin = of_get_gpio(pdev->dev.of_node, 3);
pdev->dev.platform_data = board;
mc = syscon_regmap_lookup_by_compatible("atmel,at91rm9200-sdramc");
return PTR_ERR_OR_ZERO(mc);
}
#else
static int at91_cf_dt_init(struct platform_device *pdev)
{
return -ENODEV;
}
#endif
static int at91_cf_probe(struct platform_device *pdev)
{
struct at91_cf_socket *cf;
struct at91_cf_data *board = pdev->dev.platform_data;
struct resource *io;
int status;
if (!board) {
status = at91_cf_dt_init(pdev);
if (status)
return status;
board = pdev->dev.platform_data;
}
if (IS_ERR(mc))
return PTR_ERR(mc);
if (!gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin))
return -ENODEV;
......@@ -399,7 +387,7 @@ static int at91_cf_resume(struct platform_device *pdev)
static struct platform_driver at91_cf_driver = {
.driver = {
.name = "at91_cf",
.of_match_table = of_match_ptr(at91_cf_dt_ids),
.of_match_table = at91_cf_dt_ids,
},
.probe = at91_cf_probe,
.remove = at91_cf_remove,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2,3 +2,4 @@
obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.o
obj-$(CONFIG_ASPEED_SOCINFO) += aspeed-socinfo.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment