linux/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2015 MediaTek Inc.
   4 * Authors:
   5 *      YT Shen <yt.shen@mediatek.com>
   6 *      CK Hu <ck.hu@mediatek.com>
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/of.h>
  11#include <linux/of_address.h>
  12#include <linux/of_platform.h>
  13#include <linux/platform_device.h>
  14#include <linux/soc/mediatek/mtk-cmdq.h>
  15#include <drm/drm_print.h>
  16
  17#include "mtk_disp_drv.h"
  18#include "mtk_drm_drv.h"
  19#include "mtk_drm_plane.h"
  20#include "mtk_drm_ddp_comp.h"
  21#include "mtk_drm_crtc.h"
  22
  23#define DISP_OD_EN                              0x0000
  24#define DISP_OD_INTEN                           0x0008
  25#define DISP_OD_INTSTA                          0x000c
  26#define DISP_OD_CFG                             0x0020
  27#define DISP_OD_SIZE                            0x0030
  28#define DISP_DITHER_5                           0x0114
  29#define DISP_DITHER_7                           0x011c
  30#define DISP_DITHER_15                          0x013c
  31#define DISP_DITHER_16                          0x0140
  32
  33#define DISP_REG_UFO_START                      0x0000
  34
  35#define DISP_DITHER_EN                          0x0000
  36#define DITHER_EN                               BIT(0)
  37#define DISP_DITHER_CFG                         0x0020
  38#define DITHER_RELAY_MODE                       BIT(0)
  39#define DITHER_ENGINE_EN                        BIT(1)
  40#define DISP_DITHER_SIZE                        0x0030
  41
  42#define LUT_10BIT_MASK                          0x03ff
  43
  44#define OD_RELAYMODE                            BIT(0)
  45
  46#define UFO_BYPASS                              BIT(2)
  47
  48#define DISP_DITHERING                          BIT(2)
  49#define DITHER_LSB_ERR_SHIFT_R(x)               (((x) & 0x7) << 28)
  50#define DITHER_OVFLW_BIT_R(x)                   (((x) & 0x7) << 24)
  51#define DITHER_ADD_LSHIFT_R(x)                  (((x) & 0x7) << 20)
  52#define DITHER_ADD_RSHIFT_R(x)                  (((x) & 0x7) << 16)
  53#define DITHER_NEW_BIT_MODE                     BIT(0)
  54#define DITHER_LSB_ERR_SHIFT_B(x)               (((x) & 0x7) << 28)
  55#define DITHER_OVFLW_BIT_B(x)                   (((x) & 0x7) << 24)
  56#define DITHER_ADD_LSHIFT_B(x)                  (((x) & 0x7) << 20)
  57#define DITHER_ADD_RSHIFT_B(x)                  (((x) & 0x7) << 16)
  58#define DITHER_LSB_ERR_SHIFT_G(x)               (((x) & 0x7) << 12)
  59#define DITHER_OVFLW_BIT_G(x)                   (((x) & 0x7) << 8)
  60#define DITHER_ADD_LSHIFT_G(x)                  (((x) & 0x7) << 4)
  61#define DITHER_ADD_RSHIFT_G(x)                  (((x) & 0x7) << 0)
  62
  63struct mtk_ddp_comp_dev {
  64        struct clk *clk;
  65        void __iomem *regs;
  66        struct cmdq_client_reg cmdq_reg;
  67};
  68
  69void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
  70                   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
  71                   unsigned int offset)
  72{
  73#if IS_REACHABLE(CONFIG_MTK_CMDQ)
  74        if (cmdq_pkt)
  75                cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
  76                               cmdq_reg->offset + offset, value);
  77        else
  78#endif
  79                writel(value, regs + offset);
  80}
  81
  82void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
  83                           struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
  84                           unsigned int offset)
  85{
  86#if IS_REACHABLE(CONFIG_MTK_CMDQ)
  87        if (cmdq_pkt)
  88                cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
  89                               cmdq_reg->offset + offset, value);
  90        else
  91#endif
  92                writel_relaxed(value, regs + offset);
  93}
  94
  95void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
  96                        struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
  97                        unsigned int offset, unsigned int mask)
  98{
  99#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 100        if (cmdq_pkt) {
 101                cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
 102                                    cmdq_reg->offset + offset, value, mask);
 103        } else {
 104#endif
 105                u32 tmp = readl(regs + offset);
 106
 107                tmp = (tmp & ~mask) | (value & mask);
 108                writel(tmp, regs + offset);
 109#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 110        }
 111#endif
 112}
 113
 114static int mtk_ddp_clk_enable(struct device *dev)
 115{
 116        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 117
 118        return clk_prepare_enable(priv->clk);
 119}
 120
 121static void mtk_ddp_clk_disable(struct device *dev)
 122{
 123        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 124
 125        clk_disable_unprepare(priv->clk);
 126}
 127
 128void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 129                           unsigned int bpc, unsigned int cfg,
 130                           unsigned int dither_en, struct cmdq_pkt *cmdq_pkt)
 131{
 132        /* If bpc equal to 0, the dithering function didn't be enabled */
 133        if (bpc == 0)
 134                return;
 135
 136        if (bpc >= MTK_MIN_BPC) {
 137                mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
 138                mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
 139                mtk_ddp_write(cmdq_pkt,
 140                              DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
 141                              DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
 142                              DITHER_NEW_BIT_MODE,
 143                              cmdq_reg, regs, DISP_DITHER_15);
 144                mtk_ddp_write(cmdq_pkt,
 145                              DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
 146                              DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
 147                              DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
 148                              DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
 149                              cmdq_reg, regs, DISP_DITHER_16);
 150                mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
 151        }
 152}
 153
 154static void mtk_dither_set(struct device *dev, unsigned int bpc,
 155                    unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
 156{
 157        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 158
 159        mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
 160                              DISP_DITHERING, cmdq_pkt);
 161}
 162
 163static void mtk_od_config(struct device *dev, unsigned int w,
 164                          unsigned int h, unsigned int vrefresh,
 165                          unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 166{
 167        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 168
 169        mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
 170        mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
 171        mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
 172}
 173
 174static void mtk_od_start(struct device *dev)
 175{
 176        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 177
 178        writel(1, priv->regs + DISP_OD_EN);
 179}
 180
 181static void mtk_ufoe_start(struct device *dev)
 182{
 183        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 184
 185        writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
 186}
 187
 188static void mtk_dither_config(struct device *dev, unsigned int w,
 189                              unsigned int h, unsigned int vrefresh,
 190                              unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 191{
 192        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 193
 194        mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
 195        mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
 196        mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
 197                              DITHER_ENGINE_EN, cmdq_pkt);
 198}
 199
 200static void mtk_dither_start(struct device *dev)
 201{
 202        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 203
 204        writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
 205}
 206
 207static void mtk_dither_stop(struct device *dev)
 208{
 209        struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 210
 211        writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
 212}
 213
 214static const struct mtk_ddp_comp_funcs ddp_aal = {
 215        .clk_enable = mtk_aal_clk_enable,
 216        .clk_disable = mtk_aal_clk_disable,
 217        .gamma_set = mtk_aal_gamma_set,
 218        .config = mtk_aal_config,
 219        .start = mtk_aal_start,
 220        .stop = mtk_aal_stop,
 221};
 222
 223static const struct mtk_ddp_comp_funcs ddp_ccorr = {
 224        .clk_enable = mtk_ccorr_clk_enable,
 225        .clk_disable = mtk_ccorr_clk_disable,
 226        .config = mtk_ccorr_config,
 227        .start = mtk_ccorr_start,
 228        .stop = mtk_ccorr_stop,
 229        .ctm_set = mtk_ccorr_ctm_set,
 230};
 231
 232static const struct mtk_ddp_comp_funcs ddp_color = {
 233        .clk_enable = mtk_color_clk_enable,
 234        .clk_disable = mtk_color_clk_disable,
 235        .config = mtk_color_config,
 236        .start = mtk_color_start,
 237};
 238
 239static const struct mtk_ddp_comp_funcs ddp_dither = {
 240        .clk_enable = mtk_ddp_clk_enable,
 241        .clk_disable = mtk_ddp_clk_disable,
 242        .config = mtk_dither_config,
 243        .start = mtk_dither_start,
 244        .stop = mtk_dither_stop,
 245};
 246
 247static const struct mtk_ddp_comp_funcs ddp_dpi = {
 248        .start = mtk_dpi_start,
 249        .stop = mtk_dpi_stop,
 250};
 251
 252static const struct mtk_ddp_comp_funcs ddp_dsi = {
 253        .start = mtk_dsi_ddp_start,
 254        .stop = mtk_dsi_ddp_stop,
 255};
 256
 257static const struct mtk_ddp_comp_funcs ddp_gamma = {
 258        .clk_enable = mtk_gamma_clk_enable,
 259        .clk_disable = mtk_gamma_clk_disable,
 260        .gamma_set = mtk_gamma_set,
 261        .config = mtk_gamma_config,
 262        .start = mtk_gamma_start,
 263        .stop = mtk_gamma_stop,
 264};
 265
 266static const struct mtk_ddp_comp_funcs ddp_od = {
 267        .clk_enable = mtk_ddp_clk_enable,
 268        .clk_disable = mtk_ddp_clk_disable,
 269        .config = mtk_od_config,
 270        .start = mtk_od_start,
 271};
 272
 273static const struct mtk_ddp_comp_funcs ddp_ovl = {
 274        .clk_enable = mtk_ovl_clk_enable,
 275        .clk_disable = mtk_ovl_clk_disable,
 276        .config = mtk_ovl_config,
 277        .start = mtk_ovl_start,
 278        .stop = mtk_ovl_stop,
 279        .enable_vblank = mtk_ovl_enable_vblank,
 280        .disable_vblank = mtk_ovl_disable_vblank,
 281        .supported_rotations = mtk_ovl_supported_rotations,
 282        .layer_nr = mtk_ovl_layer_nr,
 283        .layer_check = mtk_ovl_layer_check,
 284        .layer_config = mtk_ovl_layer_config,
 285        .bgclr_in_on = mtk_ovl_bgclr_in_on,
 286        .bgclr_in_off = mtk_ovl_bgclr_in_off,
 287};
 288
 289static const struct mtk_ddp_comp_funcs ddp_rdma = {
 290        .clk_enable = mtk_rdma_clk_enable,
 291        .clk_disable = mtk_rdma_clk_disable,
 292        .config = mtk_rdma_config,
 293        .start = mtk_rdma_start,
 294        .stop = mtk_rdma_stop,
 295        .enable_vblank = mtk_rdma_enable_vblank,
 296        .disable_vblank = mtk_rdma_disable_vblank,
 297        .layer_nr = mtk_rdma_layer_nr,
 298        .layer_config = mtk_rdma_layer_config,
 299};
 300
 301static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 302        .clk_enable = mtk_ddp_clk_enable,
 303        .clk_disable = mtk_ddp_clk_disable,
 304        .start = mtk_ufoe_start,
 305};
 306
 307static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 308        [MTK_DISP_OVL] = "ovl",
 309        [MTK_DISP_OVL_2L] = "ovl-2l",
 310        [MTK_DISP_RDMA] = "rdma",
 311        [MTK_DISP_WDMA] = "wdma",
 312        [MTK_DISP_COLOR] = "color",
 313        [MTK_DISP_CCORR] = "ccorr",
 314        [MTK_DISP_AAL] = "aal",
 315        [MTK_DISP_GAMMA] = "gamma",
 316        [MTK_DISP_DITHER] = "dither",
 317        [MTK_DISP_UFOE] = "ufoe",
 318        [MTK_DSI] = "dsi",
 319        [MTK_DPI] = "dpi",
 320        [MTK_DISP_PWM] = "pwm",
 321        [MTK_DISP_MUTEX] = "mutex",
 322        [MTK_DISP_OD] = "od",
 323        [MTK_DISP_BLS] = "bls",
 324};
 325
 326struct mtk_ddp_comp_match {
 327        enum mtk_ddp_comp_type type;
 328        int alias_id;
 329        const struct mtk_ddp_comp_funcs *funcs;
 330};
 331
 332static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 333        [DDP_COMPONENT_AAL0]    = { MTK_DISP_AAL,       0, &ddp_aal },
 334        [DDP_COMPONENT_AAL1]    = { MTK_DISP_AAL,       1, &ddp_aal },
 335        [DDP_COMPONENT_BLS]     = { MTK_DISP_BLS,       0, NULL },
 336        [DDP_COMPONENT_CCORR]   = { MTK_DISP_CCORR,     0, &ddp_ccorr },
 337        [DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR,     0, &ddp_color },
 338        [DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR,     1, &ddp_color },
 339        [DDP_COMPONENT_DITHER]  = { MTK_DISP_DITHER,    0, &ddp_dither },
 340        [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, &ddp_dpi },
 341        [DDP_COMPONENT_DPI1]    = { MTK_DPI,            1, &ddp_dpi },
 342        [DDP_COMPONENT_DSI0]    = { MTK_DSI,            0, &ddp_dsi },
 343        [DDP_COMPONENT_DSI1]    = { MTK_DSI,            1, &ddp_dsi },
 344        [DDP_COMPONENT_DSI2]    = { MTK_DSI,            2, &ddp_dsi },
 345        [DDP_COMPONENT_DSI3]    = { MTK_DSI,            3, &ddp_dsi },
 346        [DDP_COMPONENT_GAMMA]   = { MTK_DISP_GAMMA,     0, &ddp_gamma },
 347        [DDP_COMPONENT_OD0]     = { MTK_DISP_OD,        0, &ddp_od },
 348        [DDP_COMPONENT_OD1]     = { MTK_DISP_OD,        1, &ddp_od },
 349        [DDP_COMPONENT_OVL0]    = { MTK_DISP_OVL,       0, &ddp_ovl },
 350        [DDP_COMPONENT_OVL1]    = { MTK_DISP_OVL,       1, &ddp_ovl },
 351        [DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L,    0, &ddp_ovl },
 352        [DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L,    1, &ddp_ovl },
 353        [DDP_COMPONENT_PWM0]    = { MTK_DISP_PWM,       0, NULL },
 354        [DDP_COMPONENT_PWM1]    = { MTK_DISP_PWM,       1, NULL },
 355        [DDP_COMPONENT_PWM2]    = { MTK_DISP_PWM,       2, NULL },
 356        [DDP_COMPONENT_RDMA0]   = { MTK_DISP_RDMA,      0, &ddp_rdma },
 357        [DDP_COMPONENT_RDMA1]   = { MTK_DISP_RDMA,      1, &ddp_rdma },
 358        [DDP_COMPONENT_RDMA2]   = { MTK_DISP_RDMA,      2, &ddp_rdma },
 359        [DDP_COMPONENT_UFOE]    = { MTK_DISP_UFOE,      0, &ddp_ufoe },
 360        [DDP_COMPONENT_WDMA0]   = { MTK_DISP_WDMA,      0, NULL },
 361        [DDP_COMPONENT_WDMA1]   = { MTK_DISP_WDMA,      1, NULL },
 362};
 363
 364static bool mtk_drm_find_comp_in_ddp(struct device *dev,
 365                                     const enum mtk_ddp_comp_id *path,
 366                                     unsigned int path_len,
 367                                     struct mtk_ddp_comp *ddp_comp)
 368{
 369        unsigned int i;
 370
 371        if (path == NULL)
 372                return false;
 373
 374        for (i = 0U; i < path_len; i++)
 375                if (dev == ddp_comp[path[i]].dev)
 376                        return true;
 377
 378        return false;
 379}
 380
 381int mtk_ddp_comp_get_id(struct device_node *node,
 382                        enum mtk_ddp_comp_type comp_type)
 383{
 384        int id = of_alias_get_id(node, mtk_ddp_comp_stem[comp_type]);
 385        int i;
 386
 387        for (i = 0; i < ARRAY_SIZE(mtk_ddp_matches); i++) {
 388                if (comp_type == mtk_ddp_matches[i].type &&
 389                    (id < 0 || id == mtk_ddp_matches[i].alias_id))
 390                        return i;
 391        }
 392
 393        return -EINVAL;
 394}
 395
 396unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
 397                                                struct device *dev)
 398{
 399        struct mtk_drm_private *private = drm->dev_private;
 400        unsigned int ret = 0;
 401
 402        if (mtk_drm_find_comp_in_ddp(dev, private->data->main_path, private->data->main_len,
 403                                     private->ddp_comp))
 404                ret = BIT(0);
 405        else if (mtk_drm_find_comp_in_ddp(dev, private->data->ext_path,
 406                                          private->data->ext_len, private->ddp_comp))
 407                ret = BIT(1);
 408        else if (mtk_drm_find_comp_in_ddp(dev, private->data->third_path,
 409                                          private->data->third_len, private->ddp_comp))
 410                ret = BIT(2);
 411        else
 412                DRM_INFO("Failed to find comp in ddp table\n");
 413
 414        return ret;
 415}
 416
 417static int mtk_ddp_get_larb_dev(struct device_node *node, struct mtk_ddp_comp *comp,
 418                                struct device *dev)
 419{
 420        struct device_node *larb_node;
 421        struct platform_device *larb_pdev;
 422
 423        larb_node = of_parse_phandle(node, "mediatek,larb", 0);
 424        if (!larb_node) {
 425                dev_err(dev, "Missing mediadek,larb phandle in %pOF node\n", node);
 426                return -EINVAL;
 427        }
 428
 429        larb_pdev = of_find_device_by_node(larb_node);
 430        if (!larb_pdev) {
 431                dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
 432                of_node_put(larb_node);
 433                return -EPROBE_DEFER;
 434        }
 435        of_node_put(larb_node);
 436        comp->larb_dev = &larb_pdev->dev;
 437
 438        return 0;
 439}
 440
 441int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 442                      enum mtk_ddp_comp_id comp_id)
 443{
 444        struct platform_device *comp_pdev;
 445        enum mtk_ddp_comp_type type;
 446        struct mtk_ddp_comp_dev *priv;
 447        int ret;
 448
 449        if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
 450                return -EINVAL;
 451
 452        type = mtk_ddp_matches[comp_id].type;
 453
 454        comp->id = comp_id;
 455        comp->funcs = mtk_ddp_matches[comp_id].funcs;
 456        comp_pdev = of_find_device_by_node(node);
 457        if (!comp_pdev) {
 458                DRM_INFO("Waiting for device %s\n", node->full_name);
 459                return -EPROBE_DEFER;
 460        }
 461        comp->dev = &comp_pdev->dev;
 462
 463        /* Only DMA capable components need the LARB property */
 464        if (type == MTK_DISP_OVL ||
 465            type == MTK_DISP_OVL_2L ||
 466            type == MTK_DISP_RDMA ||
 467            type == MTK_DISP_WDMA) {
 468                ret = mtk_ddp_get_larb_dev(node, comp, comp->dev);
 469                if (ret)
 470                        return ret;
 471        }
 472
 473        if (type == MTK_DISP_AAL ||
 474            type == MTK_DISP_BLS ||
 475            type == MTK_DISP_CCORR ||
 476            type == MTK_DISP_COLOR ||
 477            type == MTK_DISP_GAMMA ||
 478            type == MTK_DPI ||
 479            type == MTK_DSI ||
 480            type == MTK_DISP_OVL ||
 481            type == MTK_DISP_OVL_2L ||
 482            type == MTK_DISP_PWM ||
 483            type == MTK_DISP_RDMA)
 484                return 0;
 485
 486        priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
 487        if (!priv)
 488                return -ENOMEM;
 489
 490        priv->regs = of_iomap(node, 0);
 491        priv->clk = of_clk_get(node, 0);
 492        if (IS_ERR(priv->clk))
 493                return PTR_ERR(priv->clk);
 494
 495#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 496        ret = cmdq_dev_get_client_reg(comp->dev, &priv->cmdq_reg, 0);
 497        if (ret)
 498                dev_dbg(comp->dev, "get mediatek,gce-client-reg fail!\n");
 499#endif
 500
 501        platform_set_drvdata(comp_pdev, priv);
 502
 503        return 0;
 504}
 505