Core MTD changes:

* otp:
   - Put factory OTP/NVRAM into the entropy pool
   - Clean up on error in mtd_otp_nvmem_add()
 
 MTD devices changes:
 * sm_ftl: Fix typos in comments
 * Use SPDX license headers
 * pismo: Switch back to use i2c_driver's .probe()
 * mtdpart: Drop useless LIST_HEAD
 * st_spi_fsm: Use the devm_clk_get_enabled() helper function
 
 DT binding changes:
 * partitions:
   - Include TP-Link SafeLoader in allowed list
   - Add missing type for "linux,rootfs"
 * Extend the nand node names filter
 * Create a file for raw NAND chip properties
 * Mark nand-ecc-placement deprecated
 * Describe nand-ecc-mode
 * Prevent NAND chip unevaluated properties in all NAND bindings with a NAND chip
   reference.
 * Qcom: Fix a property position
 * Marvell: Convert to YAML DT schema
 
 Raw NAND chip drivers changes:
 * Macronix: OTP access for MX30LFxG18AC
 * Add basic Sandisk manufacturer ops
 * Add support for Sandisk SDTNQGAMA
 
 Raw NAND controller driver changes:
 * Meson:
   - Replace integer consts with proper defines
   - Allow waiting w/o wired ready/busy pin
   - Check buffer length validity
   - Fix unaligned DMA buffers handling
   - dt-bindings: Fix 'nand-rb' property
 * Arasan: Revert "mtd: rawnand: arasan: Prevent an unsupported configuration"
   as this limitation is no longer true thanks to the recent efforts in improving
   the clocks support in this driver
 
 SPI-NAND changes:
 * Gigadevice: add support for GD5F2GQ5xExxH
 * Macronix: Add support for serial NAND flashes
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEE9HuaYnbmDhq/XIDIJWrqGEe9VoQFAmSV0L8ACgkQJWrqGEe9
 VoS4wggApYa1Qy7FRqofMEkrTxUQgLYFi4QzeCZLwdavtzUANcqck5WpOFzZE+ws
 A7cdvp0gxcbl2Y0lKKIiEU+UdJpXjr6aZpCRVK05n/8OZTFvUd7dYttK0swsh+QD
 OAN/Y8ESbDjOHhV8jT8y8ItRY2wAeNyLTAvOjI5I+i8iEJ8AK3N5Or6tFWZ5CUn8
 HX2R1hpwBfZeVfkg+uMRxnrqhG/IpzmrXRGuRYGvMBuqO1gxU1/3GuZLUIxIsVH2
 8XfhY1fdMLaHsZ20yR2ZxVKgo/53tPVxNucsdv9OwiwEZWVhxVoX8wP4t4kH3fTL
 IIgB+TVGm5KBgtQUUEwFk6mji+Yxpw==
 =dbsj
 -----END PGP SIGNATURE-----

Merge tag 'mtd/for-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux

Pull mtd updates from
 "Core MTD changes:
   - otp:
      - Put factory OTP/NVRAM into the entropy pool
      - Clean up on error in mtd_otp_nvmem_add()

  MTD devices changes:
   - sm_ftl: Fix typos in comments
   - Use SPDX license headers
   - pismo: Switch back to use i2c_driver's .probe()
   - mtdpart: Drop useless LIST_HEAD
   - st_spi_fsm: Use the devm_clk_get_enabled() helper function

  DT binding changes:
   - partitions:
      - Include TP-Link SafeLoader in allowed list
      - Add missing type for "linux,rootfs"
   - Extend the nand node names filter
   - Create a file for raw NAND chip properties
   - Mark nand-ecc-placement deprecated
   - Describe nand-ecc-mode
   - Prevent NAND chip unevaluated properties in all NAND bindings with
     a NAND chip reference.
   - Qcom: Fix a property position
   - Marvell: Convert to YAML DT schema

  Raw NAND chip drivers changes:
   - Macronix: OTP access for MX30LFxG18AC
   - Add basic Sandisk manufacturer ops
   - Add support for Sandisk SDTNQGAMA

  Raw NAND controller driver changes:
   - Meson:
      - Replace integer consts with proper defines
      - Allow waiting w/o wired ready/busy pin
      - Check buffer length validity
      - Fix unaligned DMA buffers handling
      - dt-bindings: Fix 'nand-rb' property
   - Arasan: Revert "mtd: rawnand: arasan: Prevent an unsupported
     configuration" as this limitation is no longer true thanks to the
     recent efforts in improving the clocks support in this driver

  SPI-NAND changes:
   - Gigadevice: add support for GD5F2GQ5xExxH
   - Macronix: Add support for serial NAND flashes"

* tag 'mtd/for-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (38 commits)
  dt-bindings: mtd: marvell-nand: Convert to YAML DT scheme
  dt-bindings: mtd: ti,am654: Prevent unevaluated properties
  dt-bindings: mtd: mediatek: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: mediatek: Reference raw-nand-chip.yaml
  dt-bindings: mtd: stm32: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: rockchip: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: intel: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: denali: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: brcmnand: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: meson: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: sunxi: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: ingenic: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: qcom: Prevent NAND chip unevaluated properties
  dt-bindings: mtd: qcom: Fix a property position
  dt-bindings: mtd: Describe nand-ecc-mode
  dt-bindings: mtd: Mark nand-ecc-placement deprecated
  dt-bindings: mtd: Create a file for raw NAND chip properties
  dt-bindings: mtd: Accept nand related node names
  mtd: sm_ftl: Fix typos in comments
  mtd: otp: clean up on error in mtd_otp_nvmem_add()
  ...
This commit is contained in:
Linus Torvalds 2023-06-28 14:02:03 -07:00
commit 1364b4068a
42 changed files with 805 additions and 299 deletions

View File

@ -49,13 +49,12 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
properties:
reg:
minimum: 0
maximum: 7
nand-ecc-mode: true
nand-ecc-algo:
const: bch
@ -75,7 +74,7 @@ patternProperties:
minimum: 0
maximum: 1
additionalProperties: false
unevaluatedProperties: false
required:
- compatible

View File

