root/drivers/fpga/socfpga-a10.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. socfpga_a10_fpga_writeable_reg
  2. socfpga_a10_fpga_readable_reg
  3. socfpga_a10_fpga_set_cfg_width
  4. socfpga_a10_fpga_generate_dclks
  5. socfpga_a10_fpga_encrypted
  6. socfpga_a10_fpga_compressed
  7. socfpga_a10_fpga_get_cd_ratio
  8. socfpga_a10_fpga_set_cdratio
  9. socfpga_a10_fpga_read_stat
  10. socfpga_a10_fpga_wait_for_pr_ready
  11. socfpga_a10_fpga_wait_for_pr_done
  12. socfpga_a10_fpga_write_init
  13. socfpga_a10_fpga_write
  14. socfpga_a10_fpga_write_complete
  15. socfpga_a10_fpga_state
  16. socfpga_a10_fpga_probe
  17. socfpga_a10_fpga_remove

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

/* [<][>][^][v][top][bottom][index][help] */