Access Elkhart Lake MRAM via spi-nor driver
===
### 1. Simulate spi-nor flash with spinor.aml and driver patch
[Reference Patch](https://lore.kernel.org/linux-mtd/67ad7c365fa749209eab5ddae7f8ce80@asem.it/T/)
```bash=
cat spinor.dsl
DefinitionBlock ("spinor.aml", "SSDT", 5, "", "SPINOR", 1)
{
External (\_SB.PC00.SPI0, DeviceObj)
Scope (\_SB.PC00.SPI0)
{
Device (NVR0)
{
Name (_HID, "PRP0001")
Name (_DDN, "Renesas M3008204 MRAM")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
0, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // Don't care
25000000, // 25 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PC00.SPI0", // SPI host controller
0 // Must be 0
)
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "m3008204"},
}
})
}
}
}
```
Compile
```bash=
iasl spinor.dsl
Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20190509
Copyright (c) 2000 - 2019 Intel Corporation
ASL Input: spinor.dsl - 1219 bytes 6 keywords 35 source lines
AML Output: spinor.aml - 228 bytes 0 opcodes 6 named objects
Compilation successful. 0 Errors, 0 Warnings, 0 Remarks, 1 Optimizations
```
### 2. make a directory and copy spinor.aml (source code spinor.dsl)
```bash=
mkdir -p kernel/firmware/acpi
cp spinor.aml kernel/firmware/acpi
```
### 2.1 apply spi-nor patch to 5.13 kernel (appending to everspin.c)
```bash=
git diff drivers/mtd/spi-nor/core.c
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index bd2c7717eb10..41786214f009 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3419,6 +3419,7 @@ static const struct spi_device_id spi_nor_dev_ids[] = {
{ "mr25h256" }, /* 256 Kib, 40 MHz */
{ "mr25h10" }, /* 1 Mib, 40 MHz */
{ "mr25h40" }, /* 4 Mib, 40 MHz */
+ { "m3008204" }, /* 8 Mib, 25 MHz */
{ },
};
@@ -3430,6 +3431,7 @@ static const struct of_device_id spi_nor_of_table[] = {
* JEDEC READ ID opcode (0x9F). Use this, if possible.
*/
{ .compatible = "jedec,spi-nor" },
+ { .compatible = "m3008204" }, /* MRAM */
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, spi_nor_of_table);
git diff drivers/mtd/spi-nor/everspin.c
diff --git a/drivers/mtd/spi-nor/everspin.c b/drivers/mtd/spi-nor/everspin.c
index 04a177a32283..b9012733cf3c 100644
--- a/drivers/mtd/spi-nor/everspin.c
+++ b/drivers/mtd/spi-nor/everspin.c
@@ -18,6 +18,8 @@ static const struct flash_info everspin_parts[] = {
SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
{ "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3,
SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+ { "m3008204", CAT25_INFO(1024 * 1024, 1, 256, 3,
+ SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
};
const struct spi_nor_manufacturer spi_nor_everspin = {
```
Build new kernel modules
```bash
make SUBDIRS=drivers/mtd/spi-nor/ modules
```
### 3. make a modified initrd
```bash=
find kernel | cpio -H newc --create > initrd_mod; cat /boot/initrd.img >> initrd_mod
sudo cp initrd_mod /boot
```
### 4. Reboot and update BIOS menu
Check SPI CS back to high active (BIOS default)
```
Chipset -> SerialIo Configuration -> Serial IO SPI0 Settings -> Chipselect 0 polarity to [Active High]
(change to GPIO, change to high active, change back to native)
```
### 5. Temporary update Grub2 parameter
At GRUB2 menu, press āeā to edit first menu item
Move to last line, change initrd.xxxx to initrd_mod and press āF10ā to boot
### 6. Check dmesg
```bash=
dmesg | grep -i spi
[ 0.017316] ACPI: SSDT ACPI table found in initrd [kernel/firmware/acpi/spinor.aml][0xe4]
[ 0.017681] ACPI: Table Upgrade: install [SSDT- - SPINOR]
[ 0.017685] ACPI: SSDT 0x00000000753C2000 0000E4 (v05 SPINOR 00000001 INTL 20190509)
[ 2.727961] spi-nor spi-PRP0001:00: m3008204 (1024 Kbytes)
```
### 6.1 Unload/Load spi-nor.ko
```bash=
lsmod | grep spi
spi_nor 90112 0
mtd 69632 3 spi_nor,cmdlinepart
spi_pxa2xx_platform 32768 0
sudo rmmod spi_nor
dmesg | tail
[ 4771.348943] Deleting MTD partitions on "spi-PRP0001:00":
sudo modprobe spi-nor
dmesg | tail
[ 4804.048350] spi-nor spi-PRP0001:00: m3008204 (1024 Kbytes)
```
### 7. Check MTD info
```bash=
mtdinfo --map /dev/mtd0
mtd0
Name: spi-PRP0001:00
Type: nor
Eraseblock size: 1048576 bytes, 1024.0 KiB
Amount of eraseblocks: 1 (1048576 bytes, 1024.0 KiB)
Minimum input/output unit size: 1 byte
Sub-page size: 1 byte
Character device major/minor: 90:0
Bad blocks are allowed: false
Device is writable: true
mtdinfo: error!: couldn't open MTD dev: /dev/mtd0
error 13 (Permission denied)
Eraseblock map:
0: 00000000
mtdinfo: error!: could not read locked block info
error 19 (No such device)
```
### 8. Can't format like normal SPI flash, Test with `hexdump` & `dd`
Create test binary.dat
```bash=
i=0; while [ $i -lt 256 ]; do echo -en '\x'$(printf "%0x" $i)'' >> binary.dat; i=$((i+1)); done
hexdump -C binary.dat
00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./|
00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?|
00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO|
00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_|
00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno|
00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.|
00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................|
00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................|
000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................|
000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................|
000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................|
000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................|
000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................|
000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|
00000100
```
`dd` to `/dev/mtd0`
```bash=
sudo dd if=binary.dat of=/dev/mtd0
[sudo] password for bcm:
0+1 records in
0+1 records out
256 bytes copied, 0.0190157 s, 13.5 kB/s
```
`hexdump` the result
```bash=
sudo hexdump -C /dev/mtd0
00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./|
00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?|
00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO|
00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_|
00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno|
00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.|
00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................|
00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................|
000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................|
000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................|
000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................|
000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................|
000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................|
000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001b0 00 00 00 00 00 00 00 00 2a a6 0c 9b 00 00 00 00 |........*.......|
000001c0 02 00 83 10 12 00 01 00 00 00 01 04 00 00 00 00 |................|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000 02 00 00 00 03 00 00 00 04 00 00 00 f2 00 75 00 |..............u.|
00001010 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002000 ff 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.?..............|
00002010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00002020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00003000 ff 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00003010 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
```