@ -40,6 +40,7 @@ properties:
patternProperties:
"^nand@[0-7]$":
type: object
$ref: raw-nand-chip.yaml
properties:
reg:
minimum: 0
@ -58,6 +59,14 @@ patternProperties:
meson-gxl-nfc 8, 16, 24, 30, 40, 50, 60
meson-axg-nfc 8
nand-rb:
maxItems: 1
items:
maximum: 0
unevaluatedProperties: false
required:
- compatible
- reg
@ -87,6 +96,7 @@ examples:
nand@0 {
reg = <0>;
nand-rb = <0>;
};
};

View File

@ -114,6 +114,7 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
properties:
compatible:
const: brcm,nandcs
@ -136,6 +137,8 @@ patternProperties:
layout.
$ref: /schemas/types.yaml#/definitions/uint32
unevaluatedProperties: false
allOf:
- $ref: nand-controller.yaml#
- if:

View File

@ -63,6 +63,12 @@ properties:
minItems: 1
maxItems: 2
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
unevaluatedProperties: false
allOf:
- $ref: nand-controller.yaml
@ -74,7 +80,6 @@ allOf:
then:
patternProperties:
"^nand@[a-f0-9]$":
type: object
properties:
nand-ecc-strength:
enum:
@ -92,7 +97,6 @@ allOf:
then:
patternProperties:
"^nand@[a-f0-9]$":
type: object
properties:
nand-ecc-strength:
enum:
@ -111,7 +115,6 @@ allOf:
then:
patternProperties:
"^nand@[a-f0-9]$":
type: object
properties:
nand-ecc-strength:
enum:

View File

@ -39,7 +39,9 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
properties:
rb-gpios:
description: GPIO specifier for the busy pin.
maxItems: 1
@ -48,6 +50,8 @@ patternProperties:
description: GPIO specifier for the write-protect pin.
maxItems: 1
unevaluatedProperties: false
required:
- compatible
- reg

View File

@ -42,17 +42,16 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
properties:
reg:
minimum: 0
maximum: 1
nand-ecc-mode: true
nand-ecc-algo:
const: hw
additionalProperties: false
unevaluatedProperties: false
required:
- compatible

View File

@ -0,0 +1,226 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mtd/marvell,nand-controller.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Marvell NAND Flash Controller (NFC)
maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
properties:
compatible:
oneOf:
- items:
- const: marvell,armada-8k-nand-controller
- const: marvell,armada370-nand-controller
- enum:
- marvell,armada370-nand-controller
- marvell,pxa3xx-nand-controller
- description: legacy bindings
deprecated: true
enum:
- marvell,armada-8k-nand
- marvell,armada370-nand
- marvell,pxa3xx-nand
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
description:
Shall reference the NAND controller clocks, the second one is
is only needed for the Armada 7K/8K SoCs
minItems: 1
maxItems: 2
clock-names:
minItems: 1
items:
- const: core
- const: reg
dmas:
maxItems: 1
dma-names:
items:
- const: data
marvell,system-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description: Syscon node that handles NAND controller related registers
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
properties:
reg:
minimum: 0
maximum: 3
nand-rb:
items:
- minimum: 0
maximum: 1
nand-ecc-step-size:
const: 512
nand-ecc-strength:
enum: [1, 4, 8, 12, 16]
nand-ecc-mode:
const: hw
marvell,nand-keep-config:
$ref: /schemas/types.yaml#/definitions/flag
description:
Orders the driver not to take the timings from the core and
leaving them completely untouched. Bootloader timings will then
be used.
marvell,nand-enable-arbiter:
$ref: /schemas/types.yaml#/definitions/flag
description:
To enable the arbiter, all boards blindly used it,
this bit was set by the bootloader for many boards and even if
it is marked reserved in several datasheets, it might be needed to set
it (otherwise it is harmless).
deprecated: true
required:
- reg
- nand-rb
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
- clocks
allOf:
- $ref: nand-controller.yaml#
- if:
properties:
compatible:
contains:
const: marvell,pxa3xx-nand-controller
then:
required:
- dmas
- dma-names
- if:
properties:
compatible:
contains:
const: marvell,armada-8k-nand-controller
then:
properties:
clocks:
minItems: 2
clock-names:
minItems: 2
required:
- marvell,system-controller
else:
properties:
clocks:
minItems: 1
clock-names:
minItems: 1
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
nand_controller: nand-controller@d0000 {
compatible = "marvell,armada370-nand-controller";
reg = <0xd0000 0x54>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&coredivclk 0>;
nand@0 {
reg = <0>;
label = "main-storage";
nand-rb = <0>;
nand-ecc-mode = "hw";
marvell,nand-keep-config;
nand-on-flash-bbt;
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "Rootfs";
reg = <0x00000000 0x40000000>;
};
};
};
};
- |
cp0_nand_controller: nand-controller@720000 {
compatible = "marvell,armada-8k-nand-controller",
"marvell,armada370-nand-controller";
reg = <0x720000 0x54>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <115 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "core", "reg";
clocks = <&cp0_clk 1 2>,
<&cp0_clk 1 17>;
marvell,system-controller = <&cp0_syscon0>;
nand@0 {
reg = <0>;
label = "main-storage";
nand-rb = <0>;
nand-ecc-mode = "hw";
nand-ecc-strength = <8>;
nand-ecc-step-size = <512>;
};
};
- |
nand-controller@43100000 {
compatible = "marvell,pxa3xx-nand-controller";
reg = <0x43100000 90>;
interrupts = <45>;
clocks = <&clks 1>;
clock-names = "core";
dmas = <&pdma 97 3>;
dma-names = "data";
#address-cells = <1>;
#size-cells = <0>;
nand@0 {
reg = <0>;
nand-rb = <0>;
nand-ecc-mode = "hw";
marvell,nand-keep-config;
};
};
...

View File

