linux/drivers/video/msm/mddi.c
<<
>>
Prefs
   1/*
   2 * MSM MDDI Transport
   3 *
   4 * Copyright (C) 2007 Google Incorporated
   5 * Copyright (C) 2007 QUALCOMM Incorporated
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License version 2, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/kernel.h>
  20#include <linux/dma-mapping.h>
  21#include <linux/interrupt.h>
  22#include <linux/platform_device.h>
  23#include <linux/delay.h>
  24#include <linux/gfp.h>
  25#include <linux/spinlock.h>
  26#include <linux/clk.h>
  27#include <linux/io.h>
  28#include <linux/sched.h>
  29#include <linux/platform_data/video-msm_fb.h>
  30#include "mddi_hw.h"
  31
  32#define FLAG_DISABLE_HIBERNATION 0x0001
  33#define FLAG_HAVE_CAPS           0x0002
  34#define FLAG_HAS_VSYNC_IRQ       0x0004
  35#define FLAG_HAVE_STATUS         0x0008
  36
  37#define CMD_GET_CLIENT_CAP     0x0601
  38#define CMD_GET_CLIENT_STATUS  0x0602
  39
  40union mddi_rev {
  41        unsigned char raw[MDDI_REV_BUFFER_SIZE];
  42        struct mddi_rev_packet hdr;
  43        struct mddi_client_status status;
  44        struct mddi_client_caps caps;
  45        struct mddi_register_access reg;
  46};
  47
  48struct reg_read_info {
  49        struct completion done;
  50        uint32_t reg;
  51        uint32_t status;
  52        uint32_t result;
  53};
  54
  55struct mddi_info {
  56        uint16_t flags;
  57        uint16_t version;
  58        char __iomem *base;
  59        int irq;
  60        struct clk *clk;
  61        struct msm_mddi_client_data client_data;
  62
  63        /* buffer for rev encap packets */
  64        void *rev_data;
  65        dma_addr_t rev_addr;
  66        struct mddi_llentry *reg_write_data;
  67        dma_addr_t reg_write_addr;
  68        struct mddi_llentry *reg_read_data;
  69        dma_addr_t reg_read_addr;
  70        size_t rev_data_curr;
  71
  72        spinlock_t int_lock;
  73        uint32_t int_enable;
  74        uint32_t got_int;
  75        wait_queue_head_t int_wait;
  76
  77        struct mutex reg_write_lock;
  78        struct mutex reg_read_lock;
  79        struct reg_read_info *reg_read;
  80
  81        struct mddi_client_caps caps;
  82        struct mddi_client_status status;
  83
  84        void (*power_client)(struct msm_mddi_client_data *, int);
  85
  86        /* client device published to bind us to the
  87         * appropriate mddi_client driver
  88         */
  89        char client_name[20];
  90
  91        struct platform_device client_pdev;
  92};
  93
  94static void mddi_init_rev_encap(struct mddi_info *mddi);
  95
  96#define mddi_readl(r) readl(mddi->base + (MDDI_##r))
  97#define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))
  98
  99void mddi_activate_link(struct msm_mddi_client_data *cdata)
 100{
 101        struct mddi_info *mddi = container_of(cdata, struct mddi_info,
 102                                              client_data);
 103
 104        mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
 105}
 106
 107static void mddi_handle_link_list_done(struct mddi_info *mddi)
 108{
 109}
 110
 111static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi)
 112{
 113        printk(KERN_INFO "mddi: resetting rev ptr\n");
 114        mddi->rev_data_curr = 0;
 115        mddi_writel(mddi->rev_addr, REV_PTR);
 116        mddi_writel(mddi->rev_addr, REV_PTR);
 117        mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
 118}
 119
 120static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev)
 121{
 122        int i;
 123        struct reg_read_info *ri;
 124
 125        if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) &&
 126           (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) {
 127
 128                switch (rev->hdr.type) {
 129                case TYPE_CLIENT_CAPS:
 130                        memcpy(&mddi->caps, &rev->caps,
 131                               sizeof(struct mddi_client_caps));
 132                        mddi->flags |= FLAG_HAVE_CAPS;
 133                        wake_up(&mddi->int_wait);
 134                        break;
 135                case TYPE_CLIENT_STATUS:
 136                        memcpy(&mddi->status, &rev->status,
 137                               sizeof(struct mddi_client_status));
 138                        mddi->flags |= FLAG_HAVE_STATUS;
 139                        wake_up(&mddi->int_wait);
 140                        break;
 141                case TYPE_REGISTER_ACCESS:
 142                        ri = mddi->reg_read;
 143                        if (ri == 0) {
 144                                printk(KERN_INFO "rev: got reg %x = %x without "
 145                                                 " pending read\n",
 146                                       rev->reg.register_address,
 147                                       rev->reg.register_data_list);
 148                                break;
 149                        }
 150                        if (ri->reg != rev->reg.register_address) {
 151                                printk(KERN_INFO "rev: got reg %x = %x for "
 152                                                 "wrong register, expected "
 153                                                 "%x\n",
 154                                       rev->reg.register_address,
 155                                       rev->reg.register_data_list, ri->reg);
 156                                break;
 157                        }
 158                        mddi->reg_read = NULL;
 159                        ri->status = 0;
 160                        ri->result = rev->reg.register_data_list;
 161                        complete(&ri->done);
 162                        break;
 163                default:
 164                        printk(KERN_INFO "rev: unknown reverse packet: "
 165                                         "len=%04x type=%04x CURR_REV_PTR=%x\n",
 166                               rev->hdr.length, rev->hdr.type,
 167                               mddi_readl(CURR_REV_PTR));
 168                        for (i = 0; i < rev->hdr.length + 2; i++) {
 169                                if ((i % 16) == 0)
 170                                        printk(KERN_INFO "\n");
 171                                printk(KERN_INFO " %02x", rev->raw[i]);
 172                        }
 173                        printk(KERN_INFO "\n");
 174                        mddi_reset_rev_encap_ptr(mddi);
 175                }
 176        } else {
 177                printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n",
 178                       rev->hdr.length, mddi_readl(CURR_REV_PTR));
 179                mddi_reset_rev_encap_ptr(mddi);
 180        }
 181}
 182
 183static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
 184
 185static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
 186{
 187        uint32_t rev_data_count;
 188        uint32_t rev_crc_err_count;
 189        struct reg_read_info *ri;
 190        size_t prev_offset;
 191        uint16_t length;
 192
 193        union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr;
 194
 195        /* clear the interrupt */
 196        mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT);
 197        rev_data_count = mddi_readl(REV_PKT_CNT);
 198        rev_crc_err_count = mddi_readl(REV_CRC_ERR);
 199        if (rev_data_count > 1)
 200                printk(KERN_INFO "rev_data_count %d\n", rev_data_count);
 201
 202        if (rev_crc_err_count) {
 203                printk(KERN_INFO "rev_crc_err_count %d, INT %x\n",
 204                       rev_crc_err_count,  mddi_readl(INT));
 205                ri = mddi->reg_read;
 206                if (ri == 0) {
 207                        printk(KERN_INFO "rev: got crc error without pending "
 208                               "read\n");
 209                } else {
 210                        mddi->reg_read = NULL;
 211                        ri->status = -EIO;
 212                        ri->result = -1;
 213                        complete(&ri->done);
 214                }
 215        }
 216
 217        if (rev_data_count == 0)
 218                return;
 219
 220        prev_offset = mddi->rev_data_curr;
 221
 222        length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr);
 223        mddi->rev_data_curr++;
 224        if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE)
 225                mddi->rev_data_curr = 0;
 226        length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8;
 227        mddi->rev_data_curr += 1 + length;
 228        if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE)
 229                mddi->rev_data_curr =
 230                        mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE;
 231
 232        if (length > MDDI_REV_BUFFER_SIZE - 2) {
 233                printk(KERN_INFO "mddi: rev data length greater than buffer"
 234                        "size\n");
 235                mddi_reset_rev_encap_ptr(mddi);
 236                return;
 237        }
 238
 239        if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) {
 240                union mddi_rev tmprev;
 241                size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset;
 242                memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem);
 243                memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem);
 244                mddi_handle_rev_data(mddi, &tmprev);
 245        } else {
 246                mddi_handle_rev_data(mddi, crev);
 247        }
 248
 249        if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
 250            mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
 251                mddi_writel(mddi->rev_addr, REV_PTR);
 252        }
 253}
 254
 255static irqreturn_t mddi_isr(int irq, void *data)
 256{
 257        struct msm_mddi_client_data *cdata = data;
 258        struct mddi_info *mddi = container_of(cdata, struct mddi_info,
 259                                              client_data);
 260        uint32_t active, status;
 261
 262        spin_lock(&mddi->int_lock);
 263
 264        active = mddi_readl(INT);
 265        status = mddi_readl(STAT);
 266
 267        mddi_writel(active, INT);
 268
 269        /* ignore any interrupts we have disabled */
 270        active &= mddi->int_enable;
 271
 272        mddi->got_int |= active;
 273        wake_up(&mddi->int_wait);
 274
 275        if (active & MDDI_INT_PRI_LINK_LIST_DONE) {
 276                mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE);
 277                mddi_handle_link_list_done(mddi);
 278        }
 279        if (active & MDDI_INT_REV_DATA_AVAIL)
 280                mddi_handle_rev_data_avail(mddi);
 281
 282        if (active & ~MDDI_INT_NEED_CLEAR)
 283                mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR);
 284
 285        if (active & MDDI_INT_LINK_ACTIVE) {
 286                mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE);
 287                mddi->int_enable |= MDDI_INT_IN_HIBERNATION;
 288        }
 289
 290        if (active & MDDI_INT_IN_HIBERNATION) {
 291                mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
 292                mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
 293        }
 294
 295        mddi_writel(mddi->int_enable, INTEN);
 296        spin_unlock(&mddi->int_lock);
 297
 298        return IRQ_HANDLED;
 299}
 300
 301static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
 302                                        uint32_t intmask, int timeout)
 303{
 304        unsigned long irq_flags;
 305
 306        spin_lock_irqsave(&mddi->int_lock, irq_flags);
 307        mddi->got_int &= ~intmask;
 308        mddi->int_enable |= intmask;
 309        mddi_writel(mddi->int_enable, INTEN);
 310        spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
 311        return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask,
 312                                  timeout);
 313}
 314
 315static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
 316{
 317        if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
 318                printk(KERN_INFO "mddi_wait_interrupt %d, timeout "
 319                       "waiting for %x, INT = %x, STAT = %x gotint = %x\n",
 320                       current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
 321                       mddi->got_int);
 322}
 323
 324static void mddi_init_rev_encap(struct mddi_info *mddi)
 325{
 326        memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE);
 327        mddi_writel(mddi->rev_addr, REV_PTR);
 328        mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
 329        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 330}
 331
 332void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on)
 333{
 334        struct mddi_info *mddi = container_of(cdata, struct mddi_info,
 335                                              client_data);
 336        mddi_writel(MDDI_CMD_POWERDOWN, CMD);
 337        mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
 338        mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD);
 339        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 340}
 341
 342
 343static uint16_t mddi_init_registers(struct mddi_info *mddi)
 344{
 345        mddi_writel(0x0001, VERSION);
 346        mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
 347        mddi_writel(0x0003, SPM); /* subframes per media */
 348        mddi_writel(0x0005, TA1_LEN);
 349        mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
 350        mddi_writel(0x0096, DRIVE_HI);
 351        /* 0x32 normal, 0x50 for Toshiba display */
 352        mddi_writel(0x0050, DRIVE_LO);
 353        mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
 354        mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
 355
 356        mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE);
 357        mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ);
 358
 359        /* disable periodic rev encap */
 360        mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD);
 361        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 362
 363        if (mddi_readl(PAD_CTL) == 0) {
 364                /* If we are turning on band gap, need to wait 5us before
 365                 * turning on the rest of the PAD */
 366                mddi_writel(0x08000, PAD_CTL);
 367                udelay(5);
 368        }
 369
 370        /* Recommendation from PAD hw team */
 371        mddi_writel(0xa850f, PAD_CTL);
 372
 373
 374        /* Need an even number for counts */
 375        mddi_writel(0x60006, DRIVER_START_CNT);
 376
 377        mddi_set_auto_hibernate(&mddi->client_data, 0);
 378
 379        mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
 380        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 381
 382        mddi_init_rev_encap(mddi);
 383        return mddi_readl(CORE_VER) & 0xffff;
 384}
 385
 386static void mddi_suspend(struct msm_mddi_client_data *cdata)
 387{
 388        struct mddi_info *mddi = container_of(cdata, struct mddi_info,
 389                                              client_data);
 390        /* turn off the client */
 391        if (mddi->power_client)
 392                mddi->power_client(&mddi->client_data, 0);
 393        /* turn off the link */
 394        mddi_writel(MDDI_CMD_RESET, CMD);
 395        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 396        /* turn off the clock */
 397        clk_disable(mddi->clk);
 398}
 399
 400static void mddi_resume(struct msm_mddi_client_data *cdata)
 401{
 402        struct mddi_info *mddi = container_of(cdata, struct mddi_info,
 403                                              client_data);
 404        mddi_set_auto_hibernate(&mddi->client_data, 0);
 405        /* turn on the client */
 406        if (mddi->power_client)
 407                mddi->power_client(&mddi->client_data, 1);
 408        /* turn on the clock */
 409        clk_enable(mddi->clk);
 410        /* set up the local registers */
 411        mddi->rev_data_curr = 0;
 412        mddi_init_registers(mddi);
 413        mddi_writel(mddi->int_enable, INTEN);
 414        mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
 415        mddi_writel(MDDI_CMD_SEND_RTD, CMD);
 416        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 417        mddi_set_auto_hibernate(&mddi->client_data, 1);
 418}
 419
 420static int __devinit mddi_get_client_caps(struct mddi_info *mddi)
 421{
 422        int i, j;
 423
 424        /* clear any stale interrupts */
 425        mddi_writel(0xffffffff, INT);
 426
 427        mddi->int_enable = MDDI_INT_LINK_ACTIVE |
 428                           MDDI_INT_IN_HIBERNATION |
 429                           MDDI_INT_PRI_LINK_LIST_DONE |
 430                           MDDI_INT_REV_DATA_AVAIL |
 431                           MDDI_INT_REV_OVERFLOW |
 432                           MDDI_INT_REV_OVERWRITE |
 433                           MDDI_INT_RTD_FAILURE;
 434        mddi_writel(mddi->int_enable, INTEN);
 435
 436        mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
 437        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 438
 439        for (j = 0; j < 3; j++) {
 440                /* the toshiba vga panel does not respond to get
 441                 * caps unless you SEND_RTD, but the first SEND_RTD
 442                 * will fail...
 443                 */
 444                for (i = 0; i < 4; i++) {
 445                        uint32_t stat;
 446
 447                        mddi_writel(MDDI_CMD_SEND_RTD, CMD);
 448                        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 449                        stat = mddi_readl(STAT);
 450                        printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, "
 451                                        "rtd val %x\n", mddi_readl(INT), stat,
 452                                        mddi_readl(RTD_VAL));
 453                        if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0)
 454                                break;
 455                        msleep(1);
 456                }
 457
 458                mddi_writel(CMD_GET_CLIENT_CAP, CMD);
 459                mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 460                wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS,
 461                                   HZ / 100);
 462
 463                if (mddi->flags & FLAG_HAVE_CAPS)
 464                        break;
 465                printk(KERN_INFO "mddi_init, timeout waiting for caps\n");
 466        }
 467        return mddi->flags & FLAG_HAVE_CAPS;
 468}
 469
 470/* link must be active when this is called */
 471int mddi_check_status(struct mddi_info *mddi)
 472{
 473        int ret = -1, retry = 3;
 474        mutex_lock(&mddi->reg_read_lock);
 475        mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
 476        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 477
 478        do {
 479                mddi->flags &= ~FLAG_HAVE_STATUS;
 480                mddi_writel(CMD_GET_CLIENT_STATUS, CMD);
 481                mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 482                wait_event_timeout(mddi->int_wait,
 483                                   mddi->flags & FLAG_HAVE_STATUS,
 484                                   HZ / 100);
 485
 486                if (mddi->flags & FLAG_HAVE_STATUS) {
 487                        if (mddi->status.crc_error_count)
 488                                printk(KERN_INFO "mddi status: crc_error "
 489                                        "count: %d\n",
 490                                        mddi->status.crc_error_count);
 491                        else
 492                                ret = 0;
 493                        break;
 494                } else
 495                        printk(KERN_INFO "mddi status: failed to get client "
 496                                "status\n");
 497                mddi_writel(MDDI_CMD_SEND_RTD, CMD);
 498                mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 499        } while (--retry);
 500
 501        mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
 502        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 503        mutex_unlock(&mddi->reg_read_lock);
 504        return ret;
 505}
 506
 507
 508void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
 509                       uint32_t reg)
 510{
 511        struct mddi_info *mddi = container_of(cdata, struct mddi_info,
 512                                              client_data);
 513        struct mddi_llentry *ll;
 514        struct mddi_register_access *ra;
 515
 516        mutex_lock(&mddi->reg_write_lock);
 517
 518        ll = mddi->reg_write_data;
 519
 520        ra = &(ll->u.r);
 521        ra->length = 14 + 4;
 522        ra->type = TYPE_REGISTER_ACCESS;
 523        ra->client_id = 0;
 524        ra->read_write_info = MDDI_WRITE | 1;
 525        ra->crc16 = 0;
 526
 527        ra->register_address = reg;
 528        ra->register_data_list = val;
 529
 530        ll->flags = 1;
 531        ll->header_count = 14;
 532        ll->data_count = 4;
 533        ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry,
 534                                                   u.r.register_data_list);
 535        ll->next = 0;
 536        ll->reserved = 0;
 537
 538        mddi_writel(mddi->reg_write_addr, PRI_PTR);
 539
 540        mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
 541        mutex_unlock(&mddi->reg_write_lock);
 542}
 543
 544uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
 545{
 546        struct mddi_info *mddi = container_of(cdata, struct mddi_info,
 547                                              client_data);
 548        struct mddi_llentry *ll;
 549        struct mddi_register_access *ra;
 550        struct reg_read_info ri;
 551        unsigned s;
 552        int retry_count = 2;
 553        unsigned long irq_flags;
 554
 555        mutex_lock(&mddi->reg_read_lock);
 556
 557        ll = mddi->reg_read_data;
 558
 559        ra = &(ll->u.r);
 560        ra->length = 14;
 561        ra->type = TYPE_REGISTER_ACCESS;
 562        ra->client_id = 0;
 563        ra->read_write_info = MDDI_READ | 1;
 564        ra->crc16 = 0;
 565
 566        ra->register_address = reg;
 567
 568        ll->flags = 0x11;
 569        ll->header_count = 14;
 570        ll->data_count = 0;
 571        ll->data = 0;
 572        ll->next = 0;
 573        ll->reserved = 0;
 574
 575        s = mddi_readl(STAT);
 576
 577        ri.reg = reg;
 578        ri.status = -1;
 579
 580        do {
 581                init_completion(&ri.done);
 582                mddi->reg_read = &ri;
 583                mddi_writel(mddi->reg_read_addr, PRI_PTR);
 584
 585                mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
 586
 587                /* Enable Periodic Reverse Encapsulation. */
 588                mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
 589                mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 590                if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
 591                    !ri.done.done) {
 592                        printk(KERN_INFO "mddi_remote_read(%x) timeout "
 593                                         "(%d %d %d)\n",
 594                               reg, ri.status, ri.result, ri.done.done);
 595                        spin_lock_irqsave(&mddi->int_lock, irq_flags);
 596                        mddi->reg_read = NULL;
 597                        spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
 598                        ri.status = -1;
 599                        ri.result = -1;
 600                }
 601                if (ri.status == 0)
 602                        break;
 603
 604                mddi_writel(MDDI_CMD_SEND_RTD, CMD);
 605                mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
 606                mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 607                printk(KERN_INFO "mddi_remote_read: failed, sent "
 608                       "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
 609                       "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
 610                       mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
 611        } while (retry_count-- > 0);
 612        /* Disable Periodic Reverse Encapsulation. */
 613        mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
 614        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 615        mddi->reg_read = NULL;
 616        mutex_unlock(&mddi->reg_read_lock);
 617        return ri.result;
 618}
 619
 620static struct mddi_info mddi_info[2];
 621
 622static int __devinit mddi_clk_setup(struct platform_device *pdev,
 623                                    struct mddi_info *mddi,
 624                                    unsigned long clk_rate)
 625{
 626        int ret;
 627
 628        /* set up the clocks */
 629        mddi->clk = clk_get(&pdev->dev, "mddi_clk");
 630        if (IS_ERR(mddi->clk)) {
 631                printk(KERN_INFO "mddi: failed to get clock\n");
 632                return PTR_ERR(mddi->clk);
 633        }
 634        ret =  clk_enable(mddi->clk);
 635        if (ret)
 636                goto fail;
 637        ret = clk_set_rate(mddi->clk, clk_rate);
 638        if (ret)
 639                goto fail;
 640        return 0;
 641
 642fail:
 643        clk_put(mddi->clk);
 644        return ret;
 645}
 646
 647static int __init mddi_rev_data_setup(struct mddi_info *mddi)
 648{
 649        void *dma;
 650        dma_addr_t dma_addr;
 651
 652        /* set up dma buffer */
 653        dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL);
 654        if (dma == 0)
 655                return -ENOMEM;
 656        mddi->rev_data = dma;
 657        mddi->rev_data_curr = 0;
 658        mddi->rev_addr = dma_addr;
 659        mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE;
 660        mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE;
 661        mddi->reg_read_data = mddi->reg_write_data + 1;
 662        mddi->reg_read_addr = mddi->reg_write_addr +
 663                              sizeof(*mddi->reg_write_data);
 664        return 0;
 665}
 666
 667static int __devinit mddi_probe(struct platform_device *pdev)
 668{
 669        struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
 670        struct mddi_info *mddi = &mddi_info[pdev->id];
 671        struct resource *resource;
 672        int ret, i;
 673
 674        resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 675        if (!resource) {
 676                printk(KERN_ERR "mddi: no associated mem resource!\n");
 677                return -ENOMEM;
 678        }
 679        mddi->base = ioremap(resource->start, resource_size(resource));
 680        if (!mddi->base) {
 681                printk(KERN_ERR "mddi: failed to remap base!\n");
 682                ret = -EINVAL;
 683                goto error_ioremap;
 684        }
 685        resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 686        if (!resource) {
 687                printk(KERN_ERR "mddi: no associated irq resource!\n");
 688                ret = -EINVAL;
 689                goto error_get_irq_resource;
 690        }
 691        mddi->irq = resource->start;
 692        printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
 693               mddi->irq);
 694        mddi->power_client = pdata->power_client;
 695
 696        mutex_init(&mddi->reg_write_lock);
 697        mutex_init(&mddi->reg_read_lock);
 698        spin_lock_init(&mddi->int_lock);
 699        init_waitqueue_head(&mddi->int_wait);
 700
 701        ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
 702        if (ret) {
 703                printk(KERN_ERR "mddi: failed to setup clock!\n");
 704                goto error_clk_setup;
 705        }
 706
 707        ret = mddi_rev_data_setup(mddi);
 708        if (ret) {
 709                printk(KERN_ERR "mddi: failed to setup rev data!\n");
 710                goto error_rev_data;
 711        }
 712
 713        mddi->int_enable = 0;
 714        mddi_writel(mddi->int_enable, INTEN);
 715        ret = request_irq(mddi->irq, mddi_isr, 0, "mddi",
 716                          &mddi->client_data);
 717        if (ret) {
 718                printk(KERN_ERR "mddi: failed to request enable irq!\n");
 719                goto error_request_irq;
 720        }
 721
 722        /* turn on the mddi client bridge chip */
 723        if (mddi->power_client)
 724                mddi->power_client(&mddi->client_data, 1);
 725
 726        /* initialize the mddi registers */
 727        mddi_set_auto_hibernate(&mddi->client_data, 0);
 728        mddi_writel(MDDI_CMD_RESET, CMD);
 729        mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
 730        mddi->version = mddi_init_registers(mddi);
 731        if (mddi->version < 0x20) {
 732                printk(KERN_ERR "mddi: unsupported version 0x%x\n",
 733                       mddi->version);
 734                ret = -ENODEV;
 735                goto error_mddi_version;
 736        }
 737
 738        /* read the capabilities off the client */
 739        if (!mddi_get_client_caps(mddi)) {
 740                printk(KERN_INFO "mddi: no client found\n");
 741                /* power down the panel */
 742                mddi_writel(MDDI_CMD_POWERDOWN, CMD);
 743                printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
 744                msleep(100);
 745                printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
 746                return 0;
 747        }
 748        mddi_set_auto_hibernate(&mddi->client_data, 1);
 749
 750        if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0)
 751                pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code);
 752
 753        mddi->client_pdev.id = 0;
 754        for (i = 0; i < pdata->num_clients; i++) {
 755                if (pdata->client_platform_data[i].product_id ==
 756                    (mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) {
 757                        mddi->client_data.private_client_data =
 758                                pdata->client_platform_data[i].client_data;
 759                        mddi->client_pdev.name =
 760                                pdata->client_platform_data[i].name;
 761                        mddi->client_pdev.id =
 762                                pdata->client_platform_data[i].id;
 763                        /* XXX: possibly set clock */
 764                        break;
 765                }
 766        }
 767
 768        if (i >= pdata->num_clients)
 769                mddi->client_pdev.name = "mddi_c_dummy";
 770        printk(KERN_INFO "mddi: registering panel %s\n",
 771                mddi->client_pdev.name);
 772
 773        mddi->client_data.suspend = mddi_suspend;
 774        mddi->client_data.resume = mddi_resume;
 775        mddi->client_data.activate_link = mddi_activate_link;
 776        mddi->client_data.remote_write = mddi_remote_write;
 777        mddi->client_data.remote_read = mddi_remote_read;
 778        mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
 779        mddi->client_data.fb_resource = pdata->fb_resource;
 780        if (pdev->id == 0)
 781                mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE;
 782        else if (pdev->id == 1)
 783                mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE;
 784        else {
 785                printk(KERN_ERR "mddi: can not determine interface %d!\n",
 786                       pdev->id);
 787                ret = -EINVAL;
 788                goto error_mddi_interface;
 789        }
 790
 791        mddi->client_pdev.dev.platform_data = &mddi->client_data;
 792        printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name);
 793        platform_device_register(&mddi->client_pdev);
 794        return 0;
 795
 796error_mddi_interface:
 797error_mddi_version:
 798        free_irq(mddi->irq, 0);
 799error_request_irq:
 800        dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr);
 801error_rev_data:
 802error_clk_setup:
 803error_get_irq_resource:
 804        iounmap(mddi->base);
 805error_ioremap:
 806
 807        printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret);
 808        return ret;
 809}
 810
 811
 812static struct platform_driver mddi_driver = {
 813        .probe = mddi_probe,
 814        .driver = { .name = "msm_mddi" },
 815};
 816
 817static int __init _mddi_init(void)
 818{
 819        return platform_driver_register(&mddi_driver);
 820}
 821
 822module_init(_mddi_init);
 823