Merge 0c86b42439 ("Merge tag 'drm-next-2025-03-28' of https://gitlab.freedesktop.org/drm/kernel") into android-mainline

Steps on the way to v6.15-rc1

Fix conflicts in:
	Kconfig

Change-Id: I04652afa0917b82d09ddf649c40e47a60fa32f4e
Signed-off-by: Tudor Ambarus <tudordana@google.com>
This commit is contained in:
Tudor Ambarus authored and Carlos Llamas committed 2025-04-18 03:46:46 +00:00
commit 3769b69ae8
1916 files changed
+153871 -56912

No files matched your search

+7 -5
View File
@@ -199,10 +199,11 @@ Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
<dev.kurt@vandijck-laurijssen.be> <kurt.van.dijck@eia.be>
Dikshita Agarwal <quic_dikshita@quicinc.com> <dikshita@codeaurora.org>
Dmitry Baryshkov <dbaryshkov@gmail.com>
Dmitry Baryshkov <dbaryshkov@gmail.com> <[dbaryshkov@gmail.com]>
Dmitry Baryshkov <dbaryshkov@gmail.com> <dmitry_baryshkov@mentor.com>
Dmitry Baryshkov <dbaryshkov@gmail.com> <dmitry_eremin@mentor.com>
Dmitry Baryshkov <lumag@kernel.org> <dbaryshkov@gmail.com>
Dmitry Baryshkov <lumag@kernel.org> <[dbaryshkov@gmail.com]>
Dmitry Baryshkov <lumag@kernel.org> <dmitry_baryshkov@mentor.com>
Dmitry Baryshkov <lumag@kernel.org> <dmitry_eremin@mentor.com>
Dmitry Baryshkov <lumag@kernel.org> <dmitry.baryshkov@linaro.org>
Dmitry Safonov <0x7f454c46@gmail.com> <dima@arista.com>
Dmitry Safonov <0x7f454c46@gmail.com> <d.safonov@partner.samsung.com>
Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
@@ -323,7 +324,8 @@ Jeff Johnson <jeff.johnson@oss.qualcomm.com> <quic_jjohnson@quicinc.com>
Jeff Layton <jlayton@kernel.org> <jlayton@poochiereds.net>
Jeff Layton <jlayton@kernel.org> <jlayton@primarydata.com>
Jeff Layton <jlayton@kernel.org> <jlayton@redhat.com>
Jeffrey Hugo <quic_jhugo@quicinc.com> <jhugo@codeaurora.org>
Jeff Hugo <jeff.hugo@oss.qualcomm.com> <jhugo@codeaurora.org>
Jeff Hugo <jeff.hugo@oss.qualcomm.com> <quic_jhugo@quicinc.com>
Jens Axboe <axboe@kernel.dk> <axboe@suse.de>
Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com>
Jens Axboe <axboe@kernel.dk> <axboe@fb.com>
+15
View File
@@ -2187,6 +2187,10 @@ D: Various ACPI fixes, keeping correct battery state through suspend
D: various lockdep annotations, autofs and other random bugfixes
S: Prague, Czech Republic
N: Ishizaki Kou
E: kou.ishizaki@toshiba.co.jp
D: Spidernet driver for PowerPC Cell platforms
N: Gene Kozin
E: 74604.152@compuserve.com
W: https://www.sangoma.com
@@ -2197,6 +2201,9 @@ S: Markham, Ontario
S: L3R 8B2
S: Canada
N: Christian Krafft
D: PowerPC Cell support
N: Maxim Krasnyansky
E: maxk@qualcomm.com
W: http://vtun.sf.net
@@ -2389,6 +2396,10 @@ S: ICP vortex GmbH
S: Neckarsulm
S: Germany
N: Geoff Levand
E: geoff@infradead.org
D: Spidernet driver for PowerPC Cell platforms
N: Phil Lewis
E: beans@bucket.ualr.edu
D: Promised to send money if I would put his name in the source tree.
@@ -3950,6 +3961,10 @@ S: 1 Amherst Street
S: Cambridge, Massachusetts 02139
S: USA
N: Luben Tuikov
E: Luben Tuikov <ltuikov89@gmail.com>
D: Maintainer of the DRM GPU Scheduler
N: Simmule Turner
E: sturner@tele-tv.com
D: Added swapping to filesystem
@@ -108,3 +108,19 @@ Contact: intel-xe@lists.freedesktop.org
Description: RO. Package current voltage in millivolt.
Only supported for particular Intel Xe graphics platforms.
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_input
Date: March 2025
KernelVersion: 6.14
Contact: intel-xe@lists.freedesktop.org
Description: RO. Package temperature in millidegree Celsius.
Only supported for particular Intel Xe graphics platforms.
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp3_input
Date: March 2025
KernelVersion: 6.14
Contact: intel-xe@lists.freedesktop.org
Description: RO. VRAM temperature in millidegree Celsius.
Only supported for particular Intel Xe graphics platforms.
@@ -55,4 +55,5 @@ Date: May 2024
Contact: linuxppc-dev@lists.ozlabs.org
Description: read/write
This is a special sysfs file available to setup additional
parameters to be passed to capture kernel.
parameters to be passed to capture kernel. For HASH MMU it
is exported only if RMA size higher than 768MB.
+1
View File
@@ -48,3 +48,4 @@ subdirectories.
Yama
SafeSetID
ipe
landlock
+158
View File
@@ -0,0 +1,158 @@
.. SPDX-License-Identifier: GPL-2.0
.. Copyright © 2025 Microsoft Corporation
================================
Landlock: system-wide management
================================
:Author: Mickaël Salaün
:Date: March 2025
Landlock can leverage the audit framework to log events.
User space documentation can be found here:
Documentation/userspace-api/landlock.rst.
Audit
=====
Denied access requests are logged by default for a sandboxed program if `audit`
is enabled. This default behavior can be changed with the
sys_landlock_restrict_self() flags (cf.
Documentation/userspace-api/landlock.rst). Landlock logs can also be masked
thanks to audit rules. Landlock can generate 2 audit record types.
Record types
------------
AUDIT_LANDLOCK_ACCESS
This record type identifies a denied access request to a kernel resource.
The ``domain`` field indicates the ID of the domain that blocked the
request. The ``blockers`` field indicates the cause(s) of this denial
(separated by a comma), and the following fields identify the kernel object
(similar to SELinux). There may be more than one of this record type per
audit event.
Example with a file link request generating two records in the same event::
domain=195ba459b blockers=fs.refer path="/usr/bin" dev="vda2" ino=351
domain=195ba459b blockers=fs.make_reg,fs.refer path="/usr/local" dev="vda2" ino=365
AUDIT_LANDLOCK_DOMAIN
This record type describes the status of a Landlock domain. The ``status``
field can be either ``allocated`` or ``deallocated``.
The ``allocated`` status is part of the same audit event and follows
the first logged ``AUDIT_LANDLOCK_ACCESS`` record of a domain. It identifies
Landlock domain information at the time of the sys_landlock_restrict_self()
call with the following fields:
- the ``domain`` ID
- the enforcement ``mode``
- the domain creator's ``pid``
- the domain creator's ``uid``
- the domain creator's executable path (``exe``)
- the domain creator's command line (``comm``)
Example::
domain=195ba459b status=allocated mode=enforcing pid=300 uid=0 exe="/root/sandboxer" comm="sandboxer"
The ``deallocated`` status is an event on its own and it identifies a
Landlock domain release. After such event, it is guarantee that the
related domain ID will never be reused during the lifetime of the system.
The ``domain`` field indicates the ID of the domain which is released, and
the ``denials`` field indicates the total number of denied access request,
which might not have been logged according to the audit rules and
sys_landlock_restrict_self()'s flags.
Example::
domain=195ba459b status=deallocated denials=3
Event samples
--------------
Here are two examples of log events (see serial numbers).
In this example a sandboxed program (``kill``) tries to send a signal to the
init process, which is denied because of the signal scoping restriction
(``LL_SCOPED=s``)::
$ LL_FS_RO=/ LL_FS_RW=/ LL_SCOPED=s LL_FORCE_LOG=1 ./sandboxer kill 1
This command generates two events, each identified with a unique serial
number following a timestamp (``msg=audit(1729738800.268:30)``). The first
event (serial ``30``) contains 4 records. The first record
(``type=LANDLOCK_ACCESS``) shows an access denied by the domain `1a6fdc66f`.
The cause of this denial is signal scopping restriction
(``blockers=scope.signal``). The process that would have receive this signal
is the init process (``opid=1 ocomm="systemd"``).
The second record (``type=LANDLOCK_DOMAIN``) describes (``status=allocated``)
domain `1a6fdc66f`. This domain was created by process ``286`` executing the
``/root/sandboxer`` program launched by the root user.
The third record (``type=SYSCALL``) describes the syscall, its provided
arguments, its result (``success=no exit=-1``), and the process that called it.
The fourth record (``type=PROCTITLE``) shows the command's name as an
hexadecimal value. This can be translated with ``python -c
'print(bytes.fromhex("6B696C6C0031"))'``.
Finally, the last record (``type=LANDLOCK_DOMAIN``) is also the only one from
the second event (serial ``31``). It is not tied to a direct user space action
but an asynchronous one to free resources tied to a Landlock domain
(``status=deallocated``). This can be useful to know that the following logs
will not concern the domain ``1a6fdc66f`` anymore. This record also summarize
the number of requests this domain denied (``denials=1``), whether they were
logged or not.
.. code-block::
type=LANDLOCK_ACCESS msg=audit(1729738800.268:30): domain=1a6fdc66f blockers=scope.signal opid=1 ocomm="systemd"
type=LANDLOCK_DOMAIN msg=audit(1729738800.268:30): domain=1a6fdc66f status=allocated mode=enforcing pid=286 uid=0 exe="/root/sandboxer" comm="sandboxer"
type=SYSCALL msg=audit(1729738800.268:30): arch=c000003e syscall=62 success=no exit=-1 [..] ppid=272 pid=286 auid=0 uid=0 gid=0 [...] comm="kill" [...]
type=PROCTITLE msg=audit(1729738800.268:30): proctitle=6B696C6C0031
type=LANDLOCK_DOMAIN msg=audit(1729738800.324:31): domain=1a6fdc66f status=deallocated denials=1
Here is another example showcasing filesystem access control::
$ LL_FS_RO=/ LL_FS_RW=/tmp LL_FORCE_LOG=1 ./sandboxer sh -c "echo > /etc/passwd"
The related audit logs contains 8 records from 3 different events (serials 33,
34 and 35) created by the same domain `1a6fdc679`::
type=LANDLOCK_ACCESS msg=audit(1729738800.221:33): domain=1a6fdc679 blockers=fs.write_file path="/dev/tty" dev="devtmpfs" ino=9
type=LANDLOCK_DOMAIN msg=audit(1729738800.221:33): domain=1a6fdc679 status=allocated mode=enforcing pid=289 uid=0 exe="/root/sandboxer" comm="sandboxer"
type=SYSCALL msg=audit(1729738800.221:33): arch=c000003e syscall=257 success=no exit=-13 [...] ppid=272 pid=289 auid=0 uid=0 gid=0 [...] comm="sh" [...]
type=PROCTITLE msg=audit(1729738800.221:33): proctitle=7368002D63006563686F203E202F6574632F706173737764
type=LANDLOCK_ACCESS msg=audit(1729738800.221:34): domain=1a6fdc679 blockers=fs.write_file path="/etc/passwd" dev="vda2" ino=143821
type=SYSCALL msg=audit(1729738800.221:34): arch=c000003e syscall=257 success=no exit=-13 [...] ppid=272 pid=289 auid=0 uid=0 gid=0 [...] comm="sh" [...]
type=PROCTITLE msg=audit(1729738800.221:34): proctitle=7368002D63006563686F203E202F6574632F706173737764
type=LANDLOCK_DOMAIN msg=audit(1729738800.261:35): domain=1a6fdc679 status=deallocated denials=2
Event filtering
---------------
If you get spammed with audit logs related to Landlock, this is either an
attack attempt or a bug in the security policy. We can put in place some
filters to limit noise with two complementary ways:
- with sys_landlock_restrict_self()'s flags if we can fix the sandboxed
programs,
- or with audit rules (see :manpage:`auditctl(8)`).
Additional documentation
========================
* `Linux Audit Documentation`_
* Documentation/userspace-api/landlock.rst
* Documentation/security/landlock.rst
* https://landlock.io
.. Links
.. _Linux Audit Documentation:
https://github.com/linux-audit/audit-documentation/wiki
@@ -278,12 +278,7 @@ To reduce its OS jitter, do any of the following:
due to the rtas_event_scan() function.
WARNING: Please check your CPU specifications to
make sure that this is safe on your particular system.
e. If running on Cell Processor, build your kernel with
CBE_CPUFREQ_SPU_GOVERNOR=n to avoid OS jitter from
spu_gov_work().
WARNING: Please check your CPU specifications to
make sure that this is safe on your particular system.
f. If running on PowerMAC, build your kernel with
e. If running on PowerMAC, build your kernel with
CONFIG_PMAC_RACKMETER=n to disable the CPU-meter,
avoiding OS jitter from rackmeter_do_timer().
@@ -120,6 +120,28 @@ to ensure that crash data is preserved to process later.
e.g.
# echo 1 > /sys/firmware/opal/mpipl/release_core
-- Support for Additional Kernel Arguments in Fadump
Fadump has a feature that allows passing additional kernel arguments
to the fadump kernel. This feature was primarily designed to disable
kernel functionalities that are not required for the fadump kernel
and to reduce its memory footprint while collecting the dump.
Command to Add Additional Kernel Parameters to Fadump:
e.g.
# echo "nr_cpus=16" > /sys/kernel/fadump/bootargs_append
The above command is sufficient to add additional arguments to fadump.
An explicit service restart is not required.
Command to Retrieve the Additional Fadump Arguments:
e.g.
# cat /sys/kernel/fadump/bootargs_append
Note: Additional kernel arguments for fadump with HASH MMU is only
supported if the RMA size is greater than 768 MB. If the RMA
size is less than 768 MB, the kernel does not export the
/sys/kernel/fadump/bootargs_append sysfs node.
Implementation details:
-----------------------
@@ -289,6 +289,17 @@ to be issued multiple times in order to be completely serviced. The
subsequent hcalls to the hypervisor until the hcall is completely serviced
at which point H_SUCCESS or other error is returned by the hypervisor.
**H_HTM**
| Input: flags, target, operation (op), op-param1, op-param2, op-param3
| Out: *dumphtmbufferdata*
| Return Value: *H_Success,H_Busy,H_LongBusyOrder,H_Partial,H_Parameter,
H_P2,H_P3,H_P4,H_P5,H_P6,H_State,H_Not_Available,H_Authority*
H_HTM supports setup, configuration, control and dumping of Hardware Trace
Macro (HTM) function and its data. HTM buffer stores tracing data for functions
like core instruction, core LLAT and nest.
References
==========
.. [1] "Power Architecture Platform Reference"
@@ -0,0 +1,83 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/apple,h7-display-pipe-mipi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Apple pre-DCP display controller MIPI interface
maintainers:
- Sasha Finkelstein <fnkl.kernel@gmail.com>
description:
The MIPI controller part of the pre-DCP Apple display controller
allOf:
- $ref: dsi-controller.yaml#
properties:
compatible:
items:
- enum:
- apple,t8112-display-pipe-mipi
- apple,t8103-display-pipe-mipi
- const: apple,h7-display-pipe-mipi
reg:
maxItems: 1
power-domains:
maxItems: 1
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description: Input port. Always connected to the primary controller
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: Output MIPI DSI port to the panel
required:
- port@0
- port@1
required:
- compatible
- reg
- ports
unevaluatedProperties: false
examples:
- |
dsi@28200000 {
compatible = "apple,t8103-display-pipe-mipi", "apple,h7-display-pipe-mipi";
reg = <0x28200000 0xc000>;
power-domains = <&ps_dispdfr_mipi>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dfr_adp_out_mipi: endpoint {
remote-endpoint = <&dfr_adp_out_mipi>;
};
};
port@1 {
reg = <1>;
dfr_panel_in: endpoint {
remote-endpoint = <&dfr_mipi_out_panel>;
};
};
};
};
...
@@ -0,0 +1,88 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/apple,h7-display-pipe.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Apple pre-DCP display controller
maintainers:
- Sasha Finkelstein <fnkl.kernel@gmail.com>
description:
A secondary display controller used to drive the "touchbar" on
certain Apple laptops.
properties:
compatible:
items:
- enum:
- apple,t8112-display-pipe
- apple,t8103-display-pipe
- const: apple,h7-display-pipe
reg:
items:
- description: Primary register block, controls planes and blending
- description:
Contains other configuration registers like interrupt
and FIFO control
reg-names:
items:
- const: be
- const: fe
power-domains:
description:
Phandles to pmgr entries that are needed for this controller to turn on.
Aside from that, their specific functions are unknown
maxItems: 2
interrupts:
items:
- description: Unknown function
- description: Primary interrupt. Vsync events are reported via it
interrupt-names:
items:
- const: be
- const: fe
iommus:
maxItems: 1
port:
$ref: /schemas/graph.yaml#/properties/port
description: Output port. Always connected to apple,h7-display-pipe-mipi
required:
- compatible
- reg
- interrupts
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/apple-aic.h>
display-pipe@28200000 {
compatible = "apple,t8103-display-pipe", "apple,h7-display-pipe";
reg = <0x28200000 0xc000>,
<0x28400000 0x4000>;
reg-names = "be", "fe";
power-domains = <&ps_dispdfr_fe>, <&ps_dispdfr_be>;
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 502 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 506 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "be", "fe";
iommus = <&displaydfr_dart 0>;
port {
dfr_adp_out_mipi: endpoint {
remote-endpoint = <&dfr_mipi_in_adp>;
};
};
};
...
@@ -35,6 +35,9 @@ properties:
vcc-supply:
description: A 1.8V power supply (see regulator/regulator.yaml).
interrupts:
maxItems: 1
ports:
$ref: /schemas/graph.yaml#/properties/ports
@@ -27,6 +27,7 @@ properties:
- mediatek,mt8188-dp-intf
- mediatek,mt8192-dpi
- mediatek,mt8195-dp-intf
- mediatek,mt8195-dpi
- items:
- enum:
- mediatek,mt6795-dpi
@@ -35,6 +36,10 @@ properties:
- enum:
- mediatek,mt8365-dpi
- const: mediatek,mt8192-dpi
- items:
- enum:
- mediatek,mt8188-dpi
- const: mediatek,mt8195-dpi
reg:
maxItems: 1
@@ -116,11 +121,13 @@ examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/mt8173-clk.h>
#include <dt-bindings/power/mt8173-power.h>
dpi: dpi@1401d000 {
compatible = "mediatek,mt8173-dpi";
reg = <0x1401d000 0x1000>;
interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DPI_PIXEL>,
<&mmsys CLK_MM_DPI_ENGINE>,
<&apmixedsys CLK_APMIXED_TVDPLL>;
@@ -22,6 +22,9 @@ properties:
oneOf:
- enum:
- mediatek,mt8195-disp-dsc
- items:
- const: mediatek,mt8188-disp-dsc
- const: mediatek,mt8195-disp-dsc
reg:
maxItems: 1
@@ -231,6 +231,7 @@ allOf:
then:
properties:
clocks:
minItems: 7
maxItems: 7
clock-names:
items:
@@ -248,29 +249,12 @@ allOf:
contains:
enum:
- qcom,msm8916-dsi-ctrl
then:
properties:
clocks:
maxItems: 6
clock-names:
items:
- const: mdp_core
- const: iface
- const: bus
- const: byte
- const: pixel
- const: core
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8953-dsi-ctrl
- qcom,msm8976-dsi-ctrl
then:
properties:
clocks:
minItems: 6
maxItems: 6
clock-names:
items:
@@ -291,6 +275,7 @@ allOf:
then:
properties:
clocks:
minItems: 7
maxItems: 7
clock-names:
items:
@@ -311,6 +296,7 @@ allOf:
then:
properties:
clocks:
minItems: 7
maxItems: 7
clock-names:
items:
@@ -328,28 +314,13 @@ allOf:
contains:
enum:
- qcom,msm8998-dsi-ctrl
- qcom,sm6125-dsi-ctrl
- qcom,sm6350-dsi-ctrl
then:
properties:
clocks:
maxItems: 6
clock-names:
items:
- const: byte
- const: byte_intf
- const: pixel
- const: core
- const: iface
- const: bus
- if:
properties:
compatible:
contains:
enum:
- qcom,sc7180-dsi-ctrl
- qcom,sc7280-dsi-ctrl
- qcom,sdm845-dsi-ctrl
- qcom,sm6115-dsi-ctrl
- qcom,sm6125-dsi-ctrl
- qcom,sm6350-dsi-ctrl
- qcom,sm6375-dsi-ctrl
- qcom,sm6150-dsi-ctrl
- qcom,sm7150-dsi-ctrl
- qcom,sm8150-dsi-ctrl
@@ -361,6 +332,7 @@ allOf:
then:
properties:
clocks:
minItems: 6
maxItems: 6
clock-names:
items:
@@ -380,6 +352,7 @@ allOf:
then:
properties:
clocks:
minItems: 9
maxItems: 9
clock-names:
items:
@@ -393,27 +366,6 @@ allOf:
- const: pixel
- const: core
- if:
properties:
compatible:
contains:
enum:
- qcom,sdm845-dsi-ctrl
- qcom,sm6115-dsi-ctrl
- qcom,sm6375-dsi-ctrl
then:
properties:
clocks:
maxItems: 6
clock-names:
items:
- const: byte
- const: byte_intf
- const: pixel
- const: core
- const: iface
- const: bus
unevaluatedProperties: false
examples:
@@ -15,6 +15,8 @@ description:
properties:
"#clock-cells":
const: 1
description:
See include/dt-bindings/clock/qcom,dsi-phy-28nm.h for clock IDs.
"#phy-cells":
const: 0
@@ -123,6 +123,7 @@ allOf:
compatible:
contains:
enum:
- qcom,adreno-gmu-623.0
- qcom,adreno-gmu-635.0
- qcom,adreno-gmu-660.1
- qcom,adreno-gmu-663.0
@@ -52,6 +52,13 @@ patternProperties:
items:
- const: qcom,sa8775p-dp
"^phy@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,sa8775p-edp-phy
required:
- compatible
@@ -61,6 +68,7 @@ examples:
- |
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,sa8775p-dispcc.h>
#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
@@ -158,6 +166,26 @@ examples:
};
};
mdss0_dp0_phy: phy@aec2a00 {
compatible = "qcom,sa8775p-edp-phy";
reg = <0x0aec2a00 0x200>,
<0x0aec2200 0xd0>,
<0x0aec2600 0xd0>,
<0x0aec2000 0x1c8>;
clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>,
<&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>;
clock-names = "aux",
"cfg_ahb";
#clock-cells = <1>;
#phy-cells = <0>;
vdda-phy-supply = <&vreg_l1c>;
vdda-pll-supply = <&vreg_l4a>;
};
displayport-controller@af54000 {
compatible = "qcom,sa8775p-dp";
@@ -186,9 +214,9 @@ examples:
assigned-clocks = <&dispcc_mdss_dptx0_link_clk_src>,
<&dispcc_mdss_dptx0_pixel0_clk_src>;
assigned-clock-parents = <&mdss0_edp_phy 0>, <&mdss0_edp_phy 1>;
assigned-clock-parents = <&mdss0_dp0_phy 0>, <&mdss0_dp0_phy 1>;
phys = <&mdss0_edp_phy>;
phys = <&mdss0_dp0_phy>;
phy-names = "dp";
operating-points-v2 = <&dp_opp_table>;
@@ -30,10 +30,14 @@ properties:
maxItems: 1
interconnects:
maxItems: 2
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 2
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":
@@ -91,9 +95,9 @@ examples:
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
interconnects = <&mmss_noc MASTER_MDP 0 &gem_noc SLAVE_LLCC 0>,
<&mc_virt MASTER_LLCC 0 &mc_virt SLAVE_EBI1 0>;
interconnect-names = "mdp0-mem", "mdp1-mem";
interconnects = <&mmss_noc MASTER_MDP 0 &mc_virt SLAVE_EBI1 0>,
<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_DISPLAY_CFG 0>;
interconnect-names = "mdp0-mem", "cpu-cfg";
resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
@@ -29,10 +29,14 @@ properties:
maxItems: 1
interconnects:
maxItems: 2
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 2
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":
@@ -75,12 +79,17 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
#include <dt-bindings/interconnect/qcom,sm8650-rpmh.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8650-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
interconnects = <&mmss_noc MASTER_MDP 0 &mc_virt SLAVE_EBI1 0>,
<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_DISPLAY_CFG 0>;
interconnect-names = "mdp0-mem", "cpu-cfg";
resets = <&dispcc_core_bcr>;
power-domains = <&dispcc_gdsc>;
@@ -0,0 +1,58 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/apple,summit.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Apple "Summit" display panel
maintainers:
- Sasha Finkelstein <fnkl.kernel@gmail.com>
description:
An OLED panel used as a touchbar on certain Apple laptops.
Contains a backlight device, which controls brightness of the panel itself.
The backlight common properties are included for this reason
allOf:
- $ref: panel-common.yaml#
- $ref: /schemas/leds/backlight/common.yaml#
properties:
compatible:
items:
- enum:
- apple,j293-summit
- apple,j493-summit
- const: apple,summit
reg:
maxItems: 1
required:
- compatible
- reg
- max-brightness
- port
unevaluatedProperties: false
examples:
- |
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
compatible = "apple,j293-summit", "apple,summit";
reg = <0>;
max-brightness = <255>;
port {
endpoint {
remote-endpoint = <&dfr_bridge_out>;
};
};
};
};
...
@@ -18,8 +18,14 @@ properties:
- enum:
# Boe nv110wum-l60 11.0" WUXGA TFT LCD panel
- boe,nv110wum-l60
# CSOT pna957qt1-1 10.95" WUXGA TFT LCD panel
- csot,pna957qt1-1
# IVO t109nw41 11.0" WUXGA TFT LCD panel
- ivo,t109nw41
# KINGDISPLAY KD110N11-51IE 10.95" WUXGA TFT LCD panel
- kingdisplay,kd110n11-51ie
# STARRY 2082109QFH040022-50E 10.95" WUXGA TFT LCD panel
- starry,2082109qfh040022-50e
# STARRY himax83102-j02 10.51" WUXGA TFT LCD panel
- starry,himax83102-j02
- const: himax,hx83102
@@ -40,6 +40,8 @@ properties:
- auo,g185han01
# AU Optronics Corporation 19.0" (1280x1024) TFT LCD panel
- auo,g190ean01
# BOE AV123Z7M-N17 12.3" (1920x720) LVDS TFT LCD panel
- boe,av123z7m-n17
# Kaohsiung Opto-Electronics Inc. 10.1" WUXGA (1920 x 1200) LVDS TFT LCD panel
- koe,tx26d202vm0bwa
# Lincoln Technology Solutions, LCD185-101CT 10.1" TFT 1920x1200
@@ -63,6 +63,8 @@ properties:
- auo,t215hvn01
# Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
- avic,tm070ddh03
# BOE AV101HDT-a10 10.1" 1280x720 LVDS panel
- boe,av101hdt-a10
# BOE BP082WX1-100 8.2" WXGA (1280x800) LVDS panel
- boe,bp082wx1-100
# BOE BP101WX1-100 10.1" WXGA (1280x800) LVDS panel
@@ -0,0 +1,72 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/raydium,rm67200.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Raydium RM67200 based MIPI-DSI panels
maintainers:
- Sebastian Reichel <sebastian.reichel@collabora.com>
allOf:
- $ref: panel-common.yaml#
properties:
compatible:
items:
- enum:
- wanchanglong,w552793baa
- const: raydium,rm67200
reg:
maxItems: 1
vdd-supply:
description: 2.8V Logic voltage
iovcc-supply:
description: 1.8V IO voltage
vsp-supply:
description: positive 5.5V voltage
vsn-supply:
description: negative 5.5V voltage
backlight: true
port: true
reset-gpios: true
required:
- compatible
- port
- reg
- reset-gpios
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
compatible = "wanchanglong,w552793baa", "raydium,rm67200";
reg = <0>;
vdd-supply = <&regulator1>;
iovcc-supply = <&regulator2>;
vsp-supply = <&regulator3>;
vsn-supply = <&regulator4>;
reset-gpios = <&gpiobank 42 GPIO_ACTIVE_LOW>;
port {
panel0_in: endpoint {
remote-endpoint = <&dsi0_out>;
};
};
};
};
...
@@ -0,0 +1,77 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/visionox,rm692e5.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Visionox RM692E5 6.55" 2400x1080 120Hz MIPI-DSI Panel
maintainers:
- Danila Tikhonov <danila@jiaxyga.com>
description:
The Visionox RM692E5 is a generic DSI Panel IC used to control
AMOLED panels.
allOf:
- $ref: panel-common.yaml#
properties:
compatible:
oneOf:
- enum:
- visionox,rm692e5
- items:
- enum:
- nothing,rm692e5-spacewar
- const: visionox,rm692e5
reg:
maxItems: 1
vdd-supply:
description: 3.3V source voltage rail
vddio-supply:
description: 1.8V I/O source voltage rail
reset-gpios: true
port: true
required:
- compatible
- reg
- reset-gpios
- vdd-supply
- vddio-supply
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
compatible = "nothing,rm692e5-spacewar",
"visionox,rm692e5";
reg = <0>;
reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
vdd-supply = <&vdd_oled>;
vddio-supply = <&vdd_io_oled>;
port {
panel_in: endpoint {
remote-endpoint = <&mdss_dsi0_out>;
};
};
};
};
...
@@ -47,12 +47,26 @@ properties:
maxItems: 1
# See compatible-specific constraints below.
clocks: true
clock-names: true
clocks:
minItems: 1
maxItems: 8
clock-names:
minItems: 1
maxItems: 8
interrupts:
minItems: 1
maxItems: 4
description: Interrupt specifiers, one per DU channel
resets: true
reset-names: true
resets:
minItems: 1
maxItems: 2
reset-names:
minItems: 1
maxItems: 2
power-domains:
maxItems: 1
@@ -74,7 +88,7 @@ properties:
renesas,cmms:
$ref: /schemas/types.yaml#/definitions/phandle-array
minItems: 1
minItems: 2
maxItems: 4
items:
maxItems: 1
@@ -174,6 +188,7 @@ allOf:
- pattern: '^dclkin\.[01]$'
interrupts:
minItems: 2
maxItems: 2
resets:
@@ -229,6 +244,7 @@ allOf:
- pattern: '^dclkin\.[01]$'
interrupts:
minItems: 2
maxItems: 2
resets:
@@ -282,6 +298,7 @@ allOf:
- pattern: '^dclkin\.[01]$'
interrupts:
minItems: 2
maxItems: 2
resets:
@@ -336,6 +353,7 @@ allOf:
- pattern: '^dclkin\.[01]$'
interrupts:
minItems: 2
maxItems: 2
resets:
@@ -397,6 +415,7 @@ allOf:
- pattern: '^dclkin\.[012]$'
interrupts:
minItems: 3
maxItems: 3
resets:
@@ -461,9 +480,11 @@ allOf:
- pattern: '^dclkin\.[0123]$'
interrupts:
minItems: 4
maxItems: 4
resets:
minItems: 2
maxItems: 2
reset-names:
@@ -534,9 +555,11 @@ allOf:
- pattern: '^dclkin\.[012]$'
interrupts:
minItems: 3
maxItems: 3
resets:
minItems: 2
maxItems: 2
reset-names:
@@ -605,9 +628,11 @@ allOf:
- pattern: '^dclkin\.[013]$'
interrupts:
minItems: 3
maxItems: 3
resets:
minItems: 2
maxItems: 2
reset-names:
@@ -726,6 +751,7 @@ allOf:
- pattern: '^dclkin\.[01]$'
interrupts:
minItems: 2
maxItems: 2
resets:
@@ -29,6 +29,7 @@ allOf:
properties:
compatible:
enum:
- rockchip,rk3576-dw-hdmi-qp
- rockchip,rk3588-dw-hdmi-qp
reg:
@@ -156,7 +157,7 @@ examples:
<GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "avp", "cec", "earc", "main", "hpd";
phys = <&hdptxphy_hdmi0>;
phys = <&hdptxphy0>;
power-domains = <&power RK3588_PD_VO1>;
resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>;
reset-names = "ref", "hdp";
@@ -14,12 +14,14 @@ description:
maintainers:
- Sandy Huang <hjc@rock-chips.com>
- Heiko Stuebner <heiko@sntech.de>
- Andy Yan <andyshrk@163.com>
properties:
compatible:
enum:
- rockchip,rk3566-vop
- rockchip,rk3568-vop
- rockchip,rk3576-vop
- rockchip,rk3588-vop
reg:
@@ -37,10 +39,21 @@ properties:
- const: gamma-lut
interrupts:
maxItems: 1
minItems: 1
maxItems: 4
description:
The VOP interrupt is shared by several interrupt sources, such as
frame start (VSYNC), line flag and other status interrupts.
For VOP version under rk3576, the interrupt is shared by several interrupt
sources, such as frame start (VSYNC), line flag and other interrupt status.
For VOP version from rk3576 there is a system interrupt for bus error, and
every video port has it's independent interrupts for vsync and other video
port related error interrupts.
interrupt-names:
items:
- const: sys
- const: vp0
- const: vp1
- const: vp2
# See compatible-specific constraints below.
clocks:
@@ -53,6 +66,8 @@ properties:
- description: Pixel clock for video port 2.
- description: Pixel clock for video port 3.
- description: Peripheral(vop grf/dsi) clock.
- description: Alternative pixel clock provided by HDMI0 PHY PLL.
- description: Alternative pixel clock provided by HDMI1 PHY PLL.
clock-names:
minItems: 5
@@ -64,6 +79,8 @@ properties:
- const: dclk_vp2
- const: dclk_vp3
- const: pclk_vop
- const: pll_hdmiphy0
- const: pll_hdmiphy1
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
@@ -116,6 +133,72 @@ required:
- ports
allOf:
- if:
properties:
compatible:
contains:
enum:
- rockchip,rk3566-vop
- rockchip,rk3568-vop
then:
properties:
clocks:
maxItems: 5
clock-names:
maxItems: 5
interrupts:
maxItems: 1
interrupt-names: false
ports:
required:
- port@0
- port@1
- port@2
rockchip,vo1-grf: false
rockchip,vop-grf: false
rockchip,pmu: false
required:
- rockchip,grf
- if:
properties:
compatible:
contains:
enum:
- rockchip,rk3576-vop
then:
properties:
clocks:
maxItems: 5
clock-names:
maxItems: 5
interrupts:
minItems: 4
interrupt-names:
minItems: 4
ports:
required:
- port@0
- port@1
- port@2
rockchip,vo1-grf: false
rockchip,vop-grf: false
required:
- rockchip,grf
- rockchip,pmu
- if:
properties:
compatible:
@@ -125,8 +208,16 @@ allOf:
properties:
clocks:
minItems: 7
maxItems: 9
clock-names:
minItems: 7
maxItems: 9
interrupts:
maxItems: 1
interrupt-names: false
ports:
required:
@@ -141,23 +232,6 @@ allOf:
- rockchip,vop-grf
- rockchip,pmu
else:
properties:
rockchip,vo1-grf: false
rockchip,vop-grf: false
rockchip,pmu: false
clocks:
maxItems: 5
clock-names:
maxItems: 5
ports:
required:
- port@0
- port@1
- port@2
additionalProperties: false
examples:
@@ -184,6 +258,7 @@ examples:
"dclk_vp1",
"dclk_vp2";
power-domains = <&power RK3568_PD_VO>;
rockchip,grf = <&grf>;
iommus = <&vop_mmu>;
vop_out: ports {
#address-cells = <1>;
@@ -25,6 +25,7 @@ properties:
- renesas,r9a07g044-mali
- renesas,r9a07g054-mali
- rockchip,px30-mali
- rockchip,rk3562-mali
- rockchip,rk3568-mali
- rockchip,rk3576-mali
- const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully discoverable
@@ -340,6 +340,8 @@ patternProperties:
description: Crystalfontz America, Inc.
"^csky,.*":
description: Hangzhou C-SKY Microsystems Co., Ltd
"^csot,.*":
description: Guangzhou China Star Optoelectronics Technology Co., Ltd
"^csq,.*":
description: Shenzen Chuangsiqi Technology Co.,Ltd.
"^ctera,.*":
+42 -3
View File
@@ -12,6 +12,9 @@ we have a dedicated glossary for Display Core at
The number of CUs that are active on the system. The number of active
CUs may be less than SE * SH * CU depending on the board configuration.
CE
Constant Engine
CP
Command Processor
@@ -68,6 +71,9 @@ we have a dedicated glossary for Display Core at
IB
Indirect Buffer
IMU
Integrated Management Unit (Power Management support)
IP
Intellectual Property blocks
@@ -80,6 +86,12 @@ we have a dedicated glossary for Display Core at
KIQ
Kernel Interface Queue
MC
Memory Controller
ME
MicroEngine (Graphics)
MEC
MicroEngine Compute
@@ -92,6 +104,9 @@ we have a dedicated glossary for Display Core at
MQD
Memory Queue Descriptor
PFP
Pre-Fetch Parser (Graphics)
PPLib
PowerPlay Library - PowerPlay is the power management component.
@@ -99,7 +114,10 @@ we have a dedicated glossary for Display Core at
Platform Security Processor
RLC
RunList Controller
RunList Controller. This name is a remnant of past ages and doesn't have
much meaning today. It's a group of general-purpose helper engines for
the GFX block. It's involved in GFX power management and SR-IOV, among
other things.
SDMA
System DMA
@@ -110,14 +128,35 @@ we have a dedicated glossary for Display Core at
SH
SHader array
SMU
System Management Unit
SMU/SMC
System Management Unit / System Management Controller
SRLC
Save/Restore List Control
SRLG
Save/Restore List GPM_MEM
SRLS
Save/Restore List SRM_MEM
SS
Spread Spectrum
TA
Trusted Application
TOC
Table of Contents
UVD
Unified Video Decoder
VCE
Video Compression Engine
VCN
Video Codec Next
VPE
Video Processing Engine
@@ -167,9 +167,6 @@ consider asking in the amdgfx and update this page.
MALL
Memory Access at Last Level
MC
Memory Controller
MPC/MPCC
Multiple pipes and plane combine
@@ -232,6 +229,3 @@ consider asking in the amdgfx and update this page.
VRR
Variable Refresh Rate
UVD
Unified Video Decoder
+2
View File
@@ -10,6 +10,7 @@ GPU Driver Documentation
imagination/index
mcde
meson
nouveau
pl111
tegra
tve200
@@ -24,6 +25,7 @@ GPU Driver Documentation
panfrost
panthor
zynqmp
nova/index
.. only:: subproject and html
+7
View File
@@ -208,6 +208,13 @@ follows:
``CONFIG_VIRTIO_UML`` and ``CONFIG_UML_PCI_OVER_VIRTIO`` are not
included in it because they are only required for User Mode Linux.
KUnit Coverage Rules
~~~~~~~~~~~~~~~~~~~~
KUnit support is gradually added to the DRM framework and helpers. There's no
general requirement for the framework and helpers to have KUnit tests at the
moment. However, patches that are affecting a function or helper already
covered by KUnit tests must provide tests if the change calls for one.
Legacy Support Code
===================
+113 -3
View File
@@ -371,9 +371,119 @@ Reporting causes of resets
Apart from propagating the reset through the stack so apps can recover, it's
really useful for driver developers to learn more about what caused the reset in
the first place. DRM devices should make use of devcoredump to store relevant
information about the reset, so this information can be added to user bug
reports.
the first place. For this, drivers can make use of devcoredump to store relevant
information about the reset and send device wedged event with ``none`` recovery
method (as explained in "Device Wedging" chapter) to notify userspace, so this
information can be collected and added to user bug reports.
Device Wedging
==============
Drivers can optionally make use of device wedged event (implemented as
drm_dev_wedged_event() in DRM subsystem), which notifies userspace of 'wedged'
(hanged/unusable) state of the DRM device through a uevent. This is useful
especially in cases where the device is no longer operating as expected and has
become unrecoverable from driver context. Purpose of this implementation is to
provide drivers a generic way to recover the device with the help of userspace
intervention, without taking any drastic measures (like resetting or
re-enumerating the full bus, on which the underlying physical device is sitting)
in the driver.
A 'wedged' device is basically a device that is declared dead by the driver
after exhausting all possible attempts to recover it from driver context. The
uevent is the notification that is sent to userspace along with a hint about
what could possibly be attempted to recover the device from userspace and bring
it back to usable state. Different drivers may have different ideas of a
'wedged' device depending on hardware implementation of the underlying physical
device, and hence the vendor agnostic nature of the event. It is up to the
drivers to decide when they see the need for device recovery and how they want
to recover from the available methods.
Driver prerequisites
--------------------
The driver, before opting for recovery, needs to make sure that the 'wedged'
device doesn't harm the system as a whole by taking care of the prerequisites.
Necessary actions must include disabling DMA to system memory as well as any
communication channels with other devices. Further, the driver must ensure
that all dma_fences are signalled and any device state that the core kernel
might depend on is cleaned up. All existing mmaps should be invalidated and
page faults should be redirected to a dummy page. Once the event is sent, the
device must be kept in 'wedged' state until the recovery is performed. New
accesses to the device (IOCTLs) should be rejected, preferably with an error
code that resembles the type of failure the device has encountered. This will
signify the reason for wedging, which can be reported to the application if
needed.
Recovery
--------
Current implementation defines three recovery methods, out of which, drivers
can use any one, multiple or none. Method(s) of choice will be sent in the
uevent environment as ``WEDGED=<method1>[,..,<methodN>]`` in order of less to
more side-effects. If driver is unsure about recovery or method is unknown
(like soft/hard system reboot, firmware flashing, physical device replacement
or any other procedure which can't be attempted on the fly), ``WEDGED=unknown``
will be sent instead.
Userspace consumers can parse this event and attempt recovery as per the
following expectations.
=============== ========================================
Recovery method Consumer expectations
=============== ========================================
none optional telemetry collection
rebind unbind + bind driver
bus-reset unbind + bus reset/re-enumeration + bind
unknown consumer policy
=============== ========================================
The only exception to this is ``WEDGED=none``, which signifies that the device
was temporarily 'wedged' at some point but was recovered from driver context
using device specific methods like reset. No explicit recovery is expected from
the consumer in this case, but it can still take additional steps like gathering
telemetry information (devcoredump, syslog). This is useful because the first
hang is usually the most critical one which can result in consequential hangs or
complete wedging.
Consumer prerequisites
----------------------
It is the responsibility of the consumer to make sure that the device or its
resources are not in use by any process before attempting recovery. With IOCTLs
erroring out, all device memory should be unmapped and file descriptors should
be closed to prevent leaks or undefined behaviour. The idea here is to clear the
device of all user context beforehand and set the stage for a clean recovery.
Example
-------
Udev rule::
SUBSYSTEM=="drm", ENV{WEDGED}=="rebind", DEVPATH=="*/drm/card[0-9]",
RUN+="/path/to/rebind.sh $env{DEVPATH}"
Recovery script::
#!/bin/sh
DEVPATH=$(readlink -f /sys/$1/device)
DEVICE=$(basename $DEVPATH)
DRIVER=$(readlink -f $DEVPATH/driver)
echo -n $DEVICE > $DRIVER/unbind
echo -n $DEVICE > $DRIVER/bind
Customization
-------------
Although basic recovery is possible with a simple script, consumers can define
custom policies around recovery. For example, if the driver supports multiple
recovery methods, consumers can opt for the suitable one depending on scenarios
like repeat offences or vendor specific failures. Consumers can also choose to
have the device available for debugging or telemetry collection and base their
recovery decision on the findings. This is useful especially when the driver is
unsure about recovery or method is unknown.
.. _drm_driver_ioctl:
+4 -1
View File
@@ -21,7 +21,10 @@ File format specification
- File shall contain one key value pair per one line of text.
- Colon character (`:`) must be used to delimit keys and values.
- All keys shall be prefixed with `drm-`.
- All standardised keys shall be prefixed with `drm-`.
- Driver-specific keys shall be prefixed with `driver_name-`, where
driver_name should ideally be the same as the `name` field in
`struct drm_driver`, although this is not mandatory.
- Whitespace between the delimiter and first non-whitespace character shall be
ignored when parsing.
- Keys are not allowed to contain whitespace characters.
+29
View File
@@ -0,0 +1,29 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
===============================
drm/nouveau NVIDIA GPU Driver
===============================
The drm/nouveau driver provides support for a wide range of NVIDIA GPUs,
covering GeForce, Quadro, and Tesla series, from the NV04 architecture up
to the latest Turing, Ampere, Ada families.
NVKM: NVIDIA Kernel Manager
===========================
The NVKM component serves as the core abstraction layer within the nouveau
driver, responsible for managing NVIDIA GPU hardware at the kernel level.
NVKM provides a unified interface for handling various GPU architectures.
It enables resource management, power control, memory handling, and command
submission required for the proper functioning of NVIDIA GPUs under the
nouveau driver.
NVKM plays a critical role in abstracting hardware complexities and
providing a consistent API to upper layers of the driver stack.
GSP Support
------------------------
.. kernel-doc:: drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
:doc: GSP message queue element
@@ -0,0 +1,24 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
==========
Guidelines
==========
This documents contains the guidelines for nova-core. Additionally, all common
guidelines of the Nova project do apply.
Driver API
==========
One main purpose of nova-core is to implement the abstraction around the
firmware interface of GSP and provide a firmware (version) independent API for
2nd level drivers, such as nova-drm or the vGPU manager VFIO driver.
Therefore, it is not permitted to leak firmware (version) specifics, through the
driver API, to 2nd level drivers.
Acceptance Criteria
===================
- To the extend possible, patches submitted to nova-core must be tested for
regressions with all 2nd level drivers.
+446
View File
@@ -0,0 +1,446 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
=========
Task List
=========
Tasks may have the following fields:
- ``Complexity``: Describes the required familiarity with Rust and / or the
corresponding kernel APIs or subsystems. There are four different complexities,
``Beginner``, ``Intermediate``, ``Advanced`` and ``Expert``.
- ``Reference``: References to other tasks.
- ``Link``: Links to external resources.
- ``Contact``: The person that can be contacted for further information about
the task.
Enablement (Rust)
=================
Tasks that are not directly related to nova-core, but are preconditions in terms
of required APIs.
FromPrimitive API
-----------------
Sometimes the need arises to convert a number to a value of an enum or a
structure.
A good example from nova-core would be the ``Chipset`` enum type, which defines
the value ``AD102``. When probing the GPU the value ``0x192`` can be read from a
certain register indication the chipset AD102. Hence, the enum value ``AD102``
should be derived from the number ``0x192``. Currently, nova-core uses a custom
implementation (``Chipset::from_u32`` for this.
Instead, it would be desirable to have something like the ``FromPrimitive``
trait [1] from the num crate.
Having this generalization also helps with implementing a generic macro that
automatically generates the corresponding mappings between a value and a number.
| Complexity: Beginner
| Link: https://docs.rs/num/latest/num/trait.FromPrimitive.html
Generic register abstraction
----------------------------
Work out how register constants and structures can be automatically generated
through generalized macros.
Example:
.. code-block:: rust
register!(BOOT0, 0x0, u32, pci::Bar<SIZE>, Fields [
MINOR_REVISION(3:0, RO),
MAJOR_REVISION(7:4, RO),
REVISION(7:0, RO), // Virtual register combining major and minor rev.
])
This could expand to something like:
.. code-block:: rust
const BOOT0_OFFSET: usize = 0x00000000;
const BOOT0_MINOR_REVISION_SHIFT: u8 = 0;
const BOOT0_MINOR_REVISION_MASK: u32 = 0x0000000f;
const BOOT0_MAJOR_REVISION_SHIFT: u8 = 4;
const BOOT0_MAJOR_REVISION_MASK: u32 = 0x000000f0;
const BOOT0_REVISION_SHIFT: u8 = BOOT0_MINOR_REVISION_SHIFT;
const BOOT0_REVISION_MASK: u32 = BOOT0_MINOR_REVISION_MASK | BOOT0_MAJOR_REVISION_MASK;
struct Boot0(u32);
impl Boot0 {
#[inline]
fn read(bar: &RevocableGuard<'_, pci::Bar<SIZE>>) -> Self {
Self(bar.readl(BOOT0_OFFSET))
}
#[inline]
fn minor_revision(&self) -> u32 {
(self.0 & BOOT0_MINOR_REVISION_MASK) >> BOOT0_MINOR_REVISION_SHIFT
}
#[inline]
fn major_revision(&self) -> u32 {
(self.0 & BOOT0_MAJOR_REVISION_MASK) >> BOOT0_MAJOR_REVISION_SHIFT
}
#[inline]
fn revision(&self) -> u32 {
(self.0 & BOOT0_REVISION_MASK) >> BOOT0_REVISION_SHIFT
}
}
Usage:
.. code-block:: rust
let bar = bar.try_access().ok_or(ENXIO)?;
let boot0 = Boot0::read(&bar);
pr_info!("Revision: {}\n", boot0.revision());
| Complexity: Advanced
Delay / Sleep abstractions
--------------------------
Rust abstractions for the kernel's delay() and sleep() functions.
FUJITA Tomonori plans to work on abstractions for read_poll_timeout_atomic()
(and friends) [1].
| Complexity: Beginner
| Link: https://lore.kernel.org/netdev/20250228.080550.354359820929821928.fujita.tomonori@gmail.com/ [1]
IRQ abstractions
----------------
Rust abstractions for IRQ handling.
There is active ongoing work from Daniel Almeida [1] for the "core" abstractions
to request IRQs.
Besides optional review and testing work, the required ``pci::Device`` code
around those core abstractions needs to be worked out.
| Complexity: Intermediate
| Link: https://lore.kernel.org/lkml/20250122163932.46697-1-daniel.almeida@collabora.com/ [1]
| Contact: Daniel Almeida
Page abstraction for foreign pages
----------------------------------
Rust abstractions for pages not created by the Rust page abstraction without
direct ownership.
There is active onging work from Abdiel Janulgue [1] and Lina [2].
| Complexity: Advanced
| Link: https://lore.kernel.org/linux-mm/20241119112408.779243-1-abdiel.janulgue@gmail.com/ [1]
| Link: https://lore.kernel.org/rust-for-linux/20250202-rust-page-v1-0-e3170d7fe55e@asahilina.net/ [2]
Scatterlist / sg_table abstractions
-----------------------------------
Rust abstractions for scatterlist / sg_table.
There is preceding work from Abdiel Janulgue, which hasn't made it to the
mailing list yet.
| Complexity: Intermediate
| Contact: Abdiel Janulgue
ELF utils
---------
Rust implementation of ELF header representation to retrieve section header
tables, names, and data from an ELF-formatted images.
There is preceding work from Abdiel Janulgue, which hasn't made it to the
mailing list yet.
| Complexity: Beginner
| Contact: Abdiel Janulgue
PCI MISC APIs
-------------
Extend the existing PCI device / driver abstractions by SR-IOV, config space,
capability, MSI API abstractions.
| Complexity: Beginner
Auxiliary bus abstractions
--------------------------
Rust abstraction for the auxiliary bus APIs.
This is needed to connect nova-core to the nova-drm driver.
| Complexity: Intermediate
Debugfs abstractions
--------------------
Rust abstraction for debugfs APIs.
| Reference: Export GSP log buffers
| Complexity: Intermediate
Vec extensions
--------------
Implement ``Vec::truncate`` and ``Vec::resize``.
Currently this is used for some experimental code to parse the vBIOS.
| Reference vBIOS support
| Complexity: Beginner
GPU (general)
=============
Parse firmware headers
----------------------
Parse ELF headers from the firmware files loaded from the filesystem.
| Reference: ELF utils
| Complexity: Beginner
| Contact: Abdiel Janulgue
Build radix3 page table
-----------------------
Build the radix3 page table to map the firmware.
| Complexity: Intermediate
| Contact: Abdiel Janulgue
vBIOS support
-------------
Parse the vBIOS and probe the structures required for driver initialization.
| Contact: Dave Airlie
| Reference: Vec extensions
| Complexity: Intermediate
Initial Devinit support
-----------------------
Implement BIOS Device Initialization, i.e. memory sizing, waiting, PLL
configuration.
| Contact: Dave Airlie
| Complexity: Beginner
Boot Falcon controller
----------------------
Infrastructure to load and execute falcon (sec2) firmware images; handle the
GSP falcon processor and fwsec loading.
| Complexity: Advanced
| Contact: Dave Airlie
GPU Timer support
-----------------
Support for the GPU's internal timer peripheral.
| Complexity: Beginner
| Contact: Dave Airlie
MMU / PT management
-------------------
Work out the architecture for MMU / page table management.
We need to consider that nova-drm will need rather fine-grained control,
especially in terms of locking, in order to be able to implement asynchronous
Vulkan queues.
While generally sharing the corresponding code is desirable, it needs to be
evaluated how (and if at all) sharing the corresponding code is expedient.
| Complexity: Expert
VRAM memory allocator
---------------------
Investigate options for a VRAM memory allocator.
Some possible options:
- Rust abstractions for
- RB tree (interval tree) / drm_mm
- maple_tree
- native Rust collections
| Complexity: Advanced
Instance Memory
---------------
Implement support for instmem (bar2) used to store page tables.
| Complexity: Intermediate
| Contact: Dave Airlie
GPU System Processor (GSP)
==========================
Export GSP log buffers
----------------------
Recent patches from Timur Tabi [1] added support to expose GSP-RM log buffers
(even after failure to probe the driver) through debugfs.
This is also an interesting feature for nova-core, especially in the early days.
| Link: https://lore.kernel.org/nouveau/20241030202952.694055-2-ttabi@nvidia.com/ [1]
| Reference: Debugfs abstractions
| Complexity: Intermediate
GSP firmware abstraction
------------------------
The GSP-RM firmware API is unstable and may incompatibly change from version to
version, in terms of data structures and semantics.
This problem is one of the big motivations for using Rust for nova-core, since
it turns out that Rust's procedural macro feature provides a rather elegant way
to address this issue:
1. generate Rust structures from the C headers in a separate namespace per version
2. build abstraction structures (within a generic namespace) that implement the
firmware interfaces; annotate the differences in implementation with version
identifiers
3. use a procedural macro to generate the actual per version implementation out
of this abstraction
4. instantiate the correct version type one on runtime (can be sure that all
have the same interface because it's defined by a common trait)
There is a PoC implementation of this pattern, in the context of the nova-core
PoC driver.
This task aims at refining the feature and ideally generalize it, to be usable
by other drivers as well.
| Complexity: Expert
GSP message queue
-----------------
Implement low level GSP message queue (command, status) for communication
between the kernel driver and GSP.
| Complexity: Advanced
| Contact: Dave Airlie
Bootstrap GSP
-------------
Call the boot firmware to boot the GSP processor; execute initial control
messages.
| Complexity: Intermediate
| Contact: Dave Airlie
Client / Device APIs
--------------------
Implement the GSP message interface for client / device allocation and the
corresponding client and device allocation APIs.
| Complexity: Intermediate
| Contact: Dave Airlie
Bar PDE handling
----------------
Synchronize page table handling for BARs between the kernel driver and GSP.
| Complexity: Beginner
| Contact: Dave Airlie
FIFO engine
-----------
Implement support for the FIFO engine, i.e. the corresponding GSP message
interface and provide an API for chid allocation and channel handling.
| Complexity: Advanced
| Contact: Dave Airlie
GR engine
---------
Implement support for the graphics engine, i.e. the corresponding GSP message
interface and provide an API for (golden) context creation and promotion.
| Complexity: Advanced
| Contact: Dave Airlie
CE engine
---------
Implement support for the copy engine, i.e. the corresponding GSP message
interface.
| Complexity: Intermediate
| Contact: Dave Airlie
VFN IRQ controller
------------------
Support for the VFN interrupt controller.
| Complexity: Intermediate
| Contact: Dave Airlie
External APIs
=============
nova-core base API
------------------
Work out the common pieces of the API to connect 2nd level drivers, i.e. vGPU
manager and nova-drm.
| Complexity: Advanced
vGPU manager API
----------------
Work out the API parts required by the vGPU manager, which are not covered by
the base API.
| Complexity: Advanced
nova-core C API
---------------
Implement a C wrapper for the APIs required by the vGPU manager driver.
| Complexity: Intermediate
Testing
=======
CI pipeline
-----------
Investigate option for continuous integration testing.
This can go from as simple as running KUnit tests over running (graphics) CTS to
booting up (multiple) guest VMs to test VFIO use-cases.
It might also be worth to consider the introduction of a new test suite directly
sitting on top of the uAPI for more targeted testing and debugging. There may be
options for collaboration / shared code with the Mesa project.
| Complexity: Advanced
+69
View File
@@ -0,0 +1,69 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
==========
Guidelines
==========
This document describes the general project guidelines that apply to nova-core
and nova-drm.
Language
========
The Nova project uses the Rust programming language. In this context, all rules
of the Rust for Linux project as documented in
:doc:`../../rust/general-information` apply. Additionally, the following rules
apply.
- Unless technically necessary otherwise (e.g. uAPI), any driver code is written
in Rust.
- Unless technically necessary, unsafe Rust code must be avoided. In case of
technical necessity, unsafe code should be isolated in a separate component
providing a safe API for other driver code to use.
Style
-----
All rules of the Rust for Linux project as documented in
:doc:`../../rust/coding-guidelines` apply.
For a submit checklist, please also see the `Rust for Linux Submit checklist
addendum <https://rust-for-linux.com/contributing#submit-checklist-addendum>`_.
Documentation
=============
The availability of proper documentation is essential in terms of scalability,
accessibility for new contributors and maintainability of a project in general,
but especially for a driver running as complex hardware as Nova is targeting.
Hence, adding documentation of any kind is very much encouraged by the project.
Besides that, there are some minimum requirements.
- Every non-private structure needs at least a brief doc comment explaining the
semantical sense of the structure, as well as potential locking and lifetime
requirements. It is encouraged to have the same minimum documentation for
non-trivial private structures.
- uAPIs must be fully documented with kernel-doc comments; additionally, the
semantical behavior must be explained including potential special or corner
cases.
- The APIs connecting the 1st level driver (nova-core) with 2nd level drivers
must be fully documented. This includes doc comments, potential locking and
lifetime requirements, as well as example code if applicable.
- Abbreviations must be explained when introduced; terminology must be uniquely
defined.
- Register addresses, layouts, shift values and masks must be defined properly;
unless obvious, the semantical sense must be documented. This only applies if
the author is able to obtain the corresponding information.
Acceptance Criteria
===================
- Patches must only be applied if reviewed by at least one other person on the
mailing list; this also applies for maintainers.
+30
View File
@@ -0,0 +1,30 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
=======================
nova NVIDIA GPU drivers
=======================
The nova driver project consists out of two separate drivers nova-core and
nova-drm and intends to supersede the nouveau driver for NVIDIA GPUs based on
the GPU System Processor (GSP).
The following documents apply to both nova-core and nova-drm.
.. toctree::
:titlesonly:
guidelines
nova-core
=========
The nova-core driver is the core driver for NVIDIA GPUs based on GSP. nova-core,
as the 1st level driver, provides an abstraction around the GPUs hard- and
firmware interfaces providing a common base for 2nd level drivers, such as the
vGPU manager VFIO driver and the nova-drm driver.
.. toctree::
:titlesonly:
core/guidelines
core/todo
+10
View File
@@ -26,6 +26,8 @@ the currently possible format options:
drm-cycles-panthor: 94439687187
drm-maxfreq-panthor: 1000000000 Hz
drm-curfreq-panthor: 1000000000 Hz
panthor-resident-memory: 10396 KiB
panthor-active-memory: 10396 KiB
drm-total-memory: 16480 KiB
drm-shared-memory: 0
drm-active-memory: 16200 KiB
@@ -44,3 +46,11 @@ driver by writing into the appropriate sysfs node::
Where `N` is a bit mask where cycle and timestamp sampling are respectively
enabled by the first and second bits.
Possible `panthor-*-memory` keys are: `active` and `resident`.
These values convey the sizes of the internal driver-owned shmem BO's that
aren't exposed to user-space through a DRM handle, like queue ring buffers,
sync object arrays and heap chunks. Because they are all allocated and pinned
at creation time, only `panthor-resident-memory` is necessary to tell us their
size. `panthor-active-memory` shows the size of kernel BO's associated with
VM's and groups currently being scheduled for execution by the GPU.
+112
View File
@@ -0,0 +1,112 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
===============
GPU SVM Section
===============
Agreed upon design principles
=============================
* migrate_to_ram path
* Rely only on core MM concepts (migration PTEs, page references, and
page locking).
* No driver specific locks other than locks for hardware interaction in
this path. These are not required and generally a bad idea to
invent driver defined locks to seal core MM races.
* An example of a driver-specific lock causing issues occurred before
fixing do_swap_page to lock the faulting page. A driver-exclusive lock
in migrate_to_ram produced a stable livelock if enough threads read
the faulting page.
* Partial migration is supported (i.e., a subset of pages attempting to
migrate can actually migrate, with only the faulting page guaranteed
to migrate).
* Driver handles mixed migrations via retry loops rather than locking.
* Eviction
* Eviction is defined as migrating data from the GPU back to the
CPU without a virtual address to free up GPU memory.
* Only looking at physical memory data structures and locks as opposed to
looking at virtual memory data structures and locks.
* No looking at mm/vma structs or relying on those being locked.
* The rationale for the above two points is that CPU virtual addresses
can change at any moment, while the physical pages remain stable.
* GPU page table invalidation, which requires a GPU virtual address, is
handled via the notifier that has access to the GPU virtual address.
* GPU fault side
* mmap_read only used around core MM functions which require this lock
and should strive to take mmap_read lock only in GPU SVM layer.
* Big retry loop to handle all races with the mmu notifier under the gpu
pagetable locks/mmu notifier range lock/whatever we end up calling
those.
* Races (especially against concurrent eviction or migrate_to_ram)
should not be handled on the fault side by trying to hold locks;
rather, they should be handled using retry loops. One possible
exception is holding a BO's dma-resv lock during the initial migration
to VRAM, as this is a well-defined lock that can be taken underneath
the mmap_read lock.
* One possible issue with the above approach is if a driver has a strict
migration policy requiring GPU access to occur in GPU memory.
Concurrent CPU access could cause a livelock due to endless retries.
While no current user (Xe) of GPU SVM has such a policy, it is likely
to be added in the future. Ideally, this should be resolved on the
core-MM side rather than through a driver-side lock.
* Physical memory to virtual backpointer
* This does not work, as no pointers from physical memory to virtual
memory should exist. mremap() is an example of the core MM updating
the virtual address without notifying the driver of address
change rather the driver only receiving the invalidation notifier.
* The physical memory backpointer (page->zone_device_data) should remain
stable from allocation to page free. Safely updating this against a
concurrent user would be very difficult unless the page is free.
* GPU pagetable locking
* Notifier lock only protects range tree, pages valid state for a range
(rather than seqno due to wider notifiers), pagetable entries, and
mmu notifier seqno tracking, it is not a global lock to protect
against races.
* All races handled with big retry as mentioned above.
Overview of baseline design
===========================
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Overview
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Locking
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Migration
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Partial Unmapping of Ranges
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Examples
Possible future design features
===============================
* Concurrent GPU faults
* CPU faults are concurrent so makes sense to have concurrent GPU
faults.
* Should be possible with fined grained locking in the driver GPU
fault handler.
* No expected GPU SVM changes required.
* Ranges with mixed system and device pages
* Can be added if required to drm_gpusvm_get_pages fairly easily.
* Multi-GPU support
* Work in progress and patches expected after initially landing on GPU
SVM.
* Ideally can be done with little to no changes to GPU SVM.
* Drop ranges in favor of radix tree
* May be desirable for faster notifiers.
* Compound device pages
* Nvidia, AMD, and Intel all have agreed expensive core MM functions in
migrate device layer are a performance bottleneck, having compound
device pages should help increase performance by reducing the number
of these expensive calls.
* Higher order dma mapping for migration
* 4k dma mapping adversely affects migration performance on Intel
hardware, higher order (2M) dma mapping should help here.
* Build common userptr implementation on top of GPU SVM
* Driver side madvise implementation and migration policies
* Pull in pending dma-mapping API changes from Leon / Nvidia when these land
+4
View File
@@ -16,6 +16,10 @@ host such documentation:
* Once the code has landed move all the documentation to the right places in
the main core, helper or driver sections.
.. toctree::
gpusvm.rst
.. toctree::
i915_gem_lmem.rst
@@ -55,7 +55,6 @@ Contents:
ti/cpsw_switchdev
ti/am65_nuss_cpsw_switchdev
ti/tlan
toshiba/spider_net
wangxun/txgbe
wangxun/ngbe
@@ -1,202 +0,0 @@
.. SPDX-License-Identifier: GPL-2.0
===========================
The Spidernet Device Driver
===========================
Written by Linas Vepstas <linas@austin.ibm.com>
Version of 7 June 2007
Abstract
========
This document sketches the structure of portions of the spidernet
device driver in the Linux kernel tree. The spidernet is a gigabit
ethernet device built into the Toshiba southbridge commonly used
in the SONY Playstation 3 and the IBM QS20 Cell blade.
The Structure of the RX Ring.
=============================
The receive (RX) ring is a circular linked list of RX descriptors,
together with three pointers into the ring that are used to manage its
contents.
The elements of the ring are called "descriptors" or "descrs"; they
describe the received data. This includes a pointer to a buffer
containing the received data, the buffer size, and various status bits.
There are three primary states that a descriptor can be in: "empty",
"full" and "not-in-use". An "empty" or "ready" descriptor is ready
to receive data from the hardware. A "full" descriptor has data in it,
and is waiting to be emptied and processed by the OS. A "not-in-use"
descriptor is neither empty or full; it is simply not ready. It may
not even have a data buffer in it, or is otherwise unusable.
During normal operation, on device startup, the OS (specifically, the
spidernet device driver) allocates a set of RX descriptors and RX
buffers. These are all marked "empty", ready to receive data. This
ring is handed off to the hardware, which sequentially fills in the
buffers, and marks them "full". The OS follows up, taking the full
buffers, processing them, and re-marking them empty.
This filling and emptying is managed by three pointers, the "head"
and "tail" pointers, managed by the OS, and a hardware current
descriptor pointer (GDACTDPA). The GDACTDPA points at the descr
currently being filled. When this descr is filled, the hardware
marks it full, and advances the GDACTDPA by one. Thus, when there is
flowing RX traffic, every descr behind it should be marked "full",
and everything in front of it should be "empty". If the hardware
discovers that the current descr is not empty, it will signal an
interrupt, and halt processing.
The tail pointer tails or trails the hardware pointer. When the
hardware is ahead, the tail pointer will be pointing at a "full"
descr. The OS will process this descr, and then mark it "not-in-use",
and advance the tail pointer. Thus, when there is flowing RX traffic,
all of the descrs in front of the tail pointer should be "full", and
all of those behind it should be "not-in-use". When RX traffic is not
flowing, then the tail pointer can catch up to the hardware pointer.
The OS will then note that the current tail is "empty", and halt
processing.
The head pointer (somewhat mis-named) follows after the tail pointer.
When traffic is flowing, then the head pointer will be pointing at
a "not-in-use" descr. The OS will perform various housekeeping duties
on this descr. This includes allocating a new data buffer and
dma-mapping it so as to make it visible to the hardware. The OS will
then mark the descr as "empty", ready to receive data. Thus, when there
is flowing RX traffic, everything in front of the head pointer should
be "not-in-use", and everything behind it should be "empty". If no
RX traffic is flowing, then the head pointer can catch up to the tail
pointer, at which point the OS will notice that the head descr is
"empty", and it will halt processing.
Thus, in an idle system, the GDACTDPA, tail and head pointers will
all be pointing at the same descr, which should be "empty". All of the
other descrs in the ring should be "empty" as well.
The show_rx_chain() routine will print out the locations of the
GDACTDPA, tail and head pointers. It will also summarize the contents
of the ring, starting at the tail pointer, and listing the status
of the descrs that follow.
A typical example of the output, for a nearly idle system, might be::
net eth1: Total number of descrs=256
net eth1: Chain tail located at descr=20
net eth1: Chain head is at 20
net eth1: HW curr desc (GDACTDPA) is at 21
net eth1: Have 1 descrs with stat=x40800101
net eth1: HW next desc (GDACNEXTDA) is at 22
net eth1: Last 255 descrs with stat=xa0800000
In the above, the hardware has filled in one descr, number 20. Both
head and tail are pointing at 20, because it has not yet been emptied.
Meanwhile, hw is pointing at 21, which is free.
The "Have nnn decrs" refers to the descr starting at the tail: in this
case, nnn=1 descr, starting at descr 20. The "Last nnn descrs" refers
to all of the rest of the descrs, from the last status change. The "nnn"
is a count of how many descrs have exactly the same status.
The status x4... corresponds to "full" and status xa... corresponds
to "empty". The actual value printed is RXCOMST_A.
In the device driver source code, a different set of names are
used for these same concepts, so that::
"empty" == SPIDER_NET_DESCR_CARDOWNED == 0xa
"full" == SPIDER_NET_DESCR_FRAME_END == 0x4
"not in use" == SPIDER_NET_DESCR_NOT_IN_USE == 0xf
The RX RAM full bug/feature
===========================
As long as the OS can empty out the RX buffers at a rate faster than
the hardware can fill them, there is no problem. If, for some reason,
the OS fails to empty the RX ring fast enough, the hardware GDACTDPA
pointer will catch up to the head, notice the not-empty condition,
ad stop. However, RX packets may still continue arriving on the wire.
The spidernet chip can save some limited number of these in local RAM.
When this local ram fills up, the spider chip will issue an interrupt
indicating this (GHIINT0STS will show ERRINT, and the GRMFLLINT bit
will be set in GHIINT1STS). When the RX ram full condition occurs,
a certain bug/feature is triggered that has to be specially handled.
This section describes the special handling for this condition.
When the OS finally has a chance to run, it will empty out the RX ring.
In particular, it will clear the descriptor on which the hardware had
stopped. However, once the hardware has decided that a certain
descriptor is invalid, it will not restart at that descriptor; instead
it will restart at the next descr. This potentially will lead to a
deadlock condition, as the tail pointer will be pointing at this descr,
which, from the OS point of view, is empty; the OS will be waiting for
this descr to be filled. However, the hardware has skipped this descr,
and is filling the next descrs. Since the OS doesn't see this, there
is a potential deadlock, with the OS waiting for one descr to fill,
while the hardware is waiting for a different set of descrs to become
empty.
A call to show_rx_chain() at this point indicates the nature of the
problem. A typical print when the network is hung shows the following::
net eth1: Spider RX RAM full, incoming packets might be discarded!
net eth1: Total number of descrs=256
net eth1: Chain tail located at descr=255
net eth1: Chain head is at 255
net eth1: HW curr desc (GDACTDPA) is at 0
net eth1: Have 1 descrs with stat=xa0800000
net eth1: HW next desc (GDACNEXTDA) is at 1
net eth1: Have 127 descrs with stat=x40800101
net eth1: Have 1 descrs with stat=x40800001
net eth1: Have 126 descrs with stat=x40800101
net eth1: Last 1 descrs with stat=xa0800000
Both the tail and head pointers are pointing at descr 255, which is
marked xa... which is "empty". Thus, from the OS point of view, there
is nothing to be done. In particular, there is the implicit assumption
that everything in front of the "empty" descr must surely also be empty,
as explained in the last section. The OS is waiting for descr 255 to
become non-empty, which, in this case, will never happen.
The HW pointer is at descr 0. This descr is marked 0x4.. or "full".
Since its already full, the hardware can do nothing more, and thus has
halted processing. Notice that descrs 0 through 254 are all marked
"full", while descr 254 and 255 are empty. (The "Last 1 descrs" is
descr 254, since tail was at 255.) Thus, the system is deadlocked,
and there can be no forward progress; the OS thinks there's nothing
to do, and the hardware has nowhere to put incoming data.
This bug/feature is worked around with the spider_net_resync_head_ptr()
routine. When the driver receives RX interrupts, but an examination
of the RX chain seems to show it is empty, then it is probable that
the hardware has skipped a descr or two (sometimes dozens under heavy
network conditions). The spider_net_resync_head_ptr() subroutine will
search the ring for the next full descr, and the driver will resume
operations there. Since this will leave "holes" in the ring, there
is also a spider_net_resync_tail_ptr() that will skip over such holes.
As of this writing, the spider_net_resync() strategy seems to work very
well, even under heavy network loads.
The TX ring
===========
The TX ring uses a low-watermark interrupt scheme to make sure that
the TX queue is appropriately serviced for large packet sizes.
For packet sizes greater than about 1KBytes, the kernel can fill
the TX ring quicker than the device can drain it. Once the ring
is full, the netdev is stopped. When there is room in the ring,
the netdev needs to be reawakened, so that more TX packets are placed
in the ring. The hardware can empty the ring about four times per jiffy,
so its not appropriate to wait for the poll routine to refill, since
the poll routine runs only once per jiffy. The low-watermark mechanism
marks a descr about 1/4th of the way from the bottom of the queue, so
that an interrupt is generated when the descr is processed. This
interrupt wakes up the netdev, which can then refill the queue.
For large packets, this mechanism generates a relatively small number
of interrupts, about 1K/sec. For smaller packets, this will drop to zero
interrupts, as the hardware can empty the queue faster than the kernel
can fill it.
+1
View File
@@ -63,6 +63,7 @@ Contents:
gtp
ila
ioam6-sysctl
iou-zcrx
ip_dynaddr
ipsec
ip-sysctl
+202
View File
@@ -0,0 +1,202 @@
.. SPDX-License-Identifier: GPL-2.0
=====================
io_uring zero copy Rx
=====================
Introduction
============
io_uring zero copy Rx (ZC Rx) is a feature that removes kernel-to-user copy on
the network receive path, allowing packet data to be received directly into
userspace memory. This feature is different to TCP_ZEROCOPY_RECEIVE in that
there are no strict alignment requirements and no need to mmap()/munmap().
Compared to kernel bypass solutions such as e.g. DPDK, the packet headers are
processed by the kernel TCP stack as normal.
NIC HW Requirements
===================
Several NIC HW features are required for io_uring ZC Rx to work. For now the
kernel API does not configure the NIC and it must be done by the user.
Header/data split
-----------------
Required to split packets at the L4 boundary into a header and a payload.
Headers are received into kernel memory as normal and processed by the TCP
stack as normal. Payloads are received into userspace memory directly.
Flow steering
-------------
Specific HW Rx queues are configured for this feature, but modern NICs
typically distribute flows across all HW Rx queues. Flow steering is required
to ensure that only desired flows are directed towards HW queues that are
configured for io_uring ZC Rx.
RSS
---
In addition to flow steering above, RSS is required to steer all other non-zero
copy flows away from queues that are configured for io_uring ZC Rx.
Usage
=====
Setup NIC
---------
Must be done out of band for now.
Ensure there are at least two queues::
ethtool -L eth0 combined 2
Enable header/data split::
ethtool -G eth0 tcp-data-split on
Carve out half of the HW Rx queues for zero copy using RSS::
ethtool -X eth0 equal 1
Set up flow steering, bearing in mind that queues are 0-indexed::
ethtool -N eth0 flow-type tcp6 ... action 1
Setup io_uring
--------------
This section describes the low level io_uring kernel API. Please refer to
liburing documentation for how to use the higher level API.
Create an io_uring instance with the following required setup flags::
IORING_SETUP_SINGLE_ISSUER
IORING_SETUP_DEFER_TASKRUN
IORING_SETUP_CQE32
Create memory area
------------------
Allocate userspace memory area for receiving zero copy data::
void *area_ptr = mmap(NULL, area_size,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
0, 0);
Create refill ring
------------------
Allocate memory for a shared ringbuf used for returning consumed buffers::
void *ring_ptr = mmap(NULL, ring_size,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
0, 0);
This refill ring consists of some space for the header, followed by an array of
``struct io_uring_zcrx_rqe``::
size_t rq_entries = 4096;
size_t ring_size = rq_entries * sizeof(struct io_uring_zcrx_rqe) + PAGE_SIZE;
/* align to page size */
ring_size = (ring_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
Register ZC Rx
--------------
Fill in registration structs::
struct io_uring_zcrx_area_reg area_reg = {
.addr = (__u64)(unsigned long)area_ptr,
.len = area_size,
.flags = 0,
};
struct io_uring_region_desc region_reg = {
.user_addr = (__u64)(unsigned long)ring_ptr,
.size = ring_size,
.flags = IORING_MEM_REGION_TYPE_USER,
};
struct io_uring_zcrx_ifq_reg reg = {
.if_idx = if_nametoindex("eth0"),
/* this is the HW queue with desired flow steered into it */
.if_rxq = 1,
.rq_entries = rq_entries,
.area_ptr = (__u64)(unsigned long)&area_reg,
.region_ptr = (__u64)(unsigned long)&region_reg,
};
Register with kernel::
io_uring_register_ifq(ring, &reg);
Map refill ring
---------------
The kernel fills in fields for the refill ring in the registration ``struct
io_uring_zcrx_ifq_reg``. Map it into userspace::
struct io_uring_zcrx_rq refill_ring;
refill_ring.khead = (unsigned *)((char *)ring_ptr + reg.offsets.head);
refill_ring.khead = (unsigned *)((char *)ring_ptr + reg.offsets.tail);
refill_ring.rqes =
(struct io_uring_zcrx_rqe *)((char *)ring_ptr + reg.offsets.rqes);
refill_ring.rq_tail = 0;
refill_ring.ring_ptr = ring_ptr;
Receiving data
--------------
Prepare a zero copy recv request::
struct io_uring_sqe *sqe;
sqe = io_uring_get_sqe(ring);
io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, fd, NULL, 0, 0);
sqe->ioprio |= IORING_RECV_MULTISHOT;
Now, submit and wait::
io_uring_submit_and_wait(ring, 1);
Finally, process completions::
struct io_uring_cqe *cqe;
unsigned int count = 0;
unsigned int head;
io_uring_for_each_cqe(ring, head, cqe) {
struct io_uring_zcrx_cqe *rcqe = (struct io_uring_zcrx_cqe *)(cqe + 1);
unsigned long mask = (1ULL << IORING_ZCRX_AREA_SHIFT) - 1;
unsigned char *data = area_ptr + (rcqe->off & mask);
/* do something with the data */
count++;
}
io_uring_cq_advance(ring, count);
Recycling buffers
-----------------
Return buffers back to the kernel to be used again::
struct io_uring_zcrx_rqe *rqe;
unsigned mask = refill_ring.ring_entries - 1;
rqe = &refill_ring.rqes[refill_ring.rq_tail & mask];
unsigned long area_offset = rcqe->off & ~IORING_ZCRX_AREA_MASK;
rqe->off = area_offset | area_reg.rq_area_token;
rqe->len = cqe->res;
IO_URING_WRITE_ONCE(*refill_ring.ktail, ++refill_ring.rq_tail);
Testing
=======
See ``tools/testing/selftests/drivers/net/hw/iou-zcrx.c``
+12 -1
View File
@@ -7,7 +7,7 @@ Landlock LSM: kernel documentation
==================================
:Author: Mickaël Salaün
:Date: December 2022
:Date: March 2025
Landlock's goal is to create scoped access-control (i.e. sandboxing). To
harden a whole system, this feature should be available to any process,
@@ -45,6 +45,10 @@ Guiding principles for safe access controls
sandboxed process shall retain their scoped accesses (at the time of resource
acquisition) whatever process uses them.
Cf. `File descriptor access rights`_.
* Access denials shall be logged according to system and Landlock domain
configurations. Log entries must contain information about the cause of the
denial and the owner of the related security policy. Such log generation
should have a negligible performance and memory impact on allowed requests.
Design choices
==============
@@ -124,6 +128,13 @@ makes the reasoning much easier and helps avoid pitfalls.
.. kernel-doc:: security/landlock/ruleset.h
:identifiers:
Additional documentation
========================
* Documentation/userspace-api/landlock.rst
* Documentation/admin-guide/LSM/landlock.rst
* https://landlock.io
.. Links
.. _tools/testing/selftests/landlock/:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/landlock/
+1
View File
@@ -10,3 +10,4 @@ Trusted Platform Module documentation
tpm_vtpm_proxy
xen-tpmfront
tpm_ftpm_tee
tpm_ffa_crb
@@ -0,0 +1,65 @@
.. SPDX-License-Identifier: GPL-2.0
========================
TPM CRB over FF-A Driver
========================
The TPM Command Response Buffer (CRB) interface is a standard TPM interface
defined in the TCG PC Client Platform TPM Profile (PTP) Specification [1]_.
The CRB provides a structured set of control registers a client uses when
interacting with a TPM as well as a data buffer for storing TPM commands and
responses. A CRB interface can be implemented in:
- hardware registers in a discrete TPM chip
- in memory for a TPM running in isolated environment where shared memory
allows a client to interact with the TPM
The Firmware Framework for Arm A-profile (FF-A) [2]_ is a specification
that defines interfaces and protocols for the following purposes:
- Compartmentalize firmware into software partitions that run in the Arm
Secure world environment (also know as TrustZone)
- Provide a standard interface for software components in the Non-secure
state, for example OS and Hypervisors, to communicate with this firmware.
A TPM can be implemented as an FF-A secure service. This could be a firmware
TPM or could potentially be a TPM service that acts as a proxy to a discrete
TPM chip. An FF-A based TPM abstracts hardware details (e.g. bus controller
and chip selects) away from the OS and can protect locality 4 from access
by an OS. The TCG-defined CRB interface is used by clients to interact
with the TPM service.
The Arm TPM Service Command Response Buffer Interface Over FF-A [3]_
specification defines FF-A messages that can be used by a client to signal
when updates have been made to the CRB.
How the Linux CRB driver interacts with FF-A is summarized below:
- The tpm_crb_ffa driver registers with the FF-A subsystem in the kernel
with an architected TPM service UUID defined in the CRB over FF-A spec.
- If a TPM service is discovered by FF-A, the probe() function in the
tpm_crb_ffa driver runs, and the driver initializes.
- The probing and initialization of the Linux CRB driver is triggered
by the discovery of a TPM advertised via ACPI. The CRB driver can
detect the type of TPM through the ACPI 'start' method. The start
method for Arm FF-A was defined in TCG ACPI v1.4 [4]_.
- When the CRB driver performs its normal functions such as signaling 'start'
and locality request/relinquish it invokes the tpm_crb_ffa_start() funnction
in the tpm_crb_ffa driver which handles the FF-A messaging to the TPM.
References
==========
.. [1] **TCG PC Client Platform TPM Profile (PTP) Specification**
https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
.. [2] **Arm Firmware Framework for Arm A-profile (FF-A)**
https://developer.arm.com/documentation/den0077/latest/
.. [3] **Arm TPM Service Command Response Buffer Interface Over FF-A**
https://developer.arm.com/documentation/den0138/latest/
.. [4] **TCG ACPI Specification**
https://trustedcomputinggroup.org/resource/tcg-acpi-specification/
+40 -24
View File
@@ -8,7 +8,7 @@ Landlock: unprivileged access control
=====================================
:Author: Mickaël Salaün
:Date: January 2025
:Date: March 2025
The goal of Landlock is to enable restriction of ambient rights (e.g. global
filesystem or network access) for a set of processes. Because Landlock
@@ -317,33 +317,32 @@ IPC scoping
-----------
Similar to the implicit `Ptrace restrictions`_, we may want to further restrict
interactions between sandboxes. Each Landlock domain can be explicitly scoped
for a set of actions by specifying it on a ruleset. For example, if a
sandboxed process should not be able to :manpage:`connect(2)` to a
non-sandboxed process through abstract :manpage:`unix(7)` sockets, we can
specify such a restriction with ``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET``.
Moreover, if a sandboxed process should not be able to send a signal to a
non-sandboxed process, we can specify this restriction with
``LANDLOCK_SCOPE_SIGNAL``.
interactions between sandboxes. Therefore, at ruleset creation time, each
Landlock domain can restrict the scope for certain operations, so that these
operations can only reach out to processes within the same Landlock domain or in
a nested Landlock domain (the "scope").
A sandboxed process can connect to a non-sandboxed process when its domain is
not scoped. If a process's domain is scoped, it can only connect to sockets
created by processes in the same scope.
Moreover, if a process is scoped to send signal to a non-scoped process, it can
only send signals to processes in the same scope.
The operations which can be scoped are:
A connected datagram socket behaves like a stream socket when its domain is
scoped, meaning if the domain is scoped after the socket is connected, it can
still :manpage:`send(2)` data just like a stream socket. However, in the same
scenario, a non-connected datagram socket cannot send data (with
:manpage:`sendto(2)`) outside its scope.
``LANDLOCK_SCOPE_SIGNAL``
This limits the sending of signals to target processes which run within the
same or a nested Landlock domain.
A process with a scoped domain can inherit a socket created by a non-scoped
process. The process cannot connect to this socket since it has a scoped
domain.
``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET``
This limits the set of abstract :manpage:`unix(7)` sockets to which we can
:manpage:`connect(2)` to socket addresses which were created by a process in
the same or a nested Landlock domain.
IPC scoping does not support exceptions, so if a domain is scoped, no rules can
be added to allow access to resources or processes outside of the scope.
A :manpage:`sendto(2)` on a non-connected datagram socket is treated as if
it were doing an implicit :manpage:`connect(2)` and will be blocked if the
remote end does not stem from the same or a nested Landlock domain.
A :manpage:`sendto(2)` on a socket which was previously connected will not
be restricted. This works for both datagram and stream sockets.
IPC scoping does not support exceptions via :manpage:`landlock_add_rule(2)`.
If an operation is scoped within a domain, no rules can be added to allow access
to resources or processes outside of the scope.
Truncating files
----------------
@@ -595,6 +594,16 @@ Starting with the Landlock ABI version 6, it is possible to restrict
:manpage:`signal(7)` sending by setting ``LANDLOCK_SCOPE_SIGNAL`` to the
``scoped`` ruleset attribute.
Logging (ABI < 7)
-----------------
Starting with the Landlock ABI version 7, it is possible to control logging of
Landlock audit events with the ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``,
``LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON``, and
``LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF`` flags passed to
sys_landlock_restrict_self(). See Documentation/admin-guide/LSM/landlock.rst
for more details on audit.
.. _kernel_support:
Kernel support
@@ -683,9 +692,16 @@ fine-grained restrictions). Moreover, their complexity can lead to security
issues, especially when untrusted processes can manipulate them (cf.
`Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_).
How to disable Landlock audit records?
--------------------------------------
You might want to put in place filters as explained here:
Documentation/admin-guide/LSM/landlock.rst
Additional documentation
========================
* Documentation/admin-guide/LSM/landlock.rst
* Documentation/security/landlock.rst
* https://landlock.io
+1
View File
@@ -97,3 +97,4 @@ obj-$(CONFIG_SAMPLES) += samples/
obj-$(CONFIG_NET) += net/
obj-y += virt/
obj-y += $(ARCH_DRIVERS)
obj-$(CONFIG_DRM_HEADER_TEST) += include/
+2
View File
@@ -31,5 +31,7 @@ source "lib/Kconfig.debug"
source "Documentation/Kconfig"
source "io_uring/Kconfig"
# ANDROID: Set KCONFIG_EXT_PREFIX to decend into an external project.
source "$(KCONFIG_EXT_PREFIX)Kconfig.ext"
+74 -28
View File
@@ -7166,7 +7166,7 @@ F: include/linux/power/smartreflex.h
DRM ACCEL DRIVERS FOR INTEL VPU
M: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
M: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
M: Maciej Falkowski <maciej.falkowski@linux.intel.com>
L: dri-devel@lists.freedesktop.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
@@ -7192,6 +7192,14 @@ S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/sun4i/sun8i*
DRM DRIVER FOR APPLE TOUCH BARS
M: Aun-Ali Zaidi <admin@kodeit.net>
M: Aditya Garg <gargaditya08@live.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/tiny/appletbdrm.c
DRM DRIVER FOR ARM PL111 CLCD
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
@@ -7285,8 +7293,7 @@ F: Documentation/devicetree/bindings/display/panel/panel-edp.yaml
F: drivers/gpu/drm/panel/panel-edp.c
DRM DRIVER FOR GENERIC USB DISPLAY
M: Noralf Trønnes <noralf@tronnes.org>
S: Maintained
S: Orphan
W: https://github.com/notro/gud/wiki
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/gud/
@@ -7391,15 +7398,14 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/mgag200/
DRM DRIVER FOR MI0283QT
M: Noralf Trønnes <noralf@tronnes.org>
M: Alex Lanzano <lanzano.alex@gmail.com>
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
F: drivers/gpu/drm/tiny/mi0283qt.c
DRM DRIVER FOR MIPI DBI compatible panels
M: Noralf Trønnes <noralf@tronnes.org>
S: Maintained
S: Orphan
W: https://github.com/notro/panel-mipi-dbi/wiki
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
@@ -7426,7 +7432,7 @@ F: include/uapi/drm/msm_drm.h
DRM DRIVER for Qualcomm display hardware
M: Rob Clark <robdclark@gmail.com>
M: Abhinav Kumar <quic_abhinavk@quicinc.com>
M: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
M: Dmitry Baryshkov <lumag@kernel.org>
R: Sean Paul <sean@poorly.run>
R: Marijn Suijten <marijn.suijten@somainline.org>
L: linux-arm-msm@vger.kernel.org
@@ -7438,6 +7444,7 @@ T: git https://gitlab.freedesktop.org/drm/msm.git
F: Documentation/devicetree/bindings/display/msm/
F: drivers/gpu/drm/ci/xfails/msm*
F: drivers/gpu/drm/msm/
F: include/dt-bindings/clock/qcom,dsi-phy-28nm.h
F: include/uapi/drm/msm_drm.h
DRM DRIVER FOR NOVATEK NT35510 PANELS
@@ -7483,6 +7490,17 @@ T: git https://gitlab.freedesktop.org/drm/nouveau.git
F: drivers/gpu/drm/nouveau/
F: include/uapi/drm/nouveau_drm.h
CORE DRIVER FOR NVIDIA GPUS [RUST]
M: Danilo Krummrich <dakr@kernel.org>
L: nouveau@lists.freedesktop.org
S: Supported
Q: https://patchwork.freedesktop.org/project/nouveau/
B: https://gitlab.freedesktop.org/drm/nova/-/issues
C: irc://irc.oftc.net/nouveau
T: git https://gitlab.freedesktop.org/drm/nova.git nova-next
F: Documentation/gpu/nova/
F: drivers/gpu/nova-core/
DRM DRIVER FOR OLIMEX LCD-OLINUXINO PANELS
M: Stefan Mavrodiev <stefan@olimex.com>
S: Maintained
@@ -7495,7 +7513,7 @@ F: Documentation/devicetree/bindings/display/bridge/ps8640.yaml
F: drivers/gpu/drm/bridge/parade-ps8640.c
DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS
M: Noralf Trønnes <noralf@tronnes.org>
M: Alex Lanzano <lanzano.alex@gmail.com>
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/repaper.txt
@@ -7719,8 +7737,8 @@ X: drivers/gpu/drm/mediatek/
X: drivers/gpu/drm/msm/
X: drivers/gpu/drm/nouveau/
X: drivers/gpu/drm/radeon/
X: drivers/gpu/drm/renesas/rcar-du/
X: drivers/gpu/drm/tegra/
X: drivers/gpu/drm/xe/
DRM DRIVERS FOR ALLWINNER A10
M: Maxime Ripard <mripard@kernel.org>
@@ -7873,13 +7891,30 @@ F: drivers/gpu/host1x/
F: include/linux/host1x.h
F: include/uapi/drm/tegra_drm.h
DRM DRIVERS FOR PRE-DCP APPLE DISPLAY OUTPUT
M: Sasha Finkelstein <fnkl.kernel@gmail.com>
R: Janne Grunau <j@jannau.net>
L: dri-devel@lists.freedesktop.org
L: asahi@lists.linux.dev
S: Maintained
W: https://asahilinux.org
B: https://github.com/AsahiLinux/linux/issues
C: irc://irc.oftc.net/asahi-dev
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/apple,h7-display-pipe-mipi.yaml
F: Documentation/devicetree/bindings/display/apple,h7-display-pipe.yaml
F: Documentation/devicetree/bindings/display/panel/apple,summit.yaml
F: drivers/gpu/drm/adp/
F: drivers/gpu/drm/panel/panel-summit.c
DRM DRIVERS FOR RENESAS R-CAR
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
M: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
M: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
M: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
R: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
L: dri-devel@lists.freedesktop.org
L: linux-renesas-soc@vger.kernel.org
S: Supported
T: git git://linuxtv.org/pinchartl/media drm/du/next
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml
F: Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.yaml
F: Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
@@ -8016,12 +8051,12 @@ F: Documentation/gpu/zynqmp.rst
F: drivers/gpu/drm/xlnx/
DRM GPU SCHEDULER
M: Luben Tuikov <ltuikov89@gmail.com>
M: Matthew Brost <matthew.brost@intel.com>
M: Danilo Krummrich <dakr@kernel.org>
M: Philipp Stanner <pstanner@redhat.com>
M: Philipp Stanner <phasta@kernel.org>
R: Christian König <ckoenig.leichtzumerken@gmail.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/scheduler/
F: include/drm/gpu_scheduler.h
@@ -8048,6 +8083,8 @@ F: include/drm/drm_privacy_screen*
DRM TTM SUBSYSTEM
M: Christian Koenig <christian.koenig@amd.com>
M: Huang Rui <ray.huang@amd.com>
R: Matthew Auld <matthew.auld@intel.com>
R: Matthew Brost <matthew.brost@intel.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
@@ -9161,6 +9198,22 @@ S: Odd Fixes
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/video/fbdev/core/
FRAMEBUFFER DRAWING
M: Zsolt Kajtar <soci@c64.rulez.org>
S: Odd Fixes
F: drivers/video/fbdev/core/cfbcopyarea.c
F: drivers/video/fbdev/core/cfbfillrect.c
F: drivers/video/fbdev/core/cfbimgblt.c
F: drivers/video/fbdev/core/cfbmem.h
F: drivers/video/fbdev/core/fb_copyarea.h
F: drivers/video/fbdev/core/fb_draw.h
F: drivers/video/fbdev/core/fb_fillrect.h
F: drivers/video/fbdev/core/fb_imageblit.h
F: drivers/video/fbdev/core/syscopyarea.c
F: drivers/video/fbdev/core/sysfillrect.c
F: drivers/video/fbdev/core/sysimgblt.c
F: drivers/video/fbdev/core/sysmem.h
FRAMEBUFFER LAYER
M: Helge Deller <deller@gmx.de>
L: linux-fbdev@vger.kernel.org
@@ -11731,7 +11784,7 @@ F: drivers/gpio/gpio-tangier.c
F: drivers/gpio/gpio-tangier.h
INTEL GVT-g DRIVERS (Intel GPU Virtualization)
M: Zhenyu Wang <zhenyuw@linux.intel.com>
M: Zhenyu Wang <zhenyuw.linux@gmail.com>
M: Zhi Wang <zhi.wang.linux@gmail.com>
L: intel-gvt-dev@lists.freedesktop.org
L: intel-gfx@lists.freedesktop.org
@@ -13164,6 +13217,7 @@ L: linux-security-module@vger.kernel.org
S: Supported
W: https://landlock.io
T: git https://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git
F: Documentation/admin-guide/LSM/landlock.rst
F: Documentation/security/landlock.rst
F: Documentation/userspace-api/landlock.rst
F: fs/ioctl.c
@@ -17252,8 +17306,7 @@ M: Russell King <linux@armlinux.org.uk>
S: Maintained
T: git git://git.armlinux.org.uk/~rmk/linux-arm.git drm-tda998x-devel
T: git git://git.armlinux.org.uk/~rmk/linux-arm.git drm-tda998x-fixes
F: drivers/gpu/drm/i2c/tda998x_drv.c
F: include/drm/i2c/tda998x.h
F: drivers/gpu/drm/bridge/tda998x_drv.c
F: include/dt-bindings/display/tda998x.h
K: "nxp,tda998x"
@@ -19556,7 +19609,7 @@ F: drivers/clk/qcom/
F: include/dt-bindings/clock/qcom,*
QUALCOMM CLOUD AI (QAIC) DRIVER
M: Jeffrey Hugo <quic_jhugo@quicinc.com>
M: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
R: Carl Vanderlip <quic_carlv@quicinc.com>
L: linux-arm-msm@vger.kernel.org
L: dri-devel@lists.freedesktop.org
@@ -22533,15 +22586,6 @@ F: include/linux/spi/
F: include/uapi/linux/spi/
F: tools/spi/
SPIDERNET NETWORK DRIVER for CELL
M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp>
M: Geoff Levand <geoff@infradead.org>
L: netdev@vger.kernel.org
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: Documentation/networking/device_drivers/ethernet/toshiba/spider_net.rst
F: drivers/net/ethernet/toshiba/spider_net*
SPMI SUBSYSTEM
M: Stephen Boyd <sboyd@kernel.org>
L: linux-kernel@vger.kernel.org
@@ -24202,6 +24246,8 @@ Q: https://patchwork.kernel.org/project/linux-integrity/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
F: Documentation/devicetree/bindings/tpm/
F: drivers/char/tpm/
F: include/linux/tpm*.h
F: include/uapi/linux/vtpm_proxy.h
F: tools/testing/selftests/tpm2/
TPS546D24 DRIVER
+2 -2
View File
@@ -714,10 +714,10 @@ CONFIG_VIDEO_ADV7604_CEC=y
CONFIG_VIDEO_ML86V7667=m
CONFIG_IMX_IPUV3_CORE=m
CONFIG_DRM=y
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
CONFIG_DRM_I2C_NXP_TDA998X=m
CONFIG_DRM_NOUVEAU=m
# CONFIG_DRM_NOUVEAU_CH7006 is not set
# CONFIG_DRM_NOUVEAU_SIL164 is not set
CONFIG_DRM_EXYNOS=m
CONFIG_DRM_EXYNOS_FIMD=y
CONFIG_DRM_EXYNOS_MIXER=y
+1 -3
View File
@@ -44,9 +44,7 @@ u16 crc_t10dif_arch(u16 crc, const u8 *data, size_t length)
crc_t10dif_pmull8(crc, data, length, buf);
kernel_neon_end();
crc = 0;
data = buf;
length = sizeof(buf);
return crc_t10dif_generic(0, buf, sizeof(buf));
}
}
return crc_t10dif_generic(crc, data, length);
+1 -3
View File
@@ -45,9 +45,7 @@ u16 crc_t10dif_arch(u16 crc, const u8 *data, size_t length)
crc_t10dif_pmull_p8(crc, data, length, buf);
kernel_neon_end();
crc = 0;
data = buf;
length = sizeof(buf);
return crc_t10dif_generic(0, buf, sizeof(buf));
}
}
return crc_t10dif_generic(crc, data, length);
+1 -2
View File
@@ -242,8 +242,7 @@ void __init setup_arch(char **cmdline_p)
setup_initial_init_mm((void *)PAGE_OFFSET, _etext, _edata, _end);
#if defined(CONFIG_BOOTPARAM)
strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE);
m68k_command_line[CL_SIZE - 1] = 0;
strscpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE);
#endif /* CONFIG_BOOTPARAM */
process_uboot_commandline(&m68k_command_line[0], CL_SIZE);
*cmdline_p = m68k_command_line;
-1
View File
@@ -21,7 +21,6 @@
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/console.h>
-1
View File
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/console.h>
+2 -2
View File
@@ -132,11 +132,11 @@ CONFIG_I2C=y
CONFIG_HWMON=m
CONFIG_DRM=m
CONFIG_DRM_DISPLAY_DP_AUX_CEC=y
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
CONFIG_DRM_RADEON=m
CONFIG_DRM_NOUVEAU=m
# CONFIG_DRM_NOUVEAU_BACKLIGHT is not set
# CONFIG_DRM_NOUVEAU_CH7006 is not set
# CONFIG_DRM_NOUVEAU_SIL164 is not set
CONFIG_DRM_VGEM=m
CONFIG_DRM_UDL=m
CONFIG_DRM_MGAG200=m
+2 -2
View File
@@ -193,11 +193,11 @@ CONFIG_MEDIA_SUPPORT=m
CONFIG_AGP=y
CONFIG_AGP_PARISC=y
CONFIG_DRM=y
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
CONFIG_DRM_RADEON=y
CONFIG_DRM_NOUVEAU=m
# CONFIG_DRM_NOUVEAU_BACKLIGHT is not set
# CONFIG_DRM_NOUVEAU_CH7006 is not set
# CONFIG_DRM_NOUVEAU_SIL164 is not set
CONFIG_DRM_MGAG200=m
CONFIG_FB=y
CONFIG_FB_PM2=m
+2 -9
View File
@@ -288,6 +288,7 @@ config PPC
select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,$(m32-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 -mstack-protector-guard-offset=0)
select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,$(m64-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 -mstack-protector-guard-offset=0)
select HAVE_STATIC_CALL if PPC32
select HAVE_STATIC_CALL_INLINE if PPC32
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING
select HAVE_VIRT_CPU_ACCOUNTING_GEN
@@ -413,12 +414,9 @@ config ARCH_HAS_ADD_PAGES
config PPC_DCR_NATIVE
bool
config PPC_DCR_MMIO
bool
config PPC_DCR
bool
depends on PPC_DCR_NATIVE || PPC_DCR_MMIO
depends on PPC_DCR_NATIVE
default y
config PPC_PCI_OF_BUS_MAP
@@ -444,11 +442,6 @@ config PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT
PCI domain dependent and each PCI controller on own domain can have
256 PCI buses, like it is on other Linux architectures.
config PPC_OF_PLATFORM_PCI
bool
depends on PCI
depends on PPC64 # not supported on 32 bits yet
config ARCH_SUPPORTS_UPROBES
def_bool y
-7
View File
@@ -216,13 +216,6 @@ config PPC_EARLY_DEBUG_RTAS_PANEL
help
Select this to enable early debugging via the RTAS panel.
config PPC_EARLY_DEBUG_RTAS_CONSOLE
bool "RTAS Console"
depends on PPC_RTAS
select UDBG_RTAS_CONSOLE
help
Select this to enable early debugging via the RTAS console.
config PPC_EARLY_DEBUG_PAS_REALMODE
bool "PA Semi real mode"
depends on PPC_PASEMI
-2
View File
@@ -173,7 +173,6 @@ src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S
src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
@@ -276,7 +275,6 @@ quiet_cmd_wrap = WRAP $@
image-$(CONFIG_PPC_PSERIES) += zImage.pseries
image-$(CONFIG_PPC_POWERNV) += zImage.pseries
image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
image-$(CONFIG_PPC_PS3) += dtbImage.ps3
image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
+94 -13
View File
@@ -1,4 +1,5 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
/ {
#size-cells = <0x02>;
@@ -8,6 +9,7 @@
aliases {
serial0 = &UART0;
ethernet = &enet0;
};
reserved-memory {
@@ -35,40 +37,79 @@
ibm,powerpc-cpu-features {
display-name = "Microwatt";
isa = <3000>;
isa = <3010>;
device_type = "cpu-features";
compatible = "ibm,powerpc-cpu-features";
mmu-radix {
isa = <3000>;
usable-privilege = <2>;
usable-privilege = <6>;
os-support = <0>;
};
little-endian {
isa = <2050>;
usable-privilege = <3>;
isa = <0>;
usable-privilege = <7>;
os-support = <0>;
hwcap-bit-nr = <1>;
};
cache-inhibited-large-page {
isa = <2040>;
usable-privilege = <2>;
isa = <0>;
usable-privilege = <6>;
os-support = <0>;
};
fixed-point-v3 {
isa = <3000>;
usable-privilege = <3>;
usable-privilege = <7>;
};
no-execute {
isa = <2010>;
isa = <0x00>;
usable-privilege = <2>;
os-support = <0>;
};
floating-point {
hfscr-bit-nr = <0>;
hwcap-bit-nr = <27>;
isa = <0>;
usable-privilege = <3>;
usable-privilege = <7>;
hv-support = <1>;
os-support = <0>;
};
prefixed-instructions {
hfscr-bit-nr = <13>;
fscr-bit-nr = <13>;
isa = <3010>;
usable-privilege = <7>;
os-support = <1>;
hv-support = <1>;
};
tar {
hfscr-bit-nr = <8>;
fscr-bit-nr = <8>;
isa = <2070>;
usable-privilege = <7>;
os-support = <1>;
hv-support = <1>;
hwcap-bit-nr = <58>;
};
control-register {
isa = <0>;
usable-privilege = <7>;
};
system-call-vectored {
isa = <3000>;
usable-privilege = <7>;
os-support = <1>;
fscr-bit-nr = <12>;
hwcap-bit-nr = <52>;
};
};
@@ -101,6 +142,36 @@
ibm,mmu-lpid-bits = <12>;
ibm,mmu-pid-bits = <20>;
};
PowerPC,Microwatt@1 {
i-cache-sets = <2>;
ibm,dec-bits = <64>;
reservation-granule-size = <64>;
clock-frequency = <100000000>;
timebase-frequency = <100000000>;
i-tlb-sets = <1>;
ibm,ppc-interrupt-server#s = <1>;
i-cache-block-size = <64>;
d-cache-block-size = <64>;
d-cache-sets = <2>;
i-tlb-size = <64>;
cpu-version = <0x990000>;
status = "okay";
i-cache-size = <0x1000>;
ibm,processor-radix-AP-encodings = <0x0c 0xa0000010 0x20000015 0x4000001e>;
tlb-size = <0>;
tlb-sets = <0>;
device_type = "cpu";
d-tlb-size = <128>;
d-tlb-sets = <2>;
reg = <1>;
general-purpose;
64-bit;
d-cache-size = <0x1000>;
ibm,chip-id = <0>;
ibm,mmu-lpid-bits = <12>;
ibm,mmu-pid-bits = <20>;
};
};
soc@c0000000 {
@@ -113,8 +184,8 @@
interrupt-controller@4000 {
compatible = "openpower,xics-presentation", "ibm,ppc-xicp";
ibm,interrupt-server-ranges = <0x0 0x1>;
reg = <0x4000 0x100>;
ibm,interrupt-server-ranges = <0x0 0x2>;
reg = <0x4000 0x10 0x4010 0x10>;
};
ICS: interrupt-controller@5000 {
@@ -138,7 +209,18 @@
interrupts = <0x10 0x1>;
};
ethernet@8020000 {
gpio: gpio@7000 {
device_type = "gpio";
compatible = "faraday,ftgpio010";
gpio-controller;
#gpio-cells = <2>;
reg = <0x7000 0x80>;
interrupts = <0x14 1>;
interrupt-controller;
#interrupt-cells = <2>;
};
enet0: ethernet@8020000 {
compatible = "litex,liteeth";
reg = <0x8021000 0x100
0x8020800 0x100
@@ -160,7 +242,6 @@
reg-names = "phy", "core", "reader", "writer", "irq";
bus-width = <4>;
interrupts = <0x13 1>;
cap-sd-highspeed;
clocks = <&sys_clk>;
};
};
-2
View File
@@ -25,7 +25,6 @@ CONFIG_PS3_DISK=y
CONFIG_PS3_ROM=m
CONFIG_PS3_FLASH=m
CONFIG_PS3_LPM=m
CONFIG_PPC_IBM_CELL_BLADE=y
CONFIG_RTAS_FLASH=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@@ -133,7 +132,6 @@ CONFIG_SKGE=m
CONFIG_SKY2=m
CONFIG_GELIC_NET=m
CONFIG_GELIC_WIRELESS=y
CONFIG_SPIDER_NET=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_I8042 is not set
-2
View File
@@ -51,7 +51,6 @@ CONFIG_PS3_DISK=m
CONFIG_PS3_ROM=m
CONFIG_PS3_FLASH=m
CONFIG_PS3_LPM=m
CONFIG_PPC_IBM_CELL_BLADE=y
CONFIG_RTAS_FLASH=m
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@@ -228,7 +227,6 @@ CONFIG_NETXEN_NIC=m
CONFIG_SUNGEM=y
CONFIG_GELIC_NET=m
CONFIG_GELIC_WIRELESS=y
CONFIG_SPIDER_NET=m
CONFIG_BROADCOM_PHY=m
CONFIG_MARVELL_PHY=y
CONFIG_PPP=m
+1
View File
@@ -51,3 +51,4 @@ $(obj)/aesp8-ppc.S $(obj)/ghashp8-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE
OBJECT_FILES_NON_STANDARD_aesp10-ppc.o := y
OBJECT_FILES_NON_STANDARD_ghashp10-ppc.o := y
OBJECT_FILES_NON_STANDARD_aesp8-ppc.o := y
OBJECT_FILES_NON_STANDARD_ghashp8-ppc.o := y
-56
View File
@@ -20,36 +20,9 @@
/* Macros for the pm_control register. */
#define CBE_PM_16BIT_CTR(ctr) (1 << (24 - ((ctr) & (NR_PHYS_CTRS - 1))))
#define CBE_PM_ENABLE_PERF_MON 0x80000000
#define CBE_PM_STOP_AT_MAX 0x40000000
#define CBE_PM_TRACE_MODE_GET(pm_control) (((pm_control) >> 28) & 0x3)
#define CBE_PM_TRACE_MODE_SET(mode) (((mode) & 0x3) << 28)
#define CBE_PM_TRACE_BUF_OVFLW(bit) (((bit) & 0x1) << 17)
#define CBE_PM_COUNT_MODE_SET(count) (((count) & 0x3) << 18)
#define CBE_PM_FREEZE_ALL_CTRS 0x00100000
#define CBE_PM_ENABLE_EXT_TRACE 0x00008000
#define CBE_PM_SPU_ADDR_TRACE_SET(msk) (((msk) & 0x3) << 9)
/* Macros for the trace_address register. */
#define CBE_PM_TRACE_BUF_FULL 0x00000800
#define CBE_PM_TRACE_BUF_EMPTY 0x00000400
#define CBE_PM_TRACE_BUF_DATA_COUNT(ta) ((ta) & 0x3ff)
#define CBE_PM_TRACE_BUF_MAX_COUNT 0x400
/* Macros for the pm07_control registers. */
#define CBE_PM_CTR_INPUT_MUX(pm07_control) (((pm07_control) >> 26) & 0x3f)
#define CBE_PM_CTR_INPUT_CONTROL 0x02000000
#define CBE_PM_CTR_POLARITY 0x01000000
#define CBE_PM_CTR_COUNT_CYCLES 0x00800000
#define CBE_PM_CTR_ENABLE 0x00400000
#define PM07_CTR_INPUT_MUX(x) (((x) & 0x3F) << 26)
#define PM07_CTR_INPUT_CONTROL(x) (((x) & 1) << 25)
#define PM07_CTR_POLARITY(x) (((x) & 1) << 24)
#define PM07_CTR_COUNT_CYCLES(x) (((x) & 1) << 23)
#define PM07_CTR_ENABLE(x) (((x) & 1) << 22)
/* Macros for the pm_status register. */
#define CBE_PM_CTR_OVERFLOW_INTR(ctr) (1 << (31 - ((ctr) & 7)))
enum pm_reg_name {
group_control,
@@ -62,33 +35,4 @@ enum pm_reg_name {
pm_start_stop,
};
/* Routines for reading/writing the PMU registers. */
extern u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr);
extern void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val);
extern u32 cbe_read_ctr(u32 cpu, u32 ctr);
extern void cbe_write_ctr(u32 cpu, u32 ctr, u32 val);
extern u32 cbe_read_pm07_control(u32 cpu, u32 ctr);
extern void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val);
extern u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg);
extern void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val);
extern u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr);
extern void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size);
extern void cbe_enable_pm(u32 cpu);
extern void cbe_disable_pm(u32 cpu);
extern void cbe_read_trace_buffer(u32 cpu, u64 *buf);
extern void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask);
extern void cbe_disable_pm_interrupts(u32 cpu);
extern u32 cbe_get_and_clear_pm_interrupts(u32 cpu);
extern void cbe_sync_irq(int node);
#define CBE_COUNT_SUPERVISOR_MODE 0
#define CBE_COUNT_HYPERVISOR_MODE 1
#define CBE_COUNT_PROBLEM_MODE 2
#define CBE_COUNT_ALL_MODES 3
#endif /* __ASM_CELL_PMU_H__ */
-296
View File
@@ -18,293 +18,6 @@
#include <asm/cell-pmu.h>
/*
*
* Some HID register definitions
*
*/
/* CBE specific HID0 bits */
#define HID0_CBE_THERM_WAKEUP 0x0000020000000000ul
#define HID0_CBE_SYSERR_WAKEUP 0x0000008000000000ul
#define HID0_CBE_THERM_INT_EN 0x0000000400000000ul
#define HID0_CBE_SYSERR_INT_EN 0x0000000200000000ul
#define MAX_CBE 2
/*
*
* Pervasive unit register definitions
*
*/
union spe_reg {
u64 val;
u8 spe[8];
};
union ppe_spe_reg {
u64 val;
struct {
u32 ppe;
u32 spe;
};
};
struct cbe_pmd_regs {
/* Debug Bus Control */
u64 pad_0x0000; /* 0x0000 */
u64 group_control; /* 0x0008 */
u8 pad_0x0010_0x00a8 [0x00a8 - 0x0010]; /* 0x0010 */
u64 debug_bus_control; /* 0x00a8 */
u8 pad_0x00b0_0x0100 [0x0100 - 0x00b0]; /* 0x00b0 */
u64 trace_aux_data; /* 0x0100 */
u64 trace_buffer_0_63; /* 0x0108 */
u64 trace_buffer_64_127; /* 0x0110 */
u64 trace_address; /* 0x0118 */
u64 ext_tr_timer; /* 0x0120 */
u8 pad_0x0128_0x0400 [0x0400 - 0x0128]; /* 0x0128 */
/* Performance Monitor */
u64 pm_status; /* 0x0400 */
u64 pm_control; /* 0x0408 */
u64 pm_interval; /* 0x0410 */
u64 pm_ctr[4]; /* 0x0418 */
u64 pm_start_stop; /* 0x0438 */
u64 pm07_control[8]; /* 0x0440 */
u8 pad_0x0480_0x0800 [0x0800 - 0x0480]; /* 0x0480 */
/* Thermal Sensor Registers */
union spe_reg ts_ctsr1; /* 0x0800 */
u64 ts_ctsr2; /* 0x0808 */
union spe_reg ts_mtsr1; /* 0x0810 */
u64 ts_mtsr2; /* 0x0818 */
union spe_reg ts_itr1; /* 0x0820 */
u64 ts_itr2; /* 0x0828 */
u64 ts_gitr; /* 0x0830 */
u64 ts_isr; /* 0x0838 */
u64 ts_imr; /* 0x0840 */
union spe_reg tm_cr1; /* 0x0848 */
u64 tm_cr2; /* 0x0850 */
u64 tm_simr; /* 0x0858 */
union ppe_spe_reg tm_tpr; /* 0x0860 */
union spe_reg tm_str1; /* 0x0868 */
u64 tm_str2; /* 0x0870 */
union ppe_spe_reg tm_tsr; /* 0x0878 */
/* Power Management */
u64 pmcr; /* 0x0880 */
#define CBE_PMD_PAUSE_ZERO_CONTROL 0x10000
u64 pmsr; /* 0x0888 */
/* Time Base Register */
u64 tbr; /* 0x0890 */
u8 pad_0x0898_0x0c00 [0x0c00 - 0x0898]; /* 0x0898 */
/* Fault Isolation Registers */
u64 checkstop_fir; /* 0x0c00 */
u64 recoverable_fir; /* 0x0c08 */
u64 spec_att_mchk_fir; /* 0x0c10 */
u32 fir_mode_reg; /* 0x0c18 */
u8 pad_0x0c1c_0x0c20 [4]; /* 0x0c1c */
#define CBE_PMD_FIR_MODE_M8 0x00800
u64 fir_enable_mask; /* 0x0c20 */
u8 pad_0x0c28_0x0ca8 [0x0ca8 - 0x0c28]; /* 0x0c28 */
u64 ras_esc_0; /* 0x0ca8 */
u8 pad_0x0cb0_0x1000 [0x1000 - 0x0cb0]; /* 0x0cb0 */
};
extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np);
extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu);
/*
* PMU shadow registers
*
* Many of the registers in the performance monitoring unit are write-only,
* so we need to save a copy of what we write to those registers.
*
* The actual data counters are read/write. However, writing to the counters
* only takes effect if the PMU is enabled. Otherwise the value is stored in
* a hardware latch until the next time the PMU is enabled. So we save a copy
* of the counter values if we need to read them back while the PMU is
* disabled. The counter_value_in_latch field is a bitmap indicating which
* counters currently have a value waiting to be written.
*/
struct cbe_pmd_shadow_regs {
u32 group_control;
u32 debug_bus_control;
u32 trace_address;
u32 ext_tr_timer;
u32 pm_status;
u32 pm_control;
u32 pm_interval;
u32 pm_start_stop;
u32 pm07_control[NR_CTRS];
u32 pm_ctr[NR_PHYS_CTRS];
u32 counter_value_in_latch;
};
extern struct cbe_pmd_shadow_regs *cbe_get_pmd_shadow_regs(struct device_node *np);
extern struct cbe_pmd_shadow_regs *cbe_get_cpu_pmd_shadow_regs(int cpu);
/*
*
* IIC unit register definitions
*
*/
struct cbe_iic_pending_bits {
u32 data;
u8 flags;
u8 class;
u8 source;
u8 prio;
};
#define CBE_IIC_IRQ_VALID 0x80
#define CBE_IIC_IRQ_IPI 0x40
struct cbe_iic_thread_regs {
struct cbe_iic_pending_bits pending;
struct cbe_iic_pending_bits pending_destr;
u64 generate;
u64 prio;
};
struct cbe_iic_regs {
u8 pad_0x0000_0x0400[0x0400 - 0x0000]; /* 0x0000 */
/* IIC interrupt registers */
struct cbe_iic_thread_regs thread[2]; /* 0x0400 */
u64 iic_ir; /* 0x0440 */
#define CBE_IIC_IR_PRIO(x) (((x) & 0xf) << 12)
#define CBE_IIC_IR_DEST_NODE(x) (((x) & 0xf) << 4)
#define CBE_IIC_IR_DEST_UNIT(x) ((x) & 0xf)
#define CBE_IIC_IR_IOC_0 0x0
#define CBE_IIC_IR_IOC_1S 0xb
#define CBE_IIC_IR_PT_0 0xe
#define CBE_IIC_IR_PT_1 0xf
u64 iic_is; /* 0x0448 */
#define CBE_IIC_IS_PMI 0x2
u8 pad_0x0450_0x0500[0x0500 - 0x0450]; /* 0x0450 */
/* IOC FIR */
u64 ioc_fir_reset; /* 0x0500 */
u64 ioc_fir_set; /* 0x0508 */
u64 ioc_checkstop_enable; /* 0x0510 */
u64 ioc_fir_error_mask; /* 0x0518 */
u64 ioc_syserr_enable; /* 0x0520 */
u64 ioc_fir; /* 0x0528 */
u8 pad_0x0530_0x1000[0x1000 - 0x0530]; /* 0x0530 */
};
extern struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np);
extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu);
struct cbe_mic_tm_regs {
u8 pad_0x0000_0x0040[0x0040 - 0x0000]; /* 0x0000 */
u64 mic_ctl_cnfg2; /* 0x0040 */
#define CBE_MIC_ENABLE_AUX_TRC 0x8000000000000000LL
#define CBE_MIC_DISABLE_PWR_SAV_2 0x0200000000000000LL
#define CBE_MIC_DISABLE_AUX_TRC_WRAP 0x0100000000000000LL
#define CBE_MIC_ENABLE_AUX_TRC_INT 0x0080000000000000LL
u64 pad_0x0048; /* 0x0048 */
u64 mic_aux_trc_base; /* 0x0050 */
u64 mic_aux_trc_max_addr; /* 0x0058 */
u64 mic_aux_trc_cur_addr; /* 0x0060 */
u64 mic_aux_trc_grf_addr; /* 0x0068 */
u64 mic_aux_trc_grf_data; /* 0x0070 */
u64 pad_0x0078; /* 0x0078 */
u64 mic_ctl_cnfg_0; /* 0x0080 */
#define CBE_MIC_DISABLE_PWR_SAV_0 0x8000000000000000LL
u64 pad_0x0088; /* 0x0088 */
u64 slow_fast_timer_0; /* 0x0090 */
u64 slow_next_timer_0; /* 0x0098 */
u8 pad_0x00a0_0x00f8[0x00f8 - 0x00a0]; /* 0x00a0 */
u64 mic_df_ecc_address_0; /* 0x00f8 */
u8 pad_0x0100_0x01b8[0x01b8 - 0x0100]; /* 0x0100 */
u64 mic_df_ecc_address_1; /* 0x01b8 */
u64 mic_ctl_cnfg_1; /* 0x01c0 */
#define CBE_MIC_DISABLE_PWR_SAV_1 0x8000000000000000LL
u64 pad_0x01c8; /* 0x01c8 */
u64 slow_fast_timer_1; /* 0x01d0 */
u64 slow_next_timer_1; /* 0x01d8 */
u8 pad_0x01e0_0x0208[0x0208 - 0x01e0]; /* 0x01e0 */
u64 mic_exc; /* 0x0208 */
#define CBE_MIC_EXC_BLOCK_SCRUB 0x0800000000000000ULL
#define CBE_MIC_EXC_FAST_SCRUB 0x0100000000000000ULL
u64 mic_mnt_cfg; /* 0x0210 */
#define CBE_MIC_MNT_CFG_CHAN_0_POP 0x0002000000000000ULL
#define CBE_MIC_MNT_CFG_CHAN_1_POP 0x0004000000000000ULL
u64 mic_df_config; /* 0x0218 */
#define CBE_MIC_ECC_DISABLE_0 0x4000000000000000ULL
#define CBE_MIC_ECC_REP_SINGLE_0 0x2000000000000000ULL
#define CBE_MIC_ECC_DISABLE_1 0x0080000000000000ULL
#define CBE_MIC_ECC_REP_SINGLE_1 0x0040000000000000ULL
u8 pad_0x0220_0x0230[0x0230 - 0x0220]; /* 0x0220 */
u64 mic_fir; /* 0x0230 */
#define CBE_MIC_FIR_ECC_SINGLE_0_ERR 0x0200000000000000ULL
#define CBE_MIC_FIR_ECC_MULTI_0_ERR 0x0100000000000000ULL
#define CBE_MIC_FIR_ECC_SINGLE_1_ERR 0x0080000000000000ULL
#define CBE_MIC_FIR_ECC_MULTI_1_ERR 0x0040000000000000ULL
#define CBE_MIC_FIR_ECC_ERR_MASK 0xffff000000000000ULL
#define CBE_MIC_FIR_ECC_SINGLE_0_CTE 0x0000020000000000ULL
#define CBE_MIC_FIR_ECC_MULTI_0_CTE 0x0000010000000000ULL
#define CBE_MIC_FIR_ECC_SINGLE_1_CTE 0x0000008000000000ULL
#define CBE_MIC_FIR_ECC_MULTI_1_CTE 0x0000004000000000ULL
#define CBE_MIC_FIR_ECC_CTE_MASK 0x0000ffff00000000ULL
#define CBE_MIC_FIR_ECC_SINGLE_0_RESET 0x0000000002000000ULL
#define CBE_MIC_FIR_ECC_MULTI_0_RESET 0x0000000001000000ULL
#define CBE_MIC_FIR_ECC_SINGLE_1_RESET 0x0000000000800000ULL
#define CBE_MIC_FIR_ECC_MULTI_1_RESET 0x0000000000400000ULL
#define CBE_MIC_FIR_ECC_RESET_MASK 0x00000000ffff0000ULL
#define CBE_MIC_FIR_ECC_SINGLE_0_SET 0x0000000000000200ULL
#define CBE_MIC_FIR_ECC_MULTI_0_SET 0x0000000000000100ULL
#define CBE_MIC_FIR_ECC_SINGLE_1_SET 0x0000000000000080ULL
#define CBE_MIC_FIR_ECC_MULTI_1_SET 0x0000000000000040ULL
#define CBE_MIC_FIR_ECC_SET_MASK 0x000000000000ffffULL
u64 mic_fir_debug; /* 0x0238 */
u8 pad_0x0240_0x1000[0x1000 - 0x0240]; /* 0x0240 */
};
extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np);
extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
/* Cell page table entries */
#define CBE_IOPTE_PP_W 0x8000000000000000ul /* protection: write */
#define CBE_IOPTE_PP_R 0x4000000000000000ul /* protection: read */
@@ -315,13 +28,4 @@ extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
#define CBE_IOPTE_H 0x0000000000000800ul /* cache hint */
#define CBE_IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
/* some utility functions to deal with SMT */
extern u32 cbe_get_hw_thread_id(int cpu);
extern u32 cbe_cpu_to_node(int cpu);
extern u32 cbe_node_to_cpu(int node);
/* Init this module early */
extern void cbe_regs_init(void);
#endif /* CBE_REGS_H */
-36
View File
@@ -1,36 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
* <benh@kernel.crashing.org>
*/
#ifndef _ASM_POWERPC_DCR_GENERIC_H
#define _ASM_POWERPC_DCR_GENERIC_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
enum host_type_t {DCR_HOST_MMIO, DCR_HOST_NATIVE, DCR_HOST_INVALID};
typedef struct {
enum host_type_t type;
union {
dcr_host_mmio_t mmio;
dcr_host_native_t native;
} host;
} dcr_host_t;
extern bool dcr_map_ok_generic(dcr_host_t host);
extern dcr_host_t dcr_map_generic(struct device_node *dev, unsigned int dcr_n,
unsigned int dcr_c);
extern void dcr_unmap_generic(dcr_host_t host, unsigned int dcr_c);
extern u32 dcr_read_generic(dcr_host_t host, unsigned int dcr_n);
extern void dcr_write_generic(dcr_host_t host, unsigned int dcr_n, u32 value);
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_DCR_GENERIC_H */
-44
View File
@@ -1,44 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
* <benh@kernel.crashing.org>
*/
#ifndef _ASM_POWERPC_DCR_MMIO_H
#define _ASM_POWERPC_DCR_MMIO_H
#ifdef __KERNEL__
#include <asm/io.h>
typedef struct {
void __iomem *token;
unsigned int stride;
unsigned int base;
} dcr_host_mmio_t;
static inline bool dcr_map_ok_mmio(dcr_host_mmio_t host)
{
return host.token != NULL;
}
extern dcr_host_mmio_t dcr_map_mmio(struct device_node *dev,
unsigned int dcr_n,
unsigned int dcr_c);
extern void dcr_unmap_mmio(dcr_host_mmio_t host, unsigned int dcr_c);
static inline u32 dcr_read_mmio(dcr_host_mmio_t host, unsigned int dcr_n)
{
return in_be32(host.token + ((host.base + dcr_n) * host.stride));
}
static inline void dcr_write_mmio(dcr_host_mmio_t host,
unsigned int dcr_n,
u32 value)
{
out_be32(host.token + ((host.base + dcr_n) * host.stride), value);
}
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_DCR_MMIO_H */
-32
View File
@@ -10,46 +10,14 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_PPC_DCR
#ifdef CONFIG_PPC_DCR_NATIVE
#include <asm/dcr-native.h>
#endif
#ifdef CONFIG_PPC_DCR_MMIO
#include <asm/dcr-mmio.h>
#endif
/* Indirection layer for providing both NATIVE and MMIO support. */
#if defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO)
#include <asm/dcr-generic.h>
#define DCR_MAP_OK(host) dcr_map_ok_generic(host)
#define dcr_map(dev, dcr_n, dcr_c) dcr_map_generic(dev, dcr_n, dcr_c)
#define dcr_unmap(host, dcr_c) dcr_unmap_generic(host, dcr_c)
#define dcr_read(host, dcr_n) dcr_read_generic(host, dcr_n)
#define dcr_write(host, dcr_n, value) dcr_write_generic(host, dcr_n, value)
#else
#ifdef CONFIG_PPC_DCR_NATIVE
typedef dcr_host_native_t dcr_host_t;
#define DCR_MAP_OK(host) dcr_map_ok_native(host)
#define dcr_map(dev, dcr_n, dcr_c) dcr_map_native(dev, dcr_n, dcr_c)
#define dcr_unmap(host, dcr_c) dcr_unmap_native(host, dcr_c)
#define dcr_read(host, dcr_n) dcr_read_native(host, dcr_n)
#define dcr_write(host, dcr_n, value) dcr_write_native(host, dcr_n, value)
#else
typedef dcr_host_mmio_t dcr_host_t;
#define DCR_MAP_OK(host) dcr_map_ok_mmio(host)
#define dcr_map(dev, dcr_n, dcr_c) dcr_map_mmio(dev, dcr_n, dcr_c)
#define dcr_unmap(host, dcr_c) dcr_unmap_mmio(host, dcr_c)
#define dcr_read(host, dcr_n) dcr_read_mmio(host, dcr_n)
#define dcr_write(host, dcr_n, value) dcr_write_mmio(host, dcr_n, value)
#endif
#endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */
/*
* additional helpers to read the DCR * base from the device-tree
+34
View File
@@ -348,6 +348,7 @@
#define H_SCM_FLUSH 0x44C
#define H_GET_ENERGY_SCALE_INFO 0x450
#define H_PKS_SIGNED_UPDATE 0x454
#define H_HTM 0x458
#define H_WATCHDOG 0x45C
#define H_GUEST_GET_CAPABILITIES 0x460
#define H_GUEST_SET_CAPABILITIES 0x464
@@ -498,6 +499,39 @@
#define H_GUEST_CAP_POWER11 (1UL<<(63-3))
#define H_GUEST_CAP_BITMAP2 (1UL<<(63-63))
/*
* Defines for H_HTM - Macros for hardware trace macro (HTM) function.
*/
#define H_HTM_FLAGS_HARDWARE_TARGET (1ul << 63)
#define H_HTM_FLAGS_LOGICAL_TARGET (1ul << 62)
#define H_HTM_FLAGS_PROCID_TARGET (1ul << 61)
#define H_HTM_FLAGS_NOWRAP (1ul << 60)
#define H_HTM_OP_SHIFT (63-15)
#define H_HTM_OP(x) ((unsigned long)(x)<<H_HTM_OP_SHIFT)
#define H_HTM_OP_CAPABILITIES 0x01
#define H_HTM_OP_STATUS 0x02
#define H_HTM_OP_SETUP 0x03
#define H_HTM_OP_CONFIGURE 0x04
#define H_HTM_OP_START 0x05
#define H_HTM_OP_STOP 0x06
#define H_HTM_OP_DECONFIGURE 0x07
#define H_HTM_OP_DUMP_DETAILS 0x08
#define H_HTM_OP_DUMP_DATA 0x09
#define H_HTM_OP_DUMP_SYSMEM_CONF 0x0a
#define H_HTM_OP_DUMP_SYSPROC_CONF 0x0b
#define H_HTM_TYPE_SHIFT (63-31)
#define H_HTM_TYPE(x) ((unsigned long)(x)<<H_HTM_TYPE_SHIFT)
#define H_HTM_TYPE_NEST 0x01
#define H_HTM_TYPE_CORE 0x02
#define H_HTM_TYPE_LLAT 0x03
#define H_HTM_TYPE_GLOBAL 0xff
#define H_HTM_TARGET_NODE_INDEX(x) ((unsigned long)(x)<<(63-15))
#define H_HTM_TARGET_NODAL_CHIP_INDEX(x) ((unsigned long)(x)<<(63-31))
#define H_HTM_TARGET_CORE_INDEX_ON_CHIP(x) ((unsigned long)(x)<<(63-47))
#ifndef __ASSEMBLY__
#include <linux/types.h>
+12 -58
View File
@@ -1,61 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* This file is meant to be include multiple times by other headers */
/* last 2 argments are used by platforms/cell/io-workarounds.[ch] */
DEF_PCI_AC_RET(readb, u8, (const PCI_IO_ADDR addr), (addr), mem, addr)
DEF_PCI_AC_RET(readw, u16, (const PCI_IO_ADDR addr), (addr), mem, addr)
DEF_PCI_AC_RET(readl, u32, (const PCI_IO_ADDR addr), (addr), mem, addr)
DEF_PCI_AC_RET(readw_be, u16, (const PCI_IO_ADDR addr), (addr), mem, addr)
DEF_PCI_AC_RET(readl_be, u32, (const PCI_IO_ADDR addr), (addr), mem, addr)
DEF_PCI_AC_NORET(writeb, (u8 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
DEF_PCI_AC_NORET(writew, (u16 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
DEF_PCI_AC_NORET(writel, (u32 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
DEF_PCI_AC_NORET(writew_be, (u16 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
DEF_PCI_AC_NORET(writel_be, (u32 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
#ifdef __powerpc64__
DEF_PCI_AC_RET(readq, u64, (const PCI_IO_ADDR addr), (addr), mem, addr)
DEF_PCI_AC_RET(readq_be, u64, (const PCI_IO_ADDR addr), (addr), mem, addr)
DEF_PCI_AC_NORET(writeq, (u64 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
DEF_PCI_AC_NORET(writeq_be, (u64 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
#endif /* __powerpc64__ */
DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port), pio, port)
DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port), pio, port)
DEF_PCI_AC_RET(inl, u32, (unsigned long port), (port), pio, port)
DEF_PCI_AC_NORET(outb, (u8 val, unsigned long port), (val, port), pio, port)
DEF_PCI_AC_NORET(outw, (u16 val, unsigned long port), (val, port), pio, port)
DEF_PCI_AC_NORET(outl, (u32 val, unsigned long port), (val, port), pio, port)
DEF_PCI_AC_NORET(readsb, (const PCI_IO_ADDR a, void *b, unsigned long c),
(a, b, c), mem, a)
DEF_PCI_AC_NORET(readsw, (const PCI_IO_ADDR a, void *b, unsigned long c),
(a, b, c), mem, a)
DEF_PCI_AC_NORET(readsl, (const PCI_IO_ADDR a, void *b, unsigned long c),
(a, b, c), mem, a)
DEF_PCI_AC_NORET(writesb, (PCI_IO_ADDR a, const void *b, unsigned long c),
(a, b, c), mem, a)
DEF_PCI_AC_NORET(writesw, (PCI_IO_ADDR a, const void *b, unsigned long c),
(a, b, c), mem, a)
DEF_PCI_AC_NORET(writesl, (PCI_IO_ADDR a, const void *b, unsigned long c),
(a, b, c), mem, a)
DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c),
(p, b, c), pio, p)
DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c),
(p, b, c), pio, p)
DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c),
(p, b, c), pio, p)
DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c),
(p, b, c), pio, p)
DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c),
(p, b, c), pio, p)
DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c),
(p, b, c), pio, p)
DEF_PCI_AC_NORET(memset_io, (PCI_IO_ADDR a, int c, unsigned long n),
(a, c, n), mem, a)
DEF_PCI_AC_NORET(memcpy_fromio, (void *d, const PCI_IO_ADDR s, unsigned long n),
(d, s, n), mem, s)
DEF_PCI_AC_NORET(memcpy_toio, (PCI_IO_ADDR d, const void *s, unsigned long n),
(d, s, n), mem, d)
DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port))
DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port))
DEF_PCI_AC_RET(inl, u32, (unsigned long port), (port))
DEF_PCI_AC_NORET(outb, (u8 val, unsigned long port), (val, port))
DEF_PCI_AC_NORET(outw, (u16 val, unsigned long port), (val, port))
DEF_PCI_AC_NORET(outl, (u32 val, unsigned long port), (val, port))
DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c), (p, b, c))
DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c), (p, b, c))
DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c), (p, b, c))
DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c), (p, b, c))
DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c), (p, b, c))
DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c), (p, b, c))
-55
View File
@@ -1,55 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Support PCI IO workaround
*
* (C) Copyright 2007-2008 TOSHIBA CORPORATION
*/
#ifndef _IO_WORKAROUNDS_H
#define _IO_WORKAROUNDS_H
#ifdef CONFIG_PPC_IO_WORKAROUNDS
#include <linux/io.h>
#include <asm/pci-bridge.h>
/* Bus info */
struct iowa_bus {
struct pci_controller *phb;
struct ppc_pci_io *ops;
void *private;
};
void iowa_register_bus(struct pci_controller *, struct ppc_pci_io *,
int (*)(struct iowa_bus *, void *), void *);
struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR);
struct iowa_bus *iowa_pio_find_bus(unsigned long);
extern struct ppc_pci_io spiderpci_ops;
extern int spiderpci_iowa_init(struct iowa_bus *, void *);
#define SPIDER_PCI_REG_BASE 0xd000
#define SPIDER_PCI_REG_SIZE 0x1000
#define SPIDER_PCI_VCI_CNTL_STAT 0x0110
#define SPIDER_PCI_DUMMY_READ 0x0810
#define SPIDER_PCI_DUMMY_READ_BASE 0x0814
#endif
#if defined(CONFIG_PPC_IO_WORKAROUNDS) && defined(CONFIG_PPC_INDIRECT_MMIO)
extern bool io_workaround_inited;
static inline bool iowa_is_active(void)
{
return unlikely(io_workaround_inited);
}
#else
static inline bool iowa_is_active(void)
{
return false;
}
#endif
void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
pgprot_t prot, void *caller);
#endif /* _IO_WORKAROUNDS_H */
+198 -211
View File
@@ -65,8 +65,8 @@ extern resource_size_t isa_mem_base;
extern bool isa_io_special;
#ifdef CONFIG_PPC32
#if defined(CONFIG_PPC_INDIRECT_PIO) || defined(CONFIG_PPC_INDIRECT_MMIO)
#error CONFIG_PPC_INDIRECT_{PIO,MMIO} are not yet supported on 32 bits
#ifdef CONFIG_PPC_INDIRECT_PIO
#error CONFIG_PPC_INDIRECT_PIO is not yet supported on 32 bits
#endif
#endif
@@ -80,16 +80,12 @@ extern bool isa_io_special;
*
* in_8, in_le16, in_be16, in_le32, in_be32, in_le64, in_be64
* out_8, out_le16, out_be16, out_le32, out_be32, out_le64, out_be64
* _insb, _insw_ns, _insl_ns, _outsb, _outsw_ns, _outsl_ns
* _insb, _insw, _insl, _outsb, _outsw, _outsl
*
* Those operate directly on a kernel virtual address. Note that the prototype
* for the out_* accessors has the arguments in opposite order from the usual
* linux PCI accessors. Unlike those, they take the address first and the value
* next.
*
* Note: I might drop the _ns suffix on the stream operations soon as it is
* simply normal for stream operations to not swap in the first place.
*
*/
/* -mprefixed can generate offsets beyond range, fall back hack */
@@ -228,19 +224,10 @@ static inline void out_be64(volatile u64 __iomem *addr, u64 val)
*/
extern void _insb(const volatile u8 __iomem *addr, void *buf, long count);
extern void _outsb(volatile u8 __iomem *addr,const void *buf,long count);
extern void _insw_ns(const volatile u16 __iomem *addr, void *buf, long count);
extern void _outsw_ns(volatile u16 __iomem *addr, const void *buf, long count);
extern void _insl_ns(const volatile u32 __iomem *addr, void *buf, long count);
extern void _outsl_ns(volatile u32 __iomem *addr, const void *buf, long count);
/* The _ns naming is historical and will be removed. For now, just #define
* the non _ns equivalent names
*/
#define _insw _insw_ns
#define _insl _insl_ns
#define _outsw _outsw_ns
#define _outsl _outsl_ns
extern void _insw(const volatile u16 __iomem *addr, void *buf, long count);
extern void _outsw(volatile u16 __iomem *addr, const void *buf, long count);
extern void _insl(const volatile u32 __iomem *addr, void *buf, long count);
extern void _outsl(volatile u32 __iomem *addr, const void *buf, long count);
/*
* memset_io, memcpy_toio, memcpy_fromio base implementations are out of line
@@ -261,9 +248,9 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src,
* for PowerPC is as close as possible to the x86 version of these, and thus
* provides fairly heavy weight barriers for the non-raw versions
*
* In addition, they support a hook mechanism when CONFIG_PPC_INDIRECT_MMIO
* or CONFIG_PPC_INDIRECT_PIO are set allowing the platform to provide its
* own implementation of some or all of the accessors.
* In addition, they support a hook mechanism when CONFIG_PPC_INDIRECT_PIO
* is set allowing the platform to provide its own implementation of some
* of the accessors.
*/
/*
@@ -274,116 +261,11 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src,
#include <asm/eeh.h>
#endif
/* Shortcut to the MMIO argument pointer */
#define PCI_IO_ADDR volatile void __iomem *
/* Indirect IO address tokens:
*
* When CONFIG_PPC_INDIRECT_MMIO is set, the platform can provide hooks
* on all MMIOs. (Note that this is all 64 bits only for now)
*
* To help platforms who may need to differentiate MMIO addresses in
* their hooks, a bitfield is reserved for use by the platform near the
* top of MMIO addresses (not PIO, those have to cope the hard way).
*
* The highest address in the kernel virtual space are:
*
* d0003fffffffffff # with Hash MMU
* c00fffffffffffff # with Radix MMU
*
* The top 4 bits are reserved as the region ID on hash, leaving us 8 bits
* that can be used for the field.
*
* The direct IO mapping operations will then mask off those bits
* before doing the actual access, though that only happen when
* CONFIG_PPC_INDIRECT_MMIO is set, thus be careful when you use that
* mechanism
*
* For PIO, there is a separate CONFIG_PPC_INDIRECT_PIO which makes
* all PIO functions call through a hook.
*/
#ifdef CONFIG_PPC_INDIRECT_MMIO
#define PCI_IO_IND_TOKEN_SHIFT 52
#define PCI_IO_IND_TOKEN_MASK (0xfful << PCI_IO_IND_TOKEN_SHIFT)
#define PCI_FIX_ADDR(addr) \
((PCI_IO_ADDR)(((unsigned long)(addr)) & ~PCI_IO_IND_TOKEN_MASK))
#define PCI_GET_ADDR_TOKEN(addr) \
(((unsigned long)(addr) & PCI_IO_IND_TOKEN_MASK) >> \
PCI_IO_IND_TOKEN_SHIFT)
#define PCI_SET_ADDR_TOKEN(addr, token) \
do { \
unsigned long __a = (unsigned long)(addr); \
__a &= ~PCI_IO_IND_TOKEN_MASK; \
__a |= ((unsigned long)(token)) << PCI_IO_IND_TOKEN_SHIFT; \
(addr) = (void __iomem *)__a; \
} while(0)
#else
#define PCI_FIX_ADDR(addr) (addr)
#endif
/*
* Non ordered and non-swapping "raw" accessors
*/
static inline unsigned char __raw_readb(const volatile void __iomem *addr)
{
return *(volatile unsigned char __force *)PCI_FIX_ADDR(addr);
}
#define __raw_readb __raw_readb
static inline unsigned short __raw_readw(const volatile void __iomem *addr)
{
return *(volatile unsigned short __force *)PCI_FIX_ADDR(addr);
}
#define __raw_readw __raw_readw
static inline unsigned int __raw_readl(const volatile void __iomem *addr)
{
return *(volatile unsigned int __force *)PCI_FIX_ADDR(addr);
}
#define __raw_readl __raw_readl
static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr)
{
*(volatile unsigned char __force *)PCI_FIX_ADDR(addr) = v;
}
#define __raw_writeb __raw_writeb
static inline void __raw_writew(unsigned short v, volatile void __iomem *addr)
{
*(volatile unsigned short __force *)PCI_FIX_ADDR(addr) = v;
}
#define __raw_writew __raw_writew
static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
{
*(volatile unsigned int __force *)PCI_FIX_ADDR(addr) = v;
}
#define __raw_writel __raw_writel
#define _IO_PORT(port) ((volatile void __iomem *)(_IO_BASE + (port)))
#ifdef __powerpc64__
static inline unsigned long __raw_readq(const volatile void __iomem *addr)
{
return *(volatile unsigned long __force *)PCI_FIX_ADDR(addr);
}
#define __raw_readq __raw_readq
static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
{
*(volatile unsigned long __force *)PCI_FIX_ADDR(addr) = v;
}
#define __raw_writeq __raw_writeq
static inline void __raw_writeq_be(unsigned long v, volatile void __iomem *addr)
{
__raw_writeq((__force unsigned long)cpu_to_be64(v), addr);
}
#define __raw_writeq_be __raw_writeq_be
/*
* Real mode versions of the above. Those instructions are only supposed
* Real mode versions of raw accessors. Those instructions are only supposed
* to be used in hypervisor real mode as per the architecture spec.
*/
static inline void __raw_rm_writeb(u8 val, volatile void __iomem *paddr)
@@ -551,30 +433,23 @@ __do_out_asm(_rec_outl, "stwbrx")
* possible to hook directly at the toplevel PIO operation if they have to
* be handled differently
*/
#define __do_writeb(val, addr) out_8(PCI_FIX_ADDR(addr), val)
#define __do_writew(val, addr) out_le16(PCI_FIX_ADDR(addr), val)
#define __do_writel(val, addr) out_le32(PCI_FIX_ADDR(addr), val)
#define __do_writeq(val, addr) out_le64(PCI_FIX_ADDR(addr), val)
#define __do_writew_be(val, addr) out_be16(PCI_FIX_ADDR(addr), val)
#define __do_writel_be(val, addr) out_be32(PCI_FIX_ADDR(addr), val)
#define __do_writeq_be(val, addr) out_be64(PCI_FIX_ADDR(addr), val)
#ifdef CONFIG_EEH
#define __do_readb(addr) eeh_readb(PCI_FIX_ADDR(addr))
#define __do_readw(addr) eeh_readw(PCI_FIX_ADDR(addr))
#define __do_readl(addr) eeh_readl(PCI_FIX_ADDR(addr))
#define __do_readq(addr) eeh_readq(PCI_FIX_ADDR(addr))
#define __do_readw_be(addr) eeh_readw_be(PCI_FIX_ADDR(addr))
#define __do_readl_be(addr) eeh_readl_be(PCI_FIX_ADDR(addr))
#define __do_readq_be(addr) eeh_readq_be(PCI_FIX_ADDR(addr))
#define __do_readb(addr) eeh_readb(addr)
#define __do_readw(addr) eeh_readw(addr)
#define __do_readl(addr) eeh_readl(addr)
#define __do_readq(addr) eeh_readq(addr)
#define __do_readw_be(addr) eeh_readw_be(addr)
#define __do_readl_be(addr) eeh_readl_be(addr)
#define __do_readq_be(addr) eeh_readq_be(addr)
#else /* CONFIG_EEH */
#define __do_readb(addr) in_8(PCI_FIX_ADDR(addr))
#define __do_readw(addr) in_le16(PCI_FIX_ADDR(addr))
#define __do_readl(addr) in_le32(PCI_FIX_ADDR(addr))
#define __do_readq(addr) in_le64(PCI_FIX_ADDR(addr))
#define __do_readw_be(addr) in_be16(PCI_FIX_ADDR(addr))
#define __do_readl_be(addr) in_be32(PCI_FIX_ADDR(addr))
#define __do_readq_be(addr) in_be64(PCI_FIX_ADDR(addr))
#define __do_readb(addr) in_8(addr)
#define __do_readw(addr) in_le16(addr)
#define __do_readl(addr) in_le32(addr)
#define __do_readq(addr) in_le64(addr)
#define __do_readw_be(addr) in_be16(addr)
#define __do_readl_be(addr) in_be32(addr)
#define __do_readq_be(addr) in_be64(addr)
#endif /* !defined(CONFIG_EEH) */
#ifdef CONFIG_PPC32
@@ -585,64 +460,185 @@ __do_out_asm(_rec_outl, "stwbrx")
#define __do_inw(port) _rec_inw(port)
#define __do_inl(port) _rec_inl(port)
#else /* CONFIG_PPC32 */
#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)(_IO_BASE+port));
#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)(_IO_BASE+port));
#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)(_IO_BASE+port));
#define __do_inb(port) readb((PCI_IO_ADDR)(_IO_BASE + port));
#define __do_inw(port) readw((PCI_IO_ADDR)(_IO_BASE + port));
#define __do_inl(port) readl((PCI_IO_ADDR)(_IO_BASE + port));
#define __do_outb(val, port) writeb(val,_IO_PORT(port));
#define __do_outw(val, port) writew(val,_IO_PORT(port));
#define __do_outl(val, port) writel(val,_IO_PORT(port));
#define __do_inb(port) readb(_IO_PORT(port));
#define __do_inw(port) readw(_IO_PORT(port));
#define __do_inl(port) readl(_IO_PORT(port));
#endif /* !CONFIG_PPC32 */
#ifdef CONFIG_EEH
#define __do_readsb(a, b, n) eeh_readsb(PCI_FIX_ADDR(a), (b), (n))
#define __do_readsw(a, b, n) eeh_readsw(PCI_FIX_ADDR(a), (b), (n))
#define __do_readsl(a, b, n) eeh_readsl(PCI_FIX_ADDR(a), (b), (n))
#define __do_readsb(a, b, n) eeh_readsb(a, (b), (n))
#define __do_readsw(a, b, n) eeh_readsw(a, (b), (n))
#define __do_readsl(a, b, n) eeh_readsl(a, (b), (n))
#else /* CONFIG_EEH */
#define __do_readsb(a, b, n) _insb(PCI_FIX_ADDR(a), (b), (n))
#define __do_readsw(a, b, n) _insw(PCI_FIX_ADDR(a), (b), (n))
#define __do_readsl(a, b, n) _insl(PCI_FIX_ADDR(a), (b), (n))
#define __do_readsb(a, b, n) _insb(a, (b), (n))
#define __do_readsw(a, b, n) _insw(a, (b), (n))
#define __do_readsl(a, b, n) _insl(a, (b), (n))
#endif /* !CONFIG_EEH */
#define __do_writesb(a, b, n) _outsb(PCI_FIX_ADDR(a),(b),(n))
#define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n))
#define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n))
#define __do_writesb(a, b, n) _outsb(a, (b), (n))
#define __do_writesw(a, b, n) _outsw(a, (b), (n))
#define __do_writesl(a, b, n) _outsl(a, (b), (n))
#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
#define __do_memset_io(addr, c, n) \
_memset_io(PCI_FIX_ADDR(addr), c, n)
#define __do_memcpy_toio(dst, src, n) \
_memcpy_toio(PCI_FIX_ADDR(dst), src, n)
#define __do_insb(p, b, n) readsb(_IO_PORT(p), (b), (n))
#define __do_insw(p, b, n) readsw(_IO_PORT(p), (b), (n))
#define __do_insl(p, b, n) readsl(_IO_PORT(p), (b), (n))
#define __do_outsb(p, b, n) writesb(_IO_PORT(p),(b),(n))
#define __do_outsw(p, b, n) writesw(_IO_PORT(p),(b),(n))
#define __do_outsl(p, b, n) writesl(_IO_PORT(p),(b),(n))
#ifdef CONFIG_EEH
#define __do_memcpy_fromio(dst, src, n) \
eeh_memcpy_fromio(dst, PCI_FIX_ADDR(src), n)
eeh_memcpy_fromio(dst, src, n)
#else /* CONFIG_EEH */
#define __do_memcpy_fromio(dst, src, n) \
_memcpy_fromio(dst,PCI_FIX_ADDR(src),n)
_memcpy_fromio(dst, src, n)
#endif /* !CONFIG_EEH */
#ifdef CONFIG_PPC_INDIRECT_PIO
#define DEF_PCI_HOOK_pio(x) x
#else
#define DEF_PCI_HOOK_pio(x) NULL
#endif
static inline u8 readb(const volatile void __iomem *addr)
{
return __do_readb(addr);
}
#define readb readb
#ifdef CONFIG_PPC_INDIRECT_MMIO
#define DEF_PCI_HOOK_mem(x) x
static inline u16 readw(const volatile void __iomem *addr)
{
return __do_readw(addr);
}
#define readw readw
static inline u32 readl(const volatile void __iomem *addr)
{
return __do_readl(addr);
}
#define readl readl
static inline u16 readw_be(const volatile void __iomem *addr)
{
return __do_readw_be(addr);
}
static inline u32 readl_be(const volatile void __iomem *addr)
{
return __do_readl_be(addr);
}
static inline void writeb(u8 val, volatile void __iomem *addr)
{
out_8(addr, val);
}
#define writeb writeb
static inline void writew(u16 val, volatile void __iomem *addr)
{
out_le16(addr, val);
}
#define writew writew
static inline void writel(u32 val, volatile void __iomem *addr)
{
out_le32(addr, val);
}
#define writel writel
static inline void writew_be(u16 val, volatile void __iomem *addr)
{
out_be16(addr, val);
}
static inline void writel_be(u32 val, volatile void __iomem *addr)
{
out_be32(addr, val);
}
static inline void readsb(const volatile void __iomem *a, void *b, unsigned long c)
{
__do_readsb(a, b, c);
}
#define readsb readsb
static inline void readsw(const volatile void __iomem *a, void *b, unsigned long c)
{
__do_readsw(a, b, c);
}
#define readsw readsw
static inline void readsl(const volatile void __iomem *a, void *b, unsigned long c)
{
__do_readsl(a, b, c);
}
#define readsl readsl
static inline void writesb(volatile void __iomem *a, const void *b, unsigned long c)
{
__do_writesb(a, b, c);
}
#define writesb writesb
static inline void writesw(volatile void __iomem *a, const void *b, unsigned long c)
{
__do_writesw(a, b, c);
}
#define writesw writesw
static inline void writesl(volatile void __iomem *a, const void *b, unsigned long c)
{
__do_writesl(a, b, c);
}
#define writesl writesl
static inline void memset_io(volatile void __iomem *a, int c, unsigned long n)
{
_memset_io(a, c, n);
}
#define memset_io memset_io
static inline void memcpy_fromio(void *d, const volatile void __iomem *s, unsigned long n)
{
__do_memcpy_fromio(d, s, n);
}
#define memcpy_fromio memcpy_fromio
static inline void memcpy_toio(volatile void __iomem *d, const void *s, unsigned long n)
{
_memcpy_toio(d, s, n);
}
#define memcpy_toio memcpy_toio
#ifdef __powerpc64__
static inline u64 readq(const volatile void __iomem *addr)
{
return __do_readq(addr);
}
static inline u64 readq_be(const volatile void __iomem *addr)
{
return __do_readq_be(addr);
}
static inline void writeq(u64 val, volatile void __iomem *addr)
{
out_le64(addr, val);
}
static inline void writeq_be(u64 val, volatile void __iomem *addr)
{
out_be64(addr, val);
}
#endif /* __powerpc64__ */
#ifdef CONFIG_PPC_INDIRECT_PIO
#define DEF_PCI_HOOK(x) x
#else
#define DEF_PCI_HOOK_mem(x) NULL
#define DEF_PCI_HOOK(x) NULL
#endif
/* Structure containing all the hooks */
extern struct ppc_pci_io {
#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) ret (*name) at;
#define DEF_PCI_AC_NORET(name, at, al, space, aa) void (*name) at;
#define DEF_PCI_AC_RET(name, ret, at, al) ret (*name) at;
#define DEF_PCI_AC_NORET(name, at, al) void (*name) at;
#include <asm/io-defs.h>
@@ -652,18 +648,18 @@ extern struct ppc_pci_io {
} ppc_pci_io;
/* The inline wrappers */
#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \
#define DEF_PCI_AC_RET(name, ret, at, al) \
static inline ret name at \
{ \
if (DEF_PCI_HOOK_##space(ppc_pci_io.name) != NULL) \
if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
return ppc_pci_io.name al; \
return __do_##name al; \
}
#define DEF_PCI_AC_NORET(name, at, al, space, aa) \
#define DEF_PCI_AC_NORET(name, at, al) \
static inline void name at \
{ \
if (DEF_PCI_HOOK_##space(ppc_pci_io.name) != NULL) \
if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
ppc_pci_io.name al; \
else \
__do_##name al; \
@@ -674,21 +670,7 @@ static inline void name at \
#undef DEF_PCI_AC_RET
#undef DEF_PCI_AC_NORET
/* Some drivers check for the presence of readq & writeq with
* a #ifdef, so we make them happy here.
*/
#define readb readb
#define readw readw
#define readl readl
#define writeb writeb
#define writew writew
#define writel writel
#define readsb readsb
#define readsw readsw
#define readsl readsl
#define writesb writesb
#define writesw writesw
#define writesl writesl
// Signal to asm-generic/io.h that we have implemented these.
#define inb inb
#define inw inw
#define inl inl
@@ -705,9 +687,6 @@ static inline void name at \
#define readq readq
#define writeq writeq
#endif
#define memset_io memset_io
#define memcpy_fromio memcpy_fromio
#define memcpy_toio memcpy_toio
/*
* We don't do relaxed operations yet, at least not with this semantic
@@ -982,6 +961,14 @@ static inline void * bus_to_virt(unsigned long address)
#include <asm-generic/io.h>
#ifdef __powerpc64__
static inline void __raw_writeq_be(unsigned long v, volatile void __iomem *addr)
{
__raw_writeq((__force unsigned long)cpu_to_be64(v), addr);
}
#define __raw_writeq_be __raw_writeq_be
#endif // __powerpc64__
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_IO_H */
-6
View File
@@ -317,12 +317,6 @@ extern void iommu_flush_tce(struct iommu_table *tbl);
extern enum dma_data_direction iommu_tce_direction(unsigned long tce);
extern unsigned long iommu_direction_to_tce_perm(enum dma_data_direction dir);
#ifdef CONFIG_PPC_CELL_NATIVE
extern bool iommu_fixed_is_weak;
#else
#define iommu_fixed_is_weak false
#endif
extern const struct dma_map_ops dma_iommu_ops;
#endif /* __KERNEL__ */
+1
View File
@@ -29,6 +29,7 @@ extern cpumask_var_t node_to_cpumask_map[];
#ifdef CONFIG_MEMORY_HOTPLUG
extern unsigned long max_pfn;
u64 memory_hotplug_max(void);
u64 hot_add_drconf_memory_max(void);
#else
#define memory_hotplug_max() memblock_end_of_DRAM()
#endif
+21
View File
@@ -65,6 +65,27 @@ static inline long register_dtl(unsigned long cpu, unsigned long vpa)
return vpa_call(H_VPA_REG_DTL, cpu, vpa);
}
static inline long htm_call(unsigned long flags, unsigned long target,
unsigned long operation, unsigned long param1,
unsigned long param2, unsigned long param3)
{
return plpar_hcall_norets(H_HTM, flags, target, operation,
param1, param2, param3);
}
static inline long htm_get_dump_hardware(unsigned long nodeindex,
unsigned long nodalchipindex, unsigned long coreindexonchip,
unsigned long type, unsigned long addr, unsigned long size,
unsigned long offset)
{
return htm_call(H_HTM_FLAGS_HARDWARE_TARGET,
H_HTM_TARGET_NODE_INDEX(nodeindex) |
H_HTM_TARGET_NODAL_CHIP_INDEX(nodalchipindex) |
H_HTM_TARGET_CORE_INDEX_ON_CHIP(coreindexonchip),
H_HTM_OP(H_HTM_OP_DUMP_DATA) | H_HTM_TYPE(type),
addr, size, offset);
}
extern void vpa_init(int cpu);
static inline long plpar_pte_enter(unsigned long flags,
-53
View File
@@ -1,53 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _POWERPC_PMI_H
#define _POWERPC_PMI_H
/*
* Definitions for talking with PMI device on PowerPC
*
* PMI (Platform Management Interrupt) is a way to communicate
* with the BMC (Baseboard Management Controller) via interrupts.
* Unlike IPMI it is bidirectional and has a low latency.
*
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005
*
* Author: Christian Krafft <krafft@de.ibm.com>
*/
#ifdef __KERNEL__
#define PMI_TYPE_FREQ_CHANGE 0x01
#define PMI_TYPE_POWER_BUTTON 0x02
#define PMI_READ_TYPE 0
#define PMI_READ_DATA0 1
#define PMI_READ_DATA1 2
#define PMI_READ_DATA2 3
#define PMI_WRITE_TYPE 4
#define PMI_WRITE_DATA0 5
#define PMI_WRITE_DATA1 6
#define PMI_WRITE_DATA2 7
#define PMI_ACK 0x80
#define PMI_TIMEOUT 100
typedef struct {
u8 type;
u8 data0;
u8 data1;
u8 data2;
} pmi_message_t;
struct pmi_handler {
struct list_head node;
u8 type;
void (*handle_pmi_message) (pmi_message_t);
};
int pmi_register_handler(struct pmi_handler *);
void pmi_unregister_handler(struct pmi_handler *);
int pmi_send_message(pmi_message_t);
#endif /* __KERNEL__ */
#endif /* _POWERPC_PMI_H */
+2
View File
@@ -17,6 +17,8 @@
struct device_node;
struct property;
#define MIN_RMA 768 /* Minimum RMA (in MB) for CAS negotiation */
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
#define OF_DT_END_NODE 0x2 /* End node */
#define OF_DT_PROP 0x3 /* Property: name off, size,
-2
View File
@@ -215,8 +215,6 @@ spu_disable_spu (struct spu_context *ctx)
* and only intended to be used by the platform setup code.
*/
extern const struct spu_priv1_ops spu_priv1_mmio_ops;
extern const struct spu_management_ops spu_management_of_ops;
#endif /* __KERNEL__ */
+2
View File
@@ -26,4 +26,6 @@
#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) __PPC_SCT(name, "blr")
#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name) __PPC_SCT(name, "b .+20")
#define CALL_INSN_SIZE 4
#endif /* _ASM_POWERPC_STATIC_CALL_H */
-3
View File
@@ -89,9 +89,6 @@ static inline unsigned long tb_ticks_since(unsigned long tstamp)
#define mulhdu(x, y) mul_u64_u64_shr(x, y, 64)
#endif
extern void div128_by_32(u64 dividend_high, u64 dividend_low,
unsigned divisor, struct div_result *dr);
extern void secondary_cpu_time_init(void);
extern void __init time_init(void);
-1
View File
@@ -31,7 +31,6 @@
#ifdef CONFIG_PPC_ICP_NATIVE
extern int icp_native_init(void);
extern void icp_native_flush_interrupt(void);
extern void icp_native_cause_ipi_rm(int cpu);
#else
static inline int icp_native_init(void) { return -ENODEV; }
#endif
-2
View File
@@ -12,13 +12,11 @@
#ifdef CONFIG_XMON
extern void xmon_setup(void);
void __init xmon_register_spus(struct list_head *list);
struct pt_regs;
extern int xmon(struct pt_regs *excp);
extern irqreturn_t xmon_irq(int, void *);
#else
static inline void xmon_setup(void) { }
static inline void xmon_register_spus(struct list_head *list) { }
#endif
#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
+1 -3
View File
@@ -70,7 +70,7 @@ obj-y := cputable.o syscalls.o switch.o \
signal.o sysfs.o cacheinfo.o time.o \
prom.o traps.o setup-common.o \
udbg.o misc.o io.o misc_$(BITS).o \
of_platform.o prom_parse.o firmware.o \
prom_parse.o firmware.o \
hw_breakpoint_constraints.o interrupt.o \
kdebugfs.o stacktrace.o syscall.o
obj-y += ptrace/
@@ -152,8 +152,6 @@ obj-$(CONFIG_PCI_MSI) += msi.o
obj-$(CONFIG_AUDIT) += audit.o
obj64-$(CONFIG_AUDIT) += compat_audit.o
obj-$(CONFIG_PPC_IO_WORKAROUNDS) += io-workarounds.o
obj-y += trace/
ifneq ($(CONFIG_PPC_INDIRECT_PIO),y)
+1 -1
View File
@@ -136,7 +136,7 @@ static bool dma_iommu_bypass_supported(struct device *dev, u64 mask)
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_controller *phb = pci_bus_to_host(pdev->bus);
if (iommu_fixed_is_weak || !phb->controller_ops.iommu_bypass_supported)
if (!phb->controller_ops.iommu_bypass_supported)
return false;
return phb->controller_ops.iommu_bypass_supported(pdev, mask);
}
-55
View File
@@ -2537,27 +2537,8 @@ EXC_REAL_NONE(0x1000, 0x100)
EXC_VIRT_NONE(0x5000, 0x100)
EXC_REAL_NONE(0x1100, 0x100)
EXC_VIRT_NONE(0x5100, 0x100)
#ifdef CONFIG_CBE_RAS
INT_DEFINE_BEGIN(cbe_system_error)
IVEC=0x1200
IHSRR=1
INT_DEFINE_END(cbe_system_error)
EXC_REAL_BEGIN(cbe_system_error, 0x1200, 0x100)
GEN_INT_ENTRY cbe_system_error, virt=0
EXC_REAL_END(cbe_system_error, 0x1200, 0x100)
EXC_VIRT_NONE(0x5200, 0x100)
EXC_COMMON_BEGIN(cbe_system_error_common)
GEN_COMMON cbe_system_error
addi r3,r1,STACK_INT_FRAME_REGS
bl CFUNC(cbe_system_error_exception)
b interrupt_return_hsrr
#else /* CONFIG_CBE_RAS */
EXC_REAL_NONE(0x1200, 0x100)
EXC_VIRT_NONE(0x5200, 0x100)
#endif
/**
* Interrupt 0x1300 - Instruction Address Breakpoint Interrupt.
@@ -2708,26 +2689,8 @@ EXC_COMMON_BEGIN(denorm_exception_common)
b interrupt_return_hsrr
#ifdef CONFIG_CBE_RAS
INT_DEFINE_BEGIN(cbe_maintenance)
IVEC=0x1600
IHSRR=1
INT_DEFINE_END(cbe_maintenance)
EXC_REAL_BEGIN(cbe_maintenance, 0x1600, 0x100)
GEN_INT_ENTRY cbe_maintenance, virt=0
EXC_REAL_END(cbe_maintenance, 0x1600, 0x100)
EXC_VIRT_NONE(0x5600, 0x100)
EXC_COMMON_BEGIN(cbe_maintenance_common)
GEN_COMMON cbe_maintenance
addi r3,r1,STACK_INT_FRAME_REGS
bl CFUNC(cbe_maintenance_exception)
b interrupt_return_hsrr
#else /* CONFIG_CBE_RAS */
EXC_REAL_NONE(0x1600, 0x100)
EXC_VIRT_NONE(0x5600, 0x100)
#endif
INT_DEFINE_BEGIN(altivec_assist)
@@ -2755,26 +2718,8 @@ EXC_COMMON_BEGIN(altivec_assist_common)
b interrupt_return_srr
#ifdef CONFIG_CBE_RAS
INT_DEFINE_BEGIN(cbe_thermal)
IVEC=0x1800
IHSRR=1
INT_DEFINE_END(cbe_thermal)
EXC_REAL_BEGIN(cbe_thermal, 0x1800, 0x100)
GEN_INT_ENTRY cbe_thermal, virt=0
EXC_REAL_END(cbe_thermal, 0x1800, 0x100)
EXC_VIRT_NONE(0x5800, 0x100)
EXC_COMMON_BEGIN(cbe_thermal_common)
GEN_COMMON cbe_thermal
addi r3,r1,STACK_INT_FRAME_REGS
bl CFUNC(cbe_thermal_exception)
b interrupt_return_hsrr
#else /* CONFIG_CBE_RAS */
EXC_REAL_NONE(0x1800, 0x100)
EXC_VIRT_NONE(0x5800, 0x100)
#endif
#ifdef CONFIG_PPC_WATCHDOG
+11 -10
View File
@@ -33,6 +33,7 @@
#include <asm/fadump-internal.h>
#include <asm/setup.h>
#include <asm/interrupt.h>
#include <asm/prom.h>
/*
* The CPU who acquired the lock to trigger the fadump crash should
@@ -1764,19 +1765,19 @@ void __init fadump_setup_param_area(void)
range_end = memblock_end_of_DRAM();
} else {
/*
* Passing additional parameters is supported for hash MMU only
* if the first memory block size is 768MB or higher.
* Memory range for passing additional parameters for HASH MMU
* must meet the following conditions:
* 1. The first memory block size must be higher than the
* minimum RMA (MIN_RMA) size. Bootloader can use memory
* upto RMA size. So it should be avoided.
* 2. The range should be between MIN_RMA and RMA size (ppc64_rma_size)
* 3. It must not overlap with the fadump reserved area.
*/
if (ppc64_rma_size < 0x30000000)
if (ppc64_rma_size < MIN_RMA*1024*1024)
return;
/*
* 640 MB to 768 MB is not used by PFW/bootloader. So, try reserving
* memory for passing additional parameters in this range to avoid
* being stomped on by PFW/bootloader.
*/
range_start = 0x2A000000;
range_end = range_start + 0x4000000;
range_start = MIN_RMA * 1024 * 1024;
range_end = min(ppc64_rma_size, fw_dump.boot_mem_top);
}
fw_dump.param_area = memblock_phys_alloc_range(COMMAND_LINE_SIZE,
-197
View File
@@ -1,197 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Support PCI IO workaround
*
* Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>
* IBM, Corp.
* (C) Copyright 2007-2008 TOSHIBA CORPORATION
*/
#undef DEBUG
#include <linux/kernel.h>
#include <linux/sched/mm.h> /* for init_mm */
#include <linux/pgtable.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
#include <asm/io-workarounds.h>
#include <asm/pte-walk.h>
#define IOWA_MAX_BUS 8
static struct iowa_bus iowa_busses[IOWA_MAX_BUS];
static unsigned int iowa_bus_count;
static struct iowa_bus *iowa_pci_find(unsigned long vaddr, unsigned long paddr)
{
int i, j;
struct resource *res;
unsigned long vstart, vend;
for (i = 0; i < iowa_bus_count; i++) {
struct iowa_bus *bus = &iowa_busses[i];
struct pci_controller *phb = bus->phb;
if (vaddr) {
vstart = (unsigned long)phb->io_base_virt;
vend = vstart + phb->pci_io_size - 1;
if ((vaddr >= vstart) && (vaddr <= vend))
return bus;
}
if (paddr)
for (j = 0; j < 3; j++) {
res = &phb->mem_resources[j];
if (paddr >= res->start && paddr <= res->end)
return bus;
}
}
return NULL;
}
#ifdef CONFIG_PPC_INDIRECT_MMIO
struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
{
struct iowa_bus *bus;
int token;
token = PCI_GET_ADDR_TOKEN(addr);
if (token && token <= iowa_bus_count)
bus = &iowa_busses[token - 1];
else {
unsigned long vaddr, paddr;
vaddr = (unsigned long)PCI_FIX_ADDR(addr);
if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
return NULL;
paddr = ppc_find_vmap_phys(vaddr);
bus = iowa_pci_find(vaddr, paddr);
if (bus == NULL)
return NULL;
}
return bus;
}
#else /* CONFIG_PPC_INDIRECT_MMIO */
struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
{
return NULL;
}
#endif /* !CONFIG_PPC_INDIRECT_MMIO */
#ifdef CONFIG_PPC_INDIRECT_PIO
struct iowa_bus *iowa_pio_find_bus(unsigned long port)
{
unsigned long vaddr = (unsigned long)pci_io_base + port;
return iowa_pci_find(vaddr, 0);
}
#else
struct iowa_bus *iowa_pio_find_bus(unsigned long port)
{
return NULL;
}
#endif
#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \
static ret iowa_##name at \
{ \
struct iowa_bus *bus; \
bus = iowa_##space##_find_bus(aa); \
if (bus && bus->ops && bus->ops->name) \
return bus->ops->name al; \
return __do_##name al; \
}
#define DEF_PCI_AC_NORET(name, at, al, space, aa) \
static void iowa_##name at \
{ \
struct iowa_bus *bus; \
bus = iowa_##space##_find_bus(aa); \
if (bus && bus->ops && bus->ops->name) { \
bus->ops->name al; \
return; \
} \
__do_##name al; \
}
#include <asm/io-defs.h>
#undef DEF_PCI_AC_RET
#undef DEF_PCI_AC_NORET
static const struct ppc_pci_io iowa_pci_io = {
#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) .name = iowa_##name,
#define DEF_PCI_AC_NORET(name, at, al, space, aa) .name = iowa_##name,
#include <asm/io-defs.h>
#undef DEF_PCI_AC_RET
#undef DEF_PCI_AC_NORET
};
#ifdef CONFIG_PPC_INDIRECT_MMIO
void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
pgprot_t prot, void *caller)
{
struct iowa_bus *bus;
void __iomem *res = __ioremap_caller(addr, size, prot, caller);
int busno;
bus = iowa_pci_find(0, (unsigned long)addr);
if (bus != NULL) {
busno = bus - iowa_busses;
PCI_SET_ADDR_TOKEN(res, busno + 1);
}
return res;
}
#endif /* !CONFIG_PPC_INDIRECT_MMIO */
bool io_workaround_inited;
/* Enable IO workaround */
static void io_workaround_init(void)
{
if (io_workaround_inited)
return;
ppc_pci_io = iowa_pci_io;
io_workaround_inited = true;
}
/* Register new bus to support workaround */
void iowa_register_bus(struct pci_controller *phb, struct ppc_pci_io *ops,
int (*initfunc)(struct iowa_bus *, void *), void *data)
{
struct iowa_bus *bus;
struct device_node *np = phb->dn;
io_workaround_init();
if (iowa_bus_count >= IOWA_MAX_BUS) {
pr_err("IOWA:Too many pci bridges, "
"workarounds disabled for %pOF\n", np);
return;
}
bus = &iowa_busses[iowa_bus_count];
bus->phb = phb;
bus->ops = ops;
bus->private = data;
if (initfunc)
if ((*initfunc)(bus, data))
return;
iowa_bus_count++;
pr_debug("IOWA:[%d]Add bus, %pOF.\n", iowa_bus_count-1, np);
}
+32 -26
View File
@@ -31,13 +31,14 @@ void _insb(const volatile u8 __iomem *port, void *buf, long count)
if (unlikely(count <= 0))
return;
asm volatile("sync");
mb();
do {
tmp = *(const volatile u8 __force *)port;
eieio();
*tbuf++ = tmp;
} while (--count != 0);
asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
data_barrier(tmp);
}
EXPORT_SYMBOL(_insb);
@@ -47,75 +48,80 @@ void _outsb(volatile u8 __iomem *port, const void *buf, long count)
if (unlikely(count <= 0))
return;
asm volatile("sync");
mb();
do {
*(volatile u8 __force *)port = *tbuf++;
} while (--count != 0);
asm volatile("sync");
mb();
}
EXPORT_SYMBOL(_outsb);
void _insw_ns(const volatile u16 __iomem *port, void *buf, long count)
void _insw(const volatile u16 __iomem *port, void *buf, long count)
{
u16 *tbuf = buf;
u16 tmp;
if (unlikely(count <= 0))
return;
asm volatile("sync");
mb();
do {
tmp = *(const volatile u16 __force *)port;
eieio();
*tbuf++ = tmp;
} while (--count != 0);
asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
data_barrier(tmp);
}
EXPORT_SYMBOL(_insw_ns);
EXPORT_SYMBOL(_insw);
void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
void _outsw(volatile u16 __iomem *port, const void *buf, long count)
{
const u16 *tbuf = buf;
if (unlikely(count <= 0))
return;
asm volatile("sync");
mb();
do {
*(volatile u16 __force *)port = *tbuf++;
} while (--count != 0);
asm volatile("sync");
mb();
}
EXPORT_SYMBOL(_outsw_ns);
EXPORT_SYMBOL(_outsw);
void _insl_ns(const volatile u32 __iomem *port, void *buf, long count)
void _insl(const volatile u32 __iomem *port, void *buf, long count)
{
u32 *tbuf = buf;
u32 tmp;
if (unlikely(count <= 0))
return;
asm volatile("sync");
mb();
do {
tmp = *(const volatile u32 __force *)port;
eieio();
*tbuf++ = tmp;
} while (--count != 0);
asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
data_barrier(tmp);
}
EXPORT_SYMBOL(_insl_ns);
EXPORT_SYMBOL(_insl);
void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
void _outsl(volatile u32 __iomem *port, const void *buf, long count)
{
const u32 *tbuf = buf;
if (unlikely(count <= 0))
return;
asm volatile("sync");
mb();
do {
*(volatile u32 __force *)port = *tbuf++;
} while (--count != 0);
asm volatile("sync");
mb();
}
EXPORT_SYMBOL(_outsl_ns);
EXPORT_SYMBOL(_outsl);
#define IO_CHECK_ALIGN(v,a) ((((unsigned long)(v)) & ((a) - 1)) == 0)
@@ -127,7 +133,7 @@ _memset_io(volatile void __iomem *addr, int c, unsigned long n)
lc |= lc << 8;
lc |= lc << 16;
__asm__ __volatile__ ("sync" : : : "memory");
mb();
while(n && !IO_CHECK_ALIGN(p, 4)) {
*((volatile u8 *)p) = c;
p++;
@@ -143,7 +149,7 @@ _memset_io(volatile void __iomem *addr, int c, unsigned long n)
p++;
n--;
}
__asm__ __volatile__ ("sync" : : : "memory");
mb();
}
EXPORT_SYMBOL(_memset_io);
@@ -152,7 +158,7 @@ void _memcpy_fromio(void *dest, const volatile void __iomem *src,
{
void *vsrc = (void __force *) src;
__asm__ __volatile__ ("sync" : : : "memory");
mb();
while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) {
*((u8 *)dest) = *((volatile u8 *)vsrc);
eieio();
@@ -174,7 +180,7 @@ void _memcpy_fromio(void *dest, const volatile void __iomem *src,
dest++;
n--;
}
__asm__ __volatile__ ("sync" : : : "memory");
mb();
}
EXPORT_SYMBOL(_memcpy_fromio);
@@ -182,7 +188,7 @@ void _memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
{
void *vdest = (void __force *) dest;
__asm__ __volatile__ ("sync" : : : "memory");
mb();
while(n && (!IO_CHECK_ALIGN(vdest, 4) || !IO_CHECK_ALIGN(src, 4))) {
*((volatile u8 *)vdest) = *((u8 *)src);
src++;
@@ -201,6 +207,6 @@ void _memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
vdest++;
n--;
}
__asm__ __volatile__ ("sync" : : : "memory");
mb();
}
EXPORT_SYMBOL(_memcpy_toio);
-102
View File
@@ -1,102 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
* <benh@kernel.crashing.org>
* and Arnd Bergmann, IBM Corp.
*/
#undef DEBUG
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/export.h>
#include <linux/mod_devicetable.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/atomic.h>
#include <asm/errno.h>
#include <asm/topology.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
#include <asm/eeh.h>
#ifdef CONFIG_PPC_OF_PLATFORM_PCI
/* The probing of PCI controllers from of_platform is currently
* 64 bits only, mostly due to gratuitous differences between
* the 32 and 64 bits PCI code on PowerPC and the 32 bits one
* lacking some bits needed here.
*/
static int of_pci_phb_probe(struct platform_device *dev)
{
struct pci_controller *phb;
/* Check if we can do that ... */
if (ppc_md.pci_setup_phb == NULL)
return -ENODEV;
pr_info("Setting up PCI bus %pOF\n", dev->dev.of_node);
/* Alloc and setup PHB data structure */
phb = pcibios_alloc_controller(dev->dev.of_node);
if (!phb)
return -ENODEV;
/* Setup parent in sysfs */
phb->parent = &dev->dev;
/* Setup the PHB using arch provided callback */
if (ppc_md.pci_setup_phb(phb)) {
pcibios_free_controller(phb);
return -ENODEV;
}
/* Process "ranges" property */
pci_process_bridge_OF_ranges(phb, dev->dev.of_node, 0);
/* Init pci_dn data structures */
pci_devs_phb_init_dynamic(phb);
/* Create EEH PE for the PHB */
eeh_phb_pe_create(phb);
/* Scan the bus */
pcibios_scan_phb(phb);
if (phb->bus == NULL)
return -ENXIO;
/* Claim resources. This might need some rework as well depending
* whether we are doing probe-only or not, like assigning unassigned
* resources etc...
*/
pcibios_claim_one_bus(phb->bus);
/* Add probed PCI devices to the device model */
pci_bus_add_devices(phb->bus);
return 0;
}
static const struct of_device_id of_pci_phb_ids[] = {
{ .type = "pci", },
{ .type = "pcix", },
{ .type = "pcie", },
{ .type = "pciex", },
{ .type = "ht", },
{}
};
static struct platform_driver of_pci_phb_driver = {
.probe = of_pci_phb_probe,
.driver = {
.name = "of-pci",
.of_match_table = of_pci_phb_ids,
},
};
builtin_platform_driver(of_pci_phb_driver);
#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
+3 -3
View File
@@ -1061,7 +1061,7 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = {
.virt_base = cpu_to_be32(0xffffffff),
.virt_size = cpu_to_be32(0xffffffff),
.load_base = cpu_to_be32(0xffffffff),
.min_rma = cpu_to_be32(512), /* 512MB min RMA */
.min_rma = cpu_to_be32(MIN_RMA),
.min_load = cpu_to_be32(0xffffffff), /* full client load */
.min_rma_percent = 0, /* min RMA percentage of total RAM */
.max_pft_size = 48, /* max log_2(hash table size) */
@@ -2889,11 +2889,11 @@ static void __init fixup_device_tree_pmac(void)
char type[8];
phandle node;
// Some pmacs are missing #size-cells on escc nodes
// Some pmacs are missing #size-cells on escc or i2s nodes
for (node = 0; prom_next_node(&node); ) {
type[0] = '\0';
prom_getprop(node, "device_type", type, sizeof(type));
if (prom_strcmp(type, "escc"))
if (prom_strcmp(type, "escc") && prom_strcmp(type, "i2s"))
continue;
if (prom_getproplen(node, "#size-cells") != PROM_ERROR)
-75
View File
@@ -798,66 +798,6 @@ void __init udbg_init_rtas_panel(void)
udbg_putc = call_rtas_display_status_delay;
}
#ifdef CONFIG_UDBG_RTAS_CONSOLE
/* If you think you're dying before early_init_dt_scan_rtas() does its
* work, you can hard code the token values for your firmware here and
* hardcode rtas.base/entry etc.
*/
static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE;
static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE;
static void udbg_rtascon_putc(char c)
{
int tries;
if (!rtas.base)
return;
/* Add CRs before LFs */
if (c == '\n')
udbg_rtascon_putc('\r');
/* if there is more than one character to be displayed, wait a bit */
for (tries = 0; tries < 16; tries++) {
if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0)
break;
udelay(1000);
}
}
static int udbg_rtascon_getc_poll(void)
{
int c;
if (!rtas.base)
return -1;
if (rtas_call(rtas_getchar_token, 0, 2, &c))
return -1;
return c;
}
static int udbg_rtascon_getc(void)
{
int c;
while ((c = udbg_rtascon_getc_poll()) == -1)
;
return c;
}
void __init udbg_init_rtas_console(void)
{
udbg_putc = udbg_rtascon_putc;
udbg_getc = udbg_rtascon_getc;
udbg_getc_poll = udbg_rtascon_getc_poll;
}
#endif /* CONFIG_UDBG_RTAS_CONSOLE */
void rtas_progress(char *s, unsigned short hex)
{
struct device_node *root;
@@ -2135,21 +2075,6 @@ int __init early_init_dt_scan_rtas(unsigned long node,
rtas.size = *sizep;
}
#ifdef CONFIG_UDBG_RTAS_CONSOLE
basep = of_get_flat_dt_prop(node, "put-term-char", NULL);
if (basep)
rtas_putchar_token = *basep;
basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
if (basep)
rtas_getchar_token = *basep;
if (rtas_putchar_token != RTAS_UNKNOWN_SERVICE &&
rtas_getchar_token != RTAS_UNKNOWN_SERVICE)
udbg_init_rtas_console();
#endif
/* break now */
return 1;
}
+1 -1
View File
@@ -892,7 +892,7 @@ unsigned long memory_block_size_bytes(void)
}
#endif
#if defined(CONFIG_PPC_INDIRECT_PIO) || defined(CONFIG_PPC_INDIRECT_MMIO)
#ifdef CONFIG_PPC_INDIRECT_PIO
struct ppc_pci_io ppc_pci_io;
EXPORT_SYMBOL(ppc_pci_io);
#endif
Loaded 100 of 1916 files, more files were not shown because too many files have changed in this diff. Show more