@ -1,126 +0,0 @@
Marvell NAND Flash Controller (NFC)
Required properties:
- compatible: can be one of the following:
* "marvell,armada-8k-nand-controller"
* "marvell,armada370-nand-controller"
* "marvell,pxa3xx-nand-controller"
* "marvell,armada-8k-nand" (deprecated)
* "marvell,armada370-nand" (deprecated)
* "marvell,pxa3xx-nand" (deprecated)
Compatibles marked deprecated support only the old bindings described
at the bottom.
- reg: NAND flash controller memory area.
- #address-cells: shall be set to 1. Encode the NAND CS.
- #size-cells: shall be set to 0.
- interrupts: shall define the NAND controller interrupt.
- clocks: shall reference the NAND controller clocks, the second one is
is only needed for the Armada 7K/8K SoCs
- clock-names: mandatory if there is a second clock, in this case there
should be one clock named "core" and another one named "reg"
- marvell,system-controller: Set to retrieve the syscon node that handles
NAND controller related registers (only required with the
"marvell,armada-8k-nand[-controller]" compatibles).
Optional properties:
- label: see partition.txt. New platforms shall omit this property.
- dmas: shall reference DMA channel associated to the NAND controller.
This property is only used with "marvell,pxa3xx-nand[-controller]"
compatible strings.
- dma-names: shall be "rxtx".
This property is only used with "marvell,pxa3xx-nand[-controller]"
compatible strings.
Optional children nodes:
Children nodes represent the available NAND chips.
Required properties:
- reg: shall contain the native Chip Select ids (0-3).
- nand-rb: see nand-controller.yaml (0-1).
Optional properties:
- marvell,nand-keep-config: orders the driver not to take the timings
from the core and leaving them completely untouched. Bootloader
timings will then be used.
- label: MTD name.
- nand-on-flash-bbt: see nand-controller.yaml.
- nand-ecc-mode: see nand-controller.yaml. Will use hardware ECC if not specified.
- nand-ecc-algo: see nand-controller.yaml. This property is essentially useful when
not using hardware ECC. Howerver, it may be added when using hardware
ECC for clarification but will be ignored by the driver because ECC
mode is chosen depending on the page size and the strength required by
the NAND chip. This value may be overwritten with nand-ecc-strength
property.
- nand-ecc-strength: see nand-controller.yaml.
- nand-ecc-step-size: see nand-controller.yaml. Marvell's NAND flash controller does
use fixed strength (1-bit for Hamming, 16-bit for BCH), so the actual
step size will shrink or grow in order to fit the required strength.
Step sizes are not completely random for all and follow certain
patterns described in AN-379, "Marvell SoC NFC ECC".
See Documentation/devicetree/bindings/mtd/nand-controller.yaml for more details on
generic bindings.
Example:
nand_controller: nand-controller@d0000 {
compatible = "marvell,armada370-nand-controller";
reg = <0xd0000 0x54>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&coredivclk 0>;
nand@0 {
reg = <0>;
label = "main-storage";
nand-rb = <0>;
nand-ecc-mode = "hw";
marvell,nand-keep-config;
nand-on-flash-bbt;
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "Rootfs";
reg = <0x00000000 0x40000000>;
};
};
};
};
Note on legacy bindings: One can find, in not-updated device trees,
bindings slightly different than described above with other properties
described below as well as the partitions node at the root of a so
called "nand" node (without clear controller/chip separation).
Legacy properties:
- marvell,nand-enable-arbiter: To enable the arbiter, all boards blindly
used it, this bit was set by the bootloader for many boards and even if
it is marked reserved in several datasheets, it might be needed to set
it (otherwise it is harmless) so whether or not this property is set,
the bit is selected by the driver.
- num-cs: Number of chip-select lines to use, all boards blindly set 1
to this and for a reason, other values would have failed. The value of
this property is ignored.
Example:
nand0: nand@43100000 {
compatible = "marvell,pxa3xx-nand";
reg = <0x43100000 90>;
interrupts = <45>;
dmas = <&pdma 97 0>;
dma-names = "rxtx";
#address-cells = <1>;
marvell,nand-keep-config;
marvell,nand-enable-arbiter;
num-cs = <1>;
/* Partitions (optional) */
};

View File

@ -40,12 +40,11 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
$ref: nand-chip.yaml#
$ref: raw-nand-chip.yaml#
unevaluatedProperties: false
properties:
reg:
maximum: 1
nand-on-flash-bbt: true
nand-ecc-mode:
const: hw

View File

@ -12,7 +12,7 @@ maintainers:
properties:
$nodename:
pattern: "^(flash|.*sram)(@.*)?$"
pattern: "^(flash|.*sram|nand)(@.*)?$"
label:
description:

View File

@ -16,16 +16,6 @@ description: |
children nodes of the NAND controller. This representation should be
enforced even for simple controllers supporting only one chip.
The ECC strength and ECC step size properties define the user
desires in terms of correction capability of a controller. Together,
they request the ECC engine to correct {strength} bit errors per
{size} bytes.
The interpretation of these parameters is implementation-defined, so
not all implementations must support all possible
combinations. However, implementations are encouraged to further
specify the value(s) they support.
properties:
$nodename:
pattern: "^nand-controller(@.*)?"
@ -51,79 +41,8 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
$ref: nand-chip.yaml#
properties:
reg:
description:
Contains the chip-select IDs.
nand-ecc-placement:
description:
Location of the ECC bytes. This location is unknown by default
but can be explicitly set to "oob", if all ECC bytes are
known to be stored in the OOB area, or "interleaved" if ECC
bytes will be interleaved with regular data in the main area.
$ref: /schemas/types.yaml#/definitions/string
enum: [ oob, interleaved ]
nand-bus-width:
description:
Bus width to the NAND chip
$ref: /schemas/types.yaml#/definitions/uint32
enum: [8, 16]
default: 8
nand-on-flash-bbt:
description:
With this property, the OS will search the device for a Bad
Block Table (BBT). If not found, it will create one, reserve
a few blocks at the end of the device to store it and update
it as the device ages. Otherwise, the out-of-band area of a
few pages of all the blocks will be scanned at boot time to
find Bad Block Markers (BBM). These markers will help to
build a volatile BBT in RAM.
$ref: /schemas/types.yaml#/definitions/flag
nand-ecc-maximize:
description:
Whether or not the ECC strength should be maximized. The
maximum ECC strength is both controller and chip
dependent. The ECC engine has to select the ECC config
providing the best strength and taking the OOB area size
constraint into account. This is particularly useful when
only the in-band area is used by the upper layers, and you
want to make your NAND as reliable as possible.
$ref: /schemas/types.yaml#/definitions/flag
nand-is-boot-medium:
description:
Whether or not the NAND chip is a boot medium. Drivers might
use this information to select ECC algorithms supported by
the boot ROM or similar restrictions.
$ref: /schemas/types.yaml#/definitions/flag
nand-rb:
description:
Contains the native Ready/Busy IDs.
$ref: /schemas/types.yaml#/definitions/uint32-array
rb-gpios:
description:
Contains one or more GPIO descriptor (the numper of descriptor
depends on the number of R/B pins exposed by the flash) for the
Ready/Busy pins. Active state refers to the NAND ready state and
should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted.
wp-gpios:
description:
Contains one GPIO descriptor for the Write Protect pin.
Active state refers to the NAND Write Protect state and should be
set to GPIOD_ACTIVE_LOW unless the signal is inverted.
maxItems: 1
required:
- reg
type: object
$ref: raw-nand-chip.yaml#
required:
- "#address-cells"

