linux/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2010 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21 * DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors:
  24 * Jackie Li<yaodong.li@intel.com>
  25 */
  26
  27#include <linux/freezer.h>
  28#include <video/mipi_display.h>
  29
  30#include "mdfld_dsi_output.h"
  31#include "mdfld_dsi_pkg_sender.h"
  32#include "mdfld_dsi_dpi.h"
  33
  34#define MDFLD_DSI_READ_MAX_COUNT                5000
  35
  36enum {
  37        MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
  38};
  39
  40enum {
  41        MDFLD_DSI_PKG_SENDER_FREE = 0x0,
  42        MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
  43};
  44
  45static const char *const dsi_errors[] = {
  46        "RX SOT Error",
  47        "RX SOT Sync Error",
  48        "RX EOT Sync Error",
  49        "RX Escape Mode Entry Error",
  50        "RX LP TX Sync Error",
  51        "RX HS Receive Timeout Error",
  52        "RX False Control Error",
  53        "RX ECC Single Bit Error",
  54        "RX ECC Multibit Error",
  55        "RX Checksum Error",
  56        "RX DSI Data Type Not Recognised",
  57        "RX DSI VC ID Invalid",
  58        "TX False Control Error",
  59        "TX ECC Single Bit Error",
  60        "TX ECC Multibit Error",
  61        "TX Checksum Error",
  62        "TX DSI Data Type Not Recognised",
  63        "TX DSI VC ID invalid",
  64        "High Contention",
  65        "Low contention",
  66        "DPI FIFO Under run",
  67        "HS TX Timeout",
  68        "LP RX Timeout",
  69        "Turn Around ACK Timeout",
  70        "ACK With No Error",
  71        "RX Invalid TX Length",
  72        "RX Prot Violation",
  73        "HS Generic Write FIFO Full",
  74        "LP Generic Write FIFO Full",
  75        "Generic Read Data Avail"
  76        "Special Packet Sent",
  77        "Tearing Effect",
  78};
  79
  80static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
  81                                                u32 mask)
  82{
  83        struct drm_device *dev = sender->dev;
  84        u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
  85        int retry = 0xffff;
  86
  87        while (retry--) {
  88                if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
  89                        return 0;
  90                udelay(100);
  91        }
  92        DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg));
  93        return -EIO;
  94}
  95
  96static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
  97{
  98        return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(10) | BIT(18) |
  99                                                BIT(26) | BIT(27) | BIT(28)));
 100}
 101
 102static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
 103{
 104        return wait_for_gen_fifo_empty(sender, (BIT(10) | BIT(26)));
 105}
 106
 107static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
 108{
 109        return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(18)));
 110}
 111
 112static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
 113{
 114        u32 intr_stat_reg = sender->mipi_intr_stat_reg;
 115        struct drm_device *dev = sender->dev;
 116
 117        dev_dbg(sender->dev->dev, "Handling error 0x%08x\n", mask);
 118
 119        switch (mask) {
 120        case BIT(0):
 121        case BIT(1):
 122        case BIT(2):
 123        case BIT(3):
 124        case BIT(4):
 125        case BIT(5):
 126        case BIT(6):
 127        case BIT(7):
 128        case BIT(8):
 129        case BIT(9):
 130        case BIT(10):
 131        case BIT(11):
 132        case BIT(12):
 133        case BIT(13):
 134                dev_dbg(sender->dev->dev, "No Action required\n");
 135                break;
 136        case BIT(14):
 137                /*wait for all fifo empty*/
 138                /*wait_for_all_fifos_empty(sender)*/
 139                break;
 140        case BIT(15):
 141                dev_dbg(sender->dev->dev, "No Action required\n");
 142                break;
 143        case BIT(16):
 144                break;
 145        case BIT(17):
 146                break;
 147        case BIT(18):
 148        case BIT(19):
 149                dev_dbg(sender->dev->dev, "High/Low contention detected\n");
 150                /*wait for contention recovery time*/
 151                /*mdelay(10);*/
 152                /*wait for all fifo empty*/
 153                if (0)
 154                        wait_for_all_fifos_empty(sender);
 155                break;
 156        case BIT(20):
 157                dev_dbg(sender->dev->dev, "No Action required\n");
 158                break;
 159        case BIT(21):
 160                /*wait for all fifo empty*/
 161                /*wait_for_all_fifos_empty(sender);*/
 162                break;
 163        case BIT(22):
 164                break;
 165        case BIT(23):
 166        case BIT(24):
 167        case BIT(25):
 168        case BIT(26):
 169        case BIT(27):
 170                dev_dbg(sender->dev->dev, "HS Gen fifo full\n");
 171                REG_WRITE(intr_stat_reg, mask);
 172                wait_for_hs_fifos_empty(sender);
 173                break;
 174        case BIT(28):
 175                dev_dbg(sender->dev->dev, "LP Gen fifo full\n");
 176                REG_WRITE(intr_stat_reg, mask);
 177                wait_for_lp_fifos_empty(sender);
 178                break;
 179        case BIT(29):
 180        case BIT(30):
 181        case BIT(31):
 182                dev_dbg(sender->dev->dev, "No Action required\n");
 183                break;
 184        }
 185
 186        if (mask & REG_READ(intr_stat_reg))
 187                dev_dbg(sender->dev->dev,
 188                                "Cannot clean interrupt 0x%08x\n", mask);
 189        return 0;
 190}
 191
 192static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
 193{
 194        struct drm_device *dev = sender->dev;
 195        u32 intr_stat_reg = sender->mipi_intr_stat_reg;
 196        u32 mask;
 197        u32 intr_stat;
 198        int i;
 199        int err = 0;
 200
 201        intr_stat = REG_READ(intr_stat_reg);
 202
 203        for (i = 0; i < 32; i++) {
 204                mask = (0x00000001UL) << i;
 205                if (intr_stat & mask) {
 206                        dev_dbg(sender->dev->dev, "[DSI]: %s\n", dsi_errors[i]);
 207                        err = handle_dsi_error(sender, mask);
 208                        if (err)
 209                                DRM_ERROR("Cannot handle error\n");
 210                }
 211        }
 212        return err;
 213}
 214
 215static int send_short_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
 216                        u8 cmd, u8 param, bool hs)
 217{
 218        struct drm_device *dev = sender->dev;
 219        u32 ctrl_reg;
 220        u32 val;
 221        u8 virtual_channel = 0;
 222
 223        if (hs) {
 224                ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
 225
 226                /* FIXME: wait_for_hs_fifos_empty(sender); */
 227        } else {
 228                ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
 229
 230                /* FIXME: wait_for_lp_fifos_empty(sender); */
 231        }
 232
 233        val = FLD_VAL(param, 23, 16) | FLD_VAL(cmd, 15, 8) |
 234                FLD_VAL(virtual_channel, 7, 6) | FLD_VAL(data_type, 5, 0);
 235
 236        REG_WRITE(ctrl_reg, val);
 237
 238        return 0;
 239}
 240
 241static int send_long_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
 242                        u8 *data, int len, bool hs)
 243{
 244        struct drm_device *dev = sender->dev;
 245        u32 ctrl_reg;
 246        u32 data_reg;
 247        u32 val;
 248        u8 *p;
 249        u8 b1, b2, b3, b4;
 250        u8 virtual_channel = 0;
 251        int i;
 252
 253        if (hs) {
 254                ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
 255                data_reg = sender->mipi_hs_gen_data_reg;
 256
 257                /* FIXME: wait_for_hs_fifos_empty(sender); */
 258        } else {
 259                ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
 260                data_reg = sender->mipi_lp_gen_data_reg;
 261
 262                /* FIXME: wait_for_lp_fifos_empty(sender); */
 263        }
 264
 265        p = data;
 266        for (i = 0; i < len / 4; i++) {
 267                b1 = *p++;
 268                b2 = *p++;
 269                b3 = *p++;
 270                b4 = *p++;
 271
 272                REG_WRITE(data_reg, b4 << 24 | b3 << 16 | b2 << 8 | b1);
 273        }
 274
 275        i = len % 4;
 276        if (i) {
 277                b1 = 0; b2 = 0; b3 = 0;
 278
 279                switch (i) {
 280                case 3:
 281                        b1 = *p++;
 282                        b2 = *p++;
 283                        b3 = *p++;
 284                        break;
 285                case 2:
 286                        b1 = *p++;
 287                        b2 = *p++;
 288                        break;
 289                case 1:
 290                        b1 = *p++;
 291                        break;
 292                }
 293
 294                REG_WRITE(data_reg, b3 << 16 | b2 << 8 | b1);
 295        }
 296
 297        val = FLD_VAL(len, 23, 8) | FLD_VAL(virtual_channel, 7, 6) |
 298                FLD_VAL(data_type, 5, 0);
 299
 300        REG_WRITE(ctrl_reg, val);
 301
 302        return 0;
 303}
 304
 305static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
 306                        u8 *data, u16 len)
 307{
 308        u8 cmd;
 309
 310        switch (data_type) {
 311        case MIPI_DSI_DCS_SHORT_WRITE:
 312        case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
 313        case MIPI_DSI_DCS_LONG_WRITE:
 314                cmd = *data;
 315                break;
 316        default:
 317                return 0;
 318        }
 319
 320        /*this prevents other package sending while doing msleep*/
 321        sender->status = MDFLD_DSI_PKG_SENDER_BUSY;
 322
 323        /*wait for 120 milliseconds in case exit_sleep_mode just be sent*/
 324        if (unlikely(cmd == MIPI_DCS_ENTER_SLEEP_MODE)) {
 325                /*TODO: replace it with msleep later*/
 326                mdelay(120);
 327        }
 328
 329        if (unlikely(cmd == MIPI_DCS_EXIT_SLEEP_MODE)) {
 330                /*TODO: replace it with msleep later*/
 331                mdelay(120);
 332        }
 333        return 0;
 334}
 335
 336static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
 337                        u8 *data, u16 len)
 338{
 339        u8 cmd;
 340
 341        switch (data_type) {
 342        case MIPI_DSI_DCS_SHORT_WRITE:
 343        case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
 344        case MIPI_DSI_DCS_LONG_WRITE:
 345                cmd = *data;
 346                break;
 347        default:
 348                return 0;
 349        }
 350
 351        /*update panel status*/
 352        if (unlikely(cmd == MIPI_DCS_ENTER_SLEEP_MODE)) {
 353                sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
 354                /*TODO: replace it with msleep later*/
 355                mdelay(120);
 356        } else if (unlikely(cmd == MIPI_DCS_EXIT_SLEEP_MODE)) {
 357                sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
 358                /*TODO: replace it with msleep later*/
 359                mdelay(120);
 360        } else if (unlikely(cmd == MIPI_DCS_SOFT_RESET)) {
 361                /*TODO: replace it with msleep later*/
 362                mdelay(5);
 363        }
 364
 365        sender->status = MDFLD_DSI_PKG_SENDER_FREE;
 366
 367        return 0;
 368}
 369
 370static int send_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
 371                u8 *data, u16 len, bool hs)
 372{
 373        int ret;
 374
 375        /*handle DSI error*/
 376        ret = dsi_error_handler(sender);
 377        if (ret) {
 378                DRM_ERROR("Error handling failed\n");
 379                return -EAGAIN;
 380        }
 381
 382        /* send pkg */
 383        if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
 384                DRM_ERROR("sender is busy\n");
 385                return -EAGAIN;
 386        }
 387
 388        ret = send_pkg_prepare(sender, data_type, data, len);
 389        if (ret) {
 390                DRM_ERROR("send_pkg_prepare error\n");
 391                return ret;
 392        }
 393
 394        switch (data_type) {
 395        case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
 396        case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
 397        case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
 398        case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
 399        case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
 400        case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
 401        case MIPI_DSI_DCS_SHORT_WRITE:
 402        case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
 403        case MIPI_DSI_DCS_READ:
 404                ret = send_short_pkg(sender, data_type, data[0], data[1], hs);
 405                break;
 406        case MIPI_DSI_GENERIC_LONG_WRITE:
 407        case MIPI_DSI_DCS_LONG_WRITE:
 408                ret = send_long_pkg(sender, data_type, data, len, hs);
 409                break;
 410        }
 411
 412        send_pkg_done(sender, data_type, data, len);
 413
 414        /*FIXME: should I query complete and fifo empty here?*/
 415
 416        return ret;
 417}
 418
 419int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
 420                        u32 len, bool hs)
 421{
 422        unsigned long flags;
 423
 424        if (!sender || !data || !len) {
 425                DRM_ERROR("Invalid parameters\n");
 426                return -EINVAL;
 427        }
 428
 429        spin_lock_irqsave(&sender->lock, flags);
 430        send_pkg(sender, MIPI_DSI_DCS_LONG_WRITE, data, len, hs);
 431        spin_unlock_irqrestore(&sender->lock, flags);
 432
 433        return 0;
 434}
 435
 436int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
 437                        u8 param, u8 param_num, bool hs)
 438{
 439        u8 data[2];
 440        unsigned long flags;
 441        u8 data_type;
 442
 443        if (!sender) {
 444                DRM_ERROR("Invalid parameter\n");
 445                return -EINVAL;
 446        }
 447
 448        data[0] = cmd;
 449
 450        if (param_num) {
 451                data_type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
 452                data[1] = param;
 453        } else {
 454                data_type = MIPI_DSI_DCS_SHORT_WRITE;
 455                data[1] = 0;
 456        }
 457
 458        spin_lock_irqsave(&sender->lock, flags);
 459        send_pkg(sender, data_type, data, sizeof(data), hs);
 460        spin_unlock_irqrestore(&sender->lock, flags);
 461
 462        return 0;
 463}
 464
 465int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0,
 466                        u8 param1, u8 param_num, bool hs)
 467{
 468        u8 data[2];
 469        unsigned long flags;
 470        u8 data_type;
 471
 472        if (!sender || param_num > 2) {
 473                DRM_ERROR("Invalid parameter\n");
 474                return -EINVAL;
 475        }
 476
 477        switch (param_num) {
 478        case 0:
 479                data_type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
 480                data[0] = 0;
 481                data[1] = 0;
 482                break;
 483        case 1:
 484                data_type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
 485                data[0] = param0;
 486                data[1] = 0;
 487                break;
 488        case 2:
 489                data_type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
 490                data[0] = param0;
 491                data[1] = param1;
 492                break;
 493        }
 494
 495        spin_lock_irqsave(&sender->lock, flags);
 496        send_pkg(sender, data_type, data, sizeof(data), hs);
 497        spin_unlock_irqrestore(&sender->lock, flags);
 498
 499        return 0;
 500}
 501
 502int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
 503                        u32 len, bool hs)
 504{
 505        unsigned long flags;
 506
 507        if (!sender || !data || !len) {
 508                DRM_ERROR("Invalid parameters\n");
 509                return -EINVAL;
 510        }
 511
 512        spin_lock_irqsave(&sender->lock, flags);
 513        send_pkg(sender, MIPI_DSI_GENERIC_LONG_WRITE, data, len, hs);
 514        spin_unlock_irqrestore(&sender->lock, flags);
 515
 516        return 0;
 517}
 518
 519static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
 520                        u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs)
 521{
 522        unsigned long flags;
 523        struct drm_device *dev = sender->dev;
 524        int i;
 525        u32 gen_data_reg;
 526        int retry = MDFLD_DSI_READ_MAX_COUNT;
 527
 528        if (!sender || !data_out || !len_out) {
 529                DRM_ERROR("Invalid parameters\n");
 530                return -EINVAL;
 531        }
 532
 533        /**
 534         * do reading.
 535         * 0) send out generic read request
 536         * 1) polling read data avail interrupt
 537         * 2) read data
 538         */
 539        spin_lock_irqsave(&sender->lock, flags);
 540
 541        REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));
 542
 543        if ((REG_READ(sender->mipi_intr_stat_reg) & BIT(29)))
 544                DRM_ERROR("Can NOT clean read data valid interrupt\n");
 545
 546        /*send out read request*/
 547        send_pkg(sender, data_type, data, len, hs);
 548
 549        /*polling read data avail interrupt*/
 550        while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) {
 551                udelay(100);
 552                retry--;
 553        }
 554
 555        if (!retry) {
 556                spin_unlock_irqrestore(&sender->lock, flags);
 557                return -ETIMEDOUT;
 558        }
 559
 560        REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));
 561
 562        /*read data*/
 563        if (hs)
 564                gen_data_reg = sender->mipi_hs_gen_data_reg;
 565        else
 566                gen_data_reg = sender->mipi_lp_gen_data_reg;
 567
 568        for (i = 0; i < len_out; i++)
 569                *(data_out + i) = REG_READ(gen_data_reg);
 570
 571        spin_unlock_irqrestore(&sender->lock, flags);
 572
 573        return 0;
 574}
 575
 576int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
 577                u32 *data, u16 len, bool hs)
 578{
 579        if (!sender || !data || !len) {
 580                DRM_ERROR("Invalid parameters\n");
 581                return -EINVAL;
 582        }
 583
 584        return __read_panel_data(sender, MIPI_DSI_DCS_READ, &cmd, 1,
 585                                data, len, hs);
 586}
 587
 588int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
 589                                                                int pipe)
 590{
 591        struct mdfld_dsi_pkg_sender *pkg_sender;
 592        struct mdfld_dsi_config *dsi_config =
 593                                mdfld_dsi_get_config(dsi_connector);
 594        struct drm_device *dev = dsi_config->dev;
 595        struct drm_psb_private *dev_priv = dev->dev_private;
 596        const struct psb_offset *map = &dev_priv->regmap[pipe];
 597        u32 mipi_val = 0;
 598
 599        if (!dsi_connector) {
 600                DRM_ERROR("Invalid parameter\n");
 601                return -EINVAL;
 602        }
 603
 604        pkg_sender = dsi_connector->pkg_sender;
 605
 606        if (!pkg_sender || IS_ERR(pkg_sender)) {
 607                pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
 608                                                                GFP_KERNEL);
 609                if (!pkg_sender) {
 610                        DRM_ERROR("Create DSI pkg sender failed\n");
 611                        return -ENOMEM;
 612                }
 613                dsi_connector->pkg_sender = (void *)pkg_sender;
 614        }
 615
 616        pkg_sender->dev = dev;
 617        pkg_sender->dsi_connector = dsi_connector;
 618        pkg_sender->pipe = pipe;
 619        pkg_sender->pkg_num = 0;
 620        pkg_sender->panel_mode = 0;
 621        pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;
 622
 623        /*init regs*/
 624        /* FIXME: should just copy the regmap ptr ? */
 625        pkg_sender->dpll_reg = map->dpll;
 626        pkg_sender->dspcntr_reg = map->cntr;
 627        pkg_sender->pipeconf_reg = map->conf;
 628        pkg_sender->dsplinoff_reg = map->linoff;
 629        pkg_sender->dspsurf_reg = map->surf;
 630        pkg_sender->pipestat_reg = map->status;
 631
 632        pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe);
 633        pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe);
 634        pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe);
 635        pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe);
 636        pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe);
 637        pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
 638        pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe);
 639        pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe);
 640        pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe);
 641        pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe);
 642
 643        /*init lock*/
 644        spin_lock_init(&pkg_sender->lock);
 645
 646        if (mdfld_get_panel_type(dev, pipe) != TC35876X) {
 647                /**
 648                 * For video mode, don't enable DPI timing output here,
 649                 * will init the DPI timing output during mode setting.
 650                 */
 651                mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
 652
 653                if (pipe == 0)
 654                        mipi_val |= 0x2;
 655
 656                REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val);
 657                REG_READ(MIPI_PORT_CONTROL(pipe));
 658
 659                /* do dsi controller init */
 660                mdfld_dsi_controller_init(dsi_config, pipe);
 661        }
 662
 663        return 0;
 664}
 665
 666void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
 667{
 668        if (!sender || IS_ERR(sender))
 669                return;
 670
 671        /*free*/
 672        kfree(sender);
 673}
 674
 675
 676