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 |................| * ```