View File

@ -55,6 +55,7 @@ properties:
linux,rootfs:
description: Marks partition that contains root filesystem to mount and boot
user space from
type: boolean
if:
not:

View File

@ -21,6 +21,7 @@ oneOf:
- $ref: linksys,ns-partitions.yaml
- $ref: qcom,smem-part.yaml
- $ref: redboot-fis.yaml
- $ref: tplink,safeloader-partitions.yaml
properties:
compatible: true

View File

@ -34,7 +34,9 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
properties:
nand-bus-width:
const: 8
@ -45,6 +47,24 @@ patternProperties:
enum:
- 512
qcom,boot-partitions:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
items:
- description: offset
- description: size
description:
Boot partition use a different layout where the 4 bytes of spare
data are not protected by ECC. Use this to declare these special
partitions by defining first the offset and then the size.
It's in the form of <offset1 size1 offset2 size2 offset3 ...>
and should be declared in ascending order.
Refer to the ipq8064 example on how to use this special binding.
unevaluatedProperties: false
allOf:
- $ref: nand-controller.yaml#
@ -107,22 +127,15 @@ allOf:
- qcom,ipq806x-nand
then:
properties:
qcom,boot-partitions:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
items:
- description: offset
- description: size
description:
Boot partition use a different layout where the 4 bytes of spare
data are not protected by ECC. Use this to declare these special
partitions by defining first the offset and then the size.
It's in the form of <offset1 size1 offset2 size2 offset3 ...>
and should be declared in ascending order.
Refer to the ipq8064 example on how to use this special binding.
patternProperties:
"^nand@[a-f0-9]$":
properties:
qcom,boot-partitions: true
else:
patternProperties:
"^nand@[a-f0-9]$":
properties:
qcom,boot-partitions: false
required:
- compatible

View File

@ -0,0 +1,111 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mtd/raw-nand-chip.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Raw NAND Chip Common Properties
maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
allOf:
- $ref: nand-chip.yaml#
description: |
The ECC strength and ECC step size properties define the user
desires in terms of correction capability of a controller. Together,
they request the ECC engine to correct {strength} bit errors per
{size} bytes for a particular raw NAND chip.
The interpretation of these parameters is implementation-defined, so
not all implementations must support all possible
combinations. However, implementations are encouraged to further
specify the value(s) they support.
properties:
$nodename:
pattern: "^nand@[a-f0-9]$"
reg:
description:
Contains the chip-select IDs.
nand-ecc-placement:
description:
Location of the ECC bytes. This location is unknown by default
but can be explicitly set to "oob", if all ECC bytes are
known to be stored in the OOB area, or "interleaved" if ECC
bytes will be interleaved with regular data in the main area.
$ref: /schemas/types.yaml#/definitions/string
enum: [ oob, interleaved ]
deprecated: true
nand-ecc-mode:
description:
Legacy ECC configuration mixing the ECC engine choice and
configuration.
$ref: /schemas/types.yaml#/definitions/string
enum: [none, soft, soft_bch, hw, hw_syndrome, on-die]
deprecated: true
nand-bus-width:
description:
Bus width to the NAND chip
$ref: /schemas/types.yaml#/definitions/uint32
enum: [8, 16]
default: 8
nand-on-flash-bbt:
description:
With this property, the OS will search the device for a Bad
Block Table (BBT). If not found, it will create one, reserve
a few blocks at the end of the device to store it and update
it as the device ages. Otherwise, the out-of-band area of a
few pages of all the blocks will be scanned at boot time to
find Bad Block Markers (BBM). These markers will help to
build a volatile BBT in RAM.
$ref: /schemas/types.yaml#/definitions/flag
nand-ecc-maximize:
description:
Whether or not the ECC strength should be maximized. The
maximum ECC strength is both controller and chip
dependent. The ECC engine has to select the ECC config
providing the best strength and taking the OOB area size
constraint into account. This is particularly useful when
only the in-band area is used by the upper layers, and you
want to make your NAND as reliable as possible.
$ref: /schemas/types.yaml#/definitions/flag
nand-is-boot-medium:
description:
Whether or not the NAND chip is a boot medium. Drivers might
use this information to select ECC algorithms supported by
the boot ROM or similar restrictions.
$ref: /schemas/types.yaml#/definitions/flag
nand-rb:
description:
Contains the native Ready/Busy IDs.
$ref: /schemas/types.yaml#/definitions/uint32-array
rb-gpios:
description:
Contains one or more GPIO descriptor (the numper of descriptor
depends on the number of R/B pins exposed by the flash) for the
Ready/Busy pins. Active state refers to the NAND ready state and
should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted.
wp-gpios:
description:
Contains one GPIO descriptor for the Write Protect pin.
Active state refers to the NAND Write Protect state and should be
set to GPIOD_ACTIVE_LOW unless the signal is inverted.
maxItems: 1
required:
- reg
# This is a generic file other binding inherit from and extend
additionalProperties: true

View File

@ -57,6 +57,7 @@ properties:
patternProperties:
"^nand@[0-7]$":
type: object
$ref: raw-nand-chip.yaml
properties:
reg:
minimum: 0
@ -116,6 +117,8 @@ patternProperties:
Only used in combination with 'nand-is-boot-medium'.
unevaluatedProperties: false
required:
- compatible
- reg

View File

@ -37,6 +37,7 @@ properties:
patternProperties:
"^nand@[a-f0-9]$":
type: object
$ref: raw-nand-chip.yaml
properties:
nand-ecc-step-size:
const: 512
@ -44,6 +45,8 @@ patternProperties:
nand-ecc-strength:
enum: [1, 4, 8]
unevaluatedProperties: false
allOf:
- $ref: nand-controller.yaml#

View File

@ -30,6 +30,8 @@ properties:
patternProperties:
"^flash@[0-1],[0-9a-f]+$":
type: object
$ref: mtd-physmap.yaml
unevaluatedProperties: false
required:
- compatible

View File

