aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/loaders/flash/sh_qspi/Makefile37
-rw-r--r--contrib/loaders/flash/sh_qspi/sh_qspi.S306
-rw-r--r--contrib/loaders/flash/sh_qspi/sh_qspi.inc37
-rw-r--r--contrib/loaders/flash/sh_qspi/sh_qspi.ld13
4 files changed, 393 insertions, 0 deletions
diff --git a/contrib/loaders/flash/sh_qspi/Makefile b/contrib/loaders/flash/sh_qspi/Makefile
new file mode 100644
index 00000000..2bfbad1b
--- /dev/null
+++ b/contrib/loaders/flash/sh_qspi/Makefile
@@ -0,0 +1,37 @@
+CROSS_COMPILE=arm-linux-gnueabihf-
+BIN2C = ../../../../src/helper/bin2char.sh
+
+TGT = sh_qspi
+ASRC += sh_qspi.S
+LDS = sh_qspi.ld
+
+OBJS += $(ASRC:.S=.o)
+
+CC=$(CROSS_COMPILE)gcc
+OBJCOPY=$(CROSS_COMPILE)objcopy
+OBJDUMP=$(CROSS_COMPILE)objdump
+LD=$(CROSS_COMPILE)ld
+NM=$(CROSS_COMPILE)nm
+SIZE=$(CROSS_COMPILE)size
+
+CFLAGS=-Os -Wall -nostartfiles -marm -nostdinc -ffreestanding -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -msoft-float -pipe -march=armv7-a -mtune=generic-armv7-a
+LDFLAGS=-T$(LDS) -nostdlib -Map=$(TGT).map
+
+all: $(TGT).inc
+
+%.o: %.S
+ $(CC) $(CFLAGS) -c $^ -o $@
+
+$(TGT).elf: $(OBJS)
+ $(LD) $(LDFLAGS) $^ -o $@
+
+$(TGT).bin: $(TGT).elf
+ $(OBJCOPY) $< -O binary $@
+ $(NM) -n $(TGT).elf > $(TGT).sym
+ $(SIZE) $(TGT).elf
+
+$(TGT).inc: $(TGT).bin
+ $(BIN2C) < $< > $@
+
+clean:
+ rm -rf *.elf *.hex *.map *.o *.disasm *.sym
diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.S b/contrib/loaders/flash/sh_qspi/sh_qspi.S
new file mode 100644
index 00000000..78eb1e81
--- /dev/null
+++ b/contrib/loaders/flash/sh_qspi/sh_qspi.S
@@ -0,0 +1,306 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * SH QSPI (Quad SPI) driver
+ * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+#define BIT(n) (1UL << (n))
+/* SH QSPI register bit masks <REG>_<BIT> */
+#define SPCR_MSTR 0x08
+#define SPCR_SPE 0x40
+#define SPSR_SPRFF 0x80
+#define SPSR_SPTEF 0x20
+#define SPPCR_IO3FV 0x04
+#define SPPCR_IO2FV 0x02
+#define SPPCR_IO1FV 0x01
+#define SPBDCR_RXBC0 BIT(0)
+#define SPCMD_SCKDEN BIT(15)
+#define SPCMD_SLNDEN BIT(14)
+#define SPCMD_SPNDEN BIT(13)
+#define SPCMD_SSLKP BIT(7)
+#define SPCMD_BRDV0 BIT(2)
+#define SPCMD_INIT1 SPCMD_SCKDEN | SPCMD_SLNDEN | \
+ SPCMD_SPNDEN | SPCMD_SSLKP | \
+ SPCMD_BRDV0
+#define SPCMD_INIT2 SPCMD_SPNDEN | SPCMD_SSLKP | \
+ SPCMD_BRDV0
+#define SPBFCR_TXRST BIT(7)
+#define SPBFCR_RXRST BIT(6)
+#define SPBFCR_TXTRG 0x30
+#define SPBFCR_RXTRG 0x07
+
+/* SH QSPI register set */
+#define SH_QSPI_SPCR 0x00
+#define SH_QSPI_SSLP 0x01
+#define SH_QSPI_SPPCR 0x02
+#define SH_QSPI_SPSR 0x03
+#define SH_QSPI_SPDR 0x04
+#define SH_QSPI_SPSCR 0x08
+#define SH_QSPI_SPSSR 0x09
+#define SH_QSPI_SPBR 0x0a
+#define SH_QSPI_SPDCR 0x0b
+#define SH_QSPI_SPCKD 0x0c
+#define SH_QSPI_SSLND 0x0d
+#define SH_QSPI_SPND 0x0e
+#define SH_QSPI_DUMMY0 0x0f
+#define SH_QSPI_SPCMD0 0x10
+#define SH_QSPI_SPCMD1 0x12
+#define SH_QSPI_SPCMD2 0x14
+#define SH_QSPI_SPCMD3 0x16
+#define SH_QSPI_SPBFCR 0x18
+#define SH_QSPI_DUMMY1 0x19
+#define SH_QSPI_SPBDCR 0x1a
+#define SH_QSPI_SPBMUL0 0x1c
+#define SH_QSPI_SPBMUL1 0x20
+#define SH_QSPI_SPBMUL2 0x24
+#define SH_QSPI_SPBMUL3 0x28
+
+.syntax unified
+.arm
+.text
+
+.macro wait_for_spsr, spsrbit
+ 1: ldrb r12, [r0, #SH_QSPI_SPSR]
+ tst r12, \spsrbit
+ beq 1b
+.endm
+
+.macro sh_qspi_xfer
+ bl sh_qspi_cs_activate
+ str r6, [r0, SH_QSPI_SPBMUL0]
+ bl sh_qspi_xfer_common
+ bl sh_qspi_cs_deactivate
+.endm
+
+.macro sh_qspi_write_enable
+ ldr r4, =SPIFLASH_WRITE_ENABLE
+ adr r5, _start
+ add r4, r5
+ mov r5, #0x0
+ mov r6, #0x1
+ sh_qspi_xfer
+.endm
+
+.macro sh_qspi_wait_till_ready
+ 1: ldr r4, =SPIFLASH_READ_STATUS
+ adr r5, _start
+ add r4, r5
+ mov r5, #0x0
+ mov r6, #0x2
+ sh_qspi_xfer
+ and r13, #0x1
+ cmp r13, #0x1
+ beq 1b
+.endm
+
+/*
+ * r0: controller base address
+ * r1: data buffer base address
+ * r2: BIT(31) -- page program (not read)
+ * BIT(30) -- 4-byte address (not 3-byte)
+ * BIT(29) -- 512-byte page (not 256-byte)
+ * BIT(27:20) -- SF command
+ * BIT(19:0) -- amount of data to read/write
+ * r3: SF target address
+ *
+ * r7: data size
+ * r8: page size
+ *
+ * r14: lr, link register
+ * r15: pc, program counter
+ *
+ * Clobber: r4, r5, r6, r7, r8
+ */
+
+.global _start
+_start:
+ bic r7, r2, #0xff000000
+ bic r7, r7, #0x00f00000
+
+ and r8, r2, #(1 << 31)
+ cmp r8, #(1 << 31)
+ beq do_page_program
+
+/* fast read */
+
+ bl sh_qspi_cs_activate
+
+ bl sh_qspi_setup_command
+ add r8, r6, r7
+ str r8, [r0, SH_QSPI_SPBMUL0]
+ bl sh_qspi_xfer_common
+
+ mov r4, #0x0
+ mov r5, r1
+ mov r6, r7
+ bl sh_qspi_xfer_common
+
+ bl sh_qspi_cs_deactivate
+
+ b end
+
+do_page_program:
+
+ mov r8, #0x100
+ tst r2, (1 << 29)
+ movne r8, #0x200
+
+do_pp_next_page:
+ /* Check if less then page bytes left. */
+ cmp r7, r8
+ movlt r8, r7
+
+ sh_qspi_write_enable
+
+ bl sh_qspi_cs_activate
+
+ bl sh_qspi_setup_command
+ str r6, [r0, SH_QSPI_SPBMUL0]
+ bl sh_qspi_xfer_common
+
+ mov r4, r1
+ mov r5, #0x0
+ mov r6, r8
+
+ bl sh_qspi_xfer_common
+
+ bl sh_qspi_cs_deactivate
+
+ sh_qspi_wait_till_ready
+
+ add r1, r8
+ add r3, r8
+ sub r7, r8
+ cmp r7, #0
+
+ bne do_pp_next_page
+
+end:
+ bkpt #0
+
+sh_qspi_cs_activate:
+ /* Set master mode only */
+ mov r12, #SPCR_MSTR
+ strb r12, [r0, SH_QSPI_SPCR]
+
+ /* Set command */
+ mov r12, #SPCMD_INIT1
+ strh r12, [r0, SH_QSPI_SPCMD0]
+
+ /* Reset transfer and receive Buffer */
+ ldrb r12, [r0, SH_QSPI_SPSCR]
+ orr r12, #(SPBFCR_TXRST | SPBFCR_RXRST)
+ strb r12, [r0, SH_QSPI_SPBFCR]
+
+ /* Clear transfer and receive Buffer control bit */
+ ldrb r12, [r0, SH_QSPI_SPBFCR]
+ bic r12, #(SPBFCR_TXRST | SPBFCR_RXRST)
+ strb r12, [r0, SH_QSPI_SPBFCR]
+
+ /* Set sequence control method. Use sequence0 only */
+ mov r12, #0x00
+ strb r12, [r0, SH_QSPI_SPSCR]
+
+ /* Enable SPI function */
+ ldrb r12, [r0, SH_QSPI_SPCR]
+ orr r12, #SPCR_SPE
+ strb r12, [r0, SH_QSPI_SPCR]
+
+ mov pc, lr
+
+sh_qspi_cs_deactivate:
+ /* Disable SPI function */
+ ldrb r12, [r0, SH_QSPI_SPCR]
+ bic r12, #SPCR_SPE
+ strb r12, [r0, SH_QSPI_SPCR]
+
+ mov pc, lr
+
+/*
+ * r0, controller base address
+ * r4, tx buffer
+ * r5, rx buffer
+ * r6, xfer len, non-zero
+ *
+ * Upon exit, r13 contains the last byte in SPDR
+ *
+ * Clobber: r11, r12, r13
+ */
+sh_qspi_xfer_common:
+prepcopy:
+ ldr r13, [r0, #SH_QSPI_SPBFCR]
+ orr r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG)
+ mov r11, #32
+ cmp r6, #32
+
+ biclt r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG)
+ movlt r11, #1
+
+copy:
+ str r13, [r0, #SH_QSPI_SPBFCR]
+
+ wait_for_spsr SPSR_SPTEF
+
+ mov r12, r11
+ mov r13, #0
+ cmp r4, #0
+ beq 3f
+
+2: ldrb r13, [r4], #1
+ strb r13, [r0, #SH_QSPI_SPDR]
+ subs r12, #1
+ bne 2b
+ b 4f
+
+3: strb r13, [r0, #SH_QSPI_SPDR]
+ subs r12, #1
+ bne 3b
+
+4: wait_for_spsr SPSR_SPRFF
+
+ mov r12, r11
+ cmp r5, #0
+ beq 6f
+
+5: ldrb r13, [r0, #SH_QSPI_SPDR]
+ strb r13, [r5], #1
+ subs r12, #1
+ bne 5b
+ b 7f
+
+6: ldrb r13, [r0, #SH_QSPI_SPDR]
+ subs r12, #1
+ bne 6b
+
+7: subs r6, r11
+ bne prepcopy
+
+ mov pc, lr
+
+sh_qspi_setup_command:
+ ldr r4, =SPIFLASH_SCRATCH_DATA
+ adr r5, _start
+ add r4, r5
+ and r12, r2, #0x0ff00000
+ lsr r12, #20
+ strb r12, [r4]
+ mov r12, r3
+ strb r12, [r4, #4]
+ lsr r12, #8
+ strb r12, [r4, #3]
+ lsr r12, #8
+ strb r12, [r4, #2]
+ lsr r12, #8
+ strb r12, [r4, #1]
+ lsr r12, #8
+ mov r5, #0x0
+ mov r6, #0x4
+ tst r2, (1 << 30)
+ movne r6, #0x5
+
+ mov pc, lr
+
+SPIFLASH_READ_STATUS: .byte 0x05 /* Read Status Register */
+SPIFLASH_WRITE_ENABLE: .byte 0x06 /* Write Enable */
+SPIFLASH_NOOP: .byte 0x00
+SPIFLASH_SCRATCH_DATA: .byte 0x00, 0x0, 0x0, 0x0, 0x0
diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.inc b/contrib/loaders/flash/sh_qspi/sh_qspi.inc
new file mode 100644
index 00000000..ca913923
--- /dev/null
+++ b/contrib/loaders/flash/sh_qspi/sh_qspi.inc
@@ -0,0 +1,37 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0xff,0x74,0xc2,0xe3,0x0f,0x76,0xc7,0xe3,0x02,0x81,0x02,0xe2,0x02,0x01,0x58,0xe3,
+0x0a,0x00,0x00,0x0a,0x32,0x00,0x00,0xeb,0x6c,0x00,0x00,0xeb,0x07,0x80,0x86,0xe0,
+0x1c,0x80,0x80,0xe5,0x42,0x00,0x00,0xeb,0x00,0x40,0xa0,0xe3,0x01,0x50,0xa0,0xe1,
+0x07,0x60,0xa0,0xe1,0x3e,0x00,0x00,0xeb,0x39,0x00,0x00,0xeb,0x27,0x00,0x00,0xea,
+0x01,0x8c,0xa0,0xe3,0x02,0x02,0x12,0xe3,0x02,0x8c,0xa0,0x13,0x08,0x00,0x57,0xe1,
+0x07,0x80,0xa0,0xb1,0xcc,0x41,0x9f,0xe5,0x60,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0,
+0x00,0x50,0xa0,0xe3,0x01,0x60,0xa0,0xe3,0x1d,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5,
+0x2f,0x00,0x00,0xeb,0x2a,0x00,0x00,0xeb,0x19,0x00,0x00,0xeb,0x53,0x00,0x00,0xeb,
+0x1c,0x60,0x80,0xe5,0x2a,0x00,0x00,0xeb,0x01,0x40,0xa0,0xe1,0x00,0x50,0xa0,0xe3,
+0x08,0x60,0xa0,0xe1,0x26,0x00,0x00,0xeb,0x21,0x00,0x00,0xeb,0x88,0x41,0x9f,0xe5,
+0xa8,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0,0x00,0x50,0xa0,0xe3,0x02,0x60,0xa0,0xe3,
+0x0b,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5,0x1d,0x00,0x00,0xeb,0x18,0x00,0x00,0xeb,
+0x01,0xd0,0x0d,0xe2,0x01,0x00,0x5d,0xe3,0xf3,0xff,0xff,0x0a,0x08,0x10,0x81,0xe0,
+0x08,0x30,0x83,0xe0,0x08,0x70,0x47,0xe0,0x00,0x00,0x57,0xe3,0xda,0xff,0xff,0x1a,
+0x70,0x00,0x20,0xe1,0x08,0xc0,0xa0,0xe3,0x00,0xc0,0xc0,0xe5,0x84,0xc0,0x0e,0xe3,
+0xb0,0xc1,0xc0,0xe1,0x08,0xc0,0xd0,0xe5,0xc0,0xc0,0x8c,0xe3,0x18,0xc0,0xc0,0xe5,
+0x18,0xc0,0xd0,0xe5,0xc0,0xc0,0xcc,0xe3,0x18,0xc0,0xc0,0xe5,0x00,0xc0,0xa0,0xe3,
+0x08,0xc0,0xc0,0xe5,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0x8c,0xe3,0x00,0xc0,0xc0,0xe5,
+0x0e,0xf0,0xa0,0xe1,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0xcc,0xe3,0x00,0xc0,0xc0,0xe5,
+0x0e,0xf0,0xa0,0xe1,0x18,0xd0,0x90,0xe5,0x37,0xd0,0x8d,0xe3,0x20,0xb0,0xa0,0xe3,
+0x20,0x00,0x56,0xe3,0x37,0xd0,0xcd,0xb3,0x01,0xb0,0xa0,0xb3,0x18,0xd0,0x80,0xe5,
+0x03,0xc0,0xd0,0xe5,0x20,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1,
+0x00,0xd0,0xa0,0xe3,0x00,0x00,0x54,0xe3,0x04,0x00,0x00,0x0a,0x01,0xd0,0xd4,0xe4,
+0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea,
+0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfc,0xff,0xff,0x1a,0x03,0xc0,0xd0,0xe5,
+0x80,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1,0x00,0x00,0x55,0xe3,
+0x04,0x00,0x00,0x0a,0x04,0xd0,0xd0,0xe5,0x01,0xd0,0xc5,0xe4,0x01,0xc0,0x5c,0xe2,
+0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea,0x04,0xd0,0xd0,0xe5,0x01,0xc0,0x5c,0xe2,
+0xfc,0xff,0xff,0x1a,0x0b,0x60,0x56,0xe0,0xd9,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,
+0x58,0x40,0x9f,0xe5,0x77,0x5f,0x4f,0xe2,0x05,0x40,0x84,0xe0,0xff,0xc6,0x02,0xe2,
+0x2c,0xca,0xa0,0xe1,0x00,0xc0,0xc4,0xe5,0x03,0xc0,0xa0,0xe1,0x04,0xc0,0xc4,0xe5,
+0x2c,0xc4,0xa0,0xe1,0x03,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x02,0xc0,0xc4,0xe5,
+0x2c,0xc4,0xa0,0xe1,0x01,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x00,0x50,0xa0,0xe3,
+0x04,0x60,0xa0,0xe3,0x01,0x01,0x12,0xe3,0x05,0x60,0xa0,0x13,0x0e,0xf0,0xa0,0xe1,
+0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x02,0x00,0x00,0x20,0x02,0x00,0x00,
+0x23,0x02,0x00,0x00,
diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.ld b/contrib/loaders/flash/sh_qspi/sh_qspi.ld
new file mode 100644
index 00000000..2683c520
--- /dev/null
+++ b/contrib/loaders/flash/sh_qspi/sh_qspi.ld
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x0;
+ . = ALIGN(4);
+ .text : {
+ sh_qspi.o (.text*)
+ *(.text*)
+ }
+}