^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) * FPGA Manager Driver for Altera Arria10 SoCFPGA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015-2016 Altera Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^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/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/fpga/fpga-mgr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define A10_FPGAMGR_DCLKCNT_OFST 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define A10_FPGAMGR_DCLKSTAT_OFST 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define A10_FPGAMGR_IMGCFG_CTL_00_OFST 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define A10_FPGAMGR_IMGCFG_CTL_01_OFST 0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define A10_FPGAMGR_IMGCFG_CTL_02_OFST 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define A10_FPGAMGR_IMGCFG_STAT_OFST 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define A10_FPGAMGR_DCLKSTAT_DCLKDONE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK (BIT(16) | BIT(17))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK (BIT(16) | BIT(17) | BIT(18))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* FPGA CD Ratio Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define CDRATIO_x1 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define CDRATIO_x2 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define CDRATIO_x4 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define CDRATIO_x8 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Configuration width 16/32 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define CFGWDTH_32 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define CFGWDTH_16 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * struct a10_fpga_priv - private data for fpga manager
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * @regmap: regmap for register access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @fpga_data_addr: iomap for single address data register to FPGA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @clk: clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct a10_fpga_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void __iomem *fpga_data_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static bool socfpga_a10_fpga_writeable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) case A10_FPGAMGR_DCLKCNT_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) case A10_FPGAMGR_DCLKSTAT_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static bool socfpga_a10_fpga_readable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case A10_FPGAMGR_DCLKCNT_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case A10_FPGAMGR_DCLKSTAT_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case A10_FPGAMGR_IMGCFG_STAT_OFST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static const struct regmap_config socfpga_a10_fpga_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .writeable_reg = socfpga_a10_fpga_writeable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .readable_reg = socfpga_a10_fpga_readable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .max_register = A10_FPGAMGR_IMGCFG_STAT_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .cache_type = REGCACHE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * from the register map description of cdratio in imgcfg_ctrl_02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Normal Configuration : 32bit Passive Parallel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * Partial Reconfiguration : 16bit Passive Parallel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void socfpga_a10_fpga_set_cfg_width(struct a10_fpga_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) width <<= A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void socfpga_a10_fpga_generate_dclks(struct a10_fpga_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Clear any existing DONE status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) A10_FPGAMGR_DCLKSTAT_DCLKDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Issue the DCLK regmap. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) regmap_write(priv->regmap, A10_FPGAMGR_DCLKCNT_OFST, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* wait till the dclkcnt done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) regmap_read_poll_timeout(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) val, 1, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Clear DONE status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) A10_FPGAMGR_DCLKSTAT_DCLKDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define RBF_ENCRYPTION_MODE_OFFSET 69
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define RBF_DECOMPRESS_OFFSET 229
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int socfpga_a10_fpga_encrypted(u32 *buf32, size_t buf32_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (buf32_size < RBF_ENCRYPTION_MODE_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Is the bitstream encrypted? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return ((buf32[RBF_ENCRYPTION_MODE_OFFSET] >> 2) & 3) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int socfpga_a10_fpga_compressed(u32 *buf32, size_t buf32_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (buf32_size < RBF_DECOMPRESS_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* Is the bitstream compressed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return !((buf32[RBF_DECOMPRESS_OFFSET] >> 1) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static unsigned int socfpga_a10_fpga_get_cd_ratio(unsigned int cfg_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) bool encrypt, bool compress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned int cd_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * cd ratio is dependent on cfg width and whether the bitstream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * is encrypted and/or compressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * | width | encr. | compr. | cd ratio |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * | 16 | 0 | 0 | 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * | 16 | 0 | 1 | 4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * | 16 | 1 | 0 | 2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * | 16 | 1 | 1 | 4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * | 32 | 0 | 0 | 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * | 32 | 0 | 1 | 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * | 32 | 1 | 0 | 4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * | 32 | 1 | 1 | 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (!compress && !encrypt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return CDRATIO_x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (compress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cd_ratio = CDRATIO_x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) cd_ratio = CDRATIO_x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* If 32 bit, double the cd ratio by incrementing the field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (cfg_width == CFGWDTH_32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cd_ratio += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return cd_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int socfpga_a10_fpga_set_cdratio(struct fpga_manager *mgr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int cfg_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct a10_fpga_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned int cd_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int encrypt, compress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) encrypt = socfpga_a10_fpga_encrypted((u32 *)buf, count / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (encrypt < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) compress = socfpga_a10_fpga_compressed((u32 *)buf, count / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (compress < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) cd_ratio = socfpga_a10_fpga_get_cd_ratio(cfg_width, encrypt, compress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cd_ratio << A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static u32 socfpga_a10_fpga_read_stat(struct a10_fpga_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) regmap_read(priv->regmap, A10_FPGAMGR_IMGCFG_STAT_OFST, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int socfpga_a10_fpga_wait_for_pr_ready(struct a10_fpga_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u32 reg, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) for (i = 0; i < 10 ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) reg = socfpga_a10_fpga_read_stat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int socfpga_a10_fpga_wait_for_pr_done(struct a10_fpga_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u32 reg, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) for (i = 0; i < 10 ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) reg = socfpga_a10_fpga_read_stat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Start the FPGA programming by initialize the FPGA Manager */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int socfpga_a10_fpga_write_init(struct fpga_manager *mgr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct fpga_image_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct a10_fpga_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) unsigned int cfg_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u32 msel, stat, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (info->flags & FPGA_MGR_PARTIAL_RECONFIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) cfg_width = CFGWDTH_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Check for passive parallel (msel == 000 or 001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) msel = socfpga_a10_fpga_read_stat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) msel &= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) msel >>= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if ((msel != 0) && (msel != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dev_dbg(&mgr->dev, "Fail: invalid msel=%d\n", msel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* Make sure no external devices are interfering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) stat = socfpga_a10_fpga_read_stat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if ((stat & mask) != mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Set cfg width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) socfpga_a10_fpga_set_cfg_width(priv, cfg_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* Determine cd ratio from bitstream header and set cd ratio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = socfpga_a10_fpga_set_cdratio(mgr, cfg_width, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * Clear s2f_nce to enable chip select. Leave pr_request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * unasserted and override disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Set cfg_ctrl to enable s2f dclk and data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Disable overrides not needed for pr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * s2f_config==1 leaves reset deasseted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_00_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Enable override for data, dclk, nce, and pr_request to CSS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* Send some clocks to clear out any errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) socfpga_a10_fpga_generate_dclks(priv, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Assert pr_request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* Provide 2048 DCLKs before starting the config data streaming. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) socfpga_a10_fpga_generate_dclks(priv, 0x7ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* Wait for pr_ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return socfpga_a10_fpga_wait_for_pr_ready(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * write data to the FPGA data register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int socfpga_a10_fpga_write(struct fpga_manager *mgr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct a10_fpga_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) u32 *buffer_32 = (u32 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) size_t i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (count <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Write out the complete 32-bit chunks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) while (count >= sizeof(u32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) writel(buffer_32[i++], priv->fpga_data_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) count -= sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* Write out remaining non 32-bit chunks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) switch (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) writel(buffer_32[i++] & 0x00ffffff, priv->fpga_data_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) writel(buffer_32[i++] & 0x0000ffff, priv->fpga_data_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) writel(buffer_32[i++] & 0x000000ff, priv->fpga_data_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* This will never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int socfpga_a10_fpga_write_complete(struct fpga_manager *mgr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct fpga_image_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct a10_fpga_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Wait for pr_done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret = socfpga_a10_fpga_wait_for_pr_done(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* Clear pr_request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Send some clocks to clear out any errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) socfpga_a10_fpga_generate_dclks(priv, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* Disable s2f dclk and data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Deassert chip select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* Disable data, dclk, nce, and pr_request override to CSS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Return any errors regarding pr_done or pr_error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* Final check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) reg = socfpga_a10_fpga_read_stat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) dev_dbg(&mgr->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) "Timeout in final check. Status=%08xf\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct a10_fpga_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) u32 reg = socfpga_a10_fpga_read_stat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return FPGA_MGR_STATE_OPERATING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return FPGA_MGR_STATE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return FPGA_MGR_STATE_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return FPGA_MGR_STATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .state = socfpga_a10_fpga_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .write_init = socfpga_a10_fpga_write_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .write = socfpga_a10_fpga_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .write_complete = socfpga_a10_fpga_write_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int socfpga_a10_fpga_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct a10_fpga_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct fpga_manager *mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* First mmio base is for register access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) reg_base = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (IS_ERR(reg_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return PTR_ERR(reg_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /* Second mmio base is for writing FPGA image data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) priv->fpga_data_addr = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (IS_ERR(priv->fpga_data_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return PTR_ERR(priv->fpga_data_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* regmap for register access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) priv->regmap = devm_regmap_init_mmio(dev, reg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) &socfpga_a10_fpga_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (IS_ERR(priv->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) priv->clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (IS_ERR(priv->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) dev_err(dev, "no clock specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return PTR_ERR(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ret = clk_prepare_enable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) dev_err(dev, "could not enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) mgr = devm_fpga_mgr_create(dev, "SoCFPGA Arria10 FPGA Manager",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) &socfpga_a10_fpga_mgr_ops, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) platform_set_drvdata(pdev, mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ret = fpga_mgr_register(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int socfpga_a10_fpga_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct fpga_manager *mgr = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct a10_fpga_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) fpga_mgr_unregister(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static const struct of_device_id socfpga_a10_fpga_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) { .compatible = "altr,socfpga-a10-fpga-mgr", },
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static struct platform_driver socfpga_a10_fpga_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .probe = socfpga_a10_fpga_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .remove = socfpga_a10_fpga_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .name = "socfpga_a10_fpga_manager",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .of_match_table = socfpga_a10_fpga_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) module_platform_driver(socfpga_a10_fpga_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) MODULE_LICENSE("GPL v2");