@ -12586,7 +12586,6 @@ MARVELL NAND CONTROLLER DRIVER
M: Miquel Raynal <miquel.raynal@bootlin.com>
L: linux-mtd@lists.infradead.org
S: Maintained
F: Documentation/devicetree/bindings/mtd/marvell-nand.txt
F: drivers/mtd/nand/raw/marvell_nand.c
MARVELL OCTEON ENDPOINT DRIVER

View File

@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common Flash Interface support:
* Intel Extended Vendor Command Set (ID 0x0001)
*
* (C) 2000 Red Hat. GPL'd
* (C) 2000 Red Hat.
*
*
* 10/10/2000 Nicolas Pitre <nico@fluxnic.net>

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common Flash Interface support:
* AMD & Fujitsu Standard Vendor Command Set (ID 0x0002)
@ -16,8 +17,6 @@
* 25/09/2008 Christopher Moore: TopBottom fixup for many Macronix with CFI V1.0
*
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
*
* This code is GPL
*/
#include <linux/module.h>

View File

@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common Flash Interface support:
* ST Advanced Architecture Command Set (ID 0x0020)
*
* (C) 2000 Red Hat. GPL'd
* (C) 2000 Red Hat.
*
* 10/10/2000 Nicolas Pitre <nico@fluxnic.net>
* - completely revamped method functions so they are aware and

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd.
(C) 2000 Red Hat.
*/
#include <linux/module.h>

View File

@ -1,11 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common Flash Interface support:
* Generic utility functions not dependent on command set
*
* Copyright (C) 2002 Red Hat
* Copyright (C) 2003 STMicroelectronics Limited
*
* This code is covered by the GPL.
*/
#include <linux/module.h>

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Routines common to all CFI-type probes.
* (C) 2001-2003 Red Hat, Inc.
* GPL'd
*/
#include <linux/kernel.h>

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd.
(C) 2000 Red Hat.
See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
for the standard this probe goes back to.

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common code to handle map devices which are simple RAM
* (C) 2000 Red Hat. GPL'd.
* (C) 2000 Red Hat.
*/
#include <linux/module.h>

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common code to handle map devices which are simple ROM
* (C) 2000 Red Hat. GPL'd.
* (C) 2000 Red Hat.
*/
#include <linux/module.h>

View File

@ -2046,34 +2046,26 @@ static int stfsm_probe(struct platform_device *pdev)
return PTR_ERR(fsm->base);
}
fsm->clk = devm_clk_get(&pdev->dev, NULL);
fsm->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(fsm->clk)) {
dev_err(fsm->dev, "Couldn't find EMI clock.\n");
return PTR_ERR(fsm->clk);
}
ret = clk_prepare_enable(fsm->clk);
if (ret) {
dev_err(fsm->dev, "Failed to enable EMI clock.\n");
return ret;
}
mutex_init(&fsm->lock);
ret = stfsm_init(fsm);
if (ret) {
dev_err(&pdev->dev, "Failed to initialise FSM Controller\n");
goto err_clk_unprepare;
return ret;
}
stfsm_fetch_platform_configs(pdev);
/* Detect SPI FLASH device */
info = stfsm_jedec_probe(fsm);
if (!info) {
ret = -ENODEV;
goto err_clk_unprepare;
}
if (!info)
return -ENODEV;
fsm->info = info;
/* Use device size to determine address width */
@ -2089,7 +2081,7 @@ static int stfsm_probe(struct platform_device *pdev)
else
ret = stfsm_prepare_rwe_seqs_default(fsm);
if (ret)
goto err_clk_unprepare;
return ret;
fsm->mtd.name = info->name;
fsm->mtd.dev.parent = &pdev->dev;
@ -2112,13 +2104,7 @@ static int stfsm_probe(struct platform_device *pdev)
(long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20),
fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
ret = mtd_device_register(&fsm->mtd, NULL, 0);
if (ret) {
err_clk_unprepare:
clk_disable_unprepare(fsm->clk);
}
return ret;
return mtd_device_register(&fsm->mtd, NULL, 0);
}
static int stfsm_remove(struct platform_device *pdev)
@ -2127,8 +2113,6 @@ static int stfsm_remove(struct platform_device *pdev)
WARN_ON(mtd_device_unregister(&fsm->mtd));
clk_disable_unprepare(fsm->clk);
return 0;
}

View File

@ -259,7 +259,7 @@ static struct i2c_driver pismo_driver = {
.driver = {
.name = "pismo",
},
.probe_new = pismo_probe,
.probe = pismo_probe,
.remove = pismo_remove,
.id_table = pismo_id,
};

View File

