mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
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:
commit
1364b4068a
@ -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
|
||||
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -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) */
|
||||
};
|
@ -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
|
||||
|
||||
|
@ -12,7 +12,7 @@ maintainers:
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^(flash|.*sram)(@.*)?$"
|
||||
pattern: "^(flash|.*sram|nand)(@.*)?$"
|
||||
|
||||
label:
|
||||
description:
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
111
Documentation/devicetree/bindings/mtd/raw-nand-chip.yaml
Normal file
111
Documentation/devicetree/bindings/mtd/raw-nand-chip.yaml
Normal 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
|
@ -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
|
||||
|
@ -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#
|
||||
|
||||
|
@ -30,6 +30,8 @@ properties:
|
||||
patternProperties:
|
||||
"^flash@[0-1],[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: mtd-physmap.yaml
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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)) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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"},
|
||||
|
@ -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;
|
||||
}
|
||||
|
26
drivers/mtd/nand/raw/nand_sandisk.c
Normal file
26
drivers/mtd/nand/raw/nand_sandisk.c
Normal 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,
|
||||
};
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -981,7 +981,7 @@ static int sm_cache_flush(struct sm_ftl *ftl)
|
||||
/* 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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user