mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 20:48:49 +08:00
SPI NOR core changes:
* introduce Read While Write support for flashes featuring several banks * set the 4-Byte Address Mode method based on SFDP data * allow post_sfdp hook to return errors * parse SCCR MC table and introduce support for multi-chip devices SPI NOR manufacturer drivers changes: * macronix: add support for mx25uw51245g with RWW * spansion: - determine current address mode at runtime as it can be changed in a non-volatile way and differ from factory defaults or from what SFDP advertises. - enable JFFS2 write buffer mode for few ECC'd NOR flashes: S25FS256T, s25hx and s28hx - add support for s25hl02gt and s25hs02gt -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEHUIqys8OyG1eHf7fS1VPR6WNFOkFAmQ5ZhIACgkQS1VPR6WN FOkKRQgAoqUKIUr1m1Bic3gSqB70zsySfo//q/qoPSiXZ0i6y4kfHZXtb55Xekqq sH5c6wPKbWX4LfSjbkmx7Y8rKmnopI8B7mLPM8cLwCrUdiCvzZlxIC5iHvKo2O5+ V2Aw2QTd3ty3lckw8cmfhfDZMakxRbHRxGMxEpkuAghwSVNZ5p4Df6VRC9nJAats NO5bBAqx0yQFJeUSvK/0wdPmhglU4K56sp4obhIopem2Nixpp7sI+WawpOOSxhVp xDrmMBBvoBMwD+92za37qBh2bLXPeo/gP1iQ0Agg/GB8fkVRH4dIe1AwrMs/Ozvz 1ScgmNOiR8VYH49IU25K7a0F3lowcg== =ST4w -----END PGP SIGNATURE----- Merge tag 'spi-nor/for-6.4' into mtd/next SPI NOR core changes: * introduce Read While Write support for flashes featuring several banks * set the 4-Byte Address Mode method based on SFDP data * allow post_sfdp hook to return errors * parse SCCR MC table and introduce support for multi-chip devices SPI NOR manufacturer drivers changes: * macronix: add support for mx25uw51245g with RWW * spansion: - determine current address mode at runtime as it can be changed in a non-volatile way and differ from factory defaults or from what SFDP advertises. - enable JFFS2 write buffer mode for few ECC'd NOR flashes: S25FS256T, s25hx and s28hx - add support for s25hl02gt and s25hs02gt Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
commit
38f1aa5566
10
.mailmap
10
.mailmap
@ -136,6 +136,9 @@ Erik Kaneda <erik.kaneda@intel.com> <erik.schmauss@intel.com>
|
||||
Eugen Hristev <eugen.hristev@collabora.com> <eugen.hristev@microchip.com>
|
||||
Evgeniy Polyakov <johnpol@2ka.mipt.ru>
|
||||
Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com>
|
||||
Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net>
|
||||
Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com>
|
||||
Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com>
|
||||
Felipe W Damasio <felipewd@terra.com.br>
|
||||
Felix Kuhling <fxkuehl@gmx.de>
|
||||
Felix Moeller <felix@derklecks.de>
|
||||
@ -306,6 +309,8 @@ Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@osg.samsung.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@redhat.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <m.chehab@samsung.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@s-opensource.com>
|
||||
Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@mellanox.com>
|
||||
Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@nvidia.com>
|
||||
Maxime Ripard <mripard@kernel.org> <maxime.ripard@bootlin.com>
|
||||
Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com>
|
||||
Mayuresh Janorkar <mayur@ti.com>
|
||||
@ -411,7 +416,10 @@ Shuah Khan <shuah@kernel.org> <shuah.kh@samsung.com>
|
||||
Simon Arlott <simon@octiron.net> <simon@fire.lp0.eu>
|
||||
Simon Kelley <simon@thekelleys.org.uk>
|
||||
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
|
||||
Stephen Hemminger <shemminger@osdl.org>
|
||||
Stephen Hemminger <stephen@networkplumber.org> <shemminger@linux-foundation.org>
|
||||
Stephen Hemminger <stephen@networkplumber.org> <shemminger@osdl.org>
|
||||
Stephen Hemminger <stephen@networkplumber.org> <sthemmin@microsoft.com>
|
||||
Stephen Hemminger <stephen@networkplumber.org> <sthemmin@vyatta.com>
|
||||
Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
|
||||
Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
|
||||
Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
|
||||
|
@ -705,6 +705,15 @@ Description:
|
||||
zoned will report "none".
|
||||
|
||||
|
||||
What: /sys/block/<disk>/hidden
|
||||
Date: March 2023
|
||||
Contact: linux-block@vger.kernel.org
|
||||
Description:
|
||||
[RO] the block device is hidden. it doesn’t produce events, and
|
||||
can’t be opened from userspace or using blkdev_get*.
|
||||
Used for the underlying components of multipath devices.
|
||||
|
||||
|
||||
What: /sys/block/<disk>/stat
|
||||
Date: February 2008
|
||||
Contact: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
@ -7,8 +7,8 @@ workflows related to reporting bugs, submitting patches, and queueing
|
||||
patches for stable kernels.
|
||||
|
||||
For general information about submitting patches, please refer to
|
||||
`Documentation/process/`_. This document only describes additional specifics
|
||||
related to BPF.
|
||||
Documentation/process/submitting-patches.rst. This document only describes
|
||||
additional specifics related to BPF.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
@ -461,15 +461,15 @@ needed::
|
||||
|
||||
$ sudo make run_tests
|
||||
|
||||
See the kernels selftest `Documentation/dev-tools/kselftest.rst`_
|
||||
document for further documentation.
|
||||
See :doc:`kernel selftest documentation </dev-tools/kselftest>`
|
||||
for details.
|
||||
|
||||
To maximize the number of tests passing, the .config of the kernel
|
||||
under test should match the config file fragment in
|
||||
tools/testing/selftests/bpf as closely as possible.
|
||||
|
||||
Finally to ensure support for latest BPF Type Format features -
|
||||
discussed in `Documentation/bpf/btf.rst`_ - pahole version 1.16
|
||||
discussed in Documentation/bpf/btf.rst - pahole version 1.16
|
||||
is required for kernels built with CONFIG_DEBUG_INFO_BTF=y.
|
||||
pahole is delivered in the dwarves package or can be built
|
||||
from source at
|
||||
@ -684,12 +684,8 @@ when:
|
||||
|
||||
|
||||
.. Links
|
||||
.. _Documentation/process/: https://www.kernel.org/doc/html/latest/process/
|
||||
.. _netdev-FAQ: Documentation/process/maintainer-netdev.rst
|
||||
.. _selftests:
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/bpf/
|
||||
.. _Documentation/dev-tools/kselftest.rst:
|
||||
https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html
|
||||
.. _Documentation/bpf/btf.rst: btf.rst
|
||||
|
||||
Happy BPF hacking!
|
||||
|
@ -63,6 +63,3 @@ The main API is spi_nor_scan(). Before you call the hook, a driver should
|
||||
initialize the necessary fields for spi_nor{}. Please see
|
||||
drivers/mtd/spi-nor/spi-nor.c for detail. Please also refer to spi-fsl-qspi.c
|
||||
when you want to write a new driver for a SPI NOR controller.
|
||||
Another API is spi_nor_restore(), this is used to restore the status of SPI
|
||||
flash chip such as addressing mode. Call it whenever detach the driver from
|
||||
device or reboot the system.
|
||||
|
@ -105,9 +105,9 @@ descriptors. Instead, the superblock and a single block group descriptor
|
||||
block is placed at the beginning of the first, second, and last block
|
||||
groups in a meta-block group. A meta-block group is a collection of
|
||||
block groups which can be described by a single block group descriptor
|
||||
block. Since the size of the block group descriptor structure is 32
|
||||
bytes, a meta-block group contains 32 block groups for filesystems with
|
||||
a 1KB block size, and 128 block groups for filesystems with a 4KB
|
||||
block. Since the size of the block group descriptor structure is 64
|
||||
bytes, a meta-block group contains 16 block groups for filesystems with
|
||||
a 1KB block size, and 64 block groups for filesystems with a 4KB
|
||||
blocksize. Filesystems can either be created using this new block group
|
||||
descriptor layout, or existing filesystems can be resized on-line, and
|
||||
the field s_first_meta_bg in the superblock will indicate the first
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://kernel.org/schemas/netlink/genetlink-c.yaml#
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://kernel.org/schemas/netlink/genetlink-legacy.yaml#
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://kernel.org/schemas/netlink/genetlink-legacy.yaml#
|
||||
|
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
|
||||
name: ethtool
|
||||
|
||||
protocol: genetlink-legacy
|
||||
@ -11,7 +13,6 @@ attribute-sets:
|
||||
-
|
||||
name: dev-index
|
||||
type: u32
|
||||
value: 1
|
||||
-
|
||||
name: dev-name
|
||||
type: string
|
||||
@ -25,7 +26,6 @@ attribute-sets:
|
||||
-
|
||||
name: index
|
||||
type: u32
|
||||
value: 1
|
||||
-
|
||||
name: name
|
||||
type: string
|
||||
@ -39,14 +39,12 @@ attribute-sets:
|
||||
name: bit
|
||||
type: nest
|
||||
nested-attributes: bitset-bit
|
||||
value: 1
|
||||
-
|
||||
name: bitset
|
||||
attributes:
|
||||
-
|
||||
name: nomask
|
||||
type: flag
|
||||
value: 1
|
||||
-
|
||||
name: size
|
||||
type: u32
|
||||
@ -61,7 +59,6 @@ attribute-sets:
|
||||
-
|
||||
name: index
|
||||
type: u32
|
||||
value: 1
|
||||
-
|
||||
name: value
|
||||
type: string
|
||||
@ -71,7 +68,6 @@ attribute-sets:
|
||||
-
|
||||
name: string
|
||||
type: nest
|
||||
value: 1
|
||||
multi-attr: true
|
||||
nested-attributes: string
|
||||
-
|
||||
@ -80,7 +76,6 @@ attribute-sets:
|
||||
-
|
||||
name: id
|
||||
type: u32
|
||||
value: 1
|
||||
-
|
||||
name: count
|
||||
type: u32
|
||||
@ -96,14 +91,12 @@ attribute-sets:
|
||||
name: stringset
|
||||
type: nest
|
||||
multi-attr: true
|
||||
value: 1
|
||||
nested-attributes: stringset
|
||||
-
|
||||
name: strset
|
||||
attributes:
|
||||
-
|
||||
name: header
|
||||
value: 1
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
@ -119,7 +112,6 @@ attribute-sets:
|
||||
attributes:
|
||||
-
|
||||
name: header
|
||||
value: 1
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
@ -132,7 +124,6 @@ attribute-sets:
|
||||
attributes:
|
||||
-
|
||||
name: header
|
||||
value: 1
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
@ -180,7 +171,6 @@ attribute-sets:
|
||||
attributes:
|
||||
-
|
||||
name: pad
|
||||
value: 1
|
||||
type: pad
|
||||
-
|
||||
name: reassembly-errors
|
||||
@ -205,7 +195,6 @@ attribute-sets:
|
||||
attributes:
|
||||
-
|
||||
name: header
|
||||
value: 1
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
@ -251,13 +240,11 @@ operations:
|
||||
|
||||
do: &strset-get-op
|
||||
request:
|
||||
value: 1
|
||||
attributes:
|
||||
- header
|
||||
- stringsets
|
||||
- counts-only
|
||||
reply:
|
||||
value: 1
|
||||
attributes:
|
||||
- header
|
||||
- stringsets
|
||||
|
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
|
||||
name: fou
|
||||
|
||||
protocol: genetlink-legacy
|
||||
@ -26,6 +28,7 @@ attribute-sets:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: port
|
||||
type: u16
|
||||
@ -71,6 +74,7 @@ operations:
|
||||
-
|
||||
name: unspec
|
||||
doc: unused
|
||||
value: 0
|
||||
|
||||
-
|
||||
name: add
|
||||
|
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
|
||||
name: netdev
|
||||
|
||||
doc:
|
||||
@ -48,7 +50,6 @@ attribute-sets:
|
||||
name: ifindex
|
||||
doc: netdev ifindex
|
||||
type: u32
|
||||
value: 1
|
||||
checks:
|
||||
min: 1
|
||||
-
|
||||
@ -66,7 +67,6 @@ operations:
|
||||
-
|
||||
name: dev-get
|
||||
doc: Get / dump information about a netdev.
|
||||
value: 1
|
||||
attribute-set: dev
|
||||
do:
|
||||
request:
|
||||
|
@ -24,6 +24,9 @@ YAML specifications can be found under ``Documentation/netlink/specs/``
|
||||
This document describes details of the schema.
|
||||
See :doc:`intro-specs` for a practical starting guide.
|
||||
|
||||
All specs must be licensed under ``GPL-2.0-only OR BSD-3-Clause``
|
||||
to allow for easy adoption in user space code.
|
||||
|
||||
Compatibility levels
|
||||
====================
|
||||
|
||||
@ -197,9 +200,15 @@ value
|
||||
Numerical attribute ID, used in serialized Netlink messages.
|
||||
The ``value`` property can be skipped, in which case the attribute ID
|
||||
will be the value of the previous attribute plus one (recursively)
|
||||
and ``0`` for the first attribute in the attribute set.
|
||||
and ``1`` for the first attribute in the attribute set.
|
||||
|
||||
Note that the ``value`` of an attribute is defined only in its main set.
|
||||
Attributes (and operations) use ``1`` as the default value for the first
|
||||
entry (unlike enums in definitions which start from ``0``) because
|
||||
entry ``0`` is almost always reserved as undefined. Spec can explicitly
|
||||
set value to ``0`` if needed.
|
||||
|
||||
Note that the ``value`` of an attribute is defined only in its main set
|
||||
(not in subsets).
|
||||
|
||||
enum
|
||||
~~~~
|
||||
|
12
MAINTAINERS
12
MAINTAINERS
@ -9871,10 +9871,10 @@ M: Christian Brauner <brauner@kernel.org>
|
||||
M: Seth Forshee <sforshee@kernel.org>
|
||||
L: linux-fsdevel@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git://git.kernel.org/pub/scm/linux/kernel/git/vfs/idmapping.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vfs/idmapping.git
|
||||
F: Documentation/filesystems/idmappings.rst
|
||||
F: tools/testing/selftests/mount_setattr/
|
||||
F: include/linux/mnt_idmapping.*
|
||||
F: tools/testing/selftests/mount_setattr/
|
||||
|
||||
IDT VersaClock 5 CLOCK DRIVER
|
||||
M: Luca Ceresoli <luca@lucaceresoli.net>
|
||||
@ -16391,6 +16391,7 @@ R: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
R: Jiri Olsa <jolsa@kernel.org>
|
||||
R: Namhyung Kim <namhyung@kernel.org>
|
||||
R: Ian Rogers <irogers@google.com>
|
||||
R: Adrian Hunter <adrian.hunter@intel.com>
|
||||
L: linux-perf-users@vger.kernel.org
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
@ -19863,13 +19864,6 @@ S: Maintained
|
||||
W: http://wiki.laptop.org/go/DCON
|
||||
F: drivers/staging/olpc_dcon/
|
||||
|
||||
STAGING - REALTEK RTL8188EU DRIVERS
|
||||
M: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
M: Phillip Potter <phil@philpotter.co.uk>
|
||||
R: Pavel Skripkin <paskripkin@gmail.com>
|
||||
S: Supported
|
||||
F: drivers/staging/r8188eu/
|
||||
|
||||
STAGING - REALTEK RTL8712U DRIVERS
|
||||
M: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
M: Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
|
||||
|
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 3
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -23,7 +23,7 @@ alpha_read_fp_reg (unsigned long reg)
|
||||
|
||||
if (unlikely(reg >= 32))
|
||||
return 0;
|
||||
preempt_enable();
|
||||
preempt_disable();
|
||||
if (current_thread_info()->status & TS_SAVED_FP)
|
||||
val = current_thread_info()->fp[reg];
|
||||
else switch (reg) {
|
||||
@ -133,7 +133,7 @@ alpha_read_fp_reg_s (unsigned long reg)
|
||||
if (unlikely(reg >= 32))
|
||||
return 0;
|
||||
|
||||
preempt_enable();
|
||||
preempt_disable();
|
||||
if (current_thread_info()->status & TS_SAVED_FP) {
|
||||
LDT(0, current_thread_info()->fp[reg]);
|
||||
STS(0, val);
|
||||
|
@ -326,16 +326,16 @@ void __init setup_arch(char **cmdline_p)
|
||||
panic("No configuration setup");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
if (m68k_ramdisk.size) {
|
||||
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size)
|
||||
memblock_reserve(m68k_ramdisk.addr, m68k_ramdisk.size);
|
||||
|
||||
paging_init();
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size) {
|
||||
initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
|
||||
initrd_end = initrd_start + m68k_ramdisk.size;
|
||||
pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
|
||||
}
|
||||
#endif
|
||||
|
||||
paging_init();
|
||||
|
||||
#ifdef CONFIG_NATFEAT
|
||||
nf_init();
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/extable.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/fpu.h>
|
||||
@ -545,7 +546,8 @@ static inline void bus_error030 (struct frame *fp)
|
||||
errorcode |= 2;
|
||||
|
||||
if (mmusr & (MMU_I | MMU_WP)) {
|
||||
if (ssw & 4) {
|
||||
/* We might have an exception table for this PC */
|
||||
if (ssw & 4 && !search_exception_tables(fp->ptregs.pc)) {
|
||||
pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
|
||||
ssw & RW ? "read" : "write",
|
||||
fp->un.fmtb.daddr,
|
||||
|
@ -437,7 +437,7 @@ void __init paging_init(void)
|
||||
}
|
||||
|
||||
min_addr = m68k_memory[0].addr;
|
||||
max_addr = min_addr + m68k_memory[0].size;
|
||||
max_addr = min_addr + m68k_memory[0].size - 1;
|
||||
memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0,
|
||||
MEMBLOCK_NONE);
|
||||
for (i = 1; i < m68k_num_memory;) {
|
||||
@ -452,21 +452,21 @@ void __init paging_init(void)
|
||||
}
|
||||
memblock_add_node(m68k_memory[i].addr, m68k_memory[i].size, i,
|
||||
MEMBLOCK_NONE);
|
||||
addr = m68k_memory[i].addr + m68k_memory[i].size;
|
||||
addr = m68k_memory[i].addr + m68k_memory[i].size - 1;
|
||||
if (addr > max_addr)
|
||||
max_addr = addr;
|
||||
i++;
|
||||
}
|
||||
m68k_memoffset = min_addr - PAGE_OFFSET;
|
||||
m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;
|
||||
m68k_virt_to_node_shift = fls(max_addr - min_addr) - 6;
|
||||
|
||||
module_fixup(NULL, __start_fixup, __stop_fixup);
|
||||
flush_icache();
|
||||
|
||||
high_memory = phys_to_virt(max_addr);
|
||||
high_memory = phys_to_virt(max_addr) + 1;
|
||||
|
||||
min_low_pfn = availmem >> PAGE_SHIFT;
|
||||
max_pfn = max_low_pfn = max_addr >> PAGE_SHIFT;
|
||||
max_pfn = max_low_pfn = (max_addr >> PAGE_SHIFT) + 1;
|
||||
|
||||
/* Reserve kernel text/data/bss and the memory allocated in head.S */
|
||||
memblock_reserve(m68k_memory[0].addr, availmem - m68k_memory[0].addr);
|
||||
|
@ -284,6 +284,7 @@ CONFIG_IXGB=m
|
||||
CONFIG_SKGE=m
|
||||
CONFIG_SKY2=m
|
||||
CONFIG_MYRI10GE=m
|
||||
CONFIG_FEALNX=m
|
||||
CONFIG_NATSEMI=m
|
||||
CONFIG_NS83820=m
|
||||
CONFIG_S2IO=m
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
/ {
|
||||
model = "fsl,T1040RDB-REV-A";
|
||||
compatible = "fsl,T1040RDB-REV-A";
|
||||
};
|
||||
|
||||
&seville_port0 {
|
||||
|
@ -180,6 +180,9 @@
|
||||
};
|
||||
|
||||
&seville_port8 {
|
||||
ethernet = <&enet0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&seville_port9 {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -686,6 +686,7 @@
|
||||
seville_port8: port@8 {
|
||||
reg = <8>;
|
||||
phy-mode = "internal";
|
||||
ethernet = <&enet0>;
|
||||
status = "disabled";
|
||||
|
||||
fixed-link {
|
||||
@ -697,6 +698,7 @@
|
||||
seville_port9: port@9 {
|
||||
reg = <9>;
|
||||
phy-mode = "internal";
|
||||
ethernet = <&enet1>;
|
||||
status = "disabled";
|
||||
|
||||
fixed-link {
|
||||
|
@ -461,6 +461,7 @@ CONFIG_MV643XX_ETH=m
|
||||
CONFIG_SKGE=m
|
||||
CONFIG_SKY2=m
|
||||
CONFIG_MYRI10GE=m
|
||||
CONFIG_FEALNX=m
|
||||
CONFIG_NATSEMI=m
|
||||
CONFIG_NS83820=m
|
||||
CONFIG_PCMCIA_AXNET=m
|
||||
|
@ -1275,7 +1275,7 @@ static int xmon_batch_next_cpu(void)
|
||||
while (!cpumask_empty(&xmon_batch_cpus)) {
|
||||
cpu = cpumask_next_wrap(smp_processor_id(), &xmon_batch_cpus,
|
||||
xmon_batch_start_cpu, true);
|
||||
if (cpu == nr_cpumask_bits)
|
||||
if (cpu >= nr_cpu_ids)
|
||||
break;
|
||||
if (xmon_batch_start_cpu == -1)
|
||||
xmon_batch_start_cpu = cpu;
|
||||
|
@ -84,6 +84,13 @@ endif
|
||||
# Avoid generating .eh_frame sections.
|
||||
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
|
||||
|
||||
# The RISC-V attributes frequently cause compatibility issues and provide no
|
||||
# information, so just turn them off.
|
||||
KBUILD_CFLAGS += $(call cc-option,-mno-riscv-attribute)
|
||||
KBUILD_AFLAGS += $(call cc-option,-mno-riscv-attribute)
|
||||
KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
|
||||
KBUILD_AFLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
|
||||
|
||||
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
|
||||
KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
|
||||
|
||||
|
@ -111,7 +111,7 @@ void __init_or_module sifive_errata_patch_func(struct alt_entry *begin,
|
||||
mutex_lock(&text_mutex);
|
||||
patch_text_nosync(ALT_OLD_PTR(alt), ALT_ALT_PTR(alt),
|
||||
alt->alt_len);
|
||||
mutex_lock(&text_mutex);
|
||||
mutex_unlock(&text_mutex);
|
||||
cpu_apply_errata |= tmp;
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
|
||||
#define ftrace_init_nop ftrace_init_nop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE */
|
||||
|
||||
#endif /* _ASM_RISCV_FTRACE_H */
|
||||
|
@ -9,4 +9,6 @@
|
||||
int patch_text_nosync(void *addr, const void *insns, size_t len);
|
||||
int patch_text(void *addr, u32 *insns, int ninsns);
|
||||
|
||||
extern int riscv_patch_in_stop_machine;
|
||||
|
||||
#endif /* _ASM_RISCV_PATCH_H */
|
||||
|
@ -14,6 +14,10 @@ COMPAT_LD := $(LD)
|
||||
COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
|
||||
COMPAT_LD_FLAGS := -melf32lriscv
|
||||
|
||||
# Disable attributes, as they're useless and break the build.
|
||||
COMPAT_CC_FLAGS += $(call cc-option,-mno-riscv-attribute)
|
||||
COMPAT_CC_FLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
|
||||
|
||||
# Files to link into the compat_vdso
|
||||
obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o
|
||||
|
||||
|
@ -15,10 +15,19 @@
|
||||
void ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex)
|
||||
{
|
||||
mutex_lock(&text_mutex);
|
||||
|
||||
/*
|
||||
* The code sequences we use for ftrace can't be patched while the
|
||||
* kernel is running, so we need to use stop_machine() to modify them
|
||||
* for now. This doesn't play nice with text_mutex, we use this flag
|
||||
* to elide the check.
|
||||
*/
|
||||
riscv_patch_in_stop_machine = true;
|
||||
}
|
||||
|
||||
void ftrace_arch_code_modify_post_process(void) __releases(&text_mutex)
|
||||
{
|
||||
riscv_patch_in_stop_machine = false;
|
||||
mutex_unlock(&text_mutex);
|
||||
}
|
||||
|
||||
@ -107,9 +116,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
|
||||
{
|
||||
int out;
|
||||
|
||||
ftrace_arch_code_modify_prepare();
|
||||
mutex_lock(&text_mutex);
|
||||
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
|
||||
ftrace_arch_code_modify_post_process();
|
||||
mutex_unlock(&text_mutex);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <asm/kprobes.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/patch.h>
|
||||
|
||||
struct patch_insn {
|
||||
@ -20,6 +21,8 @@ struct patch_insn {
|
||||
atomic_t cpu_count;
|
||||
};
|
||||
|
||||
int riscv_patch_in_stop_machine = false;
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/*
|
||||
* The fix_to_virt(, idx) needs a const value (not a dynamic variable of
|
||||
@ -60,8 +63,15 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
|
||||
* Before reaching here, it was expected to lock the text_mutex
|
||||
* already, so we don't need to give another lock here and could
|
||||
* ensure that it was safe between each cores.
|
||||
*
|
||||
* We're currently using stop_machine() for ftrace & kprobes, and while
|
||||
* that ensures text_mutex is held before installing the mappings it
|
||||
* does not ensure text_mutex is held by the calling thread. That's
|
||||
* safe but triggers a lockdep failure, so just elide it for that
|
||||
* specific case.
|
||||
*/
|
||||
lockdep_assert_held(&text_mutex);
|
||||
if (!riscv_patch_in_stop_machine)
|
||||
lockdep_assert_held(&text_mutex);
|
||||
|
||||
if (across_pages)
|
||||
patch_map(addr + len, FIX_TEXT_POKE1);
|
||||
@ -125,6 +135,7 @@ NOKPROBE_SYMBOL(patch_text_cb);
|
||||
|
||||
int patch_text(void *addr, u32 *insns, int ninsns)
|
||||
{
|
||||
int ret;
|
||||
struct patch_insn patch = {
|
||||
.addr = addr,
|
||||
.insns = insns,
|
||||
@ -132,7 +143,18 @@ int patch_text(void *addr, u32 *insns, int ninsns)
|
||||
.cpu_count = ATOMIC_INIT(0),
|
||||
};
|
||||
|
||||
return stop_machine_cpuslocked(patch_text_cb,
|
||||
&patch, cpu_online_mask);
|
||||
/*
|
||||
* kprobes takes text_mutex, before calling patch_text(), but as we call
|
||||
* calls stop_machine(), the lockdep assertion in patch_insn_write()
|
||||
* gets confused by the context in which the lock is taken.
|
||||
* Instead, ensure the lock is held before calling stop_machine(), and
|
||||
* set riscv_patch_in_stop_machine to skip the check in
|
||||
* patch_insn_write().
|
||||
*/
|
||||
lockdep_assert_held(&text_mutex);
|
||||
riscv_patch_in_stop_machine = true;
|
||||
ret = stop_machine_cpuslocked(patch_text_cb, &patch, cpu_online_mask);
|
||||
riscv_patch_in_stop_machine = false;
|
||||
return ret;
|
||||
}
|
||||
NOKPROBE_SYMBOL(patch_text);
|
||||
|
@ -101,7 +101,7 @@ void notrace walk_stackframe(struct task_struct *task,
|
||||
while (!kstack_end(ksp)) {
|
||||
if (__kernel_text_address(pc) && unlikely(!fn(arg, pc)))
|
||||
break;
|
||||
pc = (*ksp++) - 0x4;
|
||||
pc = READ_ONCE_NOCHECK(*ksp++) - 0x4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/filter.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/stop_machine.h>
|
||||
#include <asm/patch.h>
|
||||
#include "bpf_jit.h"
|
||||
|
||||
#define RV_REG_TCC RV_REG_A6
|
||||
|
@ -50,6 +50,7 @@
|
||||
#define SR_FD 0x00008000
|
||||
#define SR_MD 0x40000000
|
||||
|
||||
#define SR_USER_MASK 0x00000303 // M, Q, S, T bits
|
||||
/*
|
||||
* DSP structure and data
|
||||
*/
|
||||
|
@ -115,6 +115,7 @@ static int
|
||||
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p)
|
||||
{
|
||||
unsigned int err = 0;
|
||||
unsigned int sr = regs->sr & ~SR_USER_MASK;
|
||||
|
||||
#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
|
||||
COPY(regs[1]);
|
||||
@ -130,6 +131,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
|
||||
COPY(sr); COPY(pc);
|
||||
#undef COPY
|
||||
|
||||
regs->sr = (regs->sr & SR_USER_MASK) | sr;
|
||||
|
||||
#ifdef CONFIG_SH_FPU
|
||||
if (boot_cpu_data.flags & CPU_HAS_FPU) {
|
||||
int owned_fp;
|
||||
|
@ -49,7 +49,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
|
||||
* simple as possible.
|
||||
* Must be called with preemption disabled.
|
||||
*/
|
||||
static void __resctrl_sched_in(void)
|
||||
static inline void __resctrl_sched_in(struct task_struct *tsk)
|
||||
{
|
||||
struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
|
||||
u32 closid = state->default_closid;
|
||||
@ -61,13 +61,13 @@ static void __resctrl_sched_in(void)
|
||||
* Else use the closid/rmid assigned to this cpu.
|
||||
*/
|
||||
if (static_branch_likely(&rdt_alloc_enable_key)) {
|
||||
tmp = READ_ONCE(current->closid);
|
||||
tmp = READ_ONCE(tsk->closid);
|
||||
if (tmp)
|
||||
closid = tmp;
|
||||
}
|
||||
|
||||
if (static_branch_likely(&rdt_mon_enable_key)) {
|
||||
tmp = READ_ONCE(current->rmid);
|
||||
tmp = READ_ONCE(tsk->rmid);
|
||||
if (tmp)
|
||||
rmid = tmp;
|
||||
}
|
||||
@ -88,17 +88,17 @@ static inline unsigned int resctrl_arch_round_mon_val(unsigned int val)
|
||||
return val * scale;
|
||||
}
|
||||
|
||||
static inline void resctrl_sched_in(void)
|
||||
static inline void resctrl_sched_in(struct task_struct *tsk)
|
||||
{
|
||||
if (static_branch_likely(&rdt_enable_key))
|
||||
__resctrl_sched_in();
|
||||
__resctrl_sched_in(tsk);
|
||||
}
|
||||
|
||||
void resctrl_cpu_detect(struct cpuinfo_x86 *c);
|
||||
|
||||
#else
|
||||
|
||||
static inline void resctrl_sched_in(void) {}
|
||||
static inline void resctrl_sched_in(struct task_struct *tsk) {}
|
||||
static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {}
|
||||
|
||||
#endif /* CONFIG_X86_CPU_RESCTRL */
|
||||
|
@ -880,6 +880,15 @@ void init_spectral_chicken(struct cpuinfo_x86 *c)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Work around Erratum 1386. The XSAVES instruction malfunctions in
|
||||
* certain circumstances on Zen1/2 uarch, and not all parts have had
|
||||
* updated microcode at the time of writing (March 2023).
|
||||
*
|
||||
* Affected parts all have no supervisor XSAVE states, meaning that
|
||||
* the XSAVEC instruction (which works fine) is equivalent.
|
||||
*/
|
||||
clear_cpu_cap(c, X86_FEATURE_XSAVES);
|
||||
}
|
||||
|
||||
static void init_amd_zn(struct cpuinfo_x86 *c)
|
||||
|
@ -314,7 +314,7 @@ static void update_cpu_closid_rmid(void *info)
|
||||
* executing task might have its own closid selected. Just reuse
|
||||
* the context switch code.
|
||||
*/
|
||||
resctrl_sched_in();
|
||||
resctrl_sched_in(current);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -530,7 +530,7 @@ static void _update_task_closid_rmid(void *task)
|
||||
* Otherwise, the MSR is updated when the task is scheduled in.
|
||||
*/
|
||||
if (task == current)
|
||||
resctrl_sched_in();
|
||||
resctrl_sched_in(task);
|
||||
}
|
||||
|
||||
static void update_task_closid_rmid(struct task_struct *t)
|
||||
|
@ -212,7 +212,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
||||
switch_fpu_finish();
|
||||
|
||||
/* Load the Intel cache allocation PQR MSR. */
|
||||
resctrl_sched_in();
|
||||
resctrl_sched_in(next_p);
|
||||
|
||||
return prev_p;
|
||||
}
|
||||
|
@ -656,7 +656,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
||||
}
|
||||
|
||||
/* Load the Intel cache allocation PQR MSR. */
|
||||
resctrl_sched_in();
|
||||
resctrl_sched_in(next_p);
|
||||
|
||||
return prev_p;
|
||||
}
|
||||
|
@ -2854,11 +2854,11 @@ bfq_setup_stable_merge(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
{
|
||||
int proc_ref = min(bfqq_process_refs(bfqq),
|
||||
bfqq_process_refs(stable_merge_bfqq));
|
||||
struct bfq_queue *new_bfqq;
|
||||
struct bfq_queue *new_bfqq = NULL;
|
||||
|
||||
if (idling_boosts_thr_without_issues(bfqd, bfqq) ||
|
||||
proc_ref == 0)
|
||||
return NULL;
|
||||
bfqq_data->stable_merge_bfqq = NULL;
|
||||
if (idling_boosts_thr_without_issues(bfqd, bfqq) || proc_ref == 0)
|
||||
goto out;
|
||||
|
||||
/* next function will take at least one ref */
|
||||
new_bfqq = bfq_setup_merge(bfqq, stable_merge_bfqq);
|
||||
@ -2873,6 +2873,11 @@ bfq_setup_stable_merge(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
new_bfqq_data->stably_merged = true;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/* deschedule stable merge, because done or aborted here */
|
||||
bfq_put_stable_ref(stable_merge_bfqq);
|
||||
|
||||
return new_bfqq;
|
||||
}
|
||||
|
||||
@ -2933,11 +2938,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
struct bfq_queue *stable_merge_bfqq =
|
||||
bfqq_data->stable_merge_bfqq;
|
||||
|
||||
/* deschedule stable merge, because done or aborted here */
|
||||
bfq_put_stable_ref(stable_merge_bfqq);
|
||||
|
||||
bfqq_data->stable_merge_bfqq = NULL;
|
||||
|
||||
return bfq_setup_stable_merge(bfqd, bfqq,
|
||||
stable_merge_bfqq,
|
||||
bfqq_data);
|
||||
|
@ -385,7 +385,7 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
|
||||
if (IS_ERR(bdev))
|
||||
ret = PTR_ERR(bdev);
|
||||
else
|
||||
blkdev_put(bdev, mode);
|
||||
blkdev_put(bdev, mode & ~FMODE_EXCL);
|
||||
|
||||
if (!(mode & FMODE_EXCL))
|
||||
bd_abort_claiming(disk->part0, disk_scan_partitions);
|
||||
|
@ -1311,7 +1311,7 @@ static void __cold try_to_generate_entropy(void)
|
||||
/* Basic CPU round-robin, which avoids the current CPU. */
|
||||
do {
|
||||
cpu = cpumask_next(cpu, &timer_cpus);
|
||||
if (cpu == nr_cpumask_bits)
|
||||
if (cpu >= nr_cpu_ids)
|
||||
cpu = cpumask_first(&timer_cpus);
|
||||
} while (cpu == smp_processor_id() && num_cpus > 1);
|
||||
|
||||
|
@ -144,8 +144,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
|
||||
|
||||
ret = -EIO;
|
||||
virt = acpi_os_map_iomem(start, len);
|
||||
if (!virt)
|
||||
if (!virt) {
|
||||
dev_warn(&chip->dev, "%s: Failed to map ACPI memory\n", __func__);
|
||||
/* try EFI log next */
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
memcpy_fromio(log->bios_event_log, virt, len);
|
||||
|
||||
|
@ -511,6 +511,63 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some AMD fTPM versions may cause stutter
|
||||
* https://www.amd.com/en/support/kb/faq/pa-410
|
||||
*
|
||||
* Fixes are available in two series of fTPM firmware:
|
||||
* 6.x.y.z series: 6.0.18.6 +
|
||||
* 3.x.y.z series: 3.57.y.5 +
|
||||
*/
|
||||
static bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
|
||||
{
|
||||
u32 val1, val2;
|
||||
u64 version;
|
||||
int ret;
|
||||
|
||||
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
|
||||
return false;
|
||||
|
||||
ret = tpm_request_locality(chip);
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val1, NULL);
|
||||
if (ret)
|
||||
goto release;
|
||||
if (val1 != 0x414D4400U /* AMD */) {
|
||||
ret = -ENODEV;
|
||||
goto release;
|
||||
}
|
||||
ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_1, &val1, NULL);
|
||||
if (ret)
|
||||
goto release;
|
||||
ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_2, &val2, NULL);
|
||||
|
||||
release:
|
||||
tpm_relinquish_locality(chip);
|
||||
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
version = ((u64)val1 << 32) | val2;
|
||||
if ((version >> 48) == 6) {
|
||||
if (version >= 0x0006000000180006ULL)
|
||||
return false;
|
||||
} else if ((version >> 48) == 3) {
|
||||
if (version >= 0x0003005700000005ULL)
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
dev_warn(&chip->dev,
|
||||
"AMD fTPM version 0x%llx causes system stutter; hwrng disabled\n",
|
||||
version);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
|
||||
{
|
||||
struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
|
||||
@ -520,7 +577,8 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
|
||||
|
||||
static int tpm_add_hwrng(struct tpm_chip *chip)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip))
|
||||
if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip) ||
|
||||
tpm_amd_is_rng_defective(chip))
|
||||
return 0;
|
||||
|
||||
snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
|
||||
|
@ -150,6 +150,79 @@ enum tpm_sub_capabilities {
|
||||
TPM_CAP_PROP_TIS_DURATION = 0x120,
|
||||
};
|
||||
|
||||
enum tpm2_pt_props {
|
||||
TPM2_PT_NONE = 0x00000000,
|
||||
TPM2_PT_GROUP = 0x00000100,
|
||||
TPM2_PT_FIXED = TPM2_PT_GROUP * 1,
|
||||
TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0,
|
||||
TPM2_PT_LEVEL = TPM2_PT_FIXED + 1,
|
||||
TPM2_PT_REVISION = TPM2_PT_FIXED + 2,
|
||||
TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3,
|
||||
TPM2_PT_YEAR = TPM2_PT_FIXED + 4,
|
||||
TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5,
|
||||
TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6,
|
||||
TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7,
|
||||
TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8,
|
||||
TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9,
|
||||
TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10,
|
||||
TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11,
|
||||
TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12,
|
||||
TPM2_PT_INPUT_BUFFER = TPM2_PT_FIXED + 13,
|
||||
TPM2_PT_HR_TRANSIENT_MIN = TPM2_PT_FIXED + 14,
|
||||
TPM2_PT_HR_PERSISTENT_MIN = TPM2_PT_FIXED + 15,
|
||||
TPM2_PT_HR_LOADED_MIN = TPM2_PT_FIXED + 16,
|
||||
TPM2_PT_ACTIVE_SESSIONS_MAX = TPM2_PT_FIXED + 17,
|
||||
TPM2_PT_PCR_COUNT = TPM2_PT_FIXED + 18,
|
||||
TPM2_PT_PCR_SELECT_MIN = TPM2_PT_FIXED + 19,
|
||||
TPM2_PT_CONTEXT_GAP_MAX = TPM2_PT_FIXED + 20,
|
||||
TPM2_PT_NV_COUNTERS_MAX = TPM2_PT_FIXED + 22,
|
||||
TPM2_PT_NV_INDEX_MAX = TPM2_PT_FIXED + 23,
|
||||
TPM2_PT_MEMORY = TPM2_PT_FIXED + 24,
|
||||
TPM2_PT_CLOCK_UPDATE = TPM2_PT_FIXED + 25,
|
||||
TPM2_PT_CONTEXT_HASH = TPM2_PT_FIXED + 26,
|
||||
TPM2_PT_CONTEXT_SYM = TPM2_PT_FIXED + 27,
|
||||
TPM2_PT_CONTEXT_SYM_SIZE = TPM2_PT_FIXED + 28,
|
||||
TPM2_PT_ORDERLY_COUNT = TPM2_PT_FIXED + 29,
|
||||
TPM2_PT_MAX_COMMAND_SIZE = TPM2_PT_FIXED + 30,
|
||||
TPM2_PT_MAX_RESPONSE_SIZE = TPM2_PT_FIXED + 31,
|
||||
TPM2_PT_MAX_DIGEST = TPM2_PT_FIXED + 32,
|
||||
TPM2_PT_MAX_OBJECT_CONTEXT = TPM2_PT_FIXED + 33,
|
||||
TPM2_PT_MAX_SESSION_CONTEXT = TPM2_PT_FIXED + 34,
|
||||
TPM2_PT_PS_FAMILY_INDICATOR = TPM2_PT_FIXED + 35,
|
||||
TPM2_PT_PS_LEVEL = TPM2_PT_FIXED + 36,
|
||||
TPM2_PT_PS_REVISION = TPM2_PT_FIXED + 37,
|
||||
TPM2_PT_PS_DAY_OF_YEAR = TPM2_PT_FIXED + 38,
|
||||
TPM2_PT_PS_YEAR = TPM2_PT_FIXED + 39,
|
||||
TPM2_PT_SPLIT_MAX = TPM2_PT_FIXED + 40,
|
||||
TPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41,
|
||||
TPM2_PT_LIBRARY_COMMANDS = TPM2_PT_FIXED + 42,
|
||||
TPM2_PT_VENDOR_COMMANDS = TPM2_PT_FIXED + 43,
|
||||
TPM2_PT_NV_BUFFER_MAX = TPM2_PT_FIXED + 44,
|
||||
TPM2_PT_MODES = TPM2_PT_FIXED + 45,
|
||||
TPM2_PT_MAX_CAP_BUFFER = TPM2_PT_FIXED + 46,
|
||||
TPM2_PT_VAR = TPM2_PT_GROUP * 2,
|
||||
TPM2_PT_PERMANENT = TPM2_PT_VAR + 0,
|
||||
TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1,
|
||||
TPM2_PT_HR_NV_INDEX = TPM2_PT_VAR + 2,
|
||||
TPM2_PT_HR_LOADED = TPM2_PT_VAR + 3,
|
||||
TPM2_PT_HR_LOADED_AVAIL = TPM2_PT_VAR + 4,
|
||||
TPM2_PT_HR_ACTIVE = TPM2_PT_VAR + 5,
|
||||
TPM2_PT_HR_ACTIVE_AVAIL = TPM2_PT_VAR + 6,
|
||||
TPM2_PT_HR_TRANSIENT_AVAIL = TPM2_PT_VAR + 7,
|
||||
TPM2_PT_HR_PERSISTENT = TPM2_PT_VAR + 8,
|
||||
TPM2_PT_HR_PERSISTENT_AVAIL = TPM2_PT_VAR + 9,
|
||||
TPM2_PT_NV_COUNTERS = TPM2_PT_VAR + 10,
|
||||
TPM2_PT_NV_COUNTERS_AVAIL = TPM2_PT_VAR + 11,
|
||||
TPM2_PT_ALGORITHM_SET = TPM2_PT_VAR + 12,
|
||||
TPM2_PT_LOADED_CURVES = TPM2_PT_VAR + 13,
|
||||
TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14,
|
||||
TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15,
|
||||
TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16,
|
||||
TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17,
|
||||
TPM2_PT_NV_WRITE_RECOVERY = TPM2_PT_VAR + 18,
|
||||
TPM2_PT_AUDIT_COUNTER_0 = TPM2_PT_VAR + 19,
|
||||
TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
|
||||
};
|
||||
|
||||
/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
|
||||
* bytes, but 128 is still a relatively large number of random bytes and
|
||||
|
@ -543,6 +543,7 @@ static void amdgpu_discovery_read_from_harvest_table(struct amdgpu_device *adev,
|
||||
struct harvest_table *harvest_info;
|
||||
u16 offset;
|
||||
int i;
|
||||
uint32_t umc_harvest_config = 0;
|
||||
|
||||
bhdr = (struct binary_header *)adev->mman.discovery_bin;
|
||||
offset = le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset);
|
||||
@ -570,12 +571,17 @@ static void amdgpu_discovery_read_from_harvest_table(struct amdgpu_device *adev,
|
||||
adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
|
||||
break;
|
||||
case UMC_HWID:
|
||||
umc_harvest_config |=
|
||||
1 << (le16_to_cpu(harvest_info->list[i].number_instance));
|
||||
(*umc_harvest_count)++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
adev->umc.active_mask = ((1 << adev->umc.node_inst_num) - 1) &
|
||||
~umc_harvest_config;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@ -1156,8 +1162,10 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
||||
AMDGPU_MAX_SDMA_INSTANCES);
|
||||
}
|
||||
|
||||
if (le16_to_cpu(ip->hw_id) == UMC_HWID)
|
||||
if (le16_to_cpu(ip->hw_id) == UMC_HWID) {
|
||||
adev->gmc.num_umc++;
|
||||
adev->umc.node_inst_num++;
|
||||
}
|
||||
|
||||
for (k = 0; k < num_base_address; k++) {
|
||||
/*
|
||||
|
@ -1315,7 +1315,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
|
||||
|
||||
if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM ||
|
||||
!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) ||
|
||||
adev->in_suspend || adev->shutdown)
|
||||
adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev)))
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv)))
|
||||
|
@ -602,27 +602,14 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
||||
struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr)
|
||||
{
|
||||
int ret;
|
||||
int index, idx;
|
||||
int index;
|
||||
int timeout = 20000;
|
||||
bool ras_intr = false;
|
||||
bool skip_unsupport = false;
|
||||
bool dev_entered;
|
||||
|
||||
if (psp->adev->no_hw_access)
|
||||
return 0;
|
||||
|
||||
dev_entered = drm_dev_enter(adev_to_drm(psp->adev), &idx);
|
||||
/*
|
||||
* We allow sending PSP messages LOAD_ASD and UNLOAD_TA without acquiring
|
||||
* a lock in drm_dev_enter during driver unload because we must call
|
||||
* drm_dev_unplug as the beginning of unload driver sequence . It is very
|
||||
* crucial that userspace can't access device instances anymore.
|
||||
*/
|
||||
if (!dev_entered)
|
||||
WARN_ON(psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_LOAD_ASD &&
|
||||
psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_UNLOAD_TA &&
|
||||
psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_INVOKE_CMD);
|
||||
|
||||
memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
|
||||
|
||||
memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
|
||||
@ -686,8 +673,6 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
||||
}
|
||||
|
||||
exit:
|
||||
if (dev_entered)
|
||||
drm_dev_exit(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#define LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) LOOP_UMC_INST((umc_inst)) LOOP_UMC_CH_INST((ch_inst))
|
||||
|
||||
#define LOOP_UMC_NODE_INST(node_inst) \
|
||||
for ((node_inst) = 0; (node_inst) < adev->umc.node_inst_num; (node_inst)++)
|
||||
for_each_set_bit((node_inst), &(adev->umc.active_mask), adev->umc.node_inst_num)
|
||||
|
||||
#define LOOP_UMC_EACH_NODE_INST_AND_CH(node_inst, umc_inst, ch_inst) \
|
||||
LOOP_UMC_NODE_INST((node_inst)) LOOP_UMC_INST_AND_CH((umc_inst), (ch_inst))
|
||||
@ -69,7 +69,7 @@ struct amdgpu_umc {
|
||||
/* number of umc instance with memory map register access */
|
||||
uint32_t umc_inst_num;
|
||||
|
||||
/*number of umc node instance with memory map register access*/
|
||||
/* Total number of umc node instance including harvest one */
|
||||
uint32_t node_inst_num;
|
||||
|
||||
/* UMC regiser per channel offset */
|
||||
@ -82,6 +82,9 @@ struct amdgpu_umc {
|
||||
|
||||
const struct amdgpu_umc_funcs *funcs;
|
||||
struct amdgpu_umc_ras *ras;
|
||||
|
||||
/* active mask for umc node instance */
|
||||
unsigned long active_mask;
|
||||
};
|
||||
|
||||
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
|
@ -567,7 +567,6 @@ static void gmc_v11_0_set_umc_funcs(struct amdgpu_device *adev)
|
||||
case IP_VERSION(8, 10, 0):
|
||||
adev->umc.channel_inst_num = UMC_V8_10_CHANNEL_INSTANCE_NUM;
|
||||
adev->umc.umc_inst_num = UMC_V8_10_UMC_INSTANCE_NUM;
|
||||
adev->umc.node_inst_num = adev->gmc.num_umc;
|
||||
adev->umc.max_ras_err_cnt_per_query = UMC_V8_10_TOTAL_CHANNEL_NUM(adev);
|
||||
adev->umc.channel_offs = UMC_V8_10_PER_CHANNEL_OFFSET;
|
||||
adev->umc.retire_unit = UMC_V8_10_NA_COL_2BITS_POWER_OF_2_NUM;
|
||||
|
@ -382,11 +382,6 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
|
||||
if (def != data)
|
||||
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_MST_CTRL_3), data);
|
||||
break;
|
||||
case IP_VERSION(7, 5, 1):
|
||||
data = RREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2);
|
||||
data &= ~RCC_DEV2_EPF0_STRAP2__STRAP_NO_SOFT_RESET_DEV2_F0_MASK;
|
||||
WREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2, data);
|
||||
fallthrough;
|
||||
default:
|
||||
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL));
|
||||
data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL,
|
||||
@ -399,6 +394,15 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (adev->ip_versions[NBIO_HWIP][0]) {
|
||||
case IP_VERSION(7, 3, 0):
|
||||
case IP_VERSION(7, 5, 1):
|
||||
data = RREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2);
|
||||
data &= ~RCC_DEV2_EPF0_STRAP2__STRAP_NO_SOFT_RESET_DEV2_F0_MASK;
|
||||
WREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2, data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
|
||||
regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
|
||||
|
@ -444,9 +444,10 @@ static int nv_read_register(struct amdgpu_device *adev, u32 se_num,
|
||||
*value = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) {
|
||||
en = &nv_allowed_read_registers[i];
|
||||
if (adev->reg_offset[en->hwip][en->inst] &&
|
||||
reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
|
||||
+ en->reg_offset))
|
||||
if (!adev->reg_offset[en->hwip][en->inst])
|
||||
continue;
|
||||
else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
|
||||
+ en->reg_offset))
|
||||
continue;
|
||||
|
||||
*value = nv_get_register_value(adev,
|
||||
|
@ -439,8 +439,9 @@ static int soc15_read_register(struct amdgpu_device *adev, u32 se_num,
|
||||
*value = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) {
|
||||
en = &soc15_allowed_read_registers[i];
|
||||
if (adev->reg_offset[en->hwip][en->inst] &&
|
||||
reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
|
||||
if (!adev->reg_offset[en->hwip][en->inst])
|
||||
continue;
|
||||
else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
|
||||
+ en->reg_offset))
|
||||
continue;
|
||||
|
||||
|
@ -111,6 +111,7 @@ static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
||||
switch (adev->ip_versions[UVD_HWIP][0]) {
|
||||
case IP_VERSION(4, 0, 0):
|
||||
case IP_VERSION(4, 0, 2):
|
||||
case IP_VERSION(4, 0, 4):
|
||||
if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
|
||||
if (encode)
|
||||
*codecs = &vcn_4_0_0_video_codecs_encode_vcn1;
|
||||
@ -291,9 +292,10 @@ static int soc21_read_register(struct amdgpu_device *adev, u32 se_num,
|
||||
*value = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(soc21_allowed_read_registers); i++) {
|
||||
en = &soc21_allowed_read_registers[i];
|
||||
if (adev->reg_offset[en->hwip][en->inst] &&
|
||||
reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
|
||||
+ en->reg_offset))
|
||||
if (!adev->reg_offset[en->hwip][en->inst])
|
||||
continue;
|
||||
else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
|
||||
+ en->reg_offset))
|
||||
continue;
|
||||
|
||||
*value = soc21_get_register_value(adev,
|
||||
|
@ -31,9 +31,9 @@
|
||||
/* number of umc instance with memory map register access */
|
||||
#define UMC_V8_10_UMC_INSTANCE_NUM 2
|
||||
|
||||
/* Total channel instances for all umc nodes */
|
||||
/* Total channel instances for all available umc nodes */
|
||||
#define UMC_V8_10_TOTAL_CHANNEL_NUM(adev) \
|
||||
(UMC_V8_10_CHANNEL_INSTANCE_NUM * UMC_V8_10_UMC_INSTANCE_NUM * (adev)->umc.node_inst_num)
|
||||
(UMC_V8_10_CHANNEL_INSTANCE_NUM * UMC_V8_10_UMC_INSTANCE_NUM * (adev)->gmc.num_umc)
|
||||
|
||||
/* UMC regiser per channel offset */
|
||||
#define UMC_V8_10_PER_CHANNEL_OFFSET 0x400
|
||||
|
@ -280,7 +280,7 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
|
||||
if (!pdd->doorbell_index) {
|
||||
int r = kfd_alloc_process_doorbells(pdd->dev,
|
||||
&pdd->doorbell_index);
|
||||
if (r)
|
||||
if (r < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -529,6 +529,19 @@ static struct clk_bw_params vg_bw_params = {
|
||||
|
||||
};
|
||||
|
||||
static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
|
||||
{
|
||||
uint32_t max = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_clocks; ++i) {
|
||||
if (clocks[i] > max)
|
||||
max = clocks[i];
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table,
|
||||
unsigned int voltage)
|
||||
{
|
||||
@ -572,12 +585,16 @@ static void vg_clk_mgr_helper_populate_bw_params(
|
||||
|
||||
bw_params->clk_table.num_entries = j + 1;
|
||||
|
||||
for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) {
|
||||
for (i = 0; i < bw_params->clk_table.num_entries - 1; i++, j--) {
|
||||
bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage;
|
||||
bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage);
|
||||
}
|
||||
bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage;
|
||||
bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, VG_NUM_DCFCLK_DPM_LEVELS);
|
||||
|
||||
bw_params->vram_type = bios_info->memory_type;
|
||||
bw_params->num_channels = bios_info->ma_channel_number;
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "asic_reg/mp/mp_13_0_0_sh_mask.h"
|
||||
#include "smu_cmn.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "umc_v8_10.h"
|
||||
|
||||
/*
|
||||
* DO NOT use these for err/warn/info/debug messages.
|
||||
@ -90,6 +91,12 @@
|
||||
|
||||
#define DEBUGSMC_MSG_Mode1Reset 2
|
||||
|
||||
/*
|
||||
* SMU_v13_0_10 supports ECCTABLE since version 80.34.0,
|
||||
* use this to check ECCTABLE feature whether support
|
||||
*/
|
||||
#define SUPPORT_ECCTABLE_SMU_13_0_10_VERSION 0x00502200
|
||||
|
||||
static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = {
|
||||
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
|
||||
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
|
||||
@ -229,6 +236,7 @@ static struct cmn2asic_mapping smu_v13_0_0_table_map[SMU_TABLE_COUNT] = {
|
||||
TAB_MAP(ACTIVITY_MONITOR_COEFF),
|
||||
[SMU_TABLE_COMBO_PPTABLE] = {1, TABLE_COMBO_PPTABLE},
|
||||
TAB_MAP(I2C_COMMANDS),
|
||||
TAB_MAP(ECCINFO),
|
||||
};
|
||||
|
||||
static struct cmn2asic_mapping smu_v13_0_0_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
|
||||
@ -462,6 +470,8 @@ static int smu_v13_0_0_tables_init(struct smu_context *smu)
|
||||
AMDGPU_GEM_DOMAIN_VRAM);
|
||||
SMU_TABLE_INIT(tables, SMU_TABLE_COMBO_PPTABLE, MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t),
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
|
||||
smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL);
|
||||
if (!smu_table->metrics_table)
|
||||
@ -477,8 +487,14 @@ static int smu_v13_0_0_tables_init(struct smu_context *smu)
|
||||
if (!smu_table->watermarks_table)
|
||||
goto err2_out;
|
||||
|
||||
smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL);
|
||||
if (!smu_table->ecc_table)
|
||||
goto err3_out;
|
||||
|
||||
return 0;
|
||||
|
||||
err3_out:
|
||||
kfree(smu_table->watermarks_table);
|
||||
err2_out:
|
||||
kfree(smu_table->gpu_metrics_table);
|
||||
err1_out:
|
||||
@ -2036,6 +2052,64 @@ static int smu_v13_0_0_send_bad_mem_channel_flag(struct smu_context *smu,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smu_v13_0_0_check_ecc_table_support(struct smu_context *smu)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
uint32_t if_version = 0xff, smu_version = 0xff;
|
||||
int ret = 0;
|
||||
|
||||
ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
|
||||
if (ret)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)) &&
|
||||
(smu_version >= SUPPORT_ECCTABLE_SMU_13_0_10_VERSION))
|
||||
return ret;
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static ssize_t smu_v13_0_0_get_ecc_info(struct smu_context *smu,
|
||||
void *table)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
EccInfoTable_t *ecc_table = NULL;
|
||||
struct ecc_info_per_ch *ecc_info_per_channel = NULL;
|
||||
int i, ret = 0;
|
||||
struct umc_ecc_info *eccinfo = (struct umc_ecc_info *)table;
|
||||
|
||||
ret = smu_v13_0_0_check_ecc_table_support(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_cmn_update_table(smu,
|
||||
SMU_TABLE_ECCINFO,
|
||||
0,
|
||||
smu_table->ecc_table,
|
||||
false);
|
||||
if (ret) {
|
||||
dev_info(adev->dev, "Failed to export SMU ecc table!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ecc_table = (EccInfoTable_t *)smu_table->ecc_table;
|
||||
|
||||
for (i = 0; i < UMC_V8_10_TOTAL_CHANNEL_NUM(adev); i++) {
|
||||
ecc_info_per_channel = &(eccinfo->ecc[i]);
|
||||
ecc_info_per_channel->ce_count_lo_chip =
|
||||
ecc_table->EccInfo[i].ce_count_lo_chip;
|
||||
ecc_info_per_channel->ce_count_hi_chip =
|
||||
ecc_table->EccInfo[i].ce_count_hi_chip;
|
||||
ecc_info_per_channel->mca_umc_status =
|
||||
ecc_table->EccInfo[i].mca_umc_status;
|
||||
ecc_info_per_channel->mca_umc_addr =
|
||||
ecc_table->EccInfo[i].mca_umc_addr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
|
||||
.get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask,
|
||||
.set_default_dpm_table = smu_v13_0_0_set_default_dpm_table,
|
||||
@ -2111,6 +2185,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
|
||||
.send_hbm_bad_pages_num = smu_v13_0_0_smu_send_bad_mem_page_num,
|
||||
.send_hbm_bad_channel_flag = smu_v13_0_0_send_bad_mem_channel_flag,
|
||||
.gpo_control = smu_v13_0_gpo_control,
|
||||
.get_ecc_info = smu_v13_0_0_get_ecc_info,
|
||||
};
|
||||
|
||||
void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
|
||||
|
@ -44,10 +44,8 @@ int drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
|
||||
|
||||
/* Sink EOTF is Bit map while infoframe is absolute values */
|
||||
if (!is_eotf_supported(hdr_metadata->hdmi_metadata_type1.eotf,
|
||||
connector->hdr_sink_metadata.hdmi_type1.eotf)) {
|
||||
DRM_DEBUG_KMS("EOTF Not Supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
connector->hdr_sink_metadata.hdmi_type1.eotf))
|
||||
DRM_DEBUG_KMS("Unknown EOTF %d\n", hdr_metadata->hdmi_metadata_type1.eotf);
|
||||
|
||||
err = hdmi_drm_infoframe_init(frame);
|
||||
if (err < 0)
|
||||
|
@ -1070,6 +1070,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
|
||||
drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
|
||||
drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
|
||||
drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
|
||||
drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
|
||||
if (state->writeback_job && state->writeback_job->fb)
|
||||
|
@ -23,7 +23,6 @@ config DRM_MSM
|
||||
select SHMEM
|
||||
select TMPFS
|
||||
select QCOM_SCM
|
||||
select DEVFREQ_GOV_SIMPLE_ONDEMAND
|
||||
select WANT_DEV_COREDUMP
|
||||
select SND_SOC_HDMI_CODEC if SND_SOC
|
||||
select SYNC_FILE
|
||||
|
@ -151,8 +151,8 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
||||
OUT_RING(ring, 1);
|
||||
|
||||
/* Enable local preemption for finegrain preemption */
|
||||
OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
|
||||
OUT_RING(ring, 0x02);
|
||||
OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
|
||||
OUT_RING(ring, 0x1);
|
||||
|
||||
/* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
|
||||
OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
|
||||
@ -806,7 +806,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
|
||||
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
|
||||
|
||||
/* Set the highest bank bit */
|
||||
if (adreno_is_a540(adreno_gpu))
|
||||
if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
|
||||
regbit = 2;
|
||||
else
|
||||
regbit = 1;
|
||||
|
@ -63,7 +63,7 @@ static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
|
||||
struct msm_ringbuffer *ring = gpu->rb[i];
|
||||
|
||||
spin_lock_irqsave(&ring->preempt_lock, flags);
|
||||
empty = (get_wptr(ring) == ring->memptrs->rptr);
|
||||
empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring));
|
||||
spin_unlock_irqrestore(&ring->preempt_lock, flags);
|
||||
|
||||
if (!empty)
|
||||
@ -207,6 +207,7 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
|
||||
a5xx_gpu->preempt[i]->wptr = 0;
|
||||
a5xx_gpu->preempt[i]->rptr = 0;
|
||||
a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
|
||||
a5xx_gpu->preempt[i]->rptr_addr = shadowptr(a5xx_gpu, gpu->rb[i]);
|
||||
}
|
||||
|
||||
/* Write a 0 to signal that we aren't switching pagetables */
|
||||
@ -257,7 +258,6 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,
|
||||
ptr->data = 0;
|
||||
ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE;
|
||||
|
||||
ptr->rptr_addr = shadowptr(a5xx_gpu, ring);
|
||||
ptr->counter = counters_iova;
|
||||
|
||||
return 0;
|
||||
|
@ -974,7 +974,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
|
||||
int status, ret;
|
||||
|
||||
if (WARN(!gmu->initialized, "The GMU is not set up yet\n"))
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
|
||||
gmu->hung = false;
|
||||
|
||||
|
@ -1746,7 +1746,9 @@ static void a6xx_destroy(struct msm_gpu *gpu)
|
||||
|
||||
a6xx_llc_slices_destroy(a6xx_gpu);
|
||||
|
||||
mutex_lock(&a6xx_gpu->gmu.lock);
|
||||
a6xx_gmu_remove(a6xx_gpu);
|
||||
mutex_unlock(&a6xx_gpu->gmu.lock);
|
||||
|
||||
adreno_gpu_cleanup(adreno_gpu);
|
||||
|
||||
|
@ -558,7 +558,8 @@ static void adreno_unbind(struct device *dev, struct device *master,
|
||||
struct msm_drm_private *priv = dev_get_drvdata(master);
|
||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||
|
||||
WARN_ON_ONCE(adreno_system_suspend(dev));
|
||||
if (pm_runtime_enabled(dev))
|
||||
WARN_ON_ONCE(adreno_system_suspend(dev));
|
||||
gpu->funcs->destroy(gpu);
|
||||
|
||||
priv->gpu_pdev = NULL;
|
||||
|
@ -12,11 +12,15 @@
|
||||
#include "dpu_hw_catalog.h"
|
||||
#include "dpu_kms.h"
|
||||
|
||||
#define VIG_MASK \
|
||||
#define VIG_BASE_MASK \
|
||||
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
|
||||
BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\
|
||||
BIT(DPU_SSPP_CDP) |\
|
||||
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
|
||||
|
||||
#define VIG_MASK \
|
||||
(VIG_BASE_MASK | \
|
||||
BIT(DPU_SSPP_CSC_10BIT))
|
||||
|
||||
#define VIG_MSM8998_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
|
||||
|
||||
@ -26,10 +30,7 @@
|
||||
#define VIG_SC7180_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
|
||||
|
||||
#define VIG_SM8250_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
|
||||
|
||||
#define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
|
||||
#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
|
||||
|
||||
#define DMA_MSM8998_MASK \
|
||||
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
|
||||
@ -51,7 +52,7 @@
|
||||
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
|
||||
|
||||
#define MIXER_MSM8998_MASK \
|
||||
(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
|
||||
(BIT(DPU_MIXER_SOURCESPLIT))
|
||||
|
||||
#define MIXER_SDM845_MASK \
|
||||
(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
|
||||
@ -314,10 +315,9 @@ static const struct dpu_caps msm8998_dpu_caps = {
|
||||
};
|
||||
|
||||
static const struct dpu_caps qcm2290_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
|
||||
.ubwc_version = DPU_HW_UBWC_VER_20,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
.max_linewidth = 2160,
|
||||
@ -353,9 +353,9 @@ static const struct dpu_caps sc7180_dpu_caps = {
|
||||
};
|
||||
|
||||
static const struct dpu_caps sm6115_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x4,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_10,
|
||||
.has_dim_layer = true,
|
||||
@ -399,7 +399,7 @@ static const struct dpu_caps sc8180x_dpu_caps = {
|
||||
static const struct dpu_caps sc8280xp_dpu_caps = {
|
||||
.max_mixer_width = 2560,
|
||||
.max_mixer_blendstages = 11,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
@ -413,7 +413,7 @@ static const struct dpu_caps sc8280xp_dpu_caps = {
|
||||
static const struct dpu_caps sm8250_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
@ -427,7 +427,7 @@ static const struct dpu_caps sm8250_dpu_caps = {
|
||||
static const struct dpu_caps sm8350_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
@ -455,7 +455,7 @@ static const struct dpu_caps sm8450_dpu_caps = {
|
||||
static const struct dpu_caps sm8550_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
@ -525,9 +525,9 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
|
||||
.reg_off = 0x2AC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2BC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = {
|
||||
.reg_off = 0x2C4, .bit_off = 8},
|
||||
},
|
||||
};
|
||||
@ -542,9 +542,9 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = {
|
||||
.reg_off = 0x2AC, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
|
||||
.reg_off = 0x2AC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2C4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_WB2] = {
|
||||
.reg_off = 0x3B8, .bit_off = 24},
|
||||
@ -569,9 +569,9 @@ static const struct dpu_mdp_cfg sc8180x_mdp[] = {
|
||||
.reg_off = 0x2AC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2BC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = {
|
||||
.reg_off = 0x2C4, .bit_off = 8},
|
||||
},
|
||||
};
|
||||
@ -609,9 +609,9 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = {
|
||||
.reg_off = 0x2AC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2BC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = {
|
||||
.reg_off = 0x2C4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
|
||||
.reg_off = 0x2BC, .bit_off = 20},
|
||||
@ -638,9 +638,9 @@ static const struct dpu_mdp_cfg sm8350_mdp[] = {
|
||||
.reg_off = 0x2ac, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2b4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2bc, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = {
|
||||
.reg_off = 0x2c4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
|
||||
.reg_off = 0x2bc, .bit_off = 20},
|
||||
@ -666,9 +666,9 @@ static const struct dpu_mdp_cfg sm8450_mdp[] = {
|
||||
.reg_off = 0x2AC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2BC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = {
|
||||
.reg_off = 0x2C4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
|
||||
.reg_off = 0x2BC, .bit_off = 20},
|
||||
@ -685,9 +685,9 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = {
|
||||
.reg_off = 0x2AC, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
|
||||
.reg_off = 0x2AC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2C4, .bit_off = 8},
|
||||
},
|
||||
};
|
||||
@ -696,7 +696,7 @@ static const struct dpu_mdp_cfg sc8280xp_mdp[] = {
|
||||
{
|
||||
.name = "top_0", .id = MDP_TOP,
|
||||
.base = 0x0, .len = 0x494,
|
||||
.features = 0,
|
||||
.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
|
||||
.highest_bank_bit = 2,
|
||||
.ubwc_swizzle = 6,
|
||||
.clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0},
|
||||
@ -705,8 +705,8 @@ static const struct dpu_mdp_cfg sc8280xp_mdp[] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x2bc, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x2c4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20},
|
||||
},
|
||||
};
|
||||
@ -734,9 +734,9 @@ static const struct dpu_mdp_cfg sm8550_mdp[] = {
|
||||
.reg_off = 0x28330, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = {
|
||||
.reg_off = 0x2a330, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA4] = {
|
||||
.reg_off = 0x2c330, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA5] = {
|
||||
.reg_off = 0x2e330, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
|
||||
.reg_off = 0x2bc, .bit_off = 20},
|
||||
@ -828,19 +828,19 @@ static const struct dpu_ctl_cfg sdm845_ctl[] = {
|
||||
static const struct dpu_ctl_cfg sc7180_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x1000, .len = 0xE4,
|
||||
.base = 0x1000, .len = 0x1dc,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
},
|
||||
{
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x1200, .len = 0xE4,
|
||||
.base = 0x1200, .len = 0x1dc,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
},
|
||||
{
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
.base = 0x1400, .len = 0xE4,
|
||||
.base = 0x1400, .len = 0x1dc,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
|
||||
},
|
||||
@ -1190,9 +1190,9 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_MSM8998_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_MSM8998_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_MSM8998_MASK,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_cfg sdm845_sspp[] = {
|
||||
@ -1209,9 +1209,9 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 =
|
||||
@ -1226,57 +1226,57 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 =
|
||||
_VIG_SBLK("0", 2, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("0", 2, DPU_SSPP_SCALER_QSEED4);
|
||||
|
||||
static const struct dpu_sspp_cfg sm6115_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
|
||||
sm6115_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 =
|
||||
_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 =
|
||||
_VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 =
|
||||
_VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 =
|
||||
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
|
||||
|
||||
static const struct dpu_sspp_cfg sm8250_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
|
||||
sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
|
||||
sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
|
||||
sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
|
||||
sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_sub_blks sm8450_vig_sblk_0 =
|
||||
_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8450_vig_sblk_1 =
|
||||
_VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8450_vig_sblk_2 =
|
||||
_VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8450_vig_sblk_3 =
|
||||
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
|
||||
|
||||
static const struct dpu_sspp_cfg sm8450_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
|
||||
@ -1292,21 +1292,21 @@ static const struct dpu_sspp_cfg sm8450_sspp[] = {
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_0 =
|
||||
_VIG_SBLK("0", 7, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("0", 7, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_1 =
|
||||
_VIG_SBLK("1", 8, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("1", 8, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_2 =
|
||||
_VIG_SBLK("2", 9, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("2", 9, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_3 =
|
||||
_VIG_SBLK("3", 10, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("3", 10, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sm8550_dma_sblk_4 = _DMA_SBLK("12", 5);
|
||||
static const struct dpu_sspp_sub_blks sd8550_dma_sblk_5 = _DMA_SBLK("13", 6);
|
||||
static const struct dpu_sspp_sub_blks sm8550_dma_sblk_5 = _DMA_SBLK("13", 6);
|
||||
|
||||
static const struct dpu_sspp_cfg sm8550_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
|
||||
@ -1326,9 +1326,9 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
SSPP_BLK("sspp_12", SSPP_DMA4, 0x2c000, DMA_CURSOR_SDM845_MASK,
|
||||
sm8550_dma_sblk_4, 14, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sm8550_dma_sblk_4, 14, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA4),
|
||||
SSPP_BLK("sspp_13", SSPP_DMA5, 0x2e000, DMA_CURSOR_SDM845_MASK,
|
||||
sd8550_dma_sblk_5, 15, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sm8550_dma_sblk_5, 15, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA5),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_cfg sc7280_sspp[] = {
|
||||
@ -1337,37 +1337,37 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_0 =
|
||||
_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_1 =
|
||||
_VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_2 =
|
||||
_VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED4);
|
||||
static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_3 =
|
||||
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
|
||||
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
|
||||
|
||||
static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
|
||||
sc8280xp_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
|
||||
sc8280xp_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
|
||||
sc8280xp_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
|
||||
sc8280xp_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
};
|
||||
|
||||
#define _VIG_SBLK_NOSCALE(num, sdma_pri) \
|
||||
@ -1517,7 +1517,7 @@ static const struct dpu_lm_cfg sc7280_lm[] = {
|
||||
/* QCM2290 */
|
||||
|
||||
static const struct dpu_lm_sub_blks qcm2290_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.maxwidth = DEFAULT_DPU_LINE_WIDTH,
|
||||
.maxblendstages = 4, /* excluding base layer */
|
||||
.blendstage_base = { /* offsets relative to mixer base */
|
||||
0x20, 0x38, 0x50, 0x68
|
||||
@ -1714,7 +1714,7 @@ static const struct dpu_pingpong_cfg sm8350_pp[] = {
|
||||
};
|
||||
|
||||
static const struct dpu_pingpong_cfg sc7280_pp[] = {
|
||||
PP_BLK("pingpong_0", PINGPONG_0, 0x59000, 0, sc7280_pp_sblk, -1, -1),
|
||||
PP_BLK("pingpong_0", PINGPONG_0, 0x69000, 0, sc7280_pp_sblk, -1, -1),
|
||||
PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1),
|
||||
PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1),
|
||||
PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1),
|
||||
@ -2841,8 +2841,6 @@ static const struct dpu_mdss_cfg qcm2290_dpu_cfg = {
|
||||
.intf = qcm2290_intf,
|
||||
.vbif_count = ARRAY_SIZE(sdm845_vbif),
|
||||
.vbif = sdm845_vbif,
|
||||
.reg_dma_count = 1,
|
||||
.dma_cfg = &sdm845_regdma,
|
||||
.perf = &qcm2290_perf_data,
|
||||
.mdss_irqs = IRQ_SC7180_MASK,
|
||||
};
|
||||
|
@ -515,6 +515,8 @@ enum dpu_clk_ctrl_type {
|
||||
DPU_CLK_CTRL_DMA1,
|
||||
DPU_CLK_CTRL_DMA2,
|
||||
DPU_CLK_CTRL_DMA3,
|
||||
DPU_CLK_CTRL_DMA4,
|
||||
DPU_CLK_CTRL_DMA5,
|
||||
DPU_CLK_CTRL_CURSOR0,
|
||||
DPU_CLK_CTRL_CURSOR1,
|
||||
DPU_CLK_CTRL_INLINE_ROT0_SSPP,
|
||||
|
@ -446,7 +446,9 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
|
||||
* CTL_LAYER has 3-bit field (and extra bits in EXT register),
|
||||
* all EXT registers has 4-bit fields.
|
||||
*/
|
||||
if (cfg->idx == 0) {
|
||||
if (cfg->idx == -1) {
|
||||
continue;
|
||||
} else if (cfg->idx == 0) {
|
||||
mixercfg[0] |= mix << cfg->shift;
|
||||
mixercfg[1] |= ext << cfg->ext_shift;
|
||||
} else {
|
||||
|
@ -577,6 +577,8 @@ void dpu_rm_release(struct dpu_global_state *global_state,
|
||||
ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
|
||||
_dpu_rm_clear_mapping(global_state->dsc_to_enc_id,
|
||||
ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
|
||||
_dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
|
||||
ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
|
||||
}
|
||||
|
||||
int dpu_rm_reserve(
|
||||
|
@ -637,8 +637,8 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
|
||||
int ret = 0;
|
||||
uint32_t i, j;
|
||||
|
||||
post_deps = kmalloc_array(nr_syncobjs, sizeof(*post_deps),
|
||||
GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
|
||||
post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps),
|
||||
GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
|
||||
if (!post_deps)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -653,7 +653,6 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
|
||||
}
|
||||
|
||||
post_deps[i].point = syncobj_desc.point;
|
||||
post_deps[i].chain = NULL;
|
||||
|
||||
if (syncobj_desc.flags) {
|
||||
ret = -EINVAL;
|
||||
|
@ -35,8 +35,9 @@ struct nv50_wndw {
|
||||
|
||||
int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *,
|
||||
enum drm_plane_type, const char *name, int index,
|
||||
const u32 *format, enum nv50_disp_interlock_type,
|
||||
u32 interlock_data, u32 heads, struct nv50_wndw **);
|
||||
const u32 *format, u32 heads,
|
||||
enum nv50_disp_interlock_type, u32 interlock_data,
|
||||
struct nv50_wndw **);
|
||||
void nv50_wndw_flush_set(struct nv50_wndw *, u32 *interlock,
|
||||
struct nv50_wndw_atom *);
|
||||
void nv50_wndw_flush_clr(struct nv50_wndw *, u32 *interlock, bool flush,
|
||||
|
@ -2,6 +2,7 @@
|
||||
#ifndef __NVKM_FB_H__
|
||||
#define __NVKM_FB_H__
|
||||
#include <core/subdev.h>
|
||||
#include <core/falcon.h>
|
||||
#include <core/mm.h>
|
||||
|
||||
/* memory type/access flags, do not match hardware values */
|
||||
@ -33,7 +34,7 @@ struct nvkm_fb {
|
||||
const struct nvkm_fb_func *func;
|
||||
struct nvkm_subdev subdev;
|
||||
|
||||
struct nvkm_blob vpr_scrubber;
|
||||
struct nvkm_falcon_fw vpr_scrubber;
|
||||
|
||||
struct {
|
||||
struct page *flush_page;
|
||||
|
@ -143,6 +143,10 @@ nvkm_fb_mem_unlock(struct nvkm_fb *fb)
|
||||
if (!fb->func->vpr.scrub_required)
|
||||
return 0;
|
||||
|
||||
ret = nvkm_subdev_oneinit(subdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!fb->func->vpr.scrub_required(fb)) {
|
||||
nvkm_debug(subdev, "VPR not locked\n");
|
||||
return 0;
|
||||
@ -150,7 +154,7 @@ nvkm_fb_mem_unlock(struct nvkm_fb *fb)
|
||||
|
||||
nvkm_debug(subdev, "VPR locked, running scrubber binary\n");
|
||||
|
||||
if (!fb->vpr_scrubber.size) {
|
||||
if (!fb->vpr_scrubber.fw.img) {
|
||||
nvkm_warn(subdev, "VPR locked, but no scrubber binary!\n");
|
||||
return 0;
|
||||
}
|
||||
@ -229,7 +233,7 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev)
|
||||
|
||||
nvkm_ram_del(&fb->ram);
|
||||
|
||||
nvkm_blob_dtor(&fb->vpr_scrubber);
|
||||
nvkm_falcon_fw_dtor(&fb->vpr_scrubber);
|
||||
|
||||
if (fb->sysmem.flush_page) {
|
||||
dma_unmap_page(subdev->device->dev, fb->sysmem.flush_page_addr,
|
||||
|
@ -37,5 +37,5 @@ ga100_fb = {
|
||||
int
|
||||
ga100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
|
||||
{
|
||||
return gp102_fb_new_(&ga100_fb, device, type, inst, pfb);
|
||||
return gf100_fb_new_(&ga100_fb, device, type, inst, pfb);
|
||||
}
|
||||
|
@ -25,25 +25,20 @@
|
||||
#include <engine/nvdec.h>
|
||||
|
||||
static int
|
||||
ga102_fb_vpr_scrub(struct nvkm_fb *fb)
|
||||
ga102_fb_oneinit(struct nvkm_fb *fb)
|
||||
{
|
||||
struct nvkm_falcon_fw fw = {};
|
||||
int ret;
|
||||
struct nvkm_subdev *subdev = &fb->subdev;
|
||||
|
||||
ret = nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", &fb->subdev, "nvdec/scrubber",
|
||||
0, &fb->subdev.device->nvdec[0]->falcon, &fw);
|
||||
if (ret)
|
||||
return ret;
|
||||
nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", subdev, "nvdec/scrubber",
|
||||
0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber);
|
||||
|
||||
ret = nvkm_falcon_fw_boot(&fw, &fb->subdev, true, NULL, NULL, 0, 0);
|
||||
nvkm_falcon_fw_dtor(&fw);
|
||||
return ret;
|
||||
return gf100_fb_oneinit(fb);
|
||||
}
|
||||
|
||||
static const struct nvkm_fb_func
|
||||
ga102_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.oneinit = ga102_fb_oneinit,
|
||||
.init = gm200_fb_init,
|
||||
.init_page = gv100_fb_init_page,
|
||||
.init_unkn = gp100_fb_init_unkn,
|
||||
@ -51,13 +46,13 @@ ga102_fb = {
|
||||
.ram_new = ga102_ram_new,
|
||||
.default_bigpage = 16,
|
||||
.vpr.scrub_required = tu102_fb_vpr_scrub_required,
|
||||
.vpr.scrub = ga102_fb_vpr_scrub,
|
||||
.vpr.scrub = gp102_fb_vpr_scrub,
|
||||
};
|
||||
|
||||
int
|
||||
ga102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
|
||||
{
|
||||
return gp102_fb_new_(&ga102_fb, device, type, inst, pfb);
|
||||
return gf100_fb_new_(&ga102_fb, device, type, inst, pfb);
|
||||
}
|
||||
|
||||
MODULE_FIRMWARE("nvidia/ga102/nvdec/scrubber.bin");
|
||||
|
@ -29,18 +29,7 @@
|
||||
int
|
||||
gp102_fb_vpr_scrub(struct nvkm_fb *fb)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fb->subdev;
|
||||
struct nvkm_falcon_fw fw = {};
|
||||
int ret;
|
||||
|
||||
ret = nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL,
|
||||
"nvdec/scrubber", 0, &subdev->device->nvdec[0]->falcon, &fw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvkm_falcon_fw_boot(&fw, subdev, true, NULL, NULL, 0, 0x00000000);
|
||||
nvkm_falcon_fw_dtor(&fw);
|
||||
return ret;
|
||||
return nvkm_falcon_fw_boot(&fb->vpr_scrubber, &fb->subdev, true, NULL, NULL, 0, 0x00000000);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -51,10 +40,21 @@ gp102_fb_vpr_scrub_required(struct nvkm_fb *fb)
|
||||
return (nvkm_rd32(device, 0x100cd0) & 0x00000010) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
gp102_fb_oneinit(struct nvkm_fb *fb)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fb->subdev;
|
||||
|
||||
nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL, "nvdec/scrubber",
|
||||
0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber);
|
||||
|
||||
return gf100_fb_oneinit(fb);
|
||||
}
|
||||
|
||||
static const struct nvkm_fb_func
|
||||
gp102_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.oneinit = gp102_fb_oneinit,
|
||||
.init = gm200_fb_init,
|
||||
.init_remapper = gp100_fb_init_remapper,
|
||||
.init_page = gm200_fb_init_page,
|
||||
@ -64,23 +64,10 @@ gp102_fb = {
|
||||
.ram_new = gp100_ram_new,
|
||||
};
|
||||
|
||||
int
|
||||
gp102_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device,
|
||||
enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
|
||||
{
|
||||
int ret = gf100_fb_new_(func, device, type, inst, pfb);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nvkm_firmware_load_blob(&(*pfb)->subdev, "nvdec/scrubber", "", 0,
|
||||
&(*pfb)->vpr_scrubber);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gp102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
|
||||
{
|
||||
return gp102_fb_new_(&gp102_fb, device, type, inst, pfb);
|
||||
return gf100_fb_new_(&gp102_fb, device, type, inst, pfb);
|
||||
}
|
||||
|
||||
MODULE_FIRMWARE("nvidia/gp102/nvdec/scrubber.bin");
|
||||
|
@ -31,7 +31,7 @@ gv100_fb_init_page(struct nvkm_fb *fb)
|
||||
static const struct nvkm_fb_func
|
||||
gv100_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.oneinit = gp102_fb_oneinit,
|
||||
.init = gm200_fb_init,
|
||||
.init_page = gv100_fb_init_page,
|
||||
.init_unkn = gp100_fb_init_unkn,
|
||||
@ -45,7 +45,7 @@ gv100_fb = {
|
||||
int
|
||||
gv100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
|
||||
{
|
||||
return gp102_fb_new_(&gv100_fb, device, type, inst, pfb);
|
||||
return gf100_fb_new_(&gv100_fb, device, type, inst, pfb);
|
||||
}
|
||||
|
||||
MODULE_FIRMWARE("nvidia/gv100/nvdec/scrubber.bin");
|
||||
|
@ -83,8 +83,7 @@ int gm200_fb_init_page(struct nvkm_fb *);
|
||||
void gp100_fb_init_remapper(struct nvkm_fb *);
|
||||
void gp100_fb_init_unkn(struct nvkm_fb *);
|
||||
|
||||
int gp102_fb_new_(const struct nvkm_fb_func *, struct nvkm_device *, enum nvkm_subdev_type, int,
|
||||
struct nvkm_fb **);
|
||||
int gp102_fb_oneinit(struct nvkm_fb *);
|
||||
bool gp102_fb_vpr_scrub_required(struct nvkm_fb *);
|
||||
int gp102_fb_vpr_scrub(struct nvkm_fb *);
|
||||
|
||||
|
@ -31,7 +31,7 @@ tu102_fb_vpr_scrub_required(struct nvkm_fb *fb)
|
||||
static const struct nvkm_fb_func
|
||||
tu102_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.oneinit = gp102_fb_oneinit,
|
||||
.init = gm200_fb_init,
|
||||
.init_page = gv100_fb_init_page,
|
||||
.init_unkn = gp100_fb_init_unkn,
|
||||
@ -45,7 +45,7 @@ tu102_fb = {
|
||||
int
|
||||
tu102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
|
||||
{
|
||||
return gp102_fb_new_(&tu102_fb, device, type, inst, pfb);
|
||||
return gf100_fb_new_(&tu102_fb, device, type, inst, pfb);
|
||||
}
|
||||
|
||||
MODULE_FIRMWARE("nvidia/tu102/nvdec/scrubber.bin");
|
||||
|
@ -455,7 +455,7 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
|
||||
if (state->fb && cirrus->cpp != cirrus_cpp(state->fb))
|
||||
cirrus_mode_set(cirrus, &crtc->mode, state->fb);
|
||||
|
||||
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
|
||||
if (state->fb && drm_atomic_helper_damage_merged(old_state, state, &rect))
|
||||
cirrus_fb_blit_rect(state->fb, &shadow_plane_state->data[0], &rect);
|
||||
}
|
||||
|
||||
|
@ -256,6 +256,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
|
||||
{
|
||||
struct hid_report *report;
|
||||
struct hid_field *field;
|
||||
unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
|
||||
unsigned int usages;
|
||||
unsigned int offset;
|
||||
unsigned int i;
|
||||
@ -286,8 +287,11 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
|
||||
offset = report->size;
|
||||
report->size += parser->global.report_size * parser->global.report_count;
|
||||
|
||||
if (parser->device->ll_driver->max_buffer_size)
|
||||
max_buffer_size = parser->device->ll_driver->max_buffer_size;
|
||||
|
||||
/* Total size check: Allow for possible report index byte */
|
||||
if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) {
|
||||
if (report->size > (max_buffer_size - 1) << 3) {
|
||||
hid_err(parser->device, "report is too long\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1963,6 +1967,7 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
|
||||
struct hid_report_enum *report_enum = hid->report_enum + type;
|
||||
struct hid_report *report;
|
||||
struct hid_driver *hdrv;
|
||||
int max_buffer_size = HID_MAX_BUFFER_SIZE;
|
||||
u32 rsize, csize = size;
|
||||
u8 *cdata = data;
|
||||
int ret = 0;
|
||||
@ -1978,10 +1983,13 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
|
||||
|
||||
rsize = hid_compute_report_size(report);
|
||||
|
||||
if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE)
|
||||
rsize = HID_MAX_BUFFER_SIZE - 1;
|
||||
else if (rsize > HID_MAX_BUFFER_SIZE)
|
||||
rsize = HID_MAX_BUFFER_SIZE;
|
||||
if (hid->ll_driver->max_buffer_size)
|
||||
max_buffer_size = hid->ll_driver->max_buffer_size;
|
||||
|
||||
if (report_enum->numbered && rsize >= max_buffer_size)
|
||||
rsize = max_buffer_size - 1;
|
||||
else if (rsize > max_buffer_size)
|
||||
rsize = max_buffer_size;
|
||||
|
||||
if (csize < rsize) {
|
||||
dbg_hid("report %d is too short, (%d < %d)\n", report->id,
|
||||
@ -2396,7 +2404,12 @@ int hid_hw_raw_request(struct hid_device *hdev,
|
||||
unsigned char reportnum, __u8 *buf,
|
||||
size_t len, enum hid_report_type rtype, enum hid_class_request reqtype)
|
||||
{
|
||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
|
||||
unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
|
||||
|
||||
if (hdev->ll_driver->max_buffer_size)
|
||||
max_buffer_size = hdev->ll_driver->max_buffer_size;
|
||||
|
||||
if (len < 1 || len > max_buffer_size || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
|
||||
@ -2415,7 +2428,12 @@ EXPORT_SYMBOL_GPL(hid_hw_raw_request);
|
||||
*/
|
||||
int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len)
|
||||
{
|
||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
|
||||
unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
|
||||
|
||||
if (hdev->ll_driver->max_buffer_size)
|
||||
max_buffer_size = hdev->ll_driver->max_buffer_size;
|
||||
|
||||
if (len < 1 || len > max_buffer_size || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (hdev->ll_driver->output_report)
|
||||
|
@ -1354,6 +1354,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
girq->parents = NULL;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_simple_irq;
|
||||
girq->threaded = true;
|
||||
|
||||
ret = gpiochip_add_data(&dev->gc, dev);
|
||||
if (ret < 0) {
|
||||
|
@ -4399,6 +4399,8 @@ static const struct hid_device_id hidpp_devices[] = {
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb02a) },
|
||||
{ /* MX Master 3 mouse over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023) },
|
||||
{ /* MX Master 3S mouse over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb034) },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Copyright (c) 2014-2016, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/devm-helpers.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/delay.h>
|
||||
@ -621,7 +622,6 @@ static void recv_ipc(struct ishtp_device *dev, uint32_t doorbell_val)
|
||||
case MNG_RESET_NOTIFY:
|
||||
if (!ishtp_dev) {
|
||||
ishtp_dev = dev;
|
||||
INIT_WORK(&fw_reset_work, fw_reset_work_fn);
|
||||
}
|
||||
schedule_work(&fw_reset_work);
|
||||
break;
|
||||
@ -940,6 +940,7 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
|
||||
{
|
||||
struct ishtp_device *dev;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
dev = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct ishtp_device) + sizeof(struct ish_hw),
|
||||
@ -975,6 +976,12 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
|
||||
list_add_tail(&tx_buf->link, &dev->wr_free_list);
|
||||
}
|
||||
|
||||
ret = devm_work_autocancel(&pdev->dev, &fw_reset_work, fw_reset_work_fn);
|
||||
if (ret) {
|
||||
dev_err(dev->devc, "Failed to initialise FW reset work\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev->ops = &ish_hw_ops;
|
||||
dev->devc = &pdev->dev;
|
||||
dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr);
|
||||
|
@ -395,6 +395,7 @@ static const struct hid_ll_driver uhid_hid_driver = {
|
||||
.parse = uhid_hid_parse,
|
||||
.raw_request = uhid_hid_raw_request,
|
||||
.output_report = uhid_hid_output_report,
|
||||
.max_buffer_size = UHID_DATA_MAX,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
@ -561,15 +561,8 @@ static int i2c_device_probe(struct device *dev)
|
||||
goto err_detach_pm_domain;
|
||||
}
|
||||
|
||||
/*
|
||||
* When there are no more users of probe(),
|
||||
* rename probe_new to probe.
|
||||
*/
|
||||
if (driver->probe_new)
|
||||
status = driver->probe_new(client);
|
||||
else if (driver->probe)
|
||||
status = driver->probe(client,
|
||||
i2c_match_id(driver->id_table, client));
|
||||
if (driver->probe)
|
||||
status = driver->probe(client);
|
||||
else
|
||||
status = -EINVAL;
|
||||
|
||||
@ -1057,7 +1050,7 @@ static int dummy_probe(struct i2c_client *client)
|
||||
|
||||
static struct i2c_driver dummy_driver = {
|
||||
.driver.name = "dummy",
|
||||
.probe_new = dummy_probe,
|
||||
.probe = dummy_probe,
|
||||
.id_table = dummy_id,
|
||||
};
|
||||
|
||||
|
@ -646,7 +646,7 @@ static void i2cdev_dev_release(struct device *dev)
|
||||
kfree(i2c_dev);
|
||||
}
|
||||
|
||||
static int i2cdev_attach_adapter(struct device *dev, void *dummy)
|
||||
static int i2cdev_attach_adapter(struct device *dev)
|
||||
{
|
||||
struct i2c_adapter *adap;
|
||||
struct i2c_dev *i2c_dev;
|
||||
@ -685,7 +685,7 @@ err_put_i2c_dev:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int i2cdev_detach_adapter(struct device *dev, void *dummy)
|
||||
static int i2cdev_detach_adapter(struct device *dev)
|
||||
{
|
||||
struct i2c_adapter *adap;
|
||||
struct i2c_dev *i2c_dev;
|
||||
@ -711,9 +711,9 @@ static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
|
||||
|
||||
switch (action) {
|
||||
case BUS_NOTIFY_ADD_DEVICE:
|
||||
return i2cdev_attach_adapter(dev, NULL);
|
||||
return i2cdev_attach_adapter(dev);
|
||||
case BUS_NOTIFY_DEL_DEVICE:
|
||||
return i2cdev_detach_adapter(dev, NULL);
|
||||
return i2cdev_detach_adapter(dev);
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
@ -725,6 +725,18 @@ static struct notifier_block i2cdev_notifier = {
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int __init i2c_dev_attach_adapter(struct device *dev, void *dummy)
|
||||
{
|
||||
i2cdev_attach_adapter(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit i2c_dev_detach_adapter(struct device *dev, void *dummy)
|
||||
{
|
||||
i2cdev_detach_adapter(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* module load/unload record keeping
|
||||
*/
|
||||
@ -752,7 +764,7 @@ static int __init i2c_dev_init(void)
|
||||
goto out_unreg_class;
|
||||
|
||||
/* Bind to already existing adapters right away */
|
||||
i2c_for_each_dev(NULL, i2cdev_attach_adapter);
|
||||
i2c_for_each_dev(NULL, i2c_dev_attach_adapter);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -768,7 +780,7 @@ out:
|
||||
static void __exit i2c_dev_exit(void)
|
||||
{
|
||||
bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier);
|
||||
i2c_for_each_dev(NULL, i2cdev_detach_adapter);
|
||||
i2c_for_each_dev(NULL, i2c_dev_detach_adapter);
|
||||
class_destroy(i2c_dev_class);
|
||||
unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS);
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ static struct i2c_driver i2c_slave_eeprom_driver = {
|
||||
.driver = {
|
||||
.name = "i2c-slave-eeprom",
|
||||
},
|
||||
.probe_new = i2c_slave_eeprom_probe,
|
||||
.probe = i2c_slave_eeprom_probe,
|
||||
.remove = i2c_slave_eeprom_remove,
|
||||
.id_table = i2c_slave_eeprom_id,
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ static struct i2c_driver i2c_slave_testunit_driver = {
|
||||
.driver = {
|
||||
.name = "i2c-slave-testunit",
|
||||
},
|
||||
.probe_new = i2c_slave_testunit_probe,
|
||||
.probe = i2c_slave_testunit_probe,
|
||||
.remove = i2c_slave_testunit_remove,
|
||||
.id_table = i2c_slave_testunit_id,
|
||||
};
|
||||
|
@ -169,7 +169,7 @@ static struct i2c_driver smbalert_driver = {
|
||||
.driver = {
|
||||
.name = "smbus_alert",
|
||||
},
|
||||
.probe_new = smbalert_probe,
|
||||
.probe = smbalert_probe,
|
||||
.remove = smbalert_remove,
|
||||
.id_table = smbalert_ids,
|
||||
};
|
||||
|
@ -306,7 +306,7 @@ static struct i2c_driver ltc4306_driver = {
|
||||
.name = "ltc4306",
|
||||
.of_match_table = of_match_ptr(ltc4306_of_match),
|
||||
},
|
||||
.probe_new = ltc4306_probe,
|
||||
.probe = ltc4306_probe,
|
||||
.remove = ltc4306_remove,
|
||||
.id_table = ltc4306_id,
|
||||
};
|
||||
|
@ -336,7 +336,7 @@ static struct i2c_driver pca9541_driver = {
|
||||
.name = "pca9541",
|
||||
.of_match_table = of_match_ptr(pca9541_of_match),
|
||||
},
|
||||
.probe_new = pca9541_probe,
|
||||
.probe = pca9541_probe,
|
||||
.remove = pca9541_remove,
|
||||
.id_table = pca9541_id,
|
||||
};
|
||||
|
@ -554,7 +554,7 @@ static struct i2c_driver pca954x_driver = {
|
||||
.pm = &pca954x_pm,
|
||||
.of_match_table = pca954x_of_match,
|
||||
},
|
||||
.probe_new = pca954x_probe,
|
||||
.probe = pca954x_probe,
|
||||
.remove = pca954x_remove,
|
||||
.id_table = pca954x_id,
|
||||
};
|
||||
|
@ -707,8 +707,7 @@ static int ov2685_configure_regulators(struct ov2685 *ov2685)
|
||||
ov2685->supplies);
|
||||
}
|
||||
|
||||
static int ov2685_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int ov2685_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct ov2685 *ov2685;
|
||||
@ -830,7 +829,7 @@ static struct i2c_driver ov2685_i2c_driver = {
|
||||
.pm = &ov2685_pm_ops,
|
||||
.of_match_table = of_match_ptr(ov2685_of_match),
|
||||
},
|
||||
.probe = &ov2685_probe,
|
||||
.probe_new = &ov2685_probe,
|
||||
.remove = &ov2685_remove,
|
||||
};
|
||||
|
||||
|
@ -1267,8 +1267,7 @@ static int ov5695_configure_regulators(struct ov5695 *ov5695)
|
||||
ov5695->supplies);
|
||||
}
|
||||
|
||||
static int ov5695_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int ov5695_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct ov5695 *ov5695;
|
||||
@ -1393,7 +1392,7 @@ static struct i2c_driver ov5695_i2c_driver = {
|
||||
.pm = &ov5695_pm_ops,
|
||||
.of_match_table = of_match_ptr(ov5695_of_match),
|
||||
},
|
||||
.probe = &ov5695_probe,
|
||||
.probe_new = &ov5695_probe,
|
||||
.remove = &ov5695_remove,
|
||||
};
|
||||
|
||||
|
@ -50,9 +50,9 @@ static const struct ad_dpot_bus_ops bops = {
|
||||
.write_r8d16 = write_r8d16,
|
||||
};
|
||||
|
||||
static int ad_dpot_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int ad_dpot_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct ad_dpot_bus_data bdata = {
|
||||
.client = client,
|
||||
.bops = &bops,
|
||||
@ -106,7 +106,7 @@ static struct i2c_driver ad_dpot_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ad_dpot",
|
||||
},
|
||||
.probe = ad_dpot_i2c_probe,
|
||||
.probe_new = ad_dpot_i2c_probe,
|
||||
.remove = ad_dpot_i2c_remove,
|
||||
.id_table = ad_dpot_id,
|
||||
};
|
||||
|
@ -206,8 +206,7 @@ static void pismo_remove(struct i2c_client *client)
|
||||
kfree(pismo);
|
||||
}
|
||||
|
||||
static int pismo_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int pismo_probe(struct i2c_client *client)
|
||||
{
|
||||
struct pismo_pdata *pdata = client->dev.platform_data;
|
||||
struct pismo_eeprom eeprom;
|
||||
@ -260,7 +259,7 @@ static struct i2c_driver pismo_driver = {
|
||||
.driver = {
|
||||
.name = "pismo",
|
||||
},
|
||||
.probe = pismo_probe,
|
||||
.probe_new = pismo_probe,
|
||||
.remove = pismo_remove,
|
||||
.id_table = pismo_id,
|
||||
};
|
||||
|
@ -508,14 +508,16 @@ int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_set_4byte_addr_mode() - Enter/Exit 4-byte address mode.
|
||||
* spi_nor_set_4byte_addr_mode_en4b_ex4b() - Enter/Exit 4-byte address mode
|
||||
* using SPINOR_OP_EN4B/SPINOR_OP_EX4B. Typically used by
|
||||
* Winbond and Macronix.
|
||||
* @nor: pointer to 'struct spi_nor'.
|
||||
* @enable: true to enter the 4-byte address mode, false to exit the 4-byte
|
||||
* address mode.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
|
||||
int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -539,15 +541,45 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* spansion_set_4byte_addr_mode() - Set 4-byte address mode for Spansion
|
||||
* flashes.
|
||||
* spi_nor_set_4byte_addr_mode_wren_en4b_ex4b() - Set 4-byte address mode using
|
||||
* SPINOR_OP_WREN followed by SPINOR_OP_EN4B or SPINOR_OP_EX4B. Typically used
|
||||
* by ST and Micron flashes.
|
||||
* @nor: pointer to 'struct spi_nor'.
|
||||
* @enable: true to enter the 4-byte address mode, false to exit the 4-byte
|
||||
* address mode.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
|
||||
int spi_nor_set_4byte_addr_mode_wren_en4b_ex4b(struct spi_nor *nor, bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = spi_nor_set_4byte_addr_mode_en4b_ex4b(nor, enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return spi_nor_write_disable(nor);
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_set_4byte_addr_mode_brwr() - Set 4-byte address mode using
|
||||
* SPINOR_OP_BRWR. Typically used by Spansion flashes.
|
||||
* @nor: pointer to 'struct spi_nor'.
|
||||
* @enable: true to enter the 4-byte address mode, false to exit the 4-byte
|
||||
* address mode.
|
||||
*
|
||||
* 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is
|
||||
* used to enable/disable 4-byte address mode. When MSB is set to ‘1’, 4-byte
|
||||
* address mode is active and A[30:24] bits are don’t care. Write instruction is
|
||||
* SPINOR_OP_BRWR(17h) with 1 byte of data.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
int spi_nor_set_4byte_addr_mode_brwr(struct spi_nor *nor, bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -588,6 +620,65 @@ int spi_nor_sr_ready(struct spi_nor *nor)
|
||||
return !(nor->bouncebuf[0] & SR_WIP);
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_use_parallel_locking() - Checks if RWW locking scheme shall be used
|
||||
* @nor: pointer to 'struct spi_nor'.
|
||||
*
|
||||
* Return: true if parallel locking is enabled, false otherwise.
|
||||
*/
|
||||
static bool spi_nor_use_parallel_locking(struct spi_nor *nor)
|
||||
{
|
||||
return nor->flags & SNOR_F_RWW;
|
||||
}
|
||||
|
||||
/* Locking helpers for status read operations */
|
||||
static int spi_nor_rww_start_rdst(struct spi_nor *nor)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
int ret = -EAGAIN;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
if (rww->ongoing_io || rww->ongoing_rd)
|
||||
goto busy;
|
||||
|
||||
rww->ongoing_io = true;
|
||||
rww->ongoing_rd = true;
|
||||
ret = 0;
|
||||
|
||||
busy:
|
||||
mutex_unlock(&nor->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spi_nor_rww_end_rdst(struct spi_nor *nor)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
rww->ongoing_io = false;
|
||||
rww->ongoing_rd = false;
|
||||
|
||||
mutex_unlock(&nor->lock);
|
||||
}
|
||||
|
||||
static int spi_nor_lock_rdst(struct spi_nor *nor)
|
||||
{
|
||||
if (spi_nor_use_parallel_locking(nor))
|
||||
return spi_nor_rww_start_rdst(nor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spi_nor_unlock_rdst(struct spi_nor *nor)
|
||||
{
|
||||
if (spi_nor_use_parallel_locking(nor)) {
|
||||
spi_nor_rww_end_rdst(nor);
|
||||
wake_up(&nor->rww.wait);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_ready() - Query the flash to see if it is ready for new commands.
|
||||
* @nor: pointer to 'struct spi_nor'.
|
||||
@ -596,11 +687,21 @@ int spi_nor_sr_ready(struct spi_nor *nor)
|
||||
*/
|
||||
static int spi_nor_ready(struct spi_nor *nor)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spi_nor_lock_rdst(nor);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
/* Flashes might override the standard routine. */
|
||||
if (nor->params->ready)
|
||||
return nor->params->ready(nor);
|
||||
ret = nor->params->ready(nor);
|
||||
else
|
||||
ret = spi_nor_sr_ready(nor);
|
||||
|
||||
return spi_nor_sr_ready(nor);
|
||||
spi_nor_unlock_rdst(nor);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1070,27 +1171,287 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
|
||||
}
|
||||
}
|
||||
|
||||
int spi_nor_lock_and_prep(struct spi_nor *nor)
|
||||
static int spi_nor_prep(struct spi_nor *nor)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (nor->controller_ops && nor->controller_ops->prepare)
|
||||
ret = nor->controller_ops->prepare(nor);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spi_nor_unprep(struct spi_nor *nor)
|
||||
{
|
||||
if (nor->controller_ops && nor->controller_ops->unprepare)
|
||||
nor->controller_ops->unprepare(nor);
|
||||
}
|
||||
|
||||
static void spi_nor_offset_to_banks(u64 bank_size, loff_t start, size_t len,
|
||||
u8 *first, u8 *last)
|
||||
{
|
||||
/* This is currently safe, the number of banks being very small */
|
||||
*first = DIV_ROUND_DOWN_ULL(start, bank_size);
|
||||
*last = DIV_ROUND_DOWN_ULL(start + len - 1, bank_size);
|
||||
}
|
||||
|
||||
/* Generic helpers for internal locking and serialization */
|
||||
static bool spi_nor_rww_start_io(struct spi_nor *nor)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
bool start = false;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
if (nor->controller_ops && nor->controller_ops->prepare) {
|
||||
ret = nor->controller_ops->prepare(nor);
|
||||
if (ret) {
|
||||
mutex_unlock(&nor->lock);
|
||||
return ret;
|
||||
}
|
||||
if (rww->ongoing_io)
|
||||
goto busy;
|
||||
|
||||
rww->ongoing_io = true;
|
||||
start = true;
|
||||
|
||||
busy:
|
||||
mutex_unlock(&nor->lock);
|
||||
return start;
|
||||
}
|
||||
|
||||
static void spi_nor_rww_end_io(struct spi_nor *nor)
|
||||
{
|
||||
mutex_lock(&nor->lock);
|
||||
nor->rww.ongoing_io = false;
|
||||
mutex_unlock(&nor->lock);
|
||||
}
|
||||
|
||||
static int spi_nor_lock_device(struct spi_nor *nor)
|
||||
{
|
||||
if (!spi_nor_use_parallel_locking(nor))
|
||||
return 0;
|
||||
|
||||
return wait_event_killable(nor->rww.wait, spi_nor_rww_start_io(nor));
|
||||
}
|
||||
|
||||
static void spi_nor_unlock_device(struct spi_nor *nor)
|
||||
{
|
||||
if (spi_nor_use_parallel_locking(nor)) {
|
||||
spi_nor_rww_end_io(nor);
|
||||
wake_up(&nor->rww.wait);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generic helpers for internal locking and serialization */
|
||||
static bool spi_nor_rww_start_exclusive(struct spi_nor *nor)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
bool start = false;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
|
||||
goto busy;
|
||||
|
||||
rww->ongoing_io = true;
|
||||
rww->ongoing_rd = true;
|
||||
rww->ongoing_pe = true;
|
||||
start = true;
|
||||
|
||||
busy:
|
||||
mutex_unlock(&nor->lock);
|
||||
return start;
|
||||
}
|
||||
|
||||
static void spi_nor_rww_end_exclusive(struct spi_nor *nor)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
rww->ongoing_io = false;
|
||||
rww->ongoing_rd = false;
|
||||
rww->ongoing_pe = false;
|
||||
mutex_unlock(&nor->lock);
|
||||
}
|
||||
|
||||
int spi_nor_prep_and_lock(struct spi_nor *nor)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spi_nor_prep(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!spi_nor_use_parallel_locking(nor))
|
||||
mutex_lock(&nor->lock);
|
||||
else
|
||||
ret = wait_event_killable(nor->rww.wait,
|
||||
spi_nor_rww_start_exclusive(nor));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void spi_nor_unlock_and_unprep(struct spi_nor *nor)
|
||||
{
|
||||
if (nor->controller_ops && nor->controller_ops->unprepare)
|
||||
nor->controller_ops->unprepare(nor);
|
||||
if (!spi_nor_use_parallel_locking(nor)) {
|
||||
mutex_unlock(&nor->lock);
|
||||
} else {
|
||||
spi_nor_rww_end_exclusive(nor);
|
||||
wake_up(&nor->rww.wait);
|
||||
}
|
||||
|
||||
spi_nor_unprep(nor);
|
||||
}
|
||||
|
||||
/* Internal locking helpers for program and erase operations */
|
||||
static bool spi_nor_rww_start_pe(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
unsigned int used_banks = 0;
|
||||
bool started = false;
|
||||
u8 first, last;
|
||||
int bank;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
|
||||
goto busy;
|
||||
|
||||
spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
|
||||
for (bank = first; bank <= last; bank++) {
|
||||
if (rww->used_banks & BIT(bank))
|
||||
goto busy;
|
||||
|
||||
used_banks |= BIT(bank);
|
||||
}
|
||||
|
||||
rww->used_banks |= used_banks;
|
||||
rww->ongoing_pe = true;
|
||||
started = true;
|
||||
|
||||
busy:
|
||||
mutex_unlock(&nor->lock);
|
||||
return started;
|
||||
}
|
||||
|
||||
static void spi_nor_rww_end_pe(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
u8 first, last;
|
||||
int bank;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
|
||||
for (bank = first; bank <= last; bank++)
|
||||
rww->used_banks &= ~BIT(bank);
|
||||
|
||||
rww->ongoing_pe = false;
|
||||
|
||||
mutex_unlock(&nor->lock);
|
||||
}
|
||||
|
||||
static int spi_nor_prep_and_lock_pe(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spi_nor_prep(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!spi_nor_use_parallel_locking(nor))
|
||||
mutex_lock(&nor->lock);
|
||||
else
|
||||
ret = wait_event_killable(nor->rww.wait,
|
||||
spi_nor_rww_start_pe(nor, start, len));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spi_nor_unlock_and_unprep_pe(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
if (!spi_nor_use_parallel_locking(nor)) {
|
||||
mutex_unlock(&nor->lock);
|
||||
} else {
|
||||
spi_nor_rww_end_pe(nor, start, len);
|
||||
wake_up(&nor->rww.wait);
|
||||
}
|
||||
|
||||
spi_nor_unprep(nor);
|
||||
}
|
||||
|
||||
/* Internal locking helpers for read operations */
|
||||
static bool spi_nor_rww_start_rd(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
unsigned int used_banks = 0;
|
||||
bool started = false;
|
||||
u8 first, last;
|
||||
int bank;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
if (rww->ongoing_io || rww->ongoing_rd)
|
||||
goto busy;
|
||||
|
||||
spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
|
||||
for (bank = first; bank <= last; bank++) {
|
||||
if (rww->used_banks & BIT(bank))
|
||||
goto busy;
|
||||
|
||||
used_banks |= BIT(bank);
|
||||
}
|
||||
|
||||
rww->used_banks |= used_banks;
|
||||
rww->ongoing_io = true;
|
||||
rww->ongoing_rd = true;
|
||||
started = true;
|
||||
|
||||
busy:
|
||||
mutex_unlock(&nor->lock);
|
||||
return started;
|
||||
}
|
||||
|
||||
static void spi_nor_rww_end_rd(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
struct spi_nor_rww *rww = &nor->rww;
|
||||
u8 first, last;
|
||||
int bank;
|
||||
|
||||
mutex_lock(&nor->lock);
|
||||
|
||||
spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
|
||||
for (bank = first; bank <= last; bank++)
|
||||
nor->rww.used_banks &= ~BIT(bank);
|
||||
|
||||
rww->ongoing_io = false;
|
||||
rww->ongoing_rd = false;
|
||||
|
||||
mutex_unlock(&nor->lock);
|
||||
}
|
||||
|
||||
static int spi_nor_prep_and_lock_rd(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spi_nor_prep(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!spi_nor_use_parallel_locking(nor))
|
||||
mutex_lock(&nor->lock);
|
||||
else
|
||||
ret = wait_event_killable(nor->rww.wait,
|
||||
spi_nor_rww_start_rd(nor, start, len));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spi_nor_unlock_and_unprep_rd(struct spi_nor *nor, loff_t start, size_t len)
|
||||
{
|
||||
if (!spi_nor_use_parallel_locking(nor)) {
|
||||
mutex_unlock(&nor->lock);
|
||||
} else {
|
||||
spi_nor_rww_end_rd(nor, start, len);
|
||||
wake_up(&nor->rww.wait);
|
||||
}
|
||||
|
||||
spi_nor_unprep(nor);
|
||||
}
|
||||
|
||||
static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr)
|
||||
@ -1397,11 +1758,18 @@ static int spi_nor_erase_multi_sectors(struct spi_nor *nor, u64 addr, u32 len)
|
||||
dev_vdbg(nor->dev, "erase_cmd->size = 0x%08x, erase_cmd->opcode = 0x%02x, erase_cmd->count = %u\n",
|
||||
cmd->size, cmd->opcode, cmd->count);
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
ret = spi_nor_lock_device(nor);
|
||||
if (ret)
|
||||
goto destroy_erase_cmd_list;
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
if (ret) {
|
||||
spi_nor_unlock_device(nor);
|
||||
goto destroy_erase_cmd_list;
|
||||
}
|
||||
|
||||
ret = spi_nor_erase_sector(nor, addr);
|
||||
spi_nor_unlock_device(nor);
|
||||
if (ret)
|
||||
goto destroy_erase_cmd_list;
|
||||
|
||||
@ -1446,7 +1814,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
addr = instr->addr;
|
||||
len = instr->len;
|
||||
|
||||
ret = spi_nor_lock_and_prep(nor);
|
||||
ret = spi_nor_prep_and_lock_pe(nor, instr->addr, instr->len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1454,11 +1822,18 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
|
||||
unsigned long timeout;
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
ret = spi_nor_lock_device(nor);
|
||||
if (ret)
|
||||
goto erase_err;
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
if (ret) {
|
||||
spi_nor_unlock_device(nor);
|
||||
goto erase_err;
|
||||
}
|
||||
|
||||
ret = spi_nor_erase_chip(nor);
|
||||
spi_nor_unlock_device(nor);
|
||||
if (ret)
|
||||
goto erase_err;
|
||||
|
||||
@ -1483,11 +1858,18 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
/* "sector"-at-a-time erase */
|
||||
} else if (spi_nor_has_uniform_erase(nor)) {
|
||||
while (len) {
|
||||
ret = spi_nor_write_enable(nor);
|
||||
ret = spi_nor_lock_device(nor);
|
||||
if (ret)
|
||||
goto erase_err;
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
if (ret) {
|
||||
spi_nor_unlock_device(nor);
|
||||
goto erase_err;
|
||||
}
|
||||
|
||||
ret = spi_nor_erase_sector(nor, addr);
|
||||
spi_nor_unlock_device(nor);
|
||||
if (ret)
|
||||
goto erase_err;
|
||||
|
||||
@ -1509,7 +1891,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
ret = spi_nor_write_disable(nor);
|
||||
|
||||
erase_err:
|
||||
spi_nor_unlock_and_unprep(nor);
|
||||
spi_nor_unlock_and_unprep_pe(nor, instr->addr, instr->len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1702,11 +2084,13 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct spi_nor *nor = mtd_to_spi_nor(mtd);
|
||||
loff_t from_lock = from;
|
||||
size_t len_lock = len;
|
||||
ssize_t ret;
|
||||
|
||||
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
|
||||
|
||||
ret = spi_nor_lock_and_prep(nor);
|
||||
ret = spi_nor_prep_and_lock_rd(nor, from_lock, len_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1733,7 +2117,8 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
ret = 0;
|
||||
|
||||
read_err:
|
||||
spi_nor_unlock_and_unprep(nor);
|
||||
spi_nor_unlock_and_unprep_rd(nor, from_lock, len_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1752,7 +2137,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
|
||||
dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
|
||||
|
||||
ret = spi_nor_lock_and_prep(nor);
|
||||
ret = spi_nor_prep_and_lock_pe(nor, to, len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1777,11 +2162,18 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
|
||||
addr = spi_nor_convert_addr(nor, addr);
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
ret = spi_nor_lock_device(nor);
|
||||
if (ret)
|
||||
goto write_err;
|
||||
|
||||
ret = spi_nor_write_enable(nor);
|
||||
if (ret) {
|
||||
spi_nor_unlock_device(nor);
|
||||
goto write_err;
|
||||
}
|
||||
|
||||
ret = spi_nor_write_data(nor, addr, page_remain, buf + i);
|
||||
spi_nor_unlock_device(nor);
|
||||
if (ret < 0)
|
||||
goto write_err;
|
||||
written = ret;
|
||||
@ -1794,7 +2186,8 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
}
|
||||
|
||||
write_err:
|
||||
spi_nor_unlock_and_unprep(nor);
|
||||
spi_nor_unlock_and_unprep_pe(nor, to, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2470,6 +2863,10 @@ static void spi_nor_init_flags(struct spi_nor *nor)
|
||||
|
||||
if (flags & NO_CHIP_ERASE)
|
||||
nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
|
||||
|
||||
if (flags & SPI_NOR_RWW && nor->info->n_banks > 1 &&
|
||||
!nor->controller_ops)
|
||||
nor->flags |= SNOR_F_RWW;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2501,6 +2898,8 @@ static void spi_nor_init_fixup_flags(struct spi_nor *nor)
|
||||
*/
|
||||
static void spi_nor_late_init_params(struct spi_nor *nor)
|
||||
{
|
||||
struct spi_nor_flash_parameter *params = nor->params;
|
||||
|
||||
if (nor->manufacturer && nor->manufacturer->fixups &&
|
||||
nor->manufacturer->fixups->late_init)
|
||||
nor->manufacturer->fixups->late_init(nor);
|
||||
@ -2508,6 +2907,10 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
|
||||
if (nor->info->fixups && nor->info->fixups->late_init)
|
||||
nor->info->fixups->late_init(nor);
|
||||
|
||||
/* Default method kept for backward compatibility. */
|
||||
if (!params->set_4byte_addr_mode)
|
||||
params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_brwr;
|
||||
|
||||
spi_nor_init_flags(nor);
|
||||
spi_nor_init_fixup_flags(nor);
|
||||
|
||||
@ -2517,6 +2920,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
|
||||
*/
|
||||
if (nor->flags & SNOR_F_HAS_LOCK && !nor->params->locking_ops)
|
||||
spi_nor_init_default_locking_ops(nor);
|
||||
|
||||
nor->params->bank_size = div64_u64(nor->params->size, nor->info->n_banks);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2574,7 +2979,6 @@ static void spi_nor_init_default_params(struct spi_nor *nor)
|
||||
struct device_node *np = spi_nor_get_flash_node(nor);
|
||||
|
||||
params->quad_enable = spi_nor_sr2_bit1_quad_enable;
|
||||
params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
|
||||
params->otp.org = &info->otp_org;
|
||||
|
||||
/* Default to 16-bit Write Status (01h) Command */
|
||||
@ -2730,6 +3134,33 @@ static int spi_nor_quad_enable(struct spi_nor *nor)
|
||||
return nor->params->quad_enable(nor);
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_set_4byte_addr_mode() - Set address mode.
|
||||
* @nor: pointer to a 'struct spi_nor'.
|
||||
* @enable: enable/disable 4 byte address mode.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
|
||||
{
|
||||
struct spi_nor_flash_parameter *params = nor->params;
|
||||
int ret;
|
||||
|
||||
ret = params->set_4byte_addr_mode(nor, enable);
|
||||
if (ret && ret != -ENOTSUPP)
|
||||
return ret;
|
||||
|
||||
if (enable) {
|
||||
params->addr_nbytes = 4;
|
||||
params->addr_mode_nbytes = 4;
|
||||
} else {
|
||||
params->addr_nbytes = 3;
|
||||
params->addr_mode_nbytes = 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_nor_init(struct spi_nor *nor)
|
||||
{
|
||||
int err;
|
||||
@ -2773,8 +3204,8 @@ static int spi_nor_init(struct spi_nor *nor)
|
||||
*/
|
||||
WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
|
||||
"enabling reset hack; may not recover from unexpected reboots\n");
|
||||
err = nor->params->set_4byte_addr_mode(nor, true);
|
||||
if (err && err != -ENOTSUPP)
|
||||
err = spi_nor_set_4byte_addr_mode(nor, true);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -2887,14 +3318,14 @@ static void spi_nor_put_device(struct mtd_info *mtd)
|
||||
module_put(dev->driver->owner);
|
||||
}
|
||||
|
||||
void spi_nor_restore(struct spi_nor *nor)
|
||||
static void spi_nor_restore(struct spi_nor *nor)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* restore the addressing mode */
|
||||
if (nor->addr_nbytes == 4 && !(nor->flags & SNOR_F_4B_OPCODES) &&
|
||||
nor->flags & SNOR_F_BROKEN_RESET) {
|
||||
ret = nor->params->set_4byte_addr_mode(nor, false);
|
||||
ret = spi_nor_set_4byte_addr_mode(nor, false);
|
||||
if (ret)
|
||||
/*
|
||||
* Do not stop the execution in the hope that the flash
|
||||
@ -2907,7 +3338,6 @@ void spi_nor_restore(struct spi_nor *nor)
|
||||
if (nor->flags & SNOR_F_SOFT_RESET)
|
||||
spi_nor_soft_reset(nor);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_nor_restore);
|
||||
|
||||
static const struct flash_info *spi_nor_match_name(struct spi_nor *nor,
|
||||
const char *name)
|
||||
@ -2952,7 +3382,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
|
||||
* JEDEC knows better, so overwrite platform ID. We
|
||||
* can't trust partitions any longer, but we'll let
|
||||
* mtd apply them anyway, since some partitions may be
|
||||
* marked read-only, and we don't want to lose that
|
||||
* marked read-only, and we don't want to loose that
|
||||
* information, even if it's not 100% accurate.
|
||||
*/
|
||||
dev_warn(nor->dev, "found %s, expected %s\n",
|
||||
@ -2977,6 +3407,9 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
|
||||
mtd->name = dev_name(dev);
|
||||
mtd->type = MTD_NORFLASH;
|
||||
mtd->flags = MTD_CAP_NORFLASH;
|
||||
/* Unset BIT_WRITEABLE to enable JFFS2 write buffer for ECC'd NOR */
|
||||
if (nor->flags & SNOR_F_ECC)
|
||||
mtd->flags &= ~MTD_BIT_WRITEABLE;
|
||||
if (nor->info->flags & SPI_NOR_NO_ERASE)
|
||||
mtd->flags |= MTD_NO_ERASE;
|
||||
else
|
||||
@ -3064,6 +3497,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (spi_nor_use_parallel_locking(nor))
|
||||
init_waitqueue_head(&nor->rww.wait);
|
||||
|
||||
/*
|
||||
* Configure the SPI memory:
|
||||
* - select op codes for (Fast) Read, Page Program and Sector Erase.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user