@ -23,6 +23,7 @@
#include <linux/idr.h>
#include <linux/backing-dev.h>
#include <linux/gfp.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/reboot.h>
#include <linux/leds.h>
@ -966,6 +967,26 @@ static int mtd_otp_nvmem_add(struct mtd_info *mtd)
}
if (size > 0) {
/*
* The factory OTP contains thing such as a unique serial
* number and is small, so let's read it out and put it
* into the entropy pool.
*/
void *otp;
otp = kmalloc(size, GFP_KERNEL);
if (!otp) {
err = -ENOMEM;
goto err;
}
err = mtd_nvmem_fact_otp_reg_read(mtd, 0, otp, size);
if (err < 0) {
kfree(otp);
goto err;
}
add_device_randomness(otp, err);
kfree(otp);
nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size,
mtd_nvmem_fact_otp_reg_read);
if (IS_ERR(nvmem)) {

View File

@ -326,7 +326,6 @@ static int __mtd_del_partition(struct mtd_info *mtd)
static int __del_mtd_partitions(struct mtd_info *mtd)
{
struct mtd_info *child, *next;
LIST_HEAD(tmp_list);
int ret, err = 0;
list_for_each_entry_safe(child, next, &mtd->partitions, part.node) {

View File

@ -67,5 +67,6 @@ nand-objs += nand_esmt.o
nand-objs += nand_hynix.o
nand-objs += nand_macronix.o
nand-objs += nand_micron.o
nand-objs += nand_sandisk.o
nand-objs += nand_samsung.o
nand-objs += nand_toshiba.o

View File

@ -973,21 +973,6 @@ static int anfc_setup_interface(struct nand_chip *chip, int target,
nvddr = nand_get_nvddr_timings(conf);
if (IS_ERR(nvddr))
return PTR_ERR(nvddr);
/*
* The controller only supports data payload requests which are
* a multiple of 4. In practice, most data accesses are 4-byte
* aligned and this is not an issue. However, rounding up will
* simply be refused by the controller if we reached the end of
* the device *and* we are using the NV-DDR interface(!). In
* this situation, unaligned data requests ending at the device
* boundary will confuse the controller and cannot be performed.
*
* This is something that happens in nand_read_subpage() when
* selecting software ECC support and must be avoided.
*/
if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT)
return -ENOTSUPP;
} else {
sdr = nand_get_sdr_timings(conf);
if (IS_ERR(sdr))

View File

@ -73,6 +73,7 @@ extern const struct nand_manufacturer_ops hynix_nand_manuf_ops;
extern const struct nand_manufacturer_ops macronix_nand_manuf_ops;
extern const struct nand_manufacturer_ops micron_nand_manuf_ops;
extern const struct nand_manufacturer_ops samsung_nand_manuf_ops;
extern const struct nand_manufacturer_ops sandisk_nand_manuf_ops;
extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops;
/* MLC pairing schemes */

View File

@ -38,6 +38,7 @@
#define NFC_CMD_SCRAMBLER_DISABLE 0
#define NFC_CMD_SHORTMODE_DISABLE 0
#define NFC_CMD_RB_INT BIT(14)
#define NFC_CMD_RB_INT_NO_PIN ((0xb << 10) | BIT(18) | BIT(16))
#define NFC_CMD_GET_SIZE(x) (((x) >> 22) & GENMASK(4, 0))
@ -76,6 +77,7 @@
#define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff))
#define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N)
#define DMA_ADDR_ALIGN 8
#define ECC_CHECK_RETURN_FF (-1)
@ -108,6 +110,11 @@
#define PER_INFO_BYTE 8
#define NFC_CMD_RAW_LEN GENMASK(13, 0)
#define NFC_COLUMN_ADDR_0 0
#define NFC_COLUMN_ADDR_1 0
struct meson_nfc_nand_chip {
struct list_head node;
struct nand_chip nand;
@ -179,6 +186,7 @@ struct meson_nfc {
u32 info_bytes;
unsigned long assigned_cs;
bool no_rb_pin;
};
enum {
@ -280,7 +288,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
if (raw) {
len = mtd->writesize + mtd->oobsize;
cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir);
cmd = len | scrambler | DMA_DIR(dir);
writel(cmd, nfc->reg_base + NFC_REG_CMD);
return;
}
@ -392,7 +400,42 @@ static void meson_nfc_set_data_oob(struct nand_chip *nand,
}
}
static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
static int meson_nfc_wait_no_rb_pin(struct meson_nfc *nfc, int timeout_ms,
bool need_cmd_read0)
{
u32 cmd, cfg;
meson_nfc_cmd_idle(nfc, nfc->timing.twb);
meson_nfc_drain_cmd(nfc);
meson_nfc_wait_cmd_finish(nfc, CMD_FIFO_EMPTY_TIMEOUT);
cfg = readl(nfc->reg_base + NFC_REG_CFG);
cfg |= NFC_RB_IRQ_EN;
writel(cfg, nfc->reg_base + NFC_REG_CFG);
reinit_completion(&nfc->completion);
cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_STATUS;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
/* use the max erase time as the maximum clock for waiting R/B */
cmd = NFC_CMD_RB | NFC_CMD_RB_INT_NO_PIN | nfc->timing.tbers_max;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
if (!wait_for_completion_timeout(&nfc->completion,
msecs_to_jiffies(timeout_ms)))
return -ETIMEDOUT;
if (need_cmd_read0) {
cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_READ0;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
meson_nfc_drain_cmd(nfc);
meson_nfc_wait_cmd_finish(nfc, CMD_FIFO_EMPTY_TIMEOUT);
}
return 0;
}
static int meson_nfc_wait_rb_pin(struct meson_nfc *nfc, int timeout_ms)
{
u32 cmd, cfg;
int ret = 0;
@ -420,6 +463,27 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
return ret;
}
static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms,
bool need_cmd_read0)
{
if (nfc->no_rb_pin) {
/* This mode is used when there is no wired R/B pin.
* It works like 'nand_soft_waitrdy()', but instead of
* polling NAND_CMD_STATUS bit in the software loop,
* it will wait for interrupt - controllers checks IO
* bus and when it detects NAND_CMD_STATUS on it, it
* raises interrupt. After interrupt, NAND_CMD_READ0 is
* sent as terminator of the ready waiting procedure if
* needed (for all cases except page programming - this
* is reason of 'need_cmd_read0' flag).
*/
return meson_nfc_wait_no_rb_pin(nfc, timeout_ms,
need_cmd_read0);
} else {
return meson_nfc_wait_rb_pin(nfc, timeout_ms);
}
}
static void meson_nfc_set_user_byte(struct nand_chip *nand, u8 *oob_buf)
{
struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
@ -544,7 +608,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
if (ret)
goto out;
cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
cmd = NFC_CMD_N2M | len;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
meson_nfc_drain_cmd(nfc);
@ -568,7 +632,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
if (ret)
return ret;
cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
cmd = NFC_CMD_M2N | len;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
meson_nfc_drain_cmd(nfc);
@ -595,12 +659,12 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand,
cmd0 = in ? NAND_CMD_READ0 : NAND_CMD_SEQIN;
nfc->cmdfifo.rw.cmd0 = cs | NFC_CMD_CLE | cmd0;
addrs[0] = cs | NFC_CMD_ALE | 0;
addrs[0] = cs | NFC_CMD_ALE | NFC_COLUMN_ADDR_0;
if (mtd->writesize <= 512) {
cmd_num--;
row_start = 1;
} else {
addrs[1] = cs | NFC_CMD_ALE | 0;
addrs[1] = cs | NFC_CMD_ALE | NFC_COLUMN_ADDR_1;
row_start = 2;
}
@ -623,7 +687,7 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand,
if (in) {
nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART;
writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD);
meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tR_max));
meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tR_max), true);
} else {
meson_nfc_cmd_idle(nfc, nfc->timing.tadl);
}
@ -669,7 +733,7 @@ static int meson_nfc_write_page_sub(struct nand_chip *nand,
cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tPROG_max));
meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tPROG_max), false);
meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE);
@ -842,6 +906,9 @@ static int meson_nfc_read_oob(struct nand_chip *nand, int page)
static bool meson_nfc_is_buffer_dma_safe(const void *buffer)
{
if ((uintptr_t)buffer % DMA_ADDR_ALIGN)
return false;
if (virt_addr_valid(buffer) && (!object_is_on_stack(buffer)))
return true;
return false;
@ -899,6 +966,31 @@ meson_nand_op_put_dma_safe_output_buf(const struct nand_op_instr *instr,
kfree(buf);
}
static int meson_nfc_check_op(struct nand_chip *chip,
const struct nand_operation *op)
{
int op_id;
for (op_id = 0; op_id < op->ninstrs; op_id++) {
const struct nand_op_instr *instr;
instr = &op->instrs[op_id];
switch (instr->type) {
case NAND_OP_DATA_IN_INSTR:
case NAND_OP_DATA_OUT_INSTR:
if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
return -ENOTSUPP;
break;
default:
break;
}
}
return 0;
}
static int meson_nfc_exec_op(struct nand_chip *nand,
const struct nand_operation *op, bool check_only)
{
@ -907,8 +999,13 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
const struct nand_op_instr *instr = NULL;
void *buf;
u32 op_id, delay_idle, cmd;
int err;
int i;
err = meson_nfc_check_op(nand, op);
if (err)
return err;
if (check_only)
return 0;
@ -952,7 +1049,8 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
break;
case NAND_OP_WAITRDY_INSTR:
meson_nfc_queue_rb(nfc, instr->ctx.waitrdy.timeout_ms);
meson_nfc_queue_rb(nfc, instr->ctx.waitrdy.timeout_ms,
true);
if (instr->delay_ns)
meson_nfc_cmd_idle(nfc, delay_idle);
break;
@ -1181,6 +1279,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
struct mtd_info *mtd = nand_to_mtd(nand);
int nsectors = mtd->writesize / 1024;
int raw_writesize;
int ret;
if (!mtd->name) {
@ -1192,6 +1291,13 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
return -ENOMEM;
}
raw_writesize = mtd->writesize + mtd->oobsize;
if (raw_writesize > NFC_CMD_RAW_LEN) {
dev_err(nfc->dev, "too big write size in raw mode: %d > %ld\n",
raw_writesize, NFC_CMD_RAW_LEN);
return -EINVAL;
}
if (nand->bbt_options & NAND_BBT_USE_FLASH)
nand->bbt_options |= NAND_BBT_NO_OOB;
@ -1248,6 +1354,7 @@ meson_nfc_nand_chip_init(struct device *dev,
struct mtd_info *mtd;
int ret, i;
u32 tmp, nsels;
u32 nand_rb_val = 0;
nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32));
if (!nsels || nsels > MAX_CE_NUM) {
@ -1287,6 +1394,15 @@ meson_nfc_nand_chip_init(struct device *dev,
mtd->owner = THIS_MODULE;
mtd->dev.parent = dev;
ret = of_property_read_u32(np, "nand-rb", &nand_rb_val);
if (ret == -EINVAL)
nfc->no_rb_pin = true;
else if (ret)
return ret;
if (nand_rb_val)
return -EINVAL;
ret = nand_scan(nand, nsels);
if (ret)
return ret;

View File

@ -44,6 +44,9 @@ struct nand_flash_dev nand_flash_ids[] = {
{"TC58NVG6D2 64G 3.3V 8-bit",
{ .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} },
SZ_8K, SZ_8K, SZ_2M, 0, 8, 640, NAND_ECC_INFO(40, SZ_1K) },
{"SDTNQGAMA 64G 3.3V 8-bit",
{ .id = {0x45, 0xde, 0x94, 0x93, 0x76, 0x57} },
SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) },
{"SDTNRGAMA 64G 3.3V 8-bit",
{ .id = {0x45, 0xde, 0x94, 0x93, 0x76, 0x50} },
SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) },
@ -188,7 +191,7 @@ static const struct nand_manufacturer_desc nand_manufacturer_descs[] = {
{NAND_MFR_NATIONAL, "National"},
{NAND_MFR_RENESAS, "Renesas"},
{NAND_MFR_SAMSUNG, "Samsung", &samsung_nand_manuf_ops},
{NAND_MFR_SANDISK, "SanDisk"},
{NAND_MFR_SANDISK, "SanDisk", &sandisk_nand_manuf_ops},
{NAND_MFR_STMICRO, "ST Micro"},
{NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops},
{NAND_MFR_WINBOND, "Winbond"},

View File

@ -6,6 +6,7 @@
* Author: Boris Brezillon <boris.brezillon@free-electrons.com>
*/
#include <linux/slab.h>
#include "linux/delay.h"
#include "internals.h"
@ -31,6 +32,16 @@
#define MXIC_CMD_POWER_DOWN 0xB9
#define ONFI_FEATURE_ADDR_30LFXG18AC_OTP 0x90
#define MACRONIX_30LFXG18AC_OTP_START_PAGE 2
#define MACRONIX_30LFXG18AC_OTP_PAGES 30
#define MACRONIX_30LFXG18AC_OTP_PAGE_SIZE 2112
#define MACRONIX_30LFXG18AC_OTP_SIZE_BYTES \
(MACRONIX_30LFXG18AC_OTP_PAGES * \
MACRONIX_30LFXG18AC_OTP_PAGE_SIZE)
#define MACRONIX_30LFXG18AC_OTP_EN BIT(0)
struct nand_onfi_vendor_macronix {
u8 reserved;
u8 reliability_func;
@ -315,6 +326,161 @@ static void macronix_nand_deep_power_down_support(struct nand_chip *chip)
chip->ops.resume = mxic_nand_resume;
}
static int macronix_30lfxg18ac_get_otp_info(struct mtd_info *mtd, size_t len,
size_t *retlen,
struct otp_info *buf)
{
if (len < sizeof(*buf))
return -EINVAL;
/* Always report that OTP is unlocked. Reason is that this
* type of flash chip doesn't provide way to check that OTP
* is locked or not: subfeature parameter is implemented as
* volatile register. Technically OTP region could be locked
* and become readonly, but as there is no way to check it,
* don't allow to lock it ('_lock_user_prot_reg' callback
* always returns -EOPNOTSUPP) and thus we report that OTP
* is unlocked.
*/
buf->locked = 0;
buf->start = 0;
buf->length = MACRONIX_30LFXG18AC_OTP_SIZE_BYTES;
*retlen = sizeof(*buf);
return 0;
}
static int macronix_30lfxg18ac_otp_enable(struct nand_chip *nand)
{
u8 feature_buf[ONFI_SUBFEATURE_PARAM_LEN] = { 0 };
feature_buf[0] = MACRONIX_30LFXG18AC_OTP_EN;
return nand_set_features(nand, ONFI_FEATURE_ADDR_30LFXG18AC_OTP,
feature_buf);
}
static int macronix_30lfxg18ac_otp_disable(struct nand_chip *nand)
{
u8 feature_buf[ONFI_SUBFEATURE_PARAM_LEN] = { 0 };
return nand_set_features(nand, ONFI_FEATURE_ADDR_30LFXG18AC_OTP,
feature_buf);
}
static int __macronix_30lfxg18ac_rw_otp(struct mtd_info *mtd,
loff_t offs_in_flash,
size_t len, size_t *retlen,
u_char *buf, bool write)
{
struct nand_chip *nand;
size_t bytes_handled;
off_t offs_in_page;
u64 page;
int ret;
nand = mtd_to_nand(mtd);
nand_select_target(nand, 0);
ret = macronix_30lfxg18ac_otp_enable(nand);
if (ret)
goto out_otp;
page = offs_in_flash;
/* 'page' will be result of division. */
offs_in_page = do_div(page, MACRONIX_30LFXG18AC_OTP_PAGE_SIZE);
bytes_handled = 0;
while (bytes_handled < len &&
page < MACRONIX_30LFXG18AC_OTP_PAGES) {
size_t bytes_to_handle;
u64 phys_page = page + MACRONIX_30LFXG18AC_OTP_START_PAGE;
bytes_to_handle = min_t(size_t, len - bytes_handled,
MACRONIX_30LFXG18AC_OTP_PAGE_SIZE -
offs_in_page);
if (write)
ret = nand_prog_page_op(nand, phys_page, offs_in_page,
&buf[bytes_handled], bytes_to_handle);
else
ret = nand_read_page_op(nand, phys_page, offs_in_page,
&buf[bytes_handled], bytes_to_handle);
if (ret)
goto out_otp;
bytes_handled += bytes_to_handle;
offs_in_page = 0;
page++;
}
*retlen = bytes_handled;
out_otp:
if (ret)
dev_err(&mtd->dev, "failed to perform OTP IO: %i\n", ret);
ret = macronix_30lfxg18ac_otp_disable(nand);
if (ret)
dev_err(&mtd->dev, "failed to leave OTP mode after %s\n",
write ? "write" : "read");
nand_deselect_target(nand);
return ret;
}
static int macronix_30lfxg18ac_write_otp(struct mtd_info *mtd, loff_t to,
size_t len, size_t *rlen,
const u_char *buf)
{
return __macronix_30lfxg18ac_rw_otp(mtd, to, len, rlen, (u_char *)buf,
true);
}
static int macronix_30lfxg18ac_read_otp(struct mtd_info *mtd, loff_t from,
size_t len, size_t *rlen,
u_char *buf)
{
return __macronix_30lfxg18ac_rw_otp(mtd, from, len, rlen, buf, false);
}
static int macronix_30lfxg18ac_lock_otp(struct mtd_info *mtd, loff_t from,
size_t len)
{
/* See comment in 'macronix_30lfxg18ac_get_otp_info()'. */
return -EOPNOTSUPP;
}
static void macronix_nand_setup_otp(struct nand_chip *chip)
{
static const char * const supported_otp_models[] = {
"MX30LF1G18AC",
"MX30LF2G18AC",
"MX30LF4G18AC",
};
struct mtd_info *mtd;
if (match_string(supported_otp_models,
ARRAY_SIZE(supported_otp_models),
chip->parameters.model) < 0)
return;
if (!chip->parameters.supports_set_get_features)
return;
bitmap_set(chip->parameters.get_feature_list,
ONFI_FEATURE_ADDR_30LFXG18AC_OTP, 1);
bitmap_set(chip->parameters.set_feature_list,
ONFI_FEATURE_ADDR_30LFXG18AC_OTP, 1);
mtd = nand_to_mtd(chip);
mtd->_get_user_prot_info = macronix_30lfxg18ac_get_otp_info;
mtd->_read_user_prot_reg = macronix_30lfxg18ac_read_otp;
mtd->_write_user_prot_reg = macronix_30lfxg18ac_write_otp;
mtd->_lock_user_prot_reg = macronix_30lfxg18ac_lock_otp;
}
static int macronix_nand_init(struct nand_chip *chip)
{
if (nand_is_slc(chip))
@ -324,6 +490,7 @@ static int macronix_nand_init(struct nand_chip *chip)
macronix_nand_onfi_init(chip);
macronix_nand_block_protection_support(chip);
macronix_nand_deep_power_down_support(chip);
macronix_nand_setup_otp(chip);
return 0;
}

View File

@ -0,0 +1,26 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "internals.h"
static int
sdtnqgama_choose_interface_config(struct nand_chip *chip,
struct nand_interface_config *iface)
{
onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 0);
return nand_choose_best_sdr_timings(chip, iface, NULL);
}
static int sandisk_nand_init(struct nand_chip *chip)
{
if (!strncmp("SDTNQGAMA", chip->parameters.model,
sizeof("SDTNQGAMA") - 1))
chip->ops.choose_interface_config =
&sdtnqgama_choose_interface_config;
return 0;
}
const struct nand_manufacturer_ops sandisk_nand_manuf_ops = {
.init = sandisk_nand_init,
};

View File

@ -501,6 +501,16 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
gd5fxgq4uexxg_ecc_get_status)),
SPINAND_INFO("GD5F2GQ5xExxH",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
gd5fxgq4uexxg_ecc_get_status)),
};
static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {

View File

@ -299,6 +299,26 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
SPINAND_INFO("MX31LF2GE4BC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x2e),
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
SPINAND_INFO("MX3UF2GE4BC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae),
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
};
static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {

View File

@ -981,7 +981,7 @@ restart:
/* Update the FTL table */
zone->lba_to_phys_table[ftl->cache_block] = write_sector;
/* Write succesfull, so erase and free the old block */
/* Write successful, so erase and free the old block */
if (block_num > 0)
sm_erase_block(ftl, zone_num, block_num, 1);