mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
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:
@@ -49,13 +49,12 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
reg:
|
reg:
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 7
|
maximum: 7
|
||||||
|
|
||||||
nand-ecc-mode: true
|
|
||||||
|
|
||||||
nand-ecc-algo:
|
nand-ecc-algo:
|
||||||
const: bch
|
const: bch
|
||||||
|
|
||||||
@@ -75,7 +74,7 @@ patternProperties:
|
|||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 1
|
maximum: 1
|
||||||
|
|
||||||
additionalProperties: false
|
unevaluatedProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
|
@@ -40,6 +40,7 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[0-7]$":
|
"^nand@[0-7]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
reg:
|
reg:
|
||||||
minimum: 0
|
minimum: 0
|
||||||
@@ -58,6 +59,14 @@ patternProperties:
|
|||||||
meson-gxl-nfc 8, 16, 24, 30, 40, 50, 60
|
meson-gxl-nfc 8, 16, 24, 30, 40, 50, 60
|
||||||
meson-axg-nfc 8
|
meson-axg-nfc 8
|
||||||
|
|
||||||
|
nand-rb:
|
||||||
|
maxItems: 1
|
||||||
|
items:
|
||||||
|
maximum: 0
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
@@ -87,6 +96,7 @@ examples:
|
|||||||
|
|
||||||
nand@0 {
|
nand@0 {
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
|
nand-rb = <0>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -114,6 +114,7 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
const: brcm,nandcs
|
const: brcm,nandcs
|
||||||
@@ -136,6 +137,8 @@ patternProperties:
|
|||||||
layout.
|
layout.
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: nand-controller.yaml#
|
- $ref: nand-controller.yaml#
|
||||||
- if:
|
- if:
|
||||||
|
@@ -63,6 +63,12 @@ properties:
|
|||||||
minItems: 1
|
minItems: 1
|
||||||
maxItems: 2
|
maxItems: 2
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^nand@[a-f0-9]$":
|
||||||
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: nand-controller.yaml
|
- $ref: nand-controller.yaml
|
||||||
|
|
||||||
@@ -74,7 +80,6 @@ allOf:
|
|||||||
then:
|
then:
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
|
||||||
properties:
|
properties:
|
||||||
nand-ecc-strength:
|
nand-ecc-strength:
|
||||||
enum:
|
enum:
|
||||||
@@ -92,7 +97,6 @@ allOf:
|
|||||||
then:
|
then:
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
|
||||||
properties:
|
properties:
|
||||||
nand-ecc-strength:
|
nand-ecc-strength:
|
||||||
enum:
|
enum:
|
||||||
@@ -111,7 +115,6 @@ allOf:
|
|||||||
then:
|
then:
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
|
||||||
properties:
|
properties:
|
||||||
nand-ecc-strength:
|
nand-ecc-strength:
|
||||||
enum:
|
enum:
|
||||||
|
@@ -39,7 +39,9 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
|
|
||||||
rb-gpios:
|
rb-gpios:
|
||||||
description: GPIO specifier for the busy pin.
|
description: GPIO specifier for the busy pin.
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
@@ -48,6 +50,8 @@ patternProperties:
|
|||||||
description: GPIO specifier for the write-protect pin.
|
description: GPIO specifier for the write-protect pin.
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
|
@@ -42,17 +42,16 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
reg:
|
reg:
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 1
|
maximum: 1
|
||||||
|
|
||||||
nand-ecc-mode: true
|
|
||||||
|
|
||||||
nand-ecc-algo:
|
nand-ecc-algo:
|
||||||
const: hw
|
const: hw
|
||||||
|
|
||||||
additionalProperties: false
|
unevaluatedProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- 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:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
$ref: nand-chip.yaml#
|
$ref: raw-nand-chip.yaml#
|
||||||
unevaluatedProperties: false
|
unevaluatedProperties: false
|
||||||
properties:
|
properties:
|
||||||
reg:
|
reg:
|
||||||
maximum: 1
|
maximum: 1
|
||||||
nand-on-flash-bbt: true
|
|
||||||
nand-ecc-mode:
|
nand-ecc-mode:
|
||||||
const: hw
|
const: hw
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ maintainers:
|
|||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^(flash|.*sram)(@.*)?$"
|
pattern: "^(flash|.*sram|nand)(@.*)?$"
|
||||||
|
|
||||||
label:
|
label:
|
||||||
description:
|
description:
|
||||||
|
@@ -16,16 +16,6 @@ description: |
|
|||||||
children nodes of the NAND controller. This representation should be
|
children nodes of the NAND controller. This representation should be
|
||||||
enforced even for simple controllers supporting only one chip.
|
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:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^nand-controller(@.*)?"
|
pattern: "^nand-controller(@.*)?"
|
||||||
@@ -51,79 +41,8 @@ properties:
|
|||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
$ref: nand-chip.yaml#
|
type: object
|
||||||
|
$ref: raw-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
|
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- "#address-cells"
|
- "#address-cells"
|
||||||
|
@@ -55,6 +55,7 @@ properties:
|
|||||||
linux,rootfs:
|
linux,rootfs:
|
||||||
description: Marks partition that contains root filesystem to mount and boot
|
description: Marks partition that contains root filesystem to mount and boot
|
||||||
user space from
|
user space from
|
||||||
|
type: boolean
|
||||||
|
|
||||||
if:
|
if:
|
||||||
not:
|
not:
|
||||||
|
@@ -21,6 +21,7 @@ oneOf:
|
|||||||
- $ref: linksys,ns-partitions.yaml
|
- $ref: linksys,ns-partitions.yaml
|
||||||
- $ref: qcom,smem-part.yaml
|
- $ref: qcom,smem-part.yaml
|
||||||
- $ref: redboot-fis.yaml
|
- $ref: redboot-fis.yaml
|
||||||
|
- $ref: tplink,safeloader-partitions.yaml
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible: true
|
compatible: true
|
||||||
|
@@ -34,7 +34,9 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
|
|
||||||
nand-bus-width:
|
nand-bus-width:
|
||||||
const: 8
|
const: 8
|
||||||
|
|
||||||
@@ -45,6 +47,24 @@ patternProperties:
|
|||||||
enum:
|
enum:
|
||||||
- 512
|
- 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:
|
allOf:
|
||||||
- $ref: nand-controller.yaml#
|
- $ref: nand-controller.yaml#
|
||||||
|
|
||||||
@@ -107,22 +127,15 @@ allOf:
|
|||||||
- qcom,ipq806x-nand
|
- qcom,ipq806x-nand
|
||||||
|
|
||||||
then:
|
then:
|
||||||
properties:
|
patternProperties:
|
||||||
qcom,boot-partitions:
|
"^nand@[a-f0-9]$":
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32-matrix
|
properties:
|
||||||
items:
|
qcom,boot-partitions: true
|
||||||
items:
|
else:
|
||||||
- description: offset
|
patternProperties:
|
||||||
- description: size
|
"^nand@[a-f0-9]$":
|
||||||
description:
|
properties:
|
||||||
Boot partition use a different layout where the 4 bytes of spare
|
qcom,boot-partitions: false
|
||||||
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.
|
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- 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:
|
patternProperties:
|
||||||
"^nand@[0-7]$":
|
"^nand@[0-7]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
reg:
|
reg:
|
||||||
minimum: 0
|
minimum: 0
|
||||||
@@ -116,6 +117,8 @@ patternProperties:
|
|||||||
|
|
||||||
Only used in combination with 'nand-is-boot-medium'.
|
Only used in combination with 'nand-is-boot-medium'.
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
|
@@ -37,6 +37,7 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^nand@[a-f0-9]$":
|
"^nand@[a-f0-9]$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: raw-nand-chip.yaml
|
||||||
properties:
|
properties:
|
||||||
nand-ecc-step-size:
|
nand-ecc-step-size:
|
||||||
const: 512
|
const: 512
|
||||||
@@ -44,6 +45,8 @@ patternProperties:
|
|||||||
nand-ecc-strength:
|
nand-ecc-strength:
|
||||||
enum: [1, 4, 8]
|
enum: [1, 4, 8]
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: nand-controller.yaml#
|
- $ref: nand-controller.yaml#
|
||||||
|
|
||||||
|
@@ -30,6 +30,8 @@ properties:
|
|||||||
patternProperties:
|
patternProperties:
|
||||||
"^flash@[0-1],[0-9a-f]+$":
|
"^flash@[0-1],[0-9a-f]+$":
|
||||||
type: object
|
type: object
|
||||||
|
$ref: mtd-physmap.yaml
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
|
@@ -12586,7 +12586,6 @@ MARVELL NAND CONTROLLER DRIVER
|
|||||||
M: Miquel Raynal <miquel.raynal@bootlin.com>
|
M: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||||
L: linux-mtd@lists.infradead.org
|
L: linux-mtd@lists.infradead.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/mtd/marvell-nand.txt
|
|
||||||
F: drivers/mtd/nand/raw/marvell_nand.c
|
F: drivers/mtd/nand/raw/marvell_nand.c
|
||||||
|
|
||||||
MARVELL OCTEON ENDPOINT DRIVER
|
MARVELL OCTEON ENDPOINT DRIVER
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Common Flash Interface support:
|
* Common Flash Interface support:
|
||||||
* Intel Extended Vendor Command Set (ID 0x0001)
|
* 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>
|
* 10/10/2000 Nicolas Pitre <nico@fluxnic.net>
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Common Flash Interface support:
|
* Common Flash Interface support:
|
||||||
* AMD & Fujitsu Standard Vendor Command Set (ID 0x0002)
|
* 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
|
* 25/09/2008 Christopher Moore: TopBottom fixup for many Macronix with CFI V1.0
|
||||||
*
|
*
|
||||||
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
|
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
|
||||||
*
|
|
||||||
* This code is GPL
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Common Flash Interface support:
|
* Common Flash Interface support:
|
||||||
* ST Advanced Architecture Command Set (ID 0x0020)
|
* 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>
|
* 10/10/2000 Nicolas Pitre <nico@fluxnic.net>
|
||||||
* - completely revamped method functions so they are aware and
|
* - completely revamped method functions so they are aware and
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
Common Flash Interface probe code.
|
Common Flash Interface probe code.
|
||||||
(C) 2000 Red Hat. GPL'd.
|
(C) 2000 Red Hat.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@@ -1,11 +1,10 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Common Flash Interface support:
|
* Common Flash Interface support:
|
||||||
* Generic utility functions not dependent on command set
|
* Generic utility functions not dependent on command set
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002 Red Hat
|
* Copyright (C) 2002 Red Hat
|
||||||
* Copyright (C) 2003 STMicroelectronics Limited
|
* Copyright (C) 2003 STMicroelectronics Limited
|
||||||
*
|
|
||||||
* This code is covered by the GPL.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Routines common to all CFI-type probes.
|
* Routines common to all CFI-type probes.
|
||||||
* (C) 2001-2003 Red Hat, Inc.
|
* (C) 2001-2003 Red Hat, Inc.
|
||||||
* GPL'd
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
Common Flash Interface probe code.
|
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)
|
See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
|
||||||
for the standard this probe goes back to.
|
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
|
* Common code to handle map devices which are simple RAM
|
||||||
* (C) 2000 Red Hat. GPL'd.
|
* (C) 2000 Red Hat.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Common code to handle map devices which are simple ROM
|
* Common code to handle map devices which are simple ROM
|
||||||
* (C) 2000 Red Hat. GPL'd.
|
* (C) 2000 Red Hat.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@@ -2046,34 +2046,26 @@ static int stfsm_probe(struct platform_device *pdev)
|
|||||||
return PTR_ERR(fsm->base);
|
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)) {
|
if (IS_ERR(fsm->clk)) {
|
||||||
dev_err(fsm->dev, "Couldn't find EMI clock.\n");
|
dev_err(fsm->dev, "Couldn't find EMI clock.\n");
|
||||||
return PTR_ERR(fsm->clk);
|
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);
|
mutex_init(&fsm->lock);
|
||||||
|
|
||||||
ret = stfsm_init(fsm);
|
ret = stfsm_init(fsm);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Failed to initialise FSM Controller\n");
|
dev_err(&pdev->dev, "Failed to initialise FSM Controller\n");
|
||||||
goto err_clk_unprepare;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
stfsm_fetch_platform_configs(pdev);
|
stfsm_fetch_platform_configs(pdev);
|
||||||
|
|
||||||
/* Detect SPI FLASH device */
|
/* Detect SPI FLASH device */
|
||||||
info = stfsm_jedec_probe(fsm);
|
info = stfsm_jedec_probe(fsm);
|
||||||
if (!info) {
|
if (!info)
|
||||||
ret = -ENODEV;
|
return -ENODEV;
|
||||||
goto err_clk_unprepare;
|
|
||||||
}
|
|
||||||
fsm->info = info;
|
fsm->info = info;
|
||||||
|
|
||||||
/* Use device size to determine address width */
|
/* Use device size to determine address width */
|
||||||
@@ -2089,7 +2081,7 @@ static int stfsm_probe(struct platform_device *pdev)
|
|||||||
else
|
else
|
||||||
ret = stfsm_prepare_rwe_seqs_default(fsm);
|
ret = stfsm_prepare_rwe_seqs_default(fsm);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_clk_unprepare;
|
return ret;
|
||||||
|
|
||||||
fsm->mtd.name = info->name;
|
fsm->mtd.name = info->name;
|
||||||
fsm->mtd.dev.parent = &pdev->dev;
|
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),
|
(long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20),
|
||||||
fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
|
fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
|
||||||
|
|
||||||
ret = mtd_device_register(&fsm->mtd, NULL, 0);
|
return mtd_device_register(&fsm->mtd, NULL, 0);
|
||||||
if (ret) {
|
|
||||||
err_clk_unprepare:
|
|
||||||
clk_disable_unprepare(fsm->clk);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stfsm_remove(struct platform_device *pdev)
|
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));
|
WARN_ON(mtd_device_unregister(&fsm->mtd));
|
||||||
|
|
||||||
clk_disable_unprepare(fsm->clk);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -259,7 +259,7 @@ static struct i2c_driver pismo_driver = {
|
|||||||
.driver = {
|
.driver = {
|
||||||
.name = "pismo",
|
.name = "pismo",
|
||||||
},
|
},
|
||||||
.probe_new = pismo_probe,
|
.probe = pismo_probe,
|
||||||
.remove = pismo_remove,
|
.remove = pismo_remove,
|
||||||
.id_table = pismo_id,
|
.id_table = pismo_id,
|
||||||
};
|
};
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
#include <linux/backing-dev.h>
|
#include <linux/backing-dev.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
|
#include <linux/random.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
@@ -966,6 +967,26 @@ static int mtd_otp_nvmem_add(struct mtd_info *mtd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (size > 0) {
|
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,
|
nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size,
|
||||||
mtd_nvmem_fact_otp_reg_read);
|
mtd_nvmem_fact_otp_reg_read);
|
||||||
if (IS_ERR(nvmem)) {
|
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)
|
static int __del_mtd_partitions(struct mtd_info *mtd)
|
||||||
{
|
{
|
||||||
struct mtd_info *child, *next;
|
struct mtd_info *child, *next;
|
||||||
LIST_HEAD(tmp_list);
|
|
||||||
int ret, err = 0;
|
int ret, err = 0;
|
||||||
|
|
||||||
list_for_each_entry_safe(child, next, &mtd->partitions, part.node) {
|
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_hynix.o
|
||||||
nand-objs += nand_macronix.o
|
nand-objs += nand_macronix.o
|
||||||
nand-objs += nand_micron.o
|
nand-objs += nand_micron.o
|
||||||
|
nand-objs += nand_sandisk.o
|
||||||
nand-objs += nand_samsung.o
|
nand-objs += nand_samsung.o
|
||||||
nand-objs += nand_toshiba.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);
|
nvddr = nand_get_nvddr_timings(conf);
|
||||||
if (IS_ERR(nvddr))
|
if (IS_ERR(nvddr))
|
||||||
return PTR_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 {
|
} else {
|
||||||
sdr = nand_get_sdr_timings(conf);
|
sdr = nand_get_sdr_timings(conf);
|
||||||
if (IS_ERR(sdr))
|
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 macronix_nand_manuf_ops;
|
||||||
extern const struct nand_manufacturer_ops micron_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 samsung_nand_manuf_ops;
|
||||||
|
extern const struct nand_manufacturer_ops sandisk_nand_manuf_ops;
|
||||||
extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops;
|
extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops;
|
||||||
|
|
||||||
/* MLC pairing schemes */
|
/* MLC pairing schemes */
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
#define NFC_CMD_SCRAMBLER_DISABLE 0
|
#define NFC_CMD_SCRAMBLER_DISABLE 0
|
||||||
#define NFC_CMD_SHORTMODE_DISABLE 0
|
#define NFC_CMD_SHORTMODE_DISABLE 0
|
||||||
#define NFC_CMD_RB_INT BIT(14)
|
#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))
|
#define NFC_CMD_GET_SIZE(x) (((x) >> 22) & GENMASK(4, 0))
|
||||||
|
|
||||||
@@ -76,6 +77,7 @@
|
|||||||
#define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff))
|
#define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff))
|
||||||
|
|
||||||
#define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N)
|
#define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N)
|
||||||
|
#define DMA_ADDR_ALIGN 8
|
||||||
|
|
||||||
#define ECC_CHECK_RETURN_FF (-1)
|
#define ECC_CHECK_RETURN_FF (-1)
|
||||||
|
|
||||||
@@ -108,6 +110,11 @@
|
|||||||
|
|
||||||
#define PER_INFO_BYTE 8
|
#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 meson_nfc_nand_chip {
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
struct nand_chip nand;
|
struct nand_chip nand;
|
||||||
@@ -179,6 +186,7 @@ struct meson_nfc {
|
|||||||
u32 info_bytes;
|
u32 info_bytes;
|
||||||
|
|
||||||
unsigned long assigned_cs;
|
unsigned long assigned_cs;
|
||||||
|
bool no_rb_pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -280,7 +288,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
|
|||||||
|
|
||||||
if (raw) {
|
if (raw) {
|
||||||
len = mtd->writesize + mtd->oobsize;
|
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);
|
writel(cmd, nfc->reg_base + NFC_REG_CMD);
|
||||||
return;
|
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;
|
u32 cmd, cfg;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -420,6 +463,27 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
|
|||||||
return ret;
|
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)
|
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);
|
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)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
|
cmd = NFC_CMD_N2M | len;
|
||||||
writel(cmd, nfc->reg_base + NFC_REG_CMD);
|
writel(cmd, nfc->reg_base + NFC_REG_CMD);
|
||||||
|
|
||||||
meson_nfc_drain_cmd(nfc);
|
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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
|
cmd = NFC_CMD_M2N | len;
|
||||||
writel(cmd, nfc->reg_base + NFC_REG_CMD);
|
writel(cmd, nfc->reg_base + NFC_REG_CMD);
|
||||||
|
|
||||||
meson_nfc_drain_cmd(nfc);
|
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;
|
cmd0 = in ? NAND_CMD_READ0 : NAND_CMD_SEQIN;
|
||||||
nfc->cmdfifo.rw.cmd0 = cs | NFC_CMD_CLE | cmd0;
|
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) {
|
if (mtd->writesize <= 512) {
|
||||||
cmd_num--;
|
cmd_num--;
|
||||||
row_start = 1;
|
row_start = 1;
|
||||||
} else {
|
} else {
|
||||||
addrs[1] = cs | NFC_CMD_ALE | 0;
|
addrs[1] = cs | NFC_CMD_ALE | NFC_COLUMN_ADDR_1;
|
||||||
row_start = 2;
|
row_start = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,7 +687,7 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand,
|
|||||||
if (in) {
|
if (in) {
|
||||||
nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART;
|
nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART;
|
||||||
writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD);
|
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 {
|
} else {
|
||||||
meson_nfc_cmd_idle(nfc, nfc->timing.tadl);
|
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;
|
cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG;
|
||||||
writel(cmd, nfc->reg_base + NFC_REG_CMD);
|
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);
|
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)
|
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)))
|
if (virt_addr_valid(buffer) && (!object_is_on_stack(buffer)))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@@ -899,6 +966,31 @@ meson_nand_op_put_dma_safe_output_buf(const struct nand_op_instr *instr,
|
|||||||
kfree(buf);
|
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,
|
static int meson_nfc_exec_op(struct nand_chip *nand,
|
||||||
const struct nand_operation *op, bool check_only)
|
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;
|
const struct nand_op_instr *instr = NULL;
|
||||||
void *buf;
|
void *buf;
|
||||||
u32 op_id, delay_idle, cmd;
|
u32 op_id, delay_idle, cmd;
|
||||||
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
err = meson_nfc_check_op(nand, op);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
if (check_only)
|
if (check_only)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -952,7 +1049,8 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NAND_OP_WAITRDY_INSTR:
|
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)
|
if (instr->delay_ns)
|
||||||
meson_nfc_cmd_idle(nfc, delay_idle);
|
meson_nfc_cmd_idle(nfc, delay_idle);
|
||||||
break;
|
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 meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
|
||||||
struct mtd_info *mtd = nand_to_mtd(nand);
|
struct mtd_info *mtd = nand_to_mtd(nand);
|
||||||
int nsectors = mtd->writesize / 1024;
|
int nsectors = mtd->writesize / 1024;
|
||||||
|
int raw_writesize;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!mtd->name) {
|
if (!mtd->name) {
|
||||||
@@ -1192,6 +1291,13 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
|
|||||||
return -ENOMEM;
|
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)
|
if (nand->bbt_options & NAND_BBT_USE_FLASH)
|
||||||
nand->bbt_options |= NAND_BBT_NO_OOB;
|
nand->bbt_options |= NAND_BBT_NO_OOB;
|
||||||
|
|
||||||
@@ -1248,6 +1354,7 @@ meson_nfc_nand_chip_init(struct device *dev,
|
|||||||
struct mtd_info *mtd;
|
struct mtd_info *mtd;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
u32 tmp, nsels;
|
u32 tmp, nsels;
|
||||||
|
u32 nand_rb_val = 0;
|
||||||
|
|
||||||
nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32));
|
nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32));
|
||||||
if (!nsels || nsels > MAX_CE_NUM) {
|
if (!nsels || nsels > MAX_CE_NUM) {
|
||||||
@@ -1287,6 +1394,15 @@ meson_nfc_nand_chip_init(struct device *dev,
|
|||||||
mtd->owner = THIS_MODULE;
|
mtd->owner = THIS_MODULE;
|
||||||
mtd->dev.parent = dev;
|
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);
|
ret = nand_scan(nand, nsels);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -44,6 +44,9 @@ struct nand_flash_dev nand_flash_ids[] = {
|
|||||||
{"TC58NVG6D2 64G 3.3V 8-bit",
|
{"TC58NVG6D2 64G 3.3V 8-bit",
|
||||||
{ .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} },
|
{ .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} },
|
||||||
SZ_8K, SZ_8K, SZ_2M, 0, 8, 640, NAND_ECC_INFO(40, SZ_1K) },
|
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",
|
{"SDTNRGAMA 64G 3.3V 8-bit",
|
||||||
{ .id = {0x45, 0xde, 0x94, 0x93, 0x76, 0x50} },
|
{ .id = {0x45, 0xde, 0x94, 0x93, 0x76, 0x50} },
|
||||||
SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) },
|
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_NATIONAL, "National"},
|
||||||
{NAND_MFR_RENESAS, "Renesas"},
|
{NAND_MFR_RENESAS, "Renesas"},
|
||||||
{NAND_MFR_SAMSUNG, "Samsung", &samsung_nand_manuf_ops},
|
{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_STMICRO, "ST Micro"},
|
||||||
{NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops},
|
{NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops},
|
||||||
{NAND_MFR_WINBOND, "Winbond"},
|
{NAND_MFR_WINBOND, "Winbond"},
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
* Author: Boris Brezillon <boris.brezillon@free-electrons.com>
|
* Author: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
#include "linux/delay.h"
|
#include "linux/delay.h"
|
||||||
#include "internals.h"
|
#include "internals.h"
|
||||||
|
|
||||||
@@ -31,6 +32,16 @@
|
|||||||
|
|
||||||
#define MXIC_CMD_POWER_DOWN 0xB9
|
#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 {
|
struct nand_onfi_vendor_macronix {
|
||||||
u8 reserved;
|
u8 reserved;
|
||||||
u8 reliability_func;
|
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;
|
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)
|
static int macronix_nand_init(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
if (nand_is_slc(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_onfi_init(chip);
|
||||||
macronix_nand_block_protection_support(chip);
|
macronix_nand_block_protection_support(chip);
|
||||||
macronix_nand_deep_power_down_support(chip);
|
macronix_nand_deep_power_down_support(chip);
|
||||||
|
macronix_nand_setup_otp(chip);
|
||||||
|
|
||||||
return 0;
|
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_HAS_QE_BIT,
|
||||||
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
|
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
|
||||||
gd5fxgq4uexxg_ecc_get_status)),
|
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 = {
|
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,
|
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||||
mx35lf1ge4ab_ecc_get_status)),
|
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 = {
|
static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
|
||||||
|
@@ -981,7 +981,7 @@ restart:
|
|||||||
/* Update the FTL table */
|
/* Update the FTL table */
|
||||||
zone->lba_to_phys_table[ftl->cache_block] = write_sector;
|
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)
|
if (block_num > 0)
|
||||||
sm_erase_block(ftl, zone_num, block_num, 1);
|
sm_erase_block(ftl, zone_num, block_num, 1);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user