^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) STMicroelectronics 2020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* FMC2 Controller Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define FMC2_BCR1 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define FMC2_BTR1 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define FMC2_PCSCNTR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define FMC2_BWTR1 0x104
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Register: FMC2_BCR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define FMC2_BCR1_CCLKEN BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define FMC2_BCR1_FMC2EN BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Register: FMC2_BCRx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define FMC2_BCR_MBKEN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define FMC2_BCR_MUXEN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define FMC2_BCR_MTYP GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define FMC2_BCR_MWID GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define FMC2_BCR_FACCEN BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define FMC2_BCR_BURSTEN BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define FMC2_BCR_WAITPOL BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define FMC2_BCR_WAITCFG BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define FMC2_BCR_WREN BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define FMC2_BCR_WAITEN BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define FMC2_BCR_EXTMOD BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FMC2_BCR_ASYNCWAIT BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FMC2_BCR_CPSIZE GENMASK(18, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FMC2_BCR_CBURSTRW BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define FMC2_BCR_NBLSET GENMASK(23, 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Register: FMC2_BTRx/FMC2_BWTRx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define FMC2_BXTR_ADDSET GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define FMC2_BXTR_ADDHLD GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define FMC2_BXTR_DATAST GENMASK(15, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define FMC2_BXTR_BUSTURN GENMASK(19, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define FMC2_BTR_CLKDIV GENMASK(23, 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define FMC2_BTR_DATLAT GENMASK(27, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define FMC2_BXTR_ACCMOD GENMASK(29, 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define FMC2_BXTR_DATAHLD GENMASK(31, 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Register: FMC2_PCSCNTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define FMC2_MAX_EBI_CE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define FMC2_MAX_BANKS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define FMC2_BCR_CPSIZE_0 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define FMC2_BCR_CPSIZE_128 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define FMC2_BCR_CPSIZE_256 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define FMC2_BCR_CPSIZE_512 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define FMC2_BCR_CPSIZE_1024 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define FMC2_BCR_MWID_8 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define FMC2_BCR_MWID_16 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define FMC2_BCR_MTYP_SRAM 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define FMC2_BCR_MTYP_PSRAM 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define FMC2_BCR_MTYP_NOR 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define FMC2_BXTR_EXTMOD_A 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define FMC2_BXTR_EXTMOD_B 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define FMC2_BXTR_EXTMOD_C 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define FMC2_BXTR_EXTMOD_D 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define FMC2_BCR_NBLSET_MAX 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define FMC2_BXTR_ADDSET_MAX 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define FMC2_BXTR_ADDHLD_MAX 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define FMC2_BXTR_DATAST_MAX 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define FMC2_BXTR_BUSTURN_MAX 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define FMC2_BXTR_DATAHLD_MAX 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FMC2_BTR_CLKDIV_MAX 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FMC2_BTR_DATLAT_MAX 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define FMC2_PCSCNTR_CSCOUNT_MAX 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) enum stm32_fmc2_ebi_bank {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) FMC2_EBI1 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) FMC2_EBI2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) FMC2_EBI3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) FMC2_EBI4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) FMC2_NAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) enum stm32_fmc2_ebi_register_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) FMC2_REG_BCR = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) FMC2_REG_BTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) FMC2_REG_BWTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) FMC2_REG_PCSCNTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) enum stm32_fmc2_ebi_transaction_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) FMC2_ASYNC_MODE_1_SRAM = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) FMC2_ASYNC_MODE_1_PSRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) FMC2_ASYNC_MODE_A_SRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) FMC2_ASYNC_MODE_A_PSRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) FMC2_ASYNC_MODE_2_NOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) FMC2_ASYNC_MODE_B_NOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) FMC2_ASYNC_MODE_C_NOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) FMC2_ASYNC_MODE_D_NOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) FMC2_SYNC_READ_SYNC_WRITE_PSRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) FMC2_SYNC_READ_ASYNC_WRITE_PSRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) FMC2_SYNC_READ_SYNC_WRITE_NOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) FMC2_SYNC_READ_ASYNC_WRITE_NOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) enum stm32_fmc2_ebi_buswidth {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) FMC2_BUSWIDTH_8 = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) FMC2_BUSWIDTH_16 = 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) enum stm32_fmc2_ebi_cpsize {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) FMC2_CPSIZE_0 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) FMC2_CPSIZE_128 = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) FMC2_CPSIZE_256 = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) FMC2_CPSIZE_512 = 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) FMC2_CPSIZE_1024 = 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct stm32_fmc2_ebi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u8 bank_assigned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 bcr[FMC2_MAX_EBI_CE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u32 btr[FMC2_MAX_EBI_CE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u32 bwtr[FMC2_MAX_EBI_CE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 pcscntr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * struct stm32_fmc2_prop - STM32 FMC2 EBI property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @name: the device tree binding name of the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * @bprop: indicate that it is a boolean property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @mprop: indicate that it is a mandatory property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @reg_type: the register that have to be modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * @reg_mask: the bit that have to be modified in the selected register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * in case of it is a boolean property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @reset_val: the default value that have to be set in case the property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * has not been defined in the device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @check: this callback ckecks that the property is compliant with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * transaction type selected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @calculate: this callback is called to calculate for exemple a timing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * set in nanoseconds in the device tree in clock cycles or in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * clock period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * @set: this callback applies the values in the registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct stm32_fmc2_prop {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) bool bprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) bool mprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int reg_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u32 reg_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u32 reset_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int (*check)(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const struct stm32_fmc2_prop *prop, int cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 (*calculate)(struct stm32_fmc2_ebi *ebi, int cs, u32 setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int (*set)(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int cs, u32 setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u32 bcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (bcr & FMC2_BCR_MTYP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u32 bcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (bcr & FMC2_BCR_BURSTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u32 bcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 bcr, bxtr, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (prop->reg_type == FMC2_REG_BWTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) u32 bcr, bcr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) regmap_read(ebi->regmap, FMC2_BCR1, &bcr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) bcr1 = bcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int stm32_fmc2_ebi_check_cclk(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static u32 stm32_fmc2_ebi_ns_to_clock_cycles(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned long hclk = clk_get_rate(ebi->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return DIV_ROUND_UP(setup * 1000, hclkp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u32 bcr, btr, clk_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) regmap_read(ebi->regmap, FMC2_BCR1, &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (bcr & FMC2_BCR1_CCLKEN || !cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) regmap_read(ebi->regmap, FMC2_BTR1, &btr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) regmap_read(ebi->regmap, FMC2_BTR(cs), &btr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return DIV_ROUND_UP(nb_clk_cycles, clk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) switch (reg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case FMC2_REG_BCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *reg = FMC2_BCR(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) case FMC2_REG_BTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *reg = FMC2_BTR(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) case FMC2_REG_BWTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *reg = FMC2_BWTR(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case FMC2_REG_PCSCNTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) *reg = FMC2_PCSCNTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static int stm32_fmc2_ebi_set_bit_field(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) regmap_update_bits(ebi->regmap, reg, prop->reg_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) setup ? prop->reg_mask : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int stm32_fmc2_ebi_set_trans_type(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) u32 bcr_mask, bcr = FMC2_BCR_WREN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u32 btr_mask, btr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u32 bwtr_mask, bwtr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) bwtr_mask = FMC2_BXTR_ACCMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) btr_mask = FMC2_BXTR_ACCMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) bcr_mask = FMC2_BCR_MUXEN | FMC2_BCR_MTYP | FMC2_BCR_FACCEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) FMC2_BCR_WREN | FMC2_BCR_WAITEN | FMC2_BCR_BURSTEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) FMC2_BCR_EXTMOD | FMC2_BCR_CBURSTRW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) switch (setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case FMC2_ASYNC_MODE_1_SRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case FMC2_ASYNC_MODE_1_PSRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case FMC2_ASYNC_MODE_A_SRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bcr |= FMC2_BCR_EXTMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case FMC2_ASYNC_MODE_A_PSRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) bcr |= FMC2_BCR_EXTMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case FMC2_ASYNC_MODE_2_NOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) bcr |= FMC2_BCR_FACCEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case FMC2_ASYNC_MODE_B_NOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) case FMC2_ASYNC_MODE_C_NOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) case FMC2_ASYNC_MODE_D_NOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case FMC2_SYNC_READ_SYNC_WRITE_PSRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) bcr |= FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case FMC2_SYNC_READ_ASYNC_WRITE_PSRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) bcr |= FMC2_BCR_BURSTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case FMC2_SYNC_READ_SYNC_WRITE_NOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case FMC2_SYNC_READ_ASYNC_WRITE_NOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Type of transaction not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (bcr & FMC2_BCR_EXTMOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) regmap_update_bits(ebi->regmap, FMC2_BWTR(cs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) bwtr_mask, bwtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) regmap_update_bits(ebi->regmap, FMC2_BTR(cs), btr_mask, btr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) regmap_update_bits(ebi->regmap, FMC2_BCR(cs), bcr_mask, bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static int stm32_fmc2_ebi_set_buswidth(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) switch (setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case FMC2_BUSWIDTH_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) case FMC2_BUSWIDTH_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Buswidth not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MWID, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int stm32_fmc2_ebi_set_cpsize(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) switch (setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) case FMC2_CPSIZE_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) case FMC2_CPSIZE_128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) case FMC2_CPSIZE_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) case FMC2_CPSIZE_512:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) case FMC2_CPSIZE_1024:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* Cpsize not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_CPSIZE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int stm32_fmc2_ebi_set_bl_setup(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) val = min_t(u32, setup, FMC2_BCR_NBLSET_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) val = FIELD_PREP(FMC2_BCR_NBLSET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_NBLSET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) u32 bcr, bxtr, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) u32 val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (prop->reg_type == FMC2_REG_BWTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) val = min_t(u32, setup, FMC2_BXTR_ADDSET_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) val = FIELD_PREP(FMC2_BXTR_ADDSET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_ADDSET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int stm32_fmc2_ebi_set_address_hold(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) u32 val, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) val = clamp_val(setup, 1, FMC2_BXTR_ADDHLD_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) val = FIELD_PREP(FMC2_BXTR_ADDHLD, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_ADDHLD, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static int stm32_fmc2_ebi_set_data_setup(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u32 val, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) val = clamp_val(setup, 1, FMC2_BXTR_DATAST_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) val = FIELD_PREP(FMC2_BXTR_DATAST, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_DATAST, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int stm32_fmc2_ebi_set_bus_turnaround(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) u32 val, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) val = setup ? min_t(u32, setup - 1, FMC2_BXTR_BUSTURN_MAX) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) val = FIELD_PREP(FMC2_BXTR_BUSTURN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_BUSTURN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int stm32_fmc2_ebi_set_data_hold(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) u32 val, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (prop->reg_type == FMC2_REG_BWTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) val = setup ? min_t(u32, setup - 1, FMC2_BXTR_DATAHLD_MAX) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) val = min_t(u32, setup, FMC2_BXTR_DATAHLD_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) val = FIELD_PREP(FMC2_BXTR_DATAHLD, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_DATAHLD, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int stm32_fmc2_ebi_set_clk_period(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) val = FIELD_PREP(FMC2_BTR_CLKDIV, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) val = setup > 1 ? min_t(u32, setup - 2, FMC2_BTR_DATLAT_MAX) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) val = FIELD_PREP(FMC2_BTR_DATLAT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_DATLAT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) int cs, u32 setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) u32 old_val, new_val, pcscntr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (setup < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /* Enable counter for the bank */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) regmap_update_bits(ebi->regmap, FMC2_PCSCNTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) FMC2_PCSCNTR_CNTBEN(cs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) FMC2_PCSCNTR_CNTBEN(cs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) new_val = min_t(u32, setup - 1, FMC2_PCSCNTR_CSCOUNT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) old_val = FIELD_GET(FMC2_PCSCNTR_CSCOUNT, pcscntr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (old_val && new_val > old_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* Keep current counter value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) new_val = FIELD_PREP(FMC2_PCSCNTR_CSCOUNT, new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) regmap_update_bits(ebi->regmap, FMC2_PCSCNTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) FMC2_PCSCNTR_CSCOUNT, new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* st,fmc2-ebi-cs-trans-type must be the first property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .name = "st,fmc2-ebi-cs-transaction-type",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .mprop = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) .set = stm32_fmc2_ebi_set_trans_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) .name = "st,fmc2-ebi-cs-cclk-enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) .bprop = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) .reg_type = FMC2_REG_BCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) .reg_mask = FMC2_BCR1_CCLKEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .check = stm32_fmc2_ebi_check_cclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .set = stm32_fmc2_ebi_set_bit_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .name = "st,fmc2-ebi-cs-mux-enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .bprop = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) .reg_type = FMC2_REG_BCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) .reg_mask = FMC2_BCR_MUXEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) .check = stm32_fmc2_ebi_check_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .set = stm32_fmc2_ebi_set_bit_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) .name = "st,fmc2-ebi-cs-buswidth",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) .reset_val = FMC2_BUSWIDTH_16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) .set = stm32_fmc2_ebi_set_buswidth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .name = "st,fmc2-ebi-cs-waitpol-high",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) .bprop = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) .reg_type = FMC2_REG_BCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .reg_mask = FMC2_BCR_WAITPOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .set = stm32_fmc2_ebi_set_bit_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .name = "st,fmc2-ebi-cs-waitcfg-enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .bprop = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .reg_type = FMC2_REG_BCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .reg_mask = FMC2_BCR_WAITCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .check = stm32_fmc2_ebi_check_waitcfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) .set = stm32_fmc2_ebi_set_bit_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .name = "st,fmc2-ebi-cs-wait-enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .bprop = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .reg_type = FMC2_REG_BCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .reg_mask = FMC2_BCR_WAITEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .check = stm32_fmc2_ebi_check_sync_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .set = stm32_fmc2_ebi_set_bit_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .name = "st,fmc2-ebi-cs-asyncwait-enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .bprop = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) .reg_type = FMC2_REG_BCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) .reg_mask = FMC2_BCR_ASYNCWAIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .check = stm32_fmc2_ebi_check_async_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .set = stm32_fmc2_ebi_set_bit_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .name = "st,fmc2-ebi-cs-cpsize",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) .check = stm32_fmc2_ebi_check_cpsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) .set = stm32_fmc2_ebi_set_cpsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) .name = "st,fmc2-ebi-cs-byte-lane-setup-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .set = stm32_fmc2_ebi_set_bl_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .name = "st,fmc2-ebi-cs-address-setup-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .reg_type = FMC2_REG_BTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) .reset_val = FMC2_BXTR_ADDSET_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .check = stm32_fmc2_ebi_check_async_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) .set = stm32_fmc2_ebi_set_address_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) .name = "st,fmc2-ebi-cs-address-hold-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .reg_type = FMC2_REG_BTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .reset_val = FMC2_BXTR_ADDHLD_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .check = stm32_fmc2_ebi_check_address_hold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .set = stm32_fmc2_ebi_set_address_hold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .name = "st,fmc2-ebi-cs-data-setup-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .reg_type = FMC2_REG_BTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .reset_val = FMC2_BXTR_DATAST_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .check = stm32_fmc2_ebi_check_async_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) .set = stm32_fmc2_ebi_set_data_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .name = "st,fmc2-ebi-cs-bus-turnaround-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .reg_type = FMC2_REG_BTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .set = stm32_fmc2_ebi_set_bus_turnaround,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .name = "st,fmc2-ebi-cs-data-hold-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .reg_type = FMC2_REG_BTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) .check = stm32_fmc2_ebi_check_async_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .set = stm32_fmc2_ebi_set_data_hold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .name = "st,fmc2-ebi-cs-clk-period-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .reset_val = FMC2_BTR_CLKDIV_MAX + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .check = stm32_fmc2_ebi_check_clk_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .set = stm32_fmc2_ebi_set_clk_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .name = "st,fmc2-ebi-cs-data-latency-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .check = stm32_fmc2_ebi_check_sync_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .calculate = stm32_fmc2_ebi_ns_to_clk_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .set = stm32_fmc2_ebi_set_data_latency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .name = "st,fmc2-ebi-cs-write-address-setup-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) .reg_type = FMC2_REG_BWTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .reset_val = FMC2_BXTR_ADDSET_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .check = stm32_fmc2_ebi_check_async_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .set = stm32_fmc2_ebi_set_address_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .name = "st,fmc2-ebi-cs-write-address-hold-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .reg_type = FMC2_REG_BWTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .reset_val = FMC2_BXTR_ADDHLD_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .check = stm32_fmc2_ebi_check_address_hold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .set = stm32_fmc2_ebi_set_address_hold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .name = "st,fmc2-ebi-cs-write-data-setup-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .reg_type = FMC2_REG_BWTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .reset_val = FMC2_BXTR_DATAST_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .check = stm32_fmc2_ebi_check_async_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .set = stm32_fmc2_ebi_set_data_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) .reg_type = FMC2_REG_BWTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .set = stm32_fmc2_ebi_set_bus_turnaround,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .name = "st,fmc2-ebi-cs-write-data-hold-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .reg_type = FMC2_REG_BWTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .check = stm32_fmc2_ebi_check_async_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) .set = stm32_fmc2_ebi_set_data_hold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .name = "st,fmc2-ebi-cs-max-low-pulse-ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .set = stm32_fmc2_ebi_set_max_low_pulse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct device_node *dev_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) const struct stm32_fmc2_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct device *dev = ebi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) u32 setup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (!prop->set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_err(dev, "property %s is not well defined\n", prop->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (prop->check && prop->check(ebi, prop, cs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* Skeep this property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (prop->bprop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) bool bprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) bprop = of_property_read_bool(dev_node, prop->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (prop->mprop && !bprop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) dev_err(dev, "mandatory property %s not defined in the device tree\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) prop->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (bprop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) setup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ret = of_property_read_u32(dev_node, prop->name, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (prop->mprop && ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) dev_err(dev, "mandatory property %s not defined in the device tree\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) prop->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) setup = prop->reset_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) else if (prop->calculate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) setup = prop->calculate(ebi, cs, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) setup = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return prop->set(ebi, prop, cs, setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static void stm32_fmc2_ebi_enable_bank(struct stm32_fmc2_ebi *ebi, int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) regmap_update_bits(ebi->regmap, FMC2_BCR(cs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) FMC2_BCR_MBKEN, FMC2_BCR_MBKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static void stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) unsigned int cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) unsigned int cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) regmap_write(ebi->regmap, FMC2_BCR(cs), ebi->bcr[cs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) regmap_write(ebi->regmap, FMC2_BTR(cs), ebi->btr[cs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) regmap_write(ebi->regmap, FMC2_BWTR(cs), ebi->bwtr[cs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) regmap_write(ebi->regmap, FMC2_PCSCNTR, ebi->pcscntr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) unsigned int cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!(ebi->bank_assigned & BIT(cs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) stm32_fmc2_ebi_disable_bank(ebi, cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* NWAIT signal can not be connected to EBI controller and NAND controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) unsigned int cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) u32 bcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (!(ebi->bank_assigned & BIT(cs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) ebi->bank_assigned & BIT(FMC2_NAND))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) regmap_update_bits(ebi->regmap, FMC2_BCR1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static void stm32_fmc2_ebi_disable(struct stm32_fmc2_ebi *ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) regmap_update_bits(ebi->regmap, FMC2_BCR1, FMC2_BCR1_FMC2EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct device_node *dev_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) u32 cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) stm32_fmc2_ebi_disable_bank(ebi, cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) for (i = 0; i < ARRAY_SIZE(stm32_fmc2_child_props); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) const struct stm32_fmc2_prop *p = &stm32_fmc2_child_props[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) ret = stm32_fmc2_ebi_parse_prop(ebi, dev_node, p, cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) dev_err(ebi->dev, "property %s could not be set: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) p->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) stm32_fmc2_ebi_enable_bank(ebi, cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct device *dev = ebi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) bool child_found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) u32 bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) for_each_available_child_of_node(dev->of_node, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) ret = of_property_read_u32(child, "reg", &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) dev_err(dev, "could not retrieve reg property: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (bank >= FMC2_MAX_BANKS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) dev_err(dev, "invalid reg value: %d\n", bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ebi->bank_assigned & BIT(bank)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) dev_err(dev, "bank already assigned: %d\n", bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (bank < FMC2_MAX_EBI_CE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dev_err(dev, "setup chip select %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) bank, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) ebi->bank_assigned |= BIT(bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) child_found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!child_found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) dev_warn(dev, "no subnodes found, disable the driver.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) stm32_fmc2_ebi_enable(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return of_platform_populate(dev->of_node, NULL, NULL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static int stm32_fmc2_ebi_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct stm32_fmc2_ebi *ebi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct reset_control *rstc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ebi = devm_kzalloc(&pdev->dev, sizeof(*ebi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (!ebi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) ebi->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) ebi->regmap = device_node_to_regmap(dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (IS_ERR(ebi->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return PTR_ERR(ebi->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ebi->clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (IS_ERR(ebi->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return PTR_ERR(ebi->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) rstc = devm_reset_control_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (PTR_ERR(rstc) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) ret = clk_prepare_enable(ebi->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (!IS_ERR(rstc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) reset_control_assert(rstc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) reset_control_deassert(rstc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ret = stm32_fmc2_ebi_parse_dt(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) goto err_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) stm32_fmc2_ebi_save_setup(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) platform_set_drvdata(pdev, ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) err_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) stm32_fmc2_ebi_disable_banks(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) stm32_fmc2_ebi_disable(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) clk_disable_unprepare(ebi->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) static int stm32_fmc2_ebi_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct stm32_fmc2_ebi *ebi = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) of_platform_depopulate(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) stm32_fmc2_ebi_disable_banks(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) stm32_fmc2_ebi_disable(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) clk_disable_unprepare(ebi->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static int __maybe_unused stm32_fmc2_ebi_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) stm32_fmc2_ebi_disable(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) clk_disable_unprepare(ebi->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) pinctrl_pm_select_sleep_state(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static int __maybe_unused stm32_fmc2_ebi_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) pinctrl_pm_select_default_state(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) ret = clk_prepare_enable(ebi->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) stm32_fmc2_ebi_set_setup(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) stm32_fmc2_ebi_enable(ebi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static SIMPLE_DEV_PM_OPS(stm32_fmc2_ebi_pm_ops, stm32_fmc2_ebi_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) stm32_fmc2_ebi_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static const struct of_device_id stm32_fmc2_ebi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) {.compatible = "st,stm32mp1-fmc2-ebi"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) MODULE_DEVICE_TABLE(of, stm32_fmc2_ebi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static struct platform_driver stm32_fmc2_ebi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .probe = stm32_fmc2_ebi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) .remove = stm32_fmc2_ebi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .name = "stm32_fmc2_ebi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) .of_match_table = stm32_fmc2_ebi_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) .pm = &stm32_fmc2_ebi_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) module_platform_driver(stm32_fmc2_ebi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) MODULE_ALIAS("platform:stm32_fmc2_ebi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) MODULE_AUTHOR("Christophe Kerello <christophe.kerello@st.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 ebi driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) MODULE_LICENSE("GPL v2");