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 @@ ...@@ -2948,7 +2948,7 @@
mtdset= [ARM] mtdset= [ARM]
ARM/S3C2412 JIVE boot control ARM/S3C2412 JIVE boot control
See arch/arm/mach-s3c2412/mach-jive.c See arch/arm/mach-s3c/mach-jive.c
mtouchusb.raw_coordinates= mtouchusb.raw_coordinates=
[HW] Make the MicroTouch USB driver use raw coordinates [HW] Make the MicroTouch USB driver use raw coordinates
......
...@@ -29,7 +29,7 @@ GPIOLIB ...@@ -29,7 +29,7 @@ GPIOLIB
The following functions now either have a `s3c_` specific variant The following functions now either have a `s3c_` specific variant
or are merged into gpiolib. See the definitions in 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_setpin() gpio_set_value() or gpio_direction_output()
- s3c2410_gpio_getpin() gpio_get_value() or gpio_direction_input() - s3c2410_gpio_getpin() gpio_get_value() or gpio_direction_input()
...@@ -86,7 +86,7 @@ between the calls. ...@@ -86,7 +86,7 @@ between the calls.
Headers 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 of GPIO pins, and the configuration values for them. This
is included by using #include <mach/regs-gpio.h> is included by using #include <mach/regs-gpio.h>
......
...@@ -18,7 +18,7 @@ Introduction ...@@ -18,7 +18,7 @@ Introduction
versions. versions.
The S3C2416 and S3C2450 devices are very similar and S3C2450 support is 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 support for these SoCs is in, work on some of the extra peripherals
and extra interrupts is still ongoing. and extra interrupts is still ongoing.
...@@ -37,19 +37,11 @@ Configuration ...@@ -37,19 +37,11 @@ Configuration
Layout Layout
------ ------
The core support files are located in the platform code contained in The core support files, register, kernel and paltform data are located in the
arch/arm/plat-s3c24xx with headers in include/asm-arm/plat-s3c24xx. platform code contained in arch/arm/mach-s3c with headers in
This directory should be kept to items shared between the platform arch/arm/mach-s3c/include
code (arch/arm/plat-s3c24xx) and the arch/arm/mach-s3c24* code.
Each cpu has a directory with the support files for it, and the arch/arm/mach-s3c:
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:
Files in here are either common to all the s3c24xx family, Files in here are either common to all the s3c24xx family,
or are common to only some of them with names to indicate this or are common to only some of them with names to indicate this
...@@ -134,7 +126,7 @@ Adding New Machines ...@@ -134,7 +126,7 @@ Adding New Machines
should keep this in mind before altering items outside of their own should keep this in mind before altering items outside of their own
machine files. 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. and there are a number of examples that can be looked at.
Read the kernel patch submission policies as well as the Read the kernel patch submission policies as well as the
...@@ -293,7 +285,7 @@ Platform Data ...@@ -293,7 +285,7 @@ Platform Data
} }
Note, since the code is marked as __init, it should not be 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. modules via EXPORT_SYMBOL() and related functions.
......
...@@ -36,7 +36,7 @@ Board Support ...@@ -36,7 +36,7 @@ Board Support
------------- -------------
The driver attaches to a platform device, which will need to be 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 such as mach-bast.c or mach-smdk2410.c
The platform device's platform_data field is only needed if the The platform device's platform_data field is only needed if the
...@@ -51,9 +51,9 @@ Board Support ...@@ -51,9 +51,9 @@ Board Support
Platform Data 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 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 The `struct s3c2410_hcd_info` contains a pair of functions
that get called to enable over-current detection, and to that get called to enable over-current detection, and to
......
...@@ -37,5 +37,4 @@ implementation to configure pins as necessary. ...@@ -37,5 +37,4 @@ implementation to configure pins as necessary.
The s3c_gpio_cfgpin() and s3c_gpio_setpull() provide the means for a The s3c_gpio_cfgpin() and s3c_gpio_setpull() provide the means for a
driver or machine to change gpio configuration. driver or machine to change gpio configuration.
See arch/arm/plat-samsung/include/plat/gpio-cfg.h for more information See arch/arm/mach-s3c/gpio-cfg.h for more information on these functions.
on these functions.
...@@ -23,6 +23,7 @@ properties: ...@@ -23,6 +23,7 @@ properties:
enum: enum:
- qcom,sc7180-llcc - qcom,sc7180-llcc
- qcom,sdm845-llcc - qcom,sdm845-llcc
- qcom,sm8150-llcc
reg: reg:
items: items:
......
...@@ -18,8 +18,30 @@ clock-names. See ../../clock/clock-bindings.txt for details. ...@@ -18,8 +18,30 @@ clock-names. See ../../clock/clock-bindings.txt for details.
../../reset/reset.txt for details. ../../reset/reset.txt for details.
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- actmon - 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: 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 { actmon@6000c800 {
compatible = "nvidia,tegra124-actmon"; compatible = "nvidia,tegra124-actmon";
reg = <0x0 0x6000c800 0x0 0x400>; reg = <0x0 0x6000c800 0x0 0x400>;
...@@ -29,4 +51,7 @@ Example: ...@@ -29,4 +51,7 @@ Example:
clock-names = "actmon", "emc"; clock-names = "actmon", "emc";
resets = <&tegra_car 119>; resets = <&tegra_car 119>;
reset-names = "actmon"; reset-names = "actmon";
operating-points-v2 = <&dfs_opp_table>;
interconnects = <&mc TEGRA124_MC_MPCORER &emc>;
interconnect-names = "cpu";
}; };
...@@ -20,6 +20,10 @@ Required properties: ...@@ -20,6 +20,10 @@ Required properties:
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- host1x - 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 The host1x top-level node defines a number of children, each representing one
of the following host1x client modules: of the following host1x client modules:
...@@ -36,6 +40,12 @@ of the following host1x client modules: ...@@ -36,6 +40,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- mpe - 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 - vi: video input
Required properties: Required properties:
...@@ -113,6 +123,12 @@ of the following host1x client modules: ...@@ -113,6 +123,12 @@ of the following host1x client modules:
Required properties: Required properties:
- remote-endpoint: phandle to vi port 'endpoint' node. - 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 - epp: encoder pre-processor
Required properties: Required properties:
...@@ -126,6 +142,12 @@ of the following host1x client modules: ...@@ -126,6 +142,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- epp - 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 - isp: image signal processor
Required properties: Required properties:
...@@ -139,6 +161,12 @@ of the following host1x client modules: ...@@ -139,6 +161,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- isp - 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 - gr2d: 2D graphics engine
Required properties: Required properties:
...@@ -152,6 +180,12 @@ of the following host1x client modules: ...@@ -152,6 +180,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- 2d - 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 - gr3d: 3D graphics engine
Required properties: Required properties:
...@@ -170,6 +204,12 @@ of the following host1x client modules: ...@@ -170,6 +204,12 @@ of the following host1x client modules:
- 3d - 3d
- 3d2 (Only required on SoCs with two 3D clocks) - 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 - dc: display controller
Required properties: Required properties:
...@@ -197,6 +237,10 @@ of the following host1x client modules: ...@@ -197,6 +237,10 @@ of the following host1x client modules:
- nvidia,hpd-gpio: specifies a GPIO used for hotplug detection - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
- nvidia,edid: supplies a binary EDID blob - nvidia,edid: supplies a binary EDID blob
- nvidia,panel: phandle of a display panel - 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 - hdmi: High Definition Multimedia Interface
...@@ -345,6 +389,12 @@ of the following host1x client modules: ...@@ -345,6 +389,12 @@ of the following host1x client modules:
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- vic - 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: Example:
/ { / {
...@@ -498,6 +548,15 @@ Example: ...@@ -498,6 +548,15 @@ Example:
resets = <&tegra_car 27>; resets = <&tegra_car 27>;
reset-names = "dc"; 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 { rgb {
status = "disabled"; status = "disabled";
}; };
...@@ -513,6 +572,15 @@ Example: ...@@ -513,6 +572,15 @@ Example:
resets = <&tegra_car 26>; resets = <&tegra_car 26>;
reset-names = "dc"; 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 { rgb {
status = "disabled"; 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: ...@@ -29,11 +29,23 @@ properties:
items: items:
- const: emc - const: emc
"#interconnect-cells":
const: 0
nvidia,memory-controller: nvidia,memory-controller:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
description: description:
phandle of the memory controller node 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: patternProperties:
"^emc-timings-[0-9]+$": "^emc-timings-[0-9]+$":
type: object type: object
...@@ -327,6 +339,8 @@ required: ...@@ -327,6 +339,8 @@ required:
- clocks - clocks
- clock-names - clock-names
- nvidia,memory-controller - nvidia,memory-controller
- "#interconnect-cells"
- operating-points-v2
additionalProperties: false additionalProperties: false
...@@ -345,6 +359,7 @@ examples: ...@@ -345,6 +359,7 @@ examples:
#iommu-cells = <1>; #iommu-cells = <1>;
#reset-cells = <1>; #reset-cells = <1>;
#interconnect-cells = <1>;
}; };
external-memory-controller@7001b000 { external-memory-controller@7001b000 {
...@@ -354,6 +369,10 @@ examples: ...@@ -354,6 +369,10 @@ examples:
clock-names = "emc"; clock-names = "emc";
nvidia,memory-controller = <&mc>; nvidia,memory-controller = <&mc>;
operating-points-v2 = <&dvfs_opp_table>;
core-supply = <&vdd_core>;
#interconnect-cells = <0>;
emc-timings-0 { emc-timings-0 {
nvidia,ram-code = <3>; nvidia,ram-code = <3>;
......
...@@ -40,6 +40,9 @@ properties: ...@@ -40,6 +40,9 @@ properties:
"#iommu-cells": "#iommu-cells":
const: 1 const: 1
"#interconnect-cells":
const: 1
patternProperties: patternProperties:
"^emc-timings-[0-9]+$": "^emc-timings-[0-9]+$":
type: object type: object
...@@ -104,6 +107,7 @@ required: ...@@ -104,6 +107,7 @@ required:
- clock-names - clock-names
- "#reset-cells" - "#reset-cells"
- "#iommu-cells" - "#iommu-cells"
- "#interconnect-cells"
additionalProperties: false additionalProperties: false
...@@ -119,6 +123,7 @@ examples: ...@@ -119,6 +123,7 @@ examples:
#iommu-cells = <1>; #iommu-cells = <1>;
#reset-cells = <1>; #reset-cells = <1>;
#interconnect-cells = <1>;
emc-timings-3 { emc-timings-3 {
nvidia,ram-code = <3>; nvidia,ram-code = <3>;
......
...@@ -12,18 +12,44 @@ Properties: ...@@ -12,18 +12,44 @@ Properties:
irrespective of ram-code configuration. irrespective of ram-code configuration.
- interrupts : Should contain EMC General interrupt. - interrupts : Should contain EMC General interrupt.
- clocks : Should contain EMC clock. - 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. Child device nodes describe the memory settings for different configurations and clock rates.
Example: Example:
opp_table: opp-table {
compatible = "operating-points-v2";
opp@36000000 {
opp-microvolt = <950000 950000 1300000>;
opp-hz = /bits/ 64 <36000000>;
};
...
};
memory-controller@7000f400 { memory-controller@7000f400 {
#address-cells = < 1 >; #address-cells = < 1 >;
#size-cells = < 0 >; #size-cells = < 0 >;
#interconnect-cells = <0>;
compatible = "nvidia,tegra20-emc"; compatible = "nvidia,tegra20-emc";
reg = <0x7000f4000 0x200>; reg = <0x7000f400 0x400>;
interrupts = <0 78 0x04>; interrupts = <0 78 0x04>;
clocks = <&tegra_car TEGRA20_CLK_EMC>; 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: ...@@ -16,6 +16,8 @@ Required properties:
IOMMU specifier needed to encode an address. GART supports only a single IOMMU specifier needed to encode an address. GART supports only a single
address space that is shared by all devices, therefore no additional address space that is shared by all devices, therefore no additional
information needed for the address encoding. 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: Example:
mc: memory-controller@7000f000 { mc: memory-controller@7000f000 {
...@@ -27,6 +29,7 @@ Example: ...@@ -27,6 +29,7 @@ Example:
interrupts = <GIC_SPI 77 0x04>; interrupts = <GIC_SPI 77 0x04>;
#reset-cells = <1>; #reset-cells = <1>;
#iommu-cells = <0>; #iommu-cells = <0>;
#interconnect-cells = <1>;
}; };
video-codec@6001a000 { video-codec@6001a000 {
......
...@@ -31,11 +31,23 @@ properties: ...@@ -31,11 +31,23 @@ properties:
interrupts: interrupts:
maxItems: 1 maxItems: 1
"#interconnect-cells":
const: 0
nvidia,memory-controller: nvidia,memory-controller:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
description: description:
Phandle of the Memory Controller node. 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: patternProperties:
"^emc-timings-[0-9]+$": "^emc-timings-[0-9]+$":
type: object type: object
...@@ -214,6 +226,8 @@ required: ...@@ -214,6 +226,8 @@ required:
- interrupts - interrupts
- clocks - clocks
- nvidia,memory-controller - nvidia,memory-controller
- "#interconnect-cells"
- operating-points-v2
additionalProperties: false additionalProperties: false
...@@ -226,6 +240,10 @@ examples: ...@@ -226,6 +240,10 @@ examples:
clocks = <&tegra_car 57>; clocks = <&tegra_car 57>;
nvidia,memory-controller = <&mc>; nvidia,memory-controller = <&mc>;
operating-points-v2 = <&dvfs_opp_table>;
core-supply = <&vdd_core>;
#interconnect-cells = <0>;
emc-timings-1 { emc-timings-1 {
nvidia,ram-code = <1>; nvidia,ram-code = <1>;
......
...@@ -57,6 +57,9 @@ properties: ...@@ -57,6 +57,9 @@ properties:
"#iommu-cells": "#iommu-cells":
const: 1 const: 1
"#interconnect-cells":
const: 1
patternProperties: patternProperties:
"^emc-timings-[0-9]+$": "^emc-timings-[0-9]+$":
type: object type: object
...@@ -120,6 +123,7 @@ required: ...@@ -120,6 +123,7 @@ required:
- clock-names - clock-names
- "#reset-cells" - "#reset-cells"
- "#iommu-cells" - "#iommu-cells"
- "#interconnect-cells"
additionalProperties: false additionalProperties: false
...@@ -135,6 +139,7 @@ examples: ...@@ -135,6 +139,7 @@ examples:
#iommu-cells = <1>; #iommu-cells = <1>;
#reset-cells = <1>; #reset-cells = <1>;
#interconnect-cells = <1>;
emc-timings-1 { emc-timings-1 {
nvidia,ram-code = <1>; nvidia,ram-code = <1>;
......
...@@ -46,6 +46,7 @@ Required properties ...@@ -46,6 +46,7 @@ Required properties
- compatible: One of: - compatible: One of:
"aspeed,ast2400-lpc", "simple-mfd" "aspeed,ast2400-lpc", "simple-mfd"
"aspeed,ast2500-lpc", "simple-mfd" "aspeed,ast2500-lpc", "simple-mfd"
"aspeed,ast2600-lpc", "simple-mfd"
- reg: contains the physical address and length values of the Aspeed - reg: contains the physical address and length values of the Aspeed
LPC memory region. LPC memory region.
...@@ -64,6 +65,7 @@ BMC Node ...@@ -64,6 +65,7 @@ BMC Node
- compatible: One of: - compatible: One of:
"aspeed,ast2400-lpc-bmc" "aspeed,ast2400-lpc-bmc"
"aspeed,ast2500-lpc-bmc" "aspeed,ast2500-lpc-bmc"
"aspeed,ast2600-lpc-bmc"
- reg: contains the physical address and length values of the - reg: contains the physical address and length values of the
H8S/2168-compatible LPC controller memory region H8S/2168-compatible LPC controller memory region
...@@ -74,6 +76,7 @@ Host Node ...@@ -74,6 +76,7 @@ Host Node
- compatible: One of: - compatible: One of:
"aspeed,ast2400-lpc-host", "simple-mfd", "syscon" "aspeed,ast2400-lpc-host", "simple-mfd", "syscon"
"aspeed,ast2500-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 - reg: contains the address and length values of the host-related
register space for the Aspeed LPC controller register space for the Aspeed LPC controller
...@@ -128,6 +131,7 @@ Required properties: ...@@ -128,6 +131,7 @@ Required properties:
- compatible: One of: - compatible: One of:
"aspeed,ast2400-lpc-ctrl"; "aspeed,ast2400-lpc-ctrl";
"aspeed,ast2500-lpc-ctrl"; "aspeed,ast2500-lpc-ctrl";
"aspeed,ast2600-lpc-ctrl";
- reg: contains offset/length values of the host interface controller - reg: contains offset/length values of the host interface controller
memory regions memory regions
...@@ -168,6 +172,7 @@ Required properties: ...@@ -168,6 +172,7 @@ Required properties:
- compatible: One of: - compatible: One of:
"aspeed,ast2400-lhc"; "aspeed,ast2400-lhc";
"aspeed,ast2500-lhc"; "aspeed,ast2500-lhc";
"aspeed,ast2600-lhc";
- reg: contains offset/length values of the LHC memory regions. In the - reg: contains offset/length values of the LHC memory regions. In the
AST2400 and AST2500 there are two regions. AST2400 and AST2500 there are two regions.
...@@ -187,7 +192,8 @@ state of the LPC bus. Some systems may chose to modify this configuration. ...@@ -187,7 +192,8 @@ state of the LPC bus. Some systems may chose to modify this configuration.
Required properties: Required properties:
- compatible: "aspeed,ast2500-lpc-reset" or - compatible: "aspeed,ast2600-lpc-reset" or
"aspeed,ast2500-lpc-reset"
"aspeed,ast2400-lpc-reset" "aspeed,ast2400-lpc-reset"
- reg: offset and length of the IP in the LHC memory region - reg: offset and length of the IP in the LHC memory region
- #reset-controller indicates the number of reset cells expected - #reset-controller indicates the number of reset cells expected
......
...@@ -20,3 +20,29 @@ syscon: syscon@1e6e2000 { ...@@ -20,3 +20,29 @@ syscon: syscon@1e6e2000 {
#clock-cells = <1>; #clock-cells = <1>;
#reset-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: ...@@ -16,12 +16,16 @@ description:
properties: properties:
compatible: compatible:
enum: enum:
- qcom,msm8916-rpmpd
- qcom,msm8939-rpmpd
- qcom,msm8976-rpmpd - qcom,msm8976-rpmpd
- qcom,msm8996-rpmpd - qcom,msm8996-rpmpd
- qcom,msm8998-rpmpd - qcom,msm8998-rpmpd
- qcom,qcs404-rpmpd - qcom,qcs404-rpmpd
- qcom,sdm660-rpmpd
- qcom,sc7180-rpmhpd - qcom,sc7180-rpmhpd
- qcom,sdm845-rpmhpd - qcom,sdm845-rpmhpd
- qcom,sdx55-rpmhpd
- qcom,sm8150-rpmhpd - qcom,sm8150-rpmhpd
- qcom,sm8250-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: ...@@ -12,10 +12,7 @@ Required properties:
- compatible: shall be one of: - compatible: shall be one of:
"xlnx,vcu" "xlnx,vcu"
"xlnx,vcu-logicoreip-1.0" "xlnx,vcu-logicoreip-1.0"
- reg, reg-names: There are two sets of registers need to provide. - reg : The base offset and size of the VCU_PL_SLCR register space.
1. vcu slcr
2. Logicore
reg-names should contain name for the each register sequence.
- clocks: phandle for aclk and pll_ref clocksource - clocks: phandle for aclk and pll_ref clocksource
- clock-names: The identification string, "aclk", is always required for - clock-names: The identification string, "aclk", is always required for
the axi clock. "pll_ref" is required for pll. the axi clock. "pll_ref" is required for pll.
...@@ -23,9 +20,7 @@ Example: ...@@ -23,9 +20,7 @@ Example:
xlnx_vcu: vcu@a0040000 { xlnx_vcu: vcu@a0040000 {
compatible = "xlnx,vcu-logicoreip-1.0"; compatible = "xlnx,vcu-logicoreip-1.0";
reg = <0x0 0xa0040000 0x0 0x1000>, reg = <0x0 0xa0040000 0x0 0x1000>;
<0x0 0xa0041000 0x0 0x1000>;
reg-names = "vcu_slcr", "logicore";
clocks = <&si570_1>, <&clkc 71>; clocks = <&si570_1>, <&clkc 71>;
clock-names = "pll_ref", "aclk"; clock-names = "pll_ref", "aclk";
}; };
...@@ -34,7 +34,7 @@ These resources should be specified in that order, as the ordering of the ...@@ -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 two address regions is important (the driver expects these to be address
and then data). 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[] = { static struct resource bast_dm9k_resource[] = {
[0] = { [0] = {
......
...@@ -2074,7 +2074,7 @@ M: Matthias Brugger <matthias.bgg@gmail.com> ...@@ -2074,7 +2074,7 @@ M: Matthias Brugger <matthias.bgg@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
W: https://mtk.bcnfs.org/ W: https://mtk.wiki.kernel.org/
C: irc://chat.freenode.net/linux-mediatek C: irc://chat.freenode.net/linux-mediatek
F: arch/arm/boot/dts/mt6* F: arch/arm/boot/dts/mt6*
F: arch/arm/boot/dts/mt7* F: arch/arm/boot/dts/mt7*
...@@ -11429,6 +11429,7 @@ S: Maintained ...@@ -11429,6 +11429,7 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git
F: Documentation/devicetree/bindings/memory-controllers/ F: Documentation/devicetree/bindings/memory-controllers/
F: drivers/memory/ F: drivers/memory/
F: include/dt-bindings/memory/
MEMORY FREQUENCY SCALING DRIVERS FOR NVIDIA TEGRA MEMORY FREQUENCY SCALING DRIVERS FOR NVIDIA TEGRA
M: Dmitry Osipenko <digetx@gmail.com> M: Dmitry Osipenko <digetx@gmail.com>
......
...@@ -192,6 +192,11 @@ p2a: p2a-control@2c { ...@@ -192,6 +192,11 @@ p2a: p2a-control@2c {
status = "disabled"; status = "disabled";
}; };
silicon-id@7c {
compatible = "aspeed,ast2400-silicon-id", "aspeed,silicon-id";
reg = <0x7c 0x4>;
};
pinctrl: pinctrl@80 { pinctrl: pinctrl@80 {
reg = <0x80 0x18>, <0xa0 0x10>; reg = <0x80 0x18>, <0xa0 0x10>;
compatible = "aspeed,ast2400-pinctrl"; compatible = "aspeed,ast2400-pinctrl";
......
...@@ -239,6 +239,11 @@ p2a: p2a-control@2c { ...@@ -239,6 +239,11 @@ p2a: p2a-control@2c {
status = "disabled"; status = "disabled";
}; };
silicon-id@7c {
compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id";
reg = <0x7c 0x4 0x150 0x8>;
};
pinctrl: pinctrl@80 { pinctrl: pinctrl@80 {
compatible = "aspeed,ast2500-pinctrl"; compatible = "aspeed,ast2500-pinctrl";
reg = <0x80 0x18>, <0xa0 0x10>; reg = <0x80 0x18>, <0xa0 0x10>;
......
...@@ -317,6 +317,11 @@ pinctrl: pinctrl { ...@@ -317,6 +317,11 @@ pinctrl: pinctrl {
compatible = "aspeed,ast2600-pinctrl"; compatible = "aspeed,ast2600-pinctrl";
}; };
silicon-id@14 {
compatible = "aspeed,ast2600-silicon-id", "aspeed,silicon-id";
reg = <0x14 0x4 0x5b0 0x8>;
};
smp-memram@180 { smp-memram@180 {
compatible = "aspeed,ast2600-smpmem"; compatible = "aspeed,ast2600-smpmem";
reg = <0x180 0x40>; reg = <0x180 0x40>;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
*/ */
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/dma-mapping.h> #include <linux/dma-map-ops.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_address.h> #include <linux/of_address.h>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h> #include <linux/dma-map-ops.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/irq.h> #include <asm/irq.h>
......
...@@ -627,6 +627,9 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh) ...@@ -627,6 +627,9 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
{ {
struct clk_hw_omap *clk; struct clk_hw_omap *clk;
if (!oh)
return NULL;
if (oh->clkdm) { if (oh->clkdm) {
return oh->clkdm; return oh->clkdm;
} else if (oh->_clk) { } else if (oh->_clk) {
...@@ -3677,6 +3680,9 @@ static void __init omap_hwmod_setup_earlycon_flags(void) ...@@ -3677,6 +3680,9 @@ static void __init omap_hwmod_setup_earlycon_flags(void)
*/ */
static int __init omap_hwmod_setup_all(void) static int __init omap_hwmod_setup_all(void)
{ {
if (!inited)
return 0;
_ensure_mpu_hwmod_is_setup(NULL); _ensure_mpu_hwmod_is_setup(NULL);
omap_hwmod_for_each(_init, NULL); omap_hwmod_for_each(_init, NULL);
......
...@@ -580,6 +580,8 @@ static void pdata_quirks_check(struct pdata_init *quirks) ...@@ -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) 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 * We still need this for omap2420 and omap3 PM to work, others are
* using drivers/misc/sram.c already. * using drivers/misc/sram.c already.
...@@ -591,6 +593,15 @@ void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table) ...@@ -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")) if (of_machine_is_compatible("ti,omap3"))
omap3_mcbsp_init(); omap3_mcbsp_init();
pdata_quirks_check(auxdata_quirks); 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, of_platform_populate(NULL, omap_dt_match_table,
omap_auxdata_lookup, NULL); omap_auxdata_lookup, NULL);
pdata_quirks_check(pdata_quirks); pdata_quirks_check(pdata_quirks);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/async.h> #include <linux/async.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h> #include <linux/dma-map-ops.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/sh_clk.h> #include <linux/sh_clk.h>
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/dma-direct.h> #include <linux/dma-map-ops.h>
#include <linux/swiotlb.h>
#include <asm/iommu.h> #include <asm/iommu.h>
#define STA2X11_SWIOTLB_SIZE (4*1024*1024) #define STA2X11_SWIOTLB_SIZE (4*1024*1024)
......
...@@ -853,8 +853,12 @@ static int sysc_ioremap(struct sysc *ddata) ...@@ -853,8 +853,12 @@ static int sysc_ioremap(struct sysc *ddata)
*/ */
static int sysc_map_and_check_registers(struct sysc *ddata) static int sysc_map_and_check_registers(struct sysc *ddata)
{ {
struct device_node *np = ddata->dev->of_node;
int error; int error;
if (!of_get_property(np, "reg", NULL))
return 0;
error = sysc_parse_and_check_child_range(ddata); error = sysc_parse_and_check_child_range(ddata);
if (error) if (error)
return error; return error;
...@@ -1222,10 +1226,10 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev) ...@@ -1222,10 +1226,10 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
ddata->enabled = false; ddata->enabled = false;
err_allow_idle: err_allow_idle:
reset_control_assert(ddata->rsts);
sysc_clkdm_allow_idle(ddata); sysc_clkdm_allow_idle(ddata);
reset_control_assert(ddata->rsts);
return error; return error;
} }
...@@ -1379,6 +1383,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { ...@@ -1379,6 +1383,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
SYSC_QUIRK_CLKDM_NOAUTO), SYSC_QUIRK_CLKDM_NOAUTO),
SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff,
SYSC_QUIRK_CLKDM_NOAUTO), 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("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff,
SYSC_QUIRK_OPT_CLKS_NEEDED), SYSC_QUIRK_OPT_CLKS_NEEDED),
SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
...@@ -1814,6 +1820,14 @@ static void sysc_init_module_quirks(struct sysc *ddata) ...@@ -1814,6 +1820,14 @@ static void sysc_init_module_quirks(struct sysc *ddata)
return; 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) { if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) {
ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c; ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c;
ddata->post_reset_quirk = sysc_post_reset_quirk_i2c; ddata->post_reset_quirk = sysc_post_reset_quirk_i2c;
...@@ -1945,6 +1959,7 @@ static int sysc_reset(struct sysc *ddata) ...@@ -1945,6 +1959,7 @@ static int sysc_reset(struct sysc *ddata)
*/ */
static int sysc_init_module(struct sysc *ddata) static int sysc_init_module(struct sysc *ddata)
{ {
bool rstctrl_deasserted = false;
int error = 0; int error = 0;
error = sysc_clockdomain_init(ddata); error = sysc_clockdomain_init(ddata);
...@@ -1969,6 +1984,7 @@ static int sysc_init_module(struct sysc *ddata) ...@@ -1969,6 +1984,7 @@ static int sysc_init_module(struct sysc *ddata)
error = reset_control_deassert(ddata->rsts); error = reset_control_deassert(ddata->rsts);
if (error) if (error)
goto err_main_clocks; goto err_main_clocks;
rstctrl_deasserted = true;
} }
ddata->revision = sysc_read_revision(ddata); ddata->revision = sysc_read_revision(ddata);
...@@ -1978,13 +1994,13 @@ static int sysc_init_module(struct sysc *ddata) ...@@ -1978,13 +1994,13 @@ static int sysc_init_module(struct sysc *ddata)
if (ddata->legacy_mode) { if (ddata->legacy_mode) {
error = sysc_legacy_init(ddata); error = sysc_legacy_init(ddata);
if (error) if (error)
goto err_reset; goto err_main_clocks;
} }
if (!ddata->legacy_mode) { if (!ddata->legacy_mode) {
error = sysc_enable_module(ddata->dev); error = sysc_enable_module(ddata->dev);
if (error) if (error)
goto err_reset; goto err_main_clocks;
} }
error = sysc_reset(ddata); error = sysc_reset(ddata);
...@@ -1994,10 +2010,6 @@ static int sysc_init_module(struct sysc *ddata) ...@@ -1994,10 +2010,6 @@ static int sysc_init_module(struct sysc *ddata)
if (error && !ddata->legacy_mode) if (error && !ddata->legacy_mode)
sysc_disable_module(ddata->dev); 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: err_main_clocks:
if (error) if (error)
sysc_disable_main_clocks(ddata); sysc_disable_main_clocks(ddata);
...@@ -2008,6 +2020,10 @@ static int sysc_init_module(struct sysc *ddata) ...@@ -2008,6 +2020,10 @@ static int sysc_init_module(struct sysc *ddata)
sysc_clkdm_allow_idle(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; return error;
} }
...@@ -2909,6 +2925,9 @@ static int sysc_probe(struct platform_device *pdev) ...@@ -2909,6 +2925,9 @@ static int sysc_probe(struct platform_device *pdev)
if (!ddata) if (!ddata)
return -ENOMEM; return -ENOMEM;
ddata->offsets[SYSC_REVISION] = -ENODEV;
ddata->offsets[SYSC_SYSCONFIG] = -ENODEV;
ddata->offsets[SYSC_SYSSTATUS] = -ENODEV;
ddata->dev = &pdev->dev; ddata->dev = &pdev->dev;
platform_set_drvdata(pdev, ddata); platform_set_drvdata(pdev, ddata);
...@@ -2975,9 +2994,6 @@ static int sysc_probe(struct platform_device *pdev) ...@@ -2975,9 +2994,6 @@ static int sysc_probe(struct platform_device *pdev)
} }
/* Balance use counts as PM runtime should have enabled these all */ /* 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 & if (!(ddata->cfg.quirks &
(SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) { (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) {
sysc_disable_main_clocks(ddata); sysc_disable_main_clocks(ddata);
...@@ -2985,6 +3001,9 @@ static int sysc_probe(struct platform_device *pdev) ...@@ -2985,6 +3001,9 @@ static int sysc_probe(struct platform_device *pdev)
sysc_clkdm_allow_idle(ddata); sysc_clkdm_allow_idle(ddata);
} }
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
sysc_show_registers(ddata); sysc_show_registers(ddata);
ddata->dev->type = &sysc_device_type; ddata->dev->type = &sysc_device_type;
......
...@@ -19,6 +19,16 @@ config EXYNOS_AUDSS_CLK_CON ...@@ -19,6 +19,16 @@ config EXYNOS_AUDSS_CLK_CON
on some Exynos SoC variants. Choose M or Y here if you want to on some Exynos SoC variants. Choose M or Y here if you want to
use audio devices such as I2S, PCM, etc. 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: # For S3C24XX platforms, select following symbols:
config S3C2410_COMMON_CLK config S3C2410_COMMON_CLK
bool "Samsung S3C2410 clock controller support" if COMPILE_TEST bool "Samsung S3C2410 clock controller support" if COMPILE_TEST
......
...@@ -15,7 +15,7 @@ obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o ...@@ -15,7 +15,7 @@ obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.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_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o
obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
......
...@@ -9,10 +9,13 @@ ...@@ -9,10 +9,13 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.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_NR_CLKS 1
#define EXYNOS_CLKOUT_PARENTS 32 #define EXYNOS_CLKOUT_PARENTS 32
...@@ -28,41 +31,103 @@ struct exynos_clkout { ...@@ -28,41 +31,103 @@ struct exynos_clkout {
struct clk_mux mux; struct clk_mux mux;
spinlock_t slock; spinlock_t slock;
void __iomem *reg; void __iomem *reg;
struct device_node *np;
u32 pmu_debug_save; u32 pmu_debug_save;
struct clk_hw_onecell_data data; struct clk_hw_onecell_data data;
}; };
static struct exynos_clkout *clkout; struct exynos_clkout_variant {
u32 mux_mask;
};
static int exynos_clkout_suspend(void) static const struct exynos_clkout_variant exynos_clkout_exynos4 = {
{ .mux_mask = EXYNOS4_CLKOUT_MUX_MASK,
clkout->pmu_debug_save = readl(clkout->reg + EXYNOS_PMU_DEBUG_REG); };
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 = { if (!dev->parent) {
.suspend = exynos_clkout_suspend, dev_err(dev, "not instantiated from MFD\n");
.resume = exynos_clkout_resume, 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]; const char *parent_names[EXYNOS_CLKOUT_PARENTS];
struct clk *parents[EXYNOS_CLKOUT_PARENTS]; struct clk *parents[EXYNOS_CLKOUT_PARENTS];
int parent_count; struct exynos_clkout *clkout;
int ret; int parent_count, ret, i;
int i; u32 mux_mask;
clkout = kzalloc(struct_size(clkout, data.hws, EXYNOS_CLKOUT_NR_CLKS), clkout = devm_kzalloc(&pdev->dev,
GFP_KERNEL); struct_size(clkout, data.hws, EXYNOS_CLKOUT_NR_CLKS),
GFP_KERNEL);
if (!clkout) 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); spin_lock_init(&clkout->slock);
...@@ -71,7 +136,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) ...@@ -71,7 +136,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
char name[] = "clkoutXX"; char name[] = "clkoutXX";
snprintf(name, sizeof(name), "clkout%d", i); 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])) { if (IS_ERR(parents[i])) {
parent_names[i] = "none"; parent_names[i] = "none";
continue; continue;
...@@ -82,11 +147,13 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) ...@@ -82,11 +147,13 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
} }
if (!parent_count) if (!parent_count)
goto free_clkout; return -EINVAL;
clkout->reg = of_iomap(node, 0); clkout->reg = of_iomap(clkout->np, 0);
if (!clkout->reg) if (!clkout->reg) {
ret = -ENODEV;
goto clks_put; goto clks_put;
}
clkout->gate.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG; clkout->gate.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
clkout->gate.bit_idx = EXYNOS_CLKOUT_DISABLE_SHIFT; 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) ...@@ -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_mux_ops, NULL, NULL, &clkout->gate.hw,
&clk_gate_ops, CLK_SET_RATE_PARENT &clk_gate_ops, CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT); | 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; goto err_unmap;
}
clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; 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) if (ret)
goto err_clk_unreg; goto err_clk_unreg;
register_syscore_ops(&exynos_clkout_syscore_ops); return 0;
return;
err_clk_unreg: err_clk_unreg:
clk_hw_unregister(clkout->data.hws[0]); clk_hw_unregister(clkout->data.hws[0]);
...@@ -123,38 +190,56 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) ...@@ -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) for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i)
if (!IS_ERR(parents[i])) if (!IS_ERR(parents[i]))
clk_put(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;
} }
/* static int exynos_clkout_remove(struct platform_device *pdev)
* We use CLK_OF_DECLARE_DRIVER initialization method to avoid setting {
* the OF_POPULATED flag on the pmu device tree node, so later the struct exynos_clkout *clkout = platform_get_drvdata(pdev);
* Exynos PMU platform device can be properly probed with PMU driver.
*/ 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); static int __maybe_unused exynos_clkout_resume(struct device *dev)
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)
{ {
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); static SIMPLE_DEV_PM_OPS(exynos_clkout_pm_ops, exynos_clkout_suspend,
CLK_OF_DECLARE_DRIVER(exynos5410_clkout, "samsung,exynos5410-pmu", exynos_clkout_resume);
exynos5_clkout_init);
CLK_OF_DECLARE_DRIVER(exynos5420_clkout, "samsung,exynos5420-pmu", static struct platform_driver exynos_clkout_driver = {
exynos5_clkout_init); .driver = {
CLK_OF_DECLARE_DRIVER(exynos5433_clkout, "samsung,exynos5433-pmu", .name = "exynos-clkout",
exynos5_clkout_init); .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[] = { ...@@ -266,6 +266,8 @@ static const char *enable_init_clks[] = {
"dpll_ddr_m2_ck", "dpll_ddr_m2_ck",
"dpll_mpu_m2_ck", "dpll_mpu_m2_ck",
"l3_gclk", "l3_gclk",
/* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */
"l3-clkctrl:00bc:0",
"l4hs_gclk", "l4hs_gclk",
"l4fw_gclk", "l4fw_gclk",
"l4ls_gclk", "l4ls_gclk",
......
...@@ -155,8 +155,7 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int part_id) ...@@ -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[] = { static const struct of_device_id compatible_machine_match[] = {
{ .compatible = "arm,vexpress,v2p-ca15_a7" }, { .compatible = "arm,vexpress,v2p-ca15_a7" },
{ .compatible = "samsung,exynos5420" }, { .compatible = "google,peach" },
{ .compatible = "samsung,exynos5800" },
{}, {},
}; };
......
...@@ -1474,17 +1474,17 @@ int scmi_notification_init(struct scmi_handle *handle) ...@@ -1474,17 +1474,17 @@ int scmi_notification_init(struct scmi_handle *handle)
ni->gid = gid; ni->gid = gid;
ni->handle = handle; 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), ni->notify_wq = alloc_workqueue(dev_name(handle->dev),
WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS, WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
0); 0);
if (!ni->notify_wq) if (!ni->notify_wq)
goto err; 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); mutex_init(&ni->pending_mtx);
hash_init(ni->pending_events_handlers); 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) ...@@ -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_chan *dsp_chan;
struct imx_dsp_ipc *dsp_ipc;
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 imx_dsp_chan *dsp_chan;
struct mbox_client *cl; struct mbox_client *cl;
char *chan_name; char *chan_name;
int ret; int ret;
int i, j; 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++) { for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
if (i < 2) if (i < 2)
chan_name = kasprintf(GFP_KERNEL, "txdb%d", i); chan_name = kasprintf(GFP_KERNEL, "txdb%d", i);
...@@ -86,6 +104,7 @@ static int imx_dsp_probe(struct platform_device *pdev) ...@@ -86,6 +104,7 @@ static int imx_dsp_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
dsp_chan = &dsp_ipc->chans[i]; dsp_chan = &dsp_ipc->chans[i];
dsp_chan->name = chan_name;
cl = &dsp_chan->cl; cl = &dsp_chan->cl;
cl->dev = dev; cl->dev = dev;
cl->tx_block = false; cl->tx_block = false;
...@@ -104,27 +123,43 @@ static int imx_dsp_probe(struct platform_device *pdev) ...@@ -104,27 +123,43 @@ static int imx_dsp_probe(struct platform_device *pdev)
} }
dev_dbg(dev, "request mbox chan %s\n", chan_name); 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; return 0;
out: out:
kfree(chan_name);
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
dsp_chan = &dsp_ipc->chans[j]; dsp_chan = &dsp_ipc->chans[j];
mbox_free_channel(dsp_chan->ch); mbox_free_channel(dsp_chan->ch);
kfree(dsp_chan->name);
} }
return ret; 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) static int imx_dsp_remove(struct platform_device *pdev)
{ {
struct imx_dsp_chan *dsp_chan; struct imx_dsp_chan *dsp_chan;
...@@ -136,6 +171,7 @@ static int imx_dsp_remove(struct platform_device *pdev) ...@@ -136,6 +171,7 @@ static int imx_dsp_remove(struct platform_device *pdev)
for (i = 0; i < DSP_MU_CHAN_NUM; i++) { for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
dsp_chan = &dsp_ipc->chans[i]; dsp_chan = &dsp_ipc->chans[i];
mbox_free_channel(dsp_chan->ch); mbox_free_channel(dsp_chan->ch);
kfree(dsp_chan->name);
} }
return 0; return 0;
......
...@@ -160,12 +160,18 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = { ...@@ -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-pwm0", IMX_SC_R_MIPI_0_PWM_0, 1, false, 0 },
{ "mipi0-i2c", IMX_SC_R_MIPI_0_I2C_0, 2, true, 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 */ /* LVDS SS */
{ "lvds0", IMX_SC_R_LVDS_0, 1, false, 0 }, { "lvds0", IMX_SC_R_LVDS_0, 1, false, 0 },
{ "lvds1", IMX_SC_R_LVDS_1, 1, false, 0 },
/* DC SS */ /* DC SS */
{ "dc0", IMX_SC_R_DC_0, 1, false, 0 }, { "dc0", IMX_SC_R_DC_0, 1, false, 0 },
{ "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, true, 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 SS */
{ "cm40-i2c", IMX_SC_R_M4_0_I2C, 1, false, 0 }, { "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[] = { ...@@ -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-pid", IMX_SC_R_M4_1_PID0, 5, true, 0},
{ "cm41-mu-a1", IMX_SC_R_M4_1_MU_1A, 1, false, 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}, { "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 = { static const struct imx_sc_pd_soc imx8qxp_scu_pd = {
......
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
# Amlogic Secure Monitor driver # Amlogic Secure Monitor driver
# #
config MESON_SM config MESON_SM
bool tristate "Amlogic Secure Monitor driver"
default ARCH_MESON depends on ARCH_MESON || COMPILE_TEST
default y
depends on ARM64_4K_PAGES depends on ARM64_4K_PAGES
help help
Say y here to enable the Amlogic secure monitor driver Say y here to enable the Amlogic secure monitor driver
...@@ -331,3 +331,4 @@ static struct platform_driver meson_sm_driver = { ...@@ -331,3 +331,4 @@ static struct platform_driver meson_sm_driver = {
}, },
}; };
module_platform_driver_probe(meson_sm_driver, meson_sm_probe); 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, ...@@ -412,16 +412,12 @@ static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
goto out; goto out;
} }
len = strlen(ppath) + strlen(name) + 1; len = snprintf(pathbuf, pathlen, "%s%s/", ppath, name);
if (len >= pathlen) { if (len >= pathlen) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
strncpy(pathbuf, ppath, pathlen);
strncat(pathbuf, name, strlen(name));
strcat(pathbuf, "/");
err = bpmp_populate_debugfs_inband(bpmp, dentry, err = bpmp_populate_debugfs_inband(bpmp, dentry,
pathbuf); pathbuf);
if (err < 0) if (err < 0)
......
This diff is collapsed.
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#define TI_SCI_MSG_RM_RING_RECONFIG 0x1102 #define TI_SCI_MSG_RM_RING_RECONFIG 0x1102
#define TI_SCI_MSG_RM_RING_RESET 0x1103 #define TI_SCI_MSG_RM_RING_RESET 0x1103
#define TI_SCI_MSG_RM_RING_CFG 0x1110 #define TI_SCI_MSG_RM_RING_CFG 0x1110
#define TI_SCI_MSG_RM_RING_GET_CFG 0x1111
/* PSI-L requests */ /* PSI-L requests */
#define TI_SCI_MSG_RM_PSIL_PAIR 0x1280 #define TI_SCI_MSG_RM_PSIL_PAIR 0x1280
...@@ -574,8 +573,10 @@ struct ti_sci_msg_req_get_resource_range { ...@@ -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. * struct ti_sci_msg_resp_get_resource_range - Response to resource get range.
* @hdr: Generic Header * @hdr: Generic Header
* @range_start: Start index of the resource range. * @range_start: Start index of the first resource range.
* @range_num: Number of resources in the 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. * Response to request TI_SCI_MSG_GET_RESOURCE_RANGE.
*/ */
...@@ -583,6 +584,8 @@ struct ti_sci_msg_resp_get_resource_range { ...@@ -583,6 +584,8 @@ struct ti_sci_msg_resp_get_resource_range {
struct ti_sci_msg_hdr hdr; struct ti_sci_msg_hdr hdr;
u16 range_start; u16 range_start;
u16 range_num; u16 range_num;
u16 range_start_sec;
u16 range_num_sec;
} __packed; } __packed;
/** /**
...@@ -656,6 +659,8 @@ struct ti_sci_msg_req_manage_irq { ...@@ -656,6 +659,8 @@ struct ti_sci_msg_req_manage_irq {
* 3 - Valid bit for @tisci_msg_rm_ring_cfg_req mode * 3 - Valid bit for @tisci_msg_rm_ring_cfg_req mode
* 4 - Valid bit for @tisci_msg_rm_ring_cfg_req size * 4 - Valid bit for @tisci_msg_rm_ring_cfg_req size
* 5 - Valid bit for @tisci_msg_rm_ring_cfg_req order_id * 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 * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
* @index: ring index to be configured. * @index: ring index to be configured.
* @addr_lo: 32 LSBs of ring base address to be programmed into the ring's * @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 { ...@@ -669,6 +674,9 @@ struct ti_sci_msg_req_manage_irq {
* the formula (log2(size_bytes) - 2), where size_bytes cannot be * the formula (log2(size_bytes) - 2), where size_bytes cannot be
* greater than 256. * greater than 256.
* @order_id: Specifies the ring's bus order ID. * @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_rm_ring_cfg_req {
struct ti_sci_msg_hdr hdr; struct ti_sci_msg_hdr hdr;
...@@ -681,49 +689,8 @@ struct ti_sci_msg_rm_ring_cfg_req { ...@@ -681,49 +689,8 @@ struct ti_sci_msg_rm_ring_cfg_req {
u8 mode; u8 mode;
u8 size; u8 size;
u8 order_id; u8 order_id;
} __packed; u16 virtid;
u8 asel;
/**
* 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;
} __packed; } __packed;
/** /**
...@@ -910,6 +877,8 @@ struct rm_ti_sci_msg_udmap_rx_flow_opt_cfg { ...@@ -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 * 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 * 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 * 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 * @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 { ...@@ -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 * @tx_burst_size: UDMAP transmit channel burst size configuration to be
* programmed into the tx_burst_size field of the TCHAN_TCFG register. * 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_rm_udmap_tx_ch_cfg_req {
struct ti_sci_msg_hdr hdr; struct ti_sci_msg_hdr hdr;
...@@ -994,6 +972,8 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg_req { ...@@ -994,6 +972,8 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg_req {
u16 fdepth; u16 fdepth;
u8 tx_sched_priority; u8 tx_sched_priority;
u8 tx_burst_size; u8 tx_burst_size;
u8 tx_tdtype;
u8 extended_ch_type;
} __packed; } __packed;
/** /**
......
...@@ -615,13 +615,13 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_data); ...@@ -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 * zynqmp_pm_set_sd_tapdelay() - Set tap delay for the SD device
* *
* @node_id Node ID of the device * @node_id: Node ID of the device
* @type Type of tap delay to set (input/output) * @type: Type of tap delay to set (input/output)
* @value Value to set fot the tap delay * @value: Value to set fot the tap delay
* *
* This function sets input/output tap delay for the SD device. * 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) 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); ...@@ -633,12 +633,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
/** /**
* zynqmp_pm_sd_dll_reset() - Reset DLL logic * zynqmp_pm_sd_dll_reset() - Reset DLL logic
* *
* @node_id Node ID of the device * @node_id: Node ID of the device
* @type Reset type * @type: Reset type
* *
* This function resets DLL logic for the SD device. * 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) int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
{ {
...@@ -649,12 +649,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset); ...@@ -649,12 +649,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
/** /**
* zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs) * zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs)
* @index GGS register index * @index: GGS register index
* @value Register value to be written * @value: Register value to be written
* *
* This function writes value to GGS register. * 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) int zynqmp_pm_write_ggs(u32 index, u32 value)
{ {
...@@ -665,12 +665,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs); ...@@ -665,12 +665,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);
/** /**
* zynqmp_pm_write_ggs() - PM API for reading global general storage (ggs) * zynqmp_pm_write_ggs() - PM API for reading global general storage (ggs)
* @index GGS register index * @index: GGS register index
* @value Register value to be written * @value: Register value to be written
* *
* This function returns GGS register value. * 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) int zynqmp_pm_read_ggs(u32 index, u32 *value)
{ {
...@@ -682,12 +682,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs); ...@@ -682,12 +682,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs);
/** /**
* zynqmp_pm_write_pggs() - PM API for writing persistent global general * zynqmp_pm_write_pggs() - PM API for writing persistent global general
* storage (pggs) * storage (pggs)
* @index PGGS register index * @index: PGGS register index
* @value Register value to be written * @value: Register value to be written
* *
* This function writes value to PGGS register. * 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) int zynqmp_pm_write_pggs(u32 index, u32 value)
{ {
...@@ -699,12 +699,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs); ...@@ -699,12 +699,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
/** /**
* zynqmp_pm_write_pggs() - PM API for reading persistent global general * zynqmp_pm_write_pggs() - PM API for reading persistent global general
* storage (pggs) * storage (pggs)
* @index PGGS register index * @index: PGGS register index
* @value Register value to be written * @value: Register value to be written
* *
* This function returns PGGS register value. * 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) int zynqmp_pm_read_pggs(u32 index, u32 *value)
{ {
...@@ -715,12 +715,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs); ...@@ -715,12 +715,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);
/** /**
* zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status * 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 * This function sets healthy bit value to indicate boot health status
* to firmware. * 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) int zynqmp_pm_set_boot_health_status(u32 value)
{ {
...@@ -815,10 +815,10 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status); ...@@ -815,10 +815,10 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status);
* zynqmp_pm_init_finalize() - PM call to inform firmware that the caller * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
* master has initialized its own power management * 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 * This API function is to be used for notify the power management controller
* about the completed power management initialization. * about the completed power management initialization.
*
* Return: Returns status, either success or error+reason
*/ */
int zynqmp_pm_init_finalize(void) int zynqmp_pm_init_finalize(void)
{ {
......
...@@ -829,8 +829,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ...@@ -829,8 +829,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #if IS_REACHABLE(CONFIG_MTK_CMDQ)
mtk_crtc->cmdq_client = mtk_crtc->cmdq_client =
cmdq_mbox_create(mtk_crtc->mmsys_dev, cmdq_mbox_create(mtk_crtc->mmsys_dev,
drm_crtc_index(&mtk_crtc->base), drm_crtc_index(&mtk_crtc->base));
2000);
if (IS_ERR(mtk_crtc->cmdq_client)) { if (IS_ERR(mtk_crtc->cmdq_client)) {
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n", dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
drm_crtc_index(&mtk_crtc->base)); drm_crtc_index(&mtk_crtc->base));
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#define MTK_DRM_DDP_COMP_H #define MTK_DRM_DDP_COMP_H
#include <linux/io.h> #include <linux/io.h>
#include <linux/soc/mediatek/mtk-mmsys.h>
struct device; struct device;
struct device_node; struct device_node;
...@@ -35,39 +36,6 @@ enum mtk_ddp_comp_type { ...@@ -35,39 +36,6 @@ enum mtk_ddp_comp_type {
MTK_DDP_COMP_TYPE_MAX, 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 mtk_ddp_comp;
struct cmdq_pkt; struct cmdq_pkt;
struct mtk_ddp_comp_funcs { struct mtk_ddp_comp_funcs {
......
...@@ -805,25 +805,6 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, ...@@ -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); ret = of_dma_configure(drm->dev, dev->of_node, true);
if (ret) if (ret)
return 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; backend->engine.node = dev->of_node;
......
...@@ -30,7 +30,7 @@ static inline u64 __pow10(u8 x) ...@@ -30,7 +30,7 @@ static inline u64 __pow10(u8 x)
static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value) static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
{ {
s8 scale = sensor->scale; int scale = sensor->scale;
u64 f; u64 f;
switch (sensor->type) { switch (sensor->type) {
......
...@@ -167,33 +167,6 @@ static int sun4i_csi_probe(struct platform_device *pdev) ...@@ -167,33 +167,6 @@ static int sun4i_csi_probe(struct platform_device *pdev)
if (!csi->traits) if (!csi->traits)
return -EINVAL; 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; csi->mdev.dev = csi->dev;
strscpy(csi->mdev.model, "Allwinner Video Capture Device", strscpy(csi->mdev.model, "Allwinner Video Capture Device",
sizeof(csi->mdev.model)); sizeof(csi->mdev.model));
......
...@@ -881,14 +881,6 @@ static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev, ...@@ -881,14 +881,6 @@ static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev,
return 0; 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) static int sun6i_csi_probe(struct platform_device *pdev)
{ {
struct sun6i_csi_dev *sdev; struct sun6i_csi_dev *sdev;
...@@ -899,15 +891,6 @@ static int sun6i_csi_probe(struct platform_device *pdev) ...@@ -899,15 +891,6 @@ static int sun6i_csi_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
sdev->dev = &pdev->dev; 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); ret = sun6i_csi_resource_request(sdev, pdev);
if (ret) if (ret)
......
...@@ -825,10 +825,6 @@ static int deinterlace_probe(struct platform_device *pdev) ...@@ -825,10 +825,6 @@ static int deinterlace_probe(struct platform_device *pdev)
return ret; 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); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->base = devm_ioremap_resource(&pdev->dev, res); dev->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dev->base)) if (IS_ERR(dev->base))
......
...@@ -128,7 +128,7 @@ config OMAP_GPMC_DEBUG ...@@ -128,7 +128,7 @@ config OMAP_GPMC_DEBUG
config TI_EMIF_SRAM config TI_EMIF_SRAM
tristate "Texas Instruments EMIF SRAM driver" 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 depends on SRAM
help help
This driver is for the EMIF module available on Texas Instruments This driver is for the EMIF module available on Texas Instruments
...@@ -191,8 +191,8 @@ config DA8XX_DDRCTL ...@@ -191,8 +191,8 @@ config DA8XX_DDRCTL
config PL353_SMC config PL353_SMC
tristate "ARM PL35X Static Memory Controller(SMC) driver" tristate "ARM PL35X Static Memory Controller(SMC) driver"
default y if ARM default y if ARM
depends on ARM depends on ARM || COMPILE_TEST
depends on ARM_AMBA || COMPILE_TEST depends on ARM_AMBA
help help
This driver is for the ARM PL351/PL353 Static Memory This driver is for the ARM PL351/PL353 Static Memory
Controller(SMC) module. Controller(SMC) module.
......
...@@ -291,6 +291,8 @@ static int jz4780_nemc_probe(struct platform_device *pdev) ...@@ -291,6 +291,8 @@ static int jz4780_nemc_probe(struct platform_device *pdev)
nemc->dev = dev; nemc->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
/* /*
* The driver currently only uses the registers up to offset * The driver currently only uses the registers up to offset
...@@ -304,9 +306,9 @@ static int jz4780_nemc_probe(struct platform_device *pdev) ...@@ -304,9 +306,9 @@ static int jz4780_nemc_probe(struct platform_device *pdev)
} }
nemc->base = devm_ioremap(dev, res->start, NEMC_REG_LEN); 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"); dev_err(dev, "failed to get I/O memory\n");
return PTR_ERR(nemc->base); return -ENOMEM;
} }
writel(0, nemc->base + NEMC_NFCSR); writel(0, nemc->base + NEMC_NFCSR);
......
...@@ -268,6 +268,10 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = { ...@@ -268,6 +268,10 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
/* IPU0 | IPU1 | CCU */ /* 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[] = { static const struct of_device_id mtk_smi_larb_of_ids[] = {
{ {
.compatible = "mediatek,mt8167-smi-larb", .compatible = "mediatek,mt8167-smi-larb",
...@@ -293,6 +297,10 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { ...@@ -293,6 +297,10 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
.compatible = "mediatek,mt8183-smi-larb", .compatible = "mediatek,mt8183-smi-larb",
.data = &mtk_smi_larb_mt8183 .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 = { ...@@ -432,6 +440,13 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
F_MMU1_LARB(7), 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[] = { static const struct of_device_id mtk_smi_common_of_ids[] = {
{ {
.compatible = "mediatek,mt8173-smi-common", .compatible = "mediatek,mt8173-smi-common",
...@@ -457,6 +472,10 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { ...@@ -457,6 +472,10 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
.compatible = "mediatek,mt8183-smi-common", .compatible = "mediatek,mt8183-smi-common",
.data = &mtk_smi_common_mt8183, .data = &mtk_smi_common_mt8183,
}, },
{
.compatible = "mediatek,mt8192-smi-common",
.data = &mtk_smi_common_mt8192,
},
{} {}
}; };
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/reset.h> #include <linux/reset.h>
...@@ -204,18 +203,6 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev) ...@@ -204,18 +203,6 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
} }
EXPORT_SYMBOL(rpcif_sw_init); 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) void rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
{ {
u32 dummy; u32 dummy;
...@@ -508,7 +495,8 @@ int rpcif_manual_xfer(struct rpcif *rpc) ...@@ -508,7 +495,8 @@ int rpcif_manual_xfer(struct rpcif *rpc)
return ret; return ret;
err_out: 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); rpcif_hw_init(rpc, rpc->bus_size == 2);
goto exit; goto exit;
} }
...@@ -560,9 +548,11 @@ static int rpcif_probe(struct platform_device *pdev) ...@@ -560,9 +548,11 @@ static int rpcif_probe(struct platform_device *pdev)
} else if (of_device_is_compatible(flash, "cfi-flash")) { } else if (of_device_is_compatible(flash, "cfi-flash")) {
name = "rpc-if-hyperflash"; name = "rpc-if-hyperflash";
} else { } else {
of_node_put(flash);
dev_warn(&pdev->dev, "unknown flash type\n"); dev_warn(&pdev->dev, "unknown flash type\n");
return -ENODEV; return -ENODEV;
} }
of_node_put(flash);
vdev = platform_device_alloc(name, pdev->id); vdev = platform_device_alloc(name, pdev->id);
if (!vdev) if (!vdev)
......
...@@ -3,14 +3,17 @@ config TEGRA_MC ...@@ -3,14 +3,17 @@ config TEGRA_MC
bool "NVIDIA Tegra Memory Controller support" bool "NVIDIA Tegra Memory Controller support"
default y default y
depends on ARCH_TEGRA depends on ARCH_TEGRA
select INTERCONNECT
help help
This driver supports the Memory Controller (MC) hardware found on This driver supports the Memory Controller (MC) hardware found on
NVIDIA Tegra SoCs. NVIDIA Tegra SoCs.
config TEGRA20_EMC config TEGRA20_EMC
bool "NVIDIA Tegra20 External Memory Controller driver" tristate "NVIDIA Tegra20 External Memory Controller driver"
default y 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 help
This driver is for the External Memory Controller (EMC) found on This driver is for the External Memory Controller (EMC) found on
Tegra20 chips. The EMC controls the external DRAM on the board. Tegra20 chips. The EMC controls the external DRAM on the board.
...@@ -18,9 +21,10 @@ config TEGRA20_EMC ...@@ -18,9 +21,10 @@ config TEGRA20_EMC
external memory. external memory.
config TEGRA30_EMC config TEGRA30_EMC
bool "NVIDIA Tegra30 External Memory Controller driver" tristate "NVIDIA Tegra30 External Memory Controller driver"
default y default y
depends on TEGRA_MC && ARCH_TEGRA_3x_SOC depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
select PM_OPP
help help
This driver is for the External Memory Controller (EMC) found on This driver is for the External Memory Controller (EMC) found on
Tegra30 chips. The EMC controls the external DRAM on the board. Tegra30 chips. The EMC controls the external DRAM on the board.
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -42,6 +43,54 @@ static const struct of_device_id tegra_mc_of_match[] = { ...@@ -42,6 +43,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, 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, static int tegra_mc_block_dma_common(struct tegra_mc *mc,
const struct tegra_mc_reset *rst) const struct tegra_mc_reset *rst)
{ {
...@@ -298,6 +347,7 @@ int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate) ...@@ -298,6 +347,7 @@ int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra_mc_write_emem_configuration);
unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc) 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) ...@@ -309,6 +359,7 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
return dram_count; return dram_count;
} }
EXPORT_SYMBOL_GPL(tegra_mc_get_emem_device_count);
static int load_one_timing(struct tegra_mc *mc, static int load_one_timing(struct tegra_mc *mc,
struct tegra_mc_timing *timing, struct tegra_mc_timing *timing,
...@@ -591,6 +642,101 @@ static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data) ...@@ -591,6 +642,101 @@ static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
return IRQ_HANDLED; 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) static int tegra_mc_probe(struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;
...@@ -659,10 +805,8 @@ static int tegra_mc_probe(struct platform_device *pdev) ...@@ -659,10 +805,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
} }
mc->irq = platform_get_irq(pdev, 0); mc->irq = platform_get_irq(pdev, 0);
if (mc->irq < 0) { if (mc->irq < 0)
dev_err(&pdev->dev, "interrupt not specified\n");
return mc->irq; return mc->irq;
}
WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n"); 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) ...@@ -681,6 +825,11 @@ static int tegra_mc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to register reset controller: %d\n", dev_err(&pdev->dev, "failed to register reset controller: %d\n",
err); 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) { if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU) && mc->soc->smmu) {
mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc); mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc);
if (IS_ERR(mc->smmu)) { if (IS_ERR(mc->smmu)) {
......
...@@ -78,6 +78,20 @@ ...@@ -78,6 +78,20 @@
#define MC_TIMING_UPDATE BIT(0) #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) static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
{ {
return readl_relaxed(mc->regs + offset); return readl_relaxed(mc->regs + offset);
...@@ -115,4 +129,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc; ...@@ -115,4 +129,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
extern const struct tegra_mc_soc tegra210_mc_soc; extern const struct tegra_mc_soc tegra210_mc_soc;
#endif #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 */ #endif /* MEMORY_TEGRA_MC_H */
...@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra114_mc_clients[] = { ...@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra114_mc_clients[] = {
.id = 0x00, .id = 0x00,
.name = "ptcr", .name = "ptcr",
.swgroup = TEGRA_SWGROUP_PTC, .swgroup = TEGRA_SWGROUP_PTC,
.la = {
.reg = 0x34c,
.shift = 0,
.mask = 0xff,
.def = 0x0,
},
}, { }, {
.id = 0x01, .id = 0x01,
.name = "display0a", .name = "display0a",
......
...@@ -1177,10 +1177,8 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc) ...@@ -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) static int tegra_emc_probe(struct platform_device *pdev)
{ {
struct platform_device *mc;
struct device_node *np; struct device_node *np;
struct tegra_emc *emc; struct tegra_emc *emc;
struct resource *res;
u32 ram_code; u32 ram_code;
int err; int err;
...@@ -1190,25 +1188,13 @@ static int tegra_emc_probe(struct platform_device *pdev) ...@@ -1190,25 +1188,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
emc->dev = &pdev->dev; emc->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); emc->regs = devm_platform_ioremap_resource(pdev, 0);
emc->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(emc->regs)) if (IS_ERR(emc->regs))
return PTR_ERR(emc->regs); return PTR_ERR(emc->regs);
np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0); emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
if (!np) { if (IS_ERR(emc->mc))
dev_err(&pdev->dev, "could not get memory controller\n"); return PTR_ERR(emc->mc);
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;
ram_code = tegra_read_ram_code(); ram_code = tegra_read_ram_code();
......
...@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra124_mc_clients[] = { ...@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra124_mc_clients[] = {
.id = 0x00, .id = 0x00,
.name = "ptcr", .name = "ptcr",
.swgroup = TEGRA_SWGROUP_PTC, .swgroup = TEGRA_SWGROUP_PTC,
.la = {
.reg = 0x34c,
.shift = 0,
.mask = 0xff,
.def = 0x0,
},
}, { }, {
.id = 0x01, .id = 0x01,
.name = "display0a", .name = "display0a",
......
This diff is collapsed.
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. * 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 <dt-bindings/memory/tegra20-mc.h>
#include "mc.h" #include "mc.h"
...@@ -280,6 +284,78 @@ static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = { ...@@ -280,6 +284,78 @@ static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
.reset_status = tegra20_mc_reset_status, .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 = { const struct tegra_mc_soc tegra20_mc_soc = {
.clients = tegra20_mc_clients, .clients = tegra20_mc_clients,
.num_clients = ARRAY_SIZE(tegra20_mc_clients), .num_clients = ARRAY_SIZE(tegra20_mc_clients),
...@@ -290,4 +366,5 @@ const struct tegra_mc_soc tegra20_mc_soc = { ...@@ -290,4 +366,5 @@ const struct tegra_mc_soc tegra20_mc_soc = {
.reset_ops = &tegra20_mc_reset_ops, .reset_ops = &tegra20_mc_reset_ops,
.resets = tegra20_mc_resets, .resets = tegra20_mc_resets,
.num_resets = ARRAY_SIZE(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) ...@@ -1828,7 +1828,6 @@ static int tegra210_emc_probe(struct platform_device *pdev)
{ {
struct thermal_cooling_device *cd; struct thermal_cooling_device *cd;
unsigned long current_rate; unsigned long current_rate;
struct platform_device *mc;
struct tegra210_emc *emc; struct tegra210_emc *emc;
struct device_node *np; struct device_node *np;
unsigned int i; unsigned int i;
...@@ -1846,35 +1845,19 @@ static int tegra210_emc_probe(struct platform_device *pdev) ...@@ -1846,35 +1845,19 @@ static int tegra210_emc_probe(struct platform_device *pdev)
spin_lock_init(&emc->lock); spin_lock_init(&emc->lock);
emc->dev = &pdev->dev; emc->dev = &pdev->dev;
np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0); emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
if (!np) { if (IS_ERR(emc->mc))
dev_err(&pdev->dev, "could not get memory controller\n"); return PTR_ERR(emc->mc);
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->regs = devm_platform_ioremap_resource(pdev, 0); emc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(emc->regs)) { if (IS_ERR(emc->regs))
err = PTR_ERR(emc->regs); return PTR_ERR(emc->regs);
goto put_mc;
}
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
emc->channel[i] = devm_platform_ioremap_resource(pdev, 1 + i); emc->channel[i] = devm_platform_ioremap_resource(pdev, 1 + i);
if (IS_ERR(emc->channel[i])) { if (IS_ERR(emc->channel[i]))
err = PTR_ERR(emc->channel[i]); return PTR_ERR(emc->channel[i]);
goto put_mc;
}
} }
tegra210_emc_detect(emc); tegra210_emc_detect(emc);
...@@ -1884,7 +1867,7 @@ static int tegra210_emc_probe(struct platform_device *pdev) ...@@ -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"); err = of_reserved_mem_device_init_by_name(emc->dev, np, "nominal");
if (err < 0) { if (err < 0) {
dev_err(emc->dev, "failed to get nominal EMC table: %d\n", err); 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"); 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) ...@@ -2015,8 +1998,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
tegra210_clk_emc_detach(emc->clk); tegra210_clk_emc_detach(emc->clk);
release: release:
of_reserved_mem_device_release(emc->dev); of_reserved_mem_device_release(emc->dev);
put_mc:
put_device(emc->mc->dev);
return err; return err;
} }
...@@ -2027,7 +2009,6 @@ static int tegra210_emc_remove(struct platform_device *pdev) ...@@ -2027,7 +2009,6 @@ static int tegra210_emc_remove(struct platform_device *pdev)
debugfs_remove_recursive(emc->debugfs.root); debugfs_remove_recursive(emc->debugfs.root);
tegra210_clk_emc_detach(emc->clk); tegra210_clk_emc_detach(emc->clk);
of_reserved_mem_device_release(emc->dev); of_reserved_mem_device_release(emc->dev);
put_device(emc->mc->dev);
return 0; return 0;
} }
......
...@@ -24,7 +24,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -24,7 +24,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2e8, .reg = 0x2e8,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0xc2, .def = 0x1e,
}, },
}, { }, {
.id = 0x02, .id = 0x02,
...@@ -38,7 +38,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -38,7 +38,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f4, .reg = 0x2f4,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0xc6, .def = 0x1e,
}, },
}, { }, {
.id = 0x03, .id = 0x03,
...@@ -52,7 +52,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -52,7 +52,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2e8, .reg = 0x2e8,
.shift = 16, .shift = 16,
.mask = 0xff, .mask = 0xff,
.def = 0x50, .def = 0x1e,
}, },
}, { }, {
.id = 0x04, .id = 0x04,
...@@ -66,7 +66,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -66,7 +66,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f4, .reg = 0x2f4,
.shift = 16, .shift = 16,
.mask = 0xff, .mask = 0xff,
.def = 0x50, .def = 0x1e,
}, },
}, { }, {
.id = 0x05, .id = 0x05,
...@@ -80,7 +80,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -80,7 +80,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2ec, .reg = 0x2ec,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0x50, .def = 0x1e,
}, },
}, { }, {
.id = 0x06, .id = 0x06,
...@@ -94,7 +94,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -94,7 +94,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f8, .reg = 0x2f8,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0x50, .def = 0x1e,
}, },
}, { }, {
.id = 0x0e, .id = 0x0e,
...@@ -108,7 +108,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -108,7 +108,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2e0, .reg = 0x2e0,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0x13, .def = 0x2e,
}, },
}, { }, {
.id = 0x0f, .id = 0x0f,
...@@ -136,7 +136,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -136,7 +136,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f0, .reg = 0x2f0,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0x50, .def = 0x1e,
}, },
}, { }, {
.id = 0x11, .id = 0x11,
...@@ -150,7 +150,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -150,7 +150,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2fc, .reg = 0x2fc,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0x50, .def = 0x1e,
}, },
}, { }, {
.id = 0x15, .id = 0x15,
...@@ -380,7 +380,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -380,7 +380,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x350, .reg = 0x350,
.shift = 16, .shift = 16,
.mask = 0xff, .mask = 0xff,
.def = 0x65, .def = 0x80,
}, },
}, { }, {
.id = 0x44, .id = 0x44,
...@@ -620,7 +620,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -620,7 +620,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x2f0, .reg = 0x2f0,
.shift = 16, .shift = 16,
.mask = 0xff, .mask = 0xff,
.def = 0x50, .def = 0x1e,
}, },
}, { }, {
.id = 0x60, .id = 0x60,
...@@ -648,7 +648,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -648,7 +648,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x3bc, .reg = 0x3bc,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0x49, .def = 0x5a,
}, },
}, { }, {
.id = 0x62, .id = 0x62,
...@@ -676,7 +676,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -676,7 +676,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x3c4, .reg = 0x3c4,
.shift = 0, .shift = 0,
.mask = 0xff, .mask = 0xff,
.def = 0x49, .def = 0x5a,
}, },
}, { }, {
.id = 0x64, .id = 0x64,
...@@ -897,7 +897,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -897,7 +897,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.bit = 1, .bit = 1,
}, },
.la = { .la = {
.reg = 0xb98, .reg = 0x3e0,
.shift = 16, .shift = 16,
.mask = 0xff, .mask = 0xff,
.def = 0x80, .def = 0x80,
...@@ -956,7 +956,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -956,7 +956,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x3ec, .reg = 0x3ec,
.shift = 16, .shift = 16,
.mask = 0xff, .mask = 0xff,
.def = 0xff, .def = 0x80,
}, },
}, { }, {
.id = 0x86, .id = 0x86,
...@@ -1020,35 +1020,45 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { ...@@ -1020,35 +1020,45 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
}; };
static const struct tegra_smmu_swgroup tegra210_swgroups[] = { 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 = "afi", .swgroup = TEGRA_SWGROUP_AFI, .reg = 0x238 },
{ .name = "avpc", .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c }, { .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 = "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 = "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 = "ppcs", .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 },
{ .name = "sata", .swgroup = TEGRA_SWGROUP_SATA, .reg = 0x274 }, { .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_host", .swgroup = TEGRA_SWGROUP_XUSB_HOST, .reg = 0x288 },
{ .name = "xusb_dev", .swgroup = TEGRA_SWGROUP_XUSB_DEV, .reg = 0x28c }, { .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 = "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 = "sdmmc1a", .swgroup = TEGRA_SWGROUP_SDMMC1A, .reg = 0xa94 },
{ .name = "sdmmc2a", .swgroup = TEGRA_SWGROUP_SDMMC2A, .reg = 0xa98 }, { .name = "sdmmc2a", .swgroup = TEGRA_SWGROUP_SDMMC2A, .reg = 0xa98 },
{ .name = "sdmmc3a", .swgroup = TEGRA_SWGROUP_SDMMC3A, .reg = 0xa9c }, { .name = "sdmmc3a", .swgroup = TEGRA_SWGROUP_SDMMC3A, .reg = 0xa9c },
{ .name = "sdmmc4a", .swgroup = TEGRA_SWGROUP_SDMMC4A, .reg = 0xaa0 }, { .name = "sdmmc4a", .swgroup = TEGRA_SWGROUP_SDMMC4A, .reg = 0xaa0 },
{ .name = "vic", .swgroup = TEGRA_SWGROUP_VIC, .reg = 0x284 }, { .name = "isp2b", .swgroup = TEGRA_SWGROUP_ISP2B, .reg = 0xaa4 },
{ .name = "vi", .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 }, { .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 = "nvdec", .swgroup = TEGRA_SWGROUP_NVDEC, .reg = 0xab4 },
{ .name = "ape", .swgroup = TEGRA_SWGROUP_APE, .reg = 0xab8 }, { .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 = "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 = "axiap", .swgroup = TEGRA_SWGROUP_AXIAP, .reg = 0xacc },
{ .name = "etr", .swgroup = TEGRA_SWGROUP_ETR, .reg = 0xad0 }, { .name = "etr", .swgroup = TEGRA_SWGROUP_ETR, .reg = 0xad0 },
{ .name = "tsecb", .swgroup = TEGRA_SWGROUP_TSECB, .reg = 0xad4 }, { .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[] = { static const unsigned int tegra210_group_display[] = {
......
This diff is collapsed.
This diff is collapsed.
...@@ -258,6 +258,7 @@ config OMAP_CF ...@@ -258,6 +258,7 @@ config OMAP_CF
config AT91_CF config AT91_CF
tristate "AT91 CompactFlash Controller" tristate "AT91 CompactFlash Controller"
depends on PCI depends on PCI
depends on OF
depends on PCMCIA && ARCH_AT91 depends on PCMCIA && ARCH_AT91
help help
Say Y here to support the CompactFlash controller on AT91 chips. Say Y here to support the CompactFlash controller on AT91 chips.
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/platform_data/atmel.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
...@@ -35,6 +34,17 @@ ...@@ -35,6 +34,17 @@
#define CF_IO_PHYS (1 << 23) #define CF_IO_PHYS (1 << 23)
#define CF_MEM_PHYS (0x017ff800) #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; struct regmap *mc;
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
...@@ -209,16 +219,18 @@ static struct pccard_operations at91_cf_ops = { ...@@ -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[] = { static const struct of_device_id at91_cf_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-cf" }, { .compatible = "atmel,at91rm9200-cf" },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, at91_cf_dt_ids); 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); board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL);
if (!board) if (!board)
...@@ -229,33 +241,9 @@ static int at91_cf_dt_init(struct platform_device *pdev) ...@@ -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->vcc_pin = of_get_gpio(pdev->dev.of_node, 2);
board->rst_pin = of_get_gpio(pdev->dev.of_node, 3); 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"); mc = syscon_regmap_lookup_by_compatible("atmel,at91rm9200-sdramc");
if (IS_ERR(mc))
return PTR_ERR_OR_ZERO(mc); return PTR_ERR(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 (!gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin)) if (!gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin))
return -ENODEV; return -ENODEV;
...@@ -399,7 +387,7 @@ static int at91_cf_resume(struct platform_device *pdev) ...@@ -399,7 +387,7 @@ static int at91_cf_resume(struct platform_device *pdev)
static struct platform_driver at91_cf_driver = { static struct platform_driver at91_cf_driver = {
.driver = { .driver = {
.name = "at91_cf", .name = "at91_cf",
.of_match_table = of_match_ptr(at91_cf_dt_ids), .of_match_table = at91_cf_dt_ids,
}, },
.probe = at91_cf_probe, .probe = at91_cf_probe,
.remove = at91_cf_remove, .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 @@ ...@@ -2,3 +2,4 @@
obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.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