root/drivers/gpu/ipu-v3/ipu-prg.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipu_prg_lookup_by_phandle
  2. ipu_prg_max_active_channels
  3. ipu_prg_present
  4. ipu_prg_format_supported
  5. ipu_prg_enable
  6. ipu_prg_disable
  7. ipu_prg_ipu_to_prg_chan
  8. ipu_prg_get_pre
  9. ipu_prg_put_pre
  10. ipu_prg_channel_disable
  11. ipu_prg_channel_configure
  12. ipu_prg_channel_configure_pending
  13. ipu_prg_probe
  14. ipu_prg_remove
  15. prg_suspend
  16. prg_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2016-2017 Lucas Stach, Pengutronix
   4  */
   5 
   6 #include <drm/drm_fourcc.h>
   7 #include <linux/clk.h>
   8 #include <linux/err.h>
   9 #include <linux/iopoll.h>
  10 #include <linux/mfd/syscon.h>
  11 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  12 #include <linux/module.h>
  13 #include <linux/of.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/pm_runtime.h>
  16 #include <linux/regmap.h>
  17 #include <video/imx-ipu-v3.h>
  18 
  19 #include "ipu-prv.h"
  20 
  21 #define IPU_PRG_CTL                             0x00
  22 #define  IPU_PRG_CTL_BYPASS(i)                  (1 << (0 + i))
  23 #define  IPU_PRG_CTL_SOFT_ARID_MASK             0x3
  24 #define  IPU_PRG_CTL_SOFT_ARID_SHIFT(i)         (8 + i * 2)
  25 #define  IPU_PRG_CTL_SOFT_ARID(i, v)            ((v & 0x3) << (8 + 2 * i))
  26 #define  IPU_PRG_CTL_SO(i)                      (1 << (16 + i))
  27 #define  IPU_PRG_CTL_VFLIP(i)                   (1 << (19 + i))
  28 #define  IPU_PRG_CTL_BLOCK_MODE(i)              (1 << (22 + i))
  29 #define  IPU_PRG_CTL_CNT_LOAD_EN(i)             (1 << (25 + i))
  30 #define  IPU_PRG_CTL_SOFTRST                    (1 << 30)
  31 #define  IPU_PRG_CTL_SHADOW_EN                  (1 << 31)
  32 
  33 #define IPU_PRG_STATUS                          0x04
  34 #define  IPU_PRG_STATUS_BUFFER0_READY(i)        (1 << (0 + i * 2))
  35 #define  IPU_PRG_STATUS_BUFFER1_READY(i)        (1 << (1 + i * 2))
  36 
  37 #define IPU_PRG_QOS                             0x08
  38 #define  IPU_PRG_QOS_ARID_MASK                  0xf
  39 #define  IPU_PRG_QOS_ARID_SHIFT(i)              (0 + i * 4)
  40 
  41 #define IPU_PRG_REG_UPDATE                      0x0c
  42 #define  IPU_PRG_REG_UPDATE_REG_UPDATE          (1 << 0)
  43 
  44 #define IPU_PRG_STRIDE(i)                       (0x10 + i * 0x4)
  45 #define  IPU_PRG_STRIDE_STRIDE_MASK             0x3fff
  46 
  47 #define IPU_PRG_CROP_LINE                       0x1c
  48 
  49 #define IPU_PRG_THD                             0x20
  50 
  51 #define IPU_PRG_BADDR(i)                        (0x24 + i * 0x4)
  52 
  53 #define IPU_PRG_OFFSET(i)                       (0x30 + i * 0x4)
  54 
  55 #define IPU_PRG_ILO(i)                          (0x3c + i * 0x4)
  56 
  57 #define IPU_PRG_HEIGHT(i)                       (0x48 + i * 0x4)
  58 #define  IPU_PRG_HEIGHT_PRE_HEIGHT_MASK         0xfff
  59 #define  IPU_PRG_HEIGHT_PRE_HEIGHT_SHIFT        0
  60 #define  IPU_PRG_HEIGHT_IPU_HEIGHT_MASK         0xfff
  61 #define  IPU_PRG_HEIGHT_IPU_HEIGHT_SHIFT        16
  62 
  63 struct ipu_prg_channel {
  64         bool                    enabled;
  65         int                     used_pre;
  66 };
  67 
  68 struct ipu_prg {
  69         struct list_head        list;
  70         struct device           *dev;
  71         int                     id;
  72 
  73         void __iomem            *regs;
  74         struct clk              *clk_ipg, *clk_axi;
  75         struct regmap           *iomuxc_gpr;
  76         struct ipu_pre          *pres[3];
  77 
  78         struct ipu_prg_channel  chan[3];
  79 };
  80 
  81 static DEFINE_MUTEX(ipu_prg_list_mutex);
  82 static LIST_HEAD(ipu_prg_list);
  83 
  84 struct ipu_prg *
  85 ipu_prg_lookup_by_phandle(struct device *dev, const char *name, int ipu_id)
  86 {
  87         struct device_node *prg_node = of_parse_phandle(dev->of_node,
  88                                                         name, 0);
  89         struct ipu_prg *prg;
  90 
  91         mutex_lock(&ipu_prg_list_mutex);
  92         list_for_each_entry(prg, &ipu_prg_list, list) {
  93                 if (prg_node == prg->dev->of_node) {
  94                         mutex_unlock(&ipu_prg_list_mutex);
  95                         device_link_add(dev, prg->dev,
  96                                         DL_FLAG_AUTOREMOVE_CONSUMER);
  97                         prg->id = ipu_id;
  98                         of_node_put(prg_node);
  99                         return prg;
 100                 }
 101         }
 102         mutex_unlock(&ipu_prg_list_mutex);
 103 
 104         of_node_put(prg_node);
 105 
 106         return NULL;
 107 }
 108 
 109 int ipu_prg_max_active_channels(void)
 110 {
 111         return ipu_pre_get_available_count();
 112 }
 113 EXPORT_SYMBOL_GPL(ipu_prg_max_active_channels);
 114 
 115 bool ipu_prg_present(struct ipu_soc *ipu)
 116 {
 117         if (ipu->prg_priv)
 118                 return true;
 119 
 120         return false;
 121 }
 122 EXPORT_SYMBOL_GPL(ipu_prg_present);
 123 
 124 bool ipu_prg_format_supported(struct ipu_soc *ipu, uint32_t format,
 125                               uint64_t modifier)
 126 {
 127         const struct drm_format_info *info = drm_format_info(format);
 128 
 129         if (info->num_planes != 1)
 130                 return false;
 131 
 132         switch (modifier) {
 133         case DRM_FORMAT_MOD_LINEAR:
 134         case DRM_FORMAT_MOD_VIVANTE_TILED:
 135         case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
 136                 return true;
 137         default:
 138                 return false;
 139         }
 140 }
 141 EXPORT_SYMBOL_GPL(ipu_prg_format_supported);
 142 
 143 int ipu_prg_enable(struct ipu_soc *ipu)
 144 {
 145         struct ipu_prg *prg = ipu->prg_priv;
 146 
 147         if (!prg)
 148                 return 0;
 149 
 150         return pm_runtime_get_sync(prg->dev);
 151 }
 152 EXPORT_SYMBOL_GPL(ipu_prg_enable);
 153 
 154 void ipu_prg_disable(struct ipu_soc *ipu)
 155 {
 156         struct ipu_prg *prg = ipu->prg_priv;
 157 
 158         if (!prg)
 159                 return;
 160 
 161         pm_runtime_put(prg->dev);
 162 }
 163 EXPORT_SYMBOL_GPL(ipu_prg_disable);
 164 
 165 /*
 166  * The channel configuartion functions below are not thread safe, as they
 167  * must be only called from the atomic commit path in the DRM driver, which
 168  * is properly serialized.
 169  */
 170 static int ipu_prg_ipu_to_prg_chan(int ipu_chan)
 171 {
 172         /*
 173          * This isn't clearly documented in the RM, but IPU to PRG channel
 174          * assignment is fixed, as only with this mapping the control signals
 175          * match up.
 176          */
 177         switch (ipu_chan) {
 178         case IPUV3_CHANNEL_MEM_BG_SYNC:
 179                 return 0;
 180         case IPUV3_CHANNEL_MEM_FG_SYNC:
 181                 return 1;
 182         case IPUV3_CHANNEL_MEM_DC_SYNC:
 183                 return 2;
 184         default:
 185                 return -EINVAL;
 186         }
 187 }
 188 
 189 static int ipu_prg_get_pre(struct ipu_prg *prg, int prg_chan)
 190 {
 191         int i, ret;
 192 
 193         /* channel 0 is special as it is hardwired to one of the PREs */
 194         if (prg_chan == 0) {
 195                 ret = ipu_pre_get(prg->pres[0]);
 196                 if (ret)
 197                         goto fail;
 198                 prg->chan[prg_chan].used_pre = 0;
 199                 return 0;
 200         }
 201 
 202         for (i = 1; i < 3; i++) {
 203                 ret = ipu_pre_get(prg->pres[i]);
 204                 if (!ret) {
 205                         u32 val, mux;
 206                         int shift;
 207 
 208                         prg->chan[prg_chan].used_pre = i;
 209 
 210                         /* configure the PRE to PRG channel mux */
 211                         shift = (i == 1) ? 12 : 14;
 212                         mux = (prg->id << 1) | (prg_chan - 1);
 213                         regmap_update_bits(prg->iomuxc_gpr, IOMUXC_GPR5,
 214                                            0x3 << shift, mux << shift);
 215 
 216                         /* check other mux, must not point to same channel */
 217                         shift = (i == 1) ? 14 : 12;
 218                         regmap_read(prg->iomuxc_gpr, IOMUXC_GPR5, &val);
 219                         if (((val >> shift) & 0x3) == mux) {
 220                                 regmap_update_bits(prg->iomuxc_gpr, IOMUXC_GPR5,
 221                                                    0x3 << shift,
 222                                                    (mux ^ 0x1) << shift);
 223                         }
 224 
 225                         return 0;
 226                 }
 227         }
 228 
 229 fail:
 230         dev_err(prg->dev, "could not get PRE for PRG chan %d", prg_chan);
 231         return ret;
 232 }
 233 
 234 static void ipu_prg_put_pre(struct ipu_prg *prg, int prg_chan)
 235 {
 236         struct ipu_prg_channel *chan = &prg->chan[prg_chan];
 237 
 238         ipu_pre_put(prg->pres[chan->used_pre]);
 239         chan->used_pre = -1;
 240 }
 241 
 242 void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan)
 243 {
 244         int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
 245         struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
 246         struct ipu_prg_channel *chan;
 247         u32 val;
 248 
 249         if (prg_chan < 0)
 250                 return;
 251 
 252         chan = &prg->chan[prg_chan];
 253         if (!chan->enabled)
 254                 return;
 255 
 256         pm_runtime_get_sync(prg->dev);
 257 
 258         val = readl(prg->regs + IPU_PRG_CTL);
 259         val |= IPU_PRG_CTL_BYPASS(prg_chan);
 260         writel(val, prg->regs + IPU_PRG_CTL);
 261 
 262         val = IPU_PRG_REG_UPDATE_REG_UPDATE;
 263         writel(val, prg->regs + IPU_PRG_REG_UPDATE);
 264 
 265         pm_runtime_put(prg->dev);
 266 
 267         ipu_prg_put_pre(prg, prg_chan);
 268 
 269         chan->enabled = false;
 270 }
 271 EXPORT_SYMBOL_GPL(ipu_prg_channel_disable);
 272 
 273 int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan,
 274                               unsigned int axi_id, unsigned int width,
 275                               unsigned int height, unsigned int stride,
 276                               u32 format, uint64_t modifier, unsigned long *eba)
 277 {
 278         int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
 279         struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
 280         struct ipu_prg_channel *chan;
 281         u32 val;
 282         int ret;
 283 
 284         if (prg_chan < 0)
 285                 return prg_chan;
 286 
 287         chan = &prg->chan[prg_chan];
 288 
 289         if (chan->enabled) {
 290                 ipu_pre_update(prg->pres[chan->used_pre], *eba);
 291                 return 0;
 292         }
 293 
 294         ret = ipu_prg_get_pre(prg, prg_chan);
 295         if (ret)
 296                 return ret;
 297 
 298         ipu_pre_configure(prg->pres[chan->used_pre],
 299                           width, height, stride, format, modifier, *eba);
 300 
 301 
 302         pm_runtime_get_sync(prg->dev);
 303 
 304         val = (stride - 1) & IPU_PRG_STRIDE_STRIDE_MASK;
 305         writel(val, prg->regs + IPU_PRG_STRIDE(prg_chan));
 306 
 307         val = ((height & IPU_PRG_HEIGHT_PRE_HEIGHT_MASK) <<
 308                IPU_PRG_HEIGHT_PRE_HEIGHT_SHIFT) |
 309               ((height & IPU_PRG_HEIGHT_IPU_HEIGHT_MASK) <<
 310                IPU_PRG_HEIGHT_IPU_HEIGHT_SHIFT);
 311         writel(val, prg->regs + IPU_PRG_HEIGHT(prg_chan));
 312 
 313         val = ipu_pre_get_baddr(prg->pres[chan->used_pre]);
 314         *eba = val;
 315         writel(val, prg->regs + IPU_PRG_BADDR(prg_chan));
 316 
 317         val = readl(prg->regs + IPU_PRG_CTL);
 318         /* config AXI ID */
 319         val &= ~(IPU_PRG_CTL_SOFT_ARID_MASK <<
 320                  IPU_PRG_CTL_SOFT_ARID_SHIFT(prg_chan));
 321         val |= IPU_PRG_CTL_SOFT_ARID(prg_chan, axi_id);
 322         /* enable channel */
 323         val &= ~IPU_PRG_CTL_BYPASS(prg_chan);
 324         writel(val, prg->regs + IPU_PRG_CTL);
 325 
 326         val = IPU_PRG_REG_UPDATE_REG_UPDATE;
 327         writel(val, prg->regs + IPU_PRG_REG_UPDATE);
 328 
 329         /* wait for both double buffers to be filled */
 330         readl_poll_timeout(prg->regs + IPU_PRG_STATUS, val,
 331                            (val & IPU_PRG_STATUS_BUFFER0_READY(prg_chan)) &&
 332                            (val & IPU_PRG_STATUS_BUFFER1_READY(prg_chan)),
 333                            5, 1000);
 334 
 335         pm_runtime_put(prg->dev);
 336 
 337         chan->enabled = true;
 338         return 0;
 339 }
 340 EXPORT_SYMBOL_GPL(ipu_prg_channel_configure);
 341 
 342 bool ipu_prg_channel_configure_pending(struct ipuv3_channel *ipu_chan)
 343 {
 344         int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
 345         struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
 346         struct ipu_prg_channel *chan;
 347 
 348         if (prg_chan < 0)
 349                 return false;
 350 
 351         chan = &prg->chan[prg_chan];
 352         WARN_ON(!chan->enabled);
 353 
 354         return ipu_pre_update_pending(prg->pres[chan->used_pre]);
 355 }
 356 EXPORT_SYMBOL_GPL(ipu_prg_channel_configure_pending);
 357 
 358 static int ipu_prg_probe(struct platform_device *pdev)
 359 {
 360         struct device *dev = &pdev->dev;
 361         struct resource *res;
 362         struct ipu_prg *prg;
 363         u32 val;
 364         int i, ret;
 365 
 366         prg = devm_kzalloc(dev, sizeof(*prg), GFP_KERNEL);
 367         if (!prg)
 368                 return -ENOMEM;
 369 
 370         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 371         prg->regs = devm_ioremap_resource(&pdev->dev, res);
 372         if (IS_ERR(prg->regs))
 373                 return PTR_ERR(prg->regs);
 374 
 375 
 376         prg->clk_ipg = devm_clk_get(dev, "ipg");
 377         if (IS_ERR(prg->clk_ipg))
 378                 return PTR_ERR(prg->clk_ipg);
 379 
 380         prg->clk_axi = devm_clk_get(dev, "axi");
 381         if (IS_ERR(prg->clk_axi))
 382                 return PTR_ERR(prg->clk_axi);
 383 
 384         prg->iomuxc_gpr =
 385                 syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
 386         if (IS_ERR(prg->iomuxc_gpr))
 387                 return PTR_ERR(prg->iomuxc_gpr);
 388 
 389         for (i = 0; i < 3; i++) {
 390                 prg->pres[i] = ipu_pre_lookup_by_phandle(dev, "fsl,pres", i);
 391                 if (!prg->pres[i])
 392                         return -EPROBE_DEFER;
 393         }
 394 
 395         ret = clk_prepare_enable(prg->clk_ipg);
 396         if (ret)
 397                 return ret;
 398 
 399         ret = clk_prepare_enable(prg->clk_axi);
 400         if (ret) {
 401                 clk_disable_unprepare(prg->clk_ipg);
 402                 return ret;
 403         }
 404 
 405         /* init to free running mode */
 406         val = readl(prg->regs + IPU_PRG_CTL);
 407         val |= IPU_PRG_CTL_SHADOW_EN;
 408         writel(val, prg->regs + IPU_PRG_CTL);
 409 
 410         /* disable address threshold */
 411         writel(0xffffffff, prg->regs + IPU_PRG_THD);
 412 
 413         pm_runtime_set_active(dev);
 414         pm_runtime_enable(dev);
 415 
 416         prg->dev = dev;
 417         platform_set_drvdata(pdev, prg);
 418         mutex_lock(&ipu_prg_list_mutex);
 419         list_add(&prg->list, &ipu_prg_list);
 420         mutex_unlock(&ipu_prg_list_mutex);
 421 
 422         return 0;
 423 }
 424 
 425 static int ipu_prg_remove(struct platform_device *pdev)
 426 {
 427         struct ipu_prg *prg = platform_get_drvdata(pdev);
 428 
 429         mutex_lock(&ipu_prg_list_mutex);
 430         list_del(&prg->list);
 431         mutex_unlock(&ipu_prg_list_mutex);
 432 
 433         return 0;
 434 }
 435 
 436 #ifdef CONFIG_PM
 437 static int prg_suspend(struct device *dev)
 438 {
 439         struct ipu_prg *prg = dev_get_drvdata(dev);
 440 
 441         clk_disable_unprepare(prg->clk_axi);
 442         clk_disable_unprepare(prg->clk_ipg);
 443 
 444         return 0;
 445 }
 446 
 447 static int prg_resume(struct device *dev)
 448 {
 449         struct ipu_prg *prg = dev_get_drvdata(dev);
 450         int ret;
 451 
 452         ret = clk_prepare_enable(prg->clk_ipg);
 453         if (ret)
 454                 return ret;
 455 
 456         ret = clk_prepare_enable(prg->clk_axi);
 457         if (ret) {
 458                 clk_disable_unprepare(prg->clk_ipg);
 459                 return ret;
 460         }
 461 
 462         return 0;
 463 }
 464 #endif
 465 
 466 static const struct dev_pm_ops prg_pm_ops = {
 467         SET_RUNTIME_PM_OPS(prg_suspend, prg_resume, NULL)
 468 };
 469 
 470 static const struct of_device_id ipu_prg_dt_ids[] = {
 471         { .compatible = "fsl,imx6qp-prg", },
 472         { /* sentinel */ },
 473 };
 474 
 475 struct platform_driver ipu_prg_drv = {
 476         .probe          = ipu_prg_probe,
 477         .remove         = ipu_prg_remove,
 478         .driver         = {
 479                 .name   = "imx-ipu-prg",
 480                 .pm     = &prg_pm_ops,
 481                 .of_match_table = ipu_prg_dt_ids,
 482         },
 483 };

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