~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/video/omap2/dss/hdmi.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * hdmi.c
 
3
 *
 
4
 * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
 
5
 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
 
6
 * Authors: Yong Zhi
 
7
 *      Mythri pk <mythripk@ti.com>
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify it
 
10
 * under the terms of the GNU General Public License version 2 as published by
 
11
 * the Free Software Foundation.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
14
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
15
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
16
 * more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License along with
 
19
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
#define DSS_SUBSYS_NAME "HDMI"
 
23
 
 
24
#include <linux/kernel.h>
 
25
#include <linux/module.h>
 
26
#include <linux/err.h>
 
27
#include <linux/io.h>
 
28
#include <linux/interrupt.h>
 
29
#include <linux/mutex.h>
 
30
#include <linux/delay.h>
 
31
#include <linux/string.h>
 
32
#include <plat/display.h>
 
33
 
 
34
#include "dss.h"
 
35
#include "hdmi.h"
 
36
 
 
37
static struct {
 
38
        struct mutex lock;
 
39
        struct omap_display_platform_data *pdata;
 
40
        struct platform_device *pdev;
 
41
        void __iomem *base_wp;  /* HDMI wrapper */
 
42
        int code;
 
43
        int mode;
 
44
        u8 edid[HDMI_EDID_MAX_LENGTH];
 
45
        u8 edid_set;
 
46
        bool custom_set;
 
47
        struct hdmi_config cfg;
 
48
} hdmi;
 
49
 
 
50
/*
 
51
 * Logic for the below structure :
 
52
 * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
 
53
 * There is a correspondence between CEA/VESA timing and code, please
 
54
 * refer to section 6.3 in HDMI 1.3 specification for timing code.
 
55
 *
 
56
 * In the below structure, cea_vesa_timings corresponds to all OMAP4
 
57
 * supported CEA and VESA timing values.code_cea corresponds to the CEA
 
58
 * code, It is used to get the timing from cea_vesa_timing array.Similarly
 
59
 * with code_vesa. Code_index is used for back mapping, that is once EDID
 
60
 * is read from the TV, EDID is parsed to find the timing values and then
 
61
 * map it to corresponding CEA or VESA index.
 
62
 */
 
63
 
 
64
static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
 
65
        { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
 
66
        { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
 
67
        { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
 
68
        { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
 
69
        { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
 
70
        { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
 
71
        { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
 
72
        { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
 
73
        { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
 
74
        { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
 
75
        { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
 
76
        { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
 
77
        { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
 
78
        { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
 
79
        { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
 
80
        /* VESA From Here */
 
81
        { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
 
82
        { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
 
83
        { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
 
84
        { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
 
85
        { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
 
86
        { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
 
87
        { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
 
88
        { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
 
89
        { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
 
90
        { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
 
91
        { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
 
92
        { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
 
93
        { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
 
94
        { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
 
95
        { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
 
96
        { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
 
97
        { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
 
98
        { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
 
99
        { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
 
100
};
 
101
 
 
102
/*
 
103
 * This is a static mapping array which maps the timing values
 
104
 * with corresponding CEA / VESA code
 
105
 */
 
106
static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
 
107
        1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
 
108
        /* <--15 CEA 17--> vesa*/
 
109
        4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
 
110
        0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
 
111
};
 
112
 
 
113
/*
 
114
 * This is reverse static mapping which maps the CEA / VESA code
 
115
 * to the corresponding timing values
 
116
 */
 
117
static const int code_cea[39] = {
 
118
        -1,  0,  3,  3,  2,  8,  5,  5, -1, -1,
 
119
        -1, -1, -1, -1, -1, -1,  9, 10, 10,  1,
 
120
        7,   6,  6, -1, -1, -1, -1, -1, -1, 11,
 
121
        11, 12, 14, -1, -1, 13, 13,  4,  4
 
122
};
 
123
 
 
124
static const int code_vesa[85] = {
 
125
        -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
 
126
        -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
 
127
        -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
 
128
        -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
 
129
        -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
 
130
        -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
 
131
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 
132
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 
133
        -1, 27, 28, -1, 33};
 
134
 
 
135
static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
 
136
 
 
137
static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
 
138
{
 
139
        __raw_writel(val, hdmi.base_wp + idx.idx);
 
140
}
 
141
 
 
142
static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
 
143
{
 
144
        return __raw_readl(hdmi.base_wp + idx.idx);
 
145
}
 
146
 
 
147
static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
 
148
                                int b2, int b1, u32 val)
 
149
{
 
150
        u32 t = 0;
 
151
        while (val != REG_GET(idx, b2, b1)) {
 
152
                udelay(1);
 
153
                if (t++ > 10000)
 
154
                        return !val;
 
155
        }
 
156
        return val;
 
157
}
 
158
 
 
159
int hdmi_init_display(struct omap_dss_device *dssdev)
 
160
{
 
161
        DSSDBG("init_display\n");
 
162
 
 
163
        return 0;
 
164
}
 
165
 
 
166
static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
 
167
                struct hdmi_pll_info *fmt, u16 sd)
 
168
{
 
169
        u32 r;
 
170
 
 
171
        /* PLL start always use manual mode */
 
172
        REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
 
173
 
 
174
        r = hdmi_read_reg(PLLCTRL_CFG1);
 
175
        r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
 
176
        r = FLD_MOD(r, fmt->regn, 8, 1);  /* CFG1_PLL_REGN */
 
177
 
 
178
        hdmi_write_reg(PLLCTRL_CFG1, r);
 
179
 
 
180
        r = hdmi_read_reg(PLLCTRL_CFG2);
 
181
 
 
182
        r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
 
183
        r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
 
184
        r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
 
185
 
 
186
        if (dcofreq) {
 
187
                /* divider programming for frequency beyond 1000Mhz */
 
188
                REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
 
189
                r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
 
190
        } else {
 
191
                r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
 
192
        }
 
193
 
 
194
        hdmi_write_reg(PLLCTRL_CFG2, r);
 
195
 
 
196
        r = hdmi_read_reg(PLLCTRL_CFG4);
 
197
        r = FLD_MOD(r, fmt->regm2, 24, 18);
 
198
        r = FLD_MOD(r, fmt->regmf, 17, 0);
 
199
 
 
200
        hdmi_write_reg(PLLCTRL_CFG4, r);
 
201
 
 
202
        /* go now */
 
203
        REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
 
204
 
 
205
        /* wait for bit change */
 
206
        if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
 
207
                DSSERR("PLL GO bit not set\n");
 
208
                return -ETIMEDOUT;
 
209
        }
 
210
 
 
211
        /* Wait till the lock bit is set in PLL status */
 
212
        if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
 
213
                DSSWARN("cannot lock PLL\n");
 
214
                DSSWARN("CFG1 0x%x\n",
 
215
                        hdmi_read_reg(PLLCTRL_CFG1));
 
216
                DSSWARN("CFG2 0x%x\n",
 
217
                        hdmi_read_reg(PLLCTRL_CFG2));
 
218
                DSSWARN("CFG4 0x%x\n",
 
219
                        hdmi_read_reg(PLLCTRL_CFG4));
 
220
                return -ETIMEDOUT;
 
221
        }
 
222
 
 
223
        DSSDBG("PLL locked!\n");
 
224
 
 
225
        return 0;
 
226
}
 
227
 
 
228
/* PHY_PWR_CMD */
 
229
static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
 
230
{
 
231
        /* Command for power control of HDMI PHY */
 
232
        REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
 
233
 
 
234
        /* Status of the power control of HDMI PHY */
 
235
        if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
 
236
                DSSERR("Failed to set PHY power mode to %d\n", val);
 
237
                return -ETIMEDOUT;
 
238
        }
 
239
 
 
240
        return 0;
 
241
}
 
242
 
 
243
/* PLL_PWR_CMD */
 
244
static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
 
245
{
 
246
        /* Command for power control of HDMI PLL */
 
247
        REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
 
248
 
 
249
        /* wait till PHY_PWR_STATUS is set */
 
250
        if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
 
251
                DSSERR("Failed to set PHY_PWR_STATUS\n");
 
252
                return -ETIMEDOUT;
 
253
        }
 
254
 
 
255
        return 0;
 
256
}
 
257
 
 
258
static int hdmi_pll_reset(void)
 
259
{
 
260
        /* SYSRESET  controlled by power FSM */
 
261
        REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
 
262
 
 
263
        /* READ 0x0 reset is in progress */
 
264
        if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
 
265
                DSSERR("Failed to sysreset PLL\n");
 
266
                return -ETIMEDOUT;
 
267
        }
 
268
 
 
269
        return 0;
 
270
}
 
271
 
 
272
static int hdmi_phy_init(void)
 
273
{
 
274
        u16 r = 0;
 
275
 
 
276
        r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
 
277
        if (r)
 
278
                return r;
 
279
 
 
280
        r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
 
281
        if (r)
 
282
                return r;
 
283
 
 
284
        /*
 
285
         * Read address 0 in order to get the SCP reset done completed
 
286
         * Dummy access performed to make sure reset is done
 
287
         */
 
288
        hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
 
289
 
 
290
        /*
 
291
         * Write to phy address 0 to configure the clock
 
292
         * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
 
293
         */
 
294
        REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
 
295
 
 
296
        /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
 
297
        hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
 
298
 
 
299
        /* Setup max LDO voltage */
 
300
        REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
 
301
 
 
302
        /* Write to phy address 3 to change the polarity control */
 
303
        REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
 
304
 
 
305
        return 0;
 
306
}
 
307
 
 
308
static int hdmi_wait_softreset(void)
 
309
{
 
310
        /* reset W1 */
 
311
        REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
 
312
 
 
313
        /* wait till SOFTRESET == 0 */
 
314
        if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
 
315
                DSSERR("sysconfig reset failed\n");
 
316
                return -ETIMEDOUT;
 
317
        }
 
318
 
 
319
        return 0;
 
320
}
 
321
 
 
322
static int hdmi_pll_program(struct hdmi_pll_info *fmt)
 
323
{
 
324
        u16 r = 0;
 
325
        enum hdmi_clk_refsel refsel;
 
326
 
 
327
        /* wait for wrapper reset */
 
328
        r = hdmi_wait_softreset();
 
329
        if (r)
 
330
                return r;
 
331
 
 
332
        r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
 
333
        if (r)
 
334
                return r;
 
335
 
 
336
        r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
 
337
        if (r)
 
338
                return r;
 
339
 
 
340
        r = hdmi_pll_reset();
 
341
        if (r)
 
342
                return r;
 
343
 
 
344
        refsel = HDMI_REFSEL_SYSCLK;
 
345
 
 
346
        r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
 
347
        if (r)
 
348
                return r;
 
349
 
 
350
        return 0;
 
351
}
 
352
 
 
353
static void hdmi_phy_off(void)
 
354
{
 
355
        hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
 
356
}
 
357
 
 
358
static int hdmi_core_ddc_edid(u8 *pedid, int ext)
 
359
{
 
360
        u32 i, j;
 
361
        char checksum = 0;
 
362
        u32 offset = 0;
 
363
 
 
364
        /* Turn on CLK for DDC */
 
365
        REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
 
366
 
 
367
        /*
 
368
         * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
 
369
         * right shifted values( The behavior is not consistent and seen only
 
370
         * with some TV's)
 
371
         */
 
372
        usleep_range(800, 1000);
 
373
 
 
374
        if (!ext) {
 
375
                /* Clk SCL Devices */
 
376
                REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
 
377
 
 
378
                /* HDMI_CORE_DDC_STATUS_IN_PROG */
 
379
                if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
 
380
                                                4, 4, 0) != 0) {
 
381
                        DSSERR("Failed to program DDC\n");
 
382
                        return -ETIMEDOUT;
 
383
                }
 
384
 
 
385
                /* Clear FIFO */
 
386
                REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
 
387
 
 
388
                /* HDMI_CORE_DDC_STATUS_IN_PROG */
 
389
                if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
 
390
                                                4, 4, 0) != 0) {
 
391
                        DSSERR("Failed to program DDC\n");
 
392
                        return -ETIMEDOUT;
 
393
                }
 
394
 
 
395
        } else {
 
396
                if (ext % 2 != 0)
 
397
                        offset = 0x80;
 
398
        }
 
399
 
 
400
        /* Load Segment Address Register */
 
401
        REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
 
402
 
 
403
        /* Load Slave Address Register */
 
404
        REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
 
405
 
 
406
        /* Load Offset Address Register */
 
407
        REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
 
408
 
 
409
        /* Load Byte Count */
 
410
        REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
 
411
        REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
 
412
 
 
413
        /* Set DDC_CMD */
 
414
        if (ext)
 
415
                REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
 
416
        else
 
417
                REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
 
418
 
 
419
        /* HDMI_CORE_DDC_STATUS_BUS_LOW */
 
420
        if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
 
421
                DSSWARN("I2C Bus Low?\n");
 
422
                return -EIO;
 
423
        }
 
424
        /* HDMI_CORE_DDC_STATUS_NO_ACK */
 
425
        if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
 
426
                DSSWARN("I2C No Ack\n");
 
427
                return -EIO;
 
428
        }
 
429
 
 
430
        i = ext * 128;
 
431
        j = 0;
 
432
        while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
 
433
                        (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
 
434
                        j < 128) {
 
435
 
 
436
                if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
 
437
                        /* FIFO not empty */
 
438
                        pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
 
439
                        j++;
 
440
                }
 
441
        }
 
442
 
 
443
        for (j = 0; j < 128; j++)
 
444
                checksum += pedid[j];
 
445
 
 
446
        if (checksum != 0) {
 
447
                DSSERR("E-EDID checksum failed!!\n");
 
448
                return -EIO;
 
449
        }
 
450
 
 
451
        return 0;
 
452
}
 
453
 
 
454
static int read_edid(u8 *pedid, u16 max_length)
 
455
{
 
456
        int r = 0, n = 0, i = 0;
 
457
        int max_ext_blocks = (max_length / 128) - 1;
 
458
 
 
459
        r = hdmi_core_ddc_edid(pedid, 0);
 
460
        if (r) {
 
461
                return r;
 
462
        } else {
 
463
                n = pedid[0x7e];
 
464
 
 
465
                /*
 
466
                 * README: need to comply with max_length set by the caller.
 
467
                 * Better implementation should be to allocate necessary
 
468
                 * memory to store EDID according to nb_block field found
 
469
                 * in first block
 
470
                 */
 
471
                if (n > max_ext_blocks)
 
472
                        n = max_ext_blocks;
 
473
 
 
474
                for (i = 1; i <= n; i++) {
 
475
                        r = hdmi_core_ddc_edid(pedid, i);
 
476
                        if (r)
 
477
                                return r;
 
478
                }
 
479
        }
 
480
        return 0;
 
481
}
 
482
 
 
483
static int get_timings_index(void)
 
484
{
 
485
        int code;
 
486
 
 
487
        if (hdmi.mode == 0)
 
488
                code = code_vesa[hdmi.code];
 
489
        else
 
490
                code = code_cea[hdmi.code];
 
491
 
 
492
        if (code == -1) {
 
493
                /* HDMI code 4 corresponds to 640 * 480 VGA */
 
494
                hdmi.code = 4;
 
495
                /* DVI mode 1 corresponds to HDMI 0 to DVI */
 
496
                hdmi.mode = HDMI_DVI;
 
497
 
 
498
                code = code_vesa[hdmi.code];
 
499
        }
 
500
        return code;
 
501
}
 
502
 
 
503
static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
 
504
{
 
505
        int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
 
506
        int timing_vsync = 0, timing_hsync = 0;
 
507
        struct omap_video_timings temp;
 
508
        struct hdmi_cm cm = {-1};
 
509
        DSSDBG("hdmi_get_code\n");
 
510
 
 
511
        for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
 
512
                temp = cea_vesa_timings[i].timings;
 
513
                if ((temp.pixel_clock == timing->pixel_clock) &&
 
514
                        (temp.x_res == timing->x_res) &&
 
515
                        (temp.y_res == timing->y_res)) {
 
516
 
 
517
                        temp_hsync = temp.hfp + temp.hsw + temp.hbp;
 
518
                        timing_hsync = timing->hfp + timing->hsw + timing->hbp;
 
519
                        temp_vsync = temp.vfp + temp.vsw + temp.vbp;
 
520
                        timing_vsync = timing->vfp + timing->vsw + timing->vbp;
 
521
 
 
522
                        DSSDBG("temp_hsync = %d , temp_vsync = %d"
 
523
                                "timing_hsync = %d, timing_vsync = %d\n",
 
524
                                temp_hsync, temp_hsync,
 
525
                                timing_hsync, timing_vsync);
 
526
 
 
527
                        if ((temp_hsync == timing_hsync) &&
 
528
                                        (temp_vsync == timing_vsync)) {
 
529
                                code = i;
 
530
                                cm.code = code_index[i];
 
531
                                if (code < 14)
 
532
                                        cm.mode = HDMI_HDMI;
 
533
                                else
 
534
                                        cm.mode = HDMI_DVI;
 
535
                                DSSDBG("Hdmi_code = %d mode = %d\n",
 
536
                                         cm.code, cm.mode);
 
537
                                break;
 
538
                         }
 
539
                }
 
540
        }
 
541
 
 
542
        return cm;
 
543
}
 
544
 
 
545
static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
 
546
                struct omap_video_timings *timings)
 
547
{
 
548
        /* X and Y resolution */
 
549
        timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
 
550
                         edid[current_descriptor_addrs + 2]);
 
551
        timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
 
552
                         edid[current_descriptor_addrs + 5]);
 
553
 
 
554
        timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
 
555
                                edid[current_descriptor_addrs]);
 
556
 
 
557
        timings->pixel_clock = 10 * timings->pixel_clock;
 
558
 
 
559
        /* HORIZONTAL FRONT PORCH */
 
560
        timings->hfp = edid[current_descriptor_addrs + 8] |
 
561
                        ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
 
562
        /* HORIZONTAL SYNC WIDTH */
 
563
        timings->hsw = edid[current_descriptor_addrs + 9] |
 
564
                        ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
 
565
        /* HORIZONTAL BACK PORCH */
 
566
        timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
 
567
                        edid[current_descriptor_addrs + 3]) -
 
568
                        (timings->hfp + timings->hsw);
 
569
        /* VERTICAL FRONT PORCH */
 
570
        timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
 
571
                        ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
 
572
        /* VERTICAL SYNC WIDTH */
 
573
        timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
 
574
                        ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
 
575
        /* VERTICAL BACK PORCH */
 
576
        timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
 
577
                        edid[current_descriptor_addrs + 6]) -
 
578
                        (timings->vfp + timings->vsw);
 
579
 
 
580
}
 
581
 
 
582
/* Description : This function gets the resolution information from EDID */
 
583
static void get_edid_timing_data(u8 *edid)
 
584
{
 
585
        u8 count;
 
586
        u16 current_descriptor_addrs;
 
587
        struct hdmi_cm cm;
 
588
        struct omap_video_timings edid_timings;
 
589
 
 
590
        /* search block 0, there are 4 DTDs arranged in priority order */
 
591
        for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
 
592
                current_descriptor_addrs =
 
593
                        EDID_DESCRIPTOR_BLOCK0_ADDRESS +
 
594
                        count * EDID_TIMING_DESCRIPTOR_SIZE;
 
595
                get_horz_vert_timing_info(current_descriptor_addrs,
 
596
                                edid, &edid_timings);
 
597
                cm = hdmi_get_code(&edid_timings);
 
598
                DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
 
599
                        count, cm.code, cm.mode);
 
600
                if (cm.code == -1) {
 
601
                        continue;
 
602
                } else {
 
603
                        hdmi.code = cm.code;
 
604
                        hdmi.mode = cm.mode;
 
605
                        DSSDBG("code = %d , mode = %d\n",
 
606
                                hdmi.code, hdmi.mode);
 
607
                        return;
 
608
                }
 
609
        }
 
610
        if (edid[0x7e] != 0x00) {
 
611
                for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
 
612
                        count++) {
 
613
                        current_descriptor_addrs =
 
614
                        EDID_DESCRIPTOR_BLOCK1_ADDRESS +
 
615
                        count * EDID_TIMING_DESCRIPTOR_SIZE;
 
616
                        get_horz_vert_timing_info(current_descriptor_addrs,
 
617
                                                edid, &edid_timings);
 
618
                        cm = hdmi_get_code(&edid_timings);
 
619
                        DSSDBG("Block1[%d] value matches code = %d, mode = %d",
 
620
                                count, cm.code, cm.mode);
 
621
                        if (cm.code == -1) {
 
622
                                continue;
 
623
                        } else {
 
624
                                hdmi.code = cm.code;
 
625
                                hdmi.mode = cm.mode;
 
626
                                DSSDBG("code = %d , mode = %d\n",
 
627
                                        hdmi.code, hdmi.mode);
 
628
                                return;
 
629
                        }
 
630
                }
 
631
        }
 
632
 
 
633
        DSSINFO("no valid timing found , falling back to VGA\n");
 
634
        hdmi.code = 4; /* setting default value of 640 480 VGA */
 
635
        hdmi.mode = HDMI_DVI;
 
636
}
 
637
 
 
638
static void hdmi_read_edid(struct omap_video_timings *dp)
 
639
{
 
640
        int ret = 0, code;
 
641
 
 
642
        memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
 
643
 
 
644
        if (!hdmi.edid_set)
 
645
                ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
 
646
 
 
647
        if (!ret) {
 
648
                if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
 
649
                        /* search for timings of default resolution */
 
650
                        get_edid_timing_data(hdmi.edid);
 
651
                        hdmi.edid_set = true;
 
652
                }
 
653
        } else {
 
654
                DSSWARN("failed to read E-EDID\n");
 
655
        }
 
656
 
 
657
        if (!hdmi.edid_set) {
 
658
                DSSINFO("fallback to VGA\n");
 
659
                hdmi.code = 4; /* setting default value of 640 480 VGA */
 
660
                hdmi.mode = HDMI_DVI;
 
661
        }
 
662
 
 
663
        code = get_timings_index();
 
664
 
 
665
        *dp = cea_vesa_timings[code].timings;
 
666
}
 
667
 
 
668
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
 
669
                        struct hdmi_core_infoframe_avi *avi_cfg,
 
670
                        struct hdmi_core_packet_enable_repeat *repeat_cfg)
 
671
{
 
672
        DSSDBG("Enter hdmi_core_init\n");
 
673
 
 
674
        /* video core */
 
675
        video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
 
676
        video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
 
677
        video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
 
678
        video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
 
679
        video_cfg->hdmi_dvi = HDMI_DVI;
 
680
        video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
 
681
 
 
682
        /* info frame */
 
683
        avi_cfg->db1_format = 0;
 
684
        avi_cfg->db1_active_info = 0;
 
685
        avi_cfg->db1_bar_info_dv = 0;
 
686
        avi_cfg->db1_scan_info = 0;
 
687
        avi_cfg->db2_colorimetry = 0;
 
688
        avi_cfg->db2_aspect_ratio = 0;
 
689
        avi_cfg->db2_active_fmt_ar = 0;
 
690
        avi_cfg->db3_itc = 0;
 
691
        avi_cfg->db3_ec = 0;
 
692
        avi_cfg->db3_q_range = 0;
 
693
        avi_cfg->db3_nup_scaling = 0;
 
694
        avi_cfg->db4_videocode = 0;
 
695
        avi_cfg->db5_pixel_repeat = 0;
 
696
        avi_cfg->db6_7_line_eoftop = 0 ;
 
697
        avi_cfg->db8_9_line_sofbottom = 0;
 
698
        avi_cfg->db10_11_pixel_eofleft = 0;
 
699
        avi_cfg->db12_13_pixel_sofright = 0;
 
700
 
 
701
        /* packet enable and repeat */
 
702
        repeat_cfg->audio_pkt = 0;
 
703
        repeat_cfg->audio_pkt_repeat = 0;
 
704
        repeat_cfg->avi_infoframe = 0;
 
705
        repeat_cfg->avi_infoframe_repeat = 0;
 
706
        repeat_cfg->gen_cntrl_pkt = 0;
 
707
        repeat_cfg->gen_cntrl_pkt_repeat = 0;
 
708
        repeat_cfg->generic_pkt = 0;
 
709
        repeat_cfg->generic_pkt_repeat = 0;
 
710
}
 
711
 
 
712
static void hdmi_core_powerdown_disable(void)
 
713
{
 
714
        DSSDBG("Enter hdmi_core_powerdown_disable\n");
 
715
        REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
 
716
}
 
717
 
 
718
static void hdmi_core_swreset_release(void)
 
719
{
 
720
        DSSDBG("Enter hdmi_core_swreset_release\n");
 
721
        REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
 
722
}
 
723
 
 
724
static void hdmi_core_swreset_assert(void)
 
725
{
 
726
        DSSDBG("Enter hdmi_core_swreset_assert\n");
 
727
        REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
 
728
}
 
729
 
 
730
/* DSS_HDMI_CORE_VIDEO_CONFIG */
 
731
static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
 
732
{
 
733
        u32 r = 0;
 
734
 
 
735
        /* sys_ctrl1 default configuration not tunable */
 
736
        r = hdmi_read_reg(HDMI_CORE_CTRL1);
 
737
        r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
 
738
        r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
 
739
        r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
 
740
        r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
 
741
        hdmi_write_reg(HDMI_CORE_CTRL1, r);
 
742
 
 
743
        REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
 
744
 
 
745
        /* Vid_Mode */
 
746
        r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
 
747
 
 
748
        /* dither truncation configuration */
 
749
        if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
 
750
                r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
 
751
                r = FLD_MOD(r, 1, 5, 5);
 
752
        } else {
 
753
                r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
 
754
                r = FLD_MOD(r, 0, 5, 5);
 
755
        }
 
756
        hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
 
757
 
 
758
        /* HDMI_Ctrl */
 
759
        r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
 
760
        r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
 
761
        r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
 
762
        r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
 
763
        hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
 
764
 
 
765
        /* TMDS_CTRL */
 
766
        REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
 
767
                cfg->tclk_sel_clkmult, 6, 5);
 
768
}
 
769
 
 
770
static void hdmi_core_aux_infoframe_avi_config(
 
771
                struct hdmi_core_infoframe_avi info_avi)
 
772
{
 
773
        u32 val;
 
774
        char sum = 0, checksum = 0;
 
775
 
 
776
        sum += 0x82 + 0x002 + 0x00D;
 
777
        hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
 
778
        hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
 
779
        hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
 
780
 
 
781
        val = (info_avi.db1_format << 5) |
 
782
                (info_avi.db1_active_info << 4) |
 
783
                (info_avi.db1_bar_info_dv << 2) |
 
784
                (info_avi.db1_scan_info);
 
785
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
 
786
        sum += val;
 
787
 
 
788
        val = (info_avi.db2_colorimetry << 6) |
 
789
                (info_avi.db2_aspect_ratio << 4) |
 
790
                (info_avi.db2_active_fmt_ar);
 
791
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
 
792
        sum += val;
 
793
 
 
794
        val = (info_avi.db3_itc << 7) |
 
795
                (info_avi.db3_ec << 4) |
 
796
                (info_avi.db3_q_range << 2) |
 
797
                (info_avi.db3_nup_scaling);
 
798
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
 
799
        sum += val;
 
800
 
 
801
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
 
802
        sum += info_avi.db4_videocode;
 
803
 
 
804
        val = info_avi.db5_pixel_repeat;
 
805
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
 
806
        sum += val;
 
807
 
 
808
        val = info_avi.db6_7_line_eoftop & 0x00FF;
 
809
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
 
810
        sum += val;
 
811
 
 
812
        val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
 
813
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
 
814
        sum += val;
 
815
 
 
816
        val = info_avi.db8_9_line_sofbottom & 0x00FF;
 
817
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
 
818
        sum += val;
 
819
 
 
820
        val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
 
821
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
 
822
        sum += val;
 
823
 
 
824
        val = info_avi.db10_11_pixel_eofleft & 0x00FF;
 
825
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
 
826
        sum += val;
 
827
 
 
828
        val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
 
829
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
 
830
        sum += val;
 
831
 
 
832
        val = info_avi.db12_13_pixel_sofright & 0x00FF;
 
833
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
 
834
        sum += val;
 
835
 
 
836
        val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
 
837
        hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
 
838
        sum += val;
 
839
 
 
840
        checksum = 0x100 - sum;
 
841
        hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
 
842
}
 
843
 
 
844
static void hdmi_core_av_packet_config(
 
845
                struct hdmi_core_packet_enable_repeat repeat_cfg)
 
846
{
 
847
        /* enable/repeat the infoframe */
 
848
        hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
 
849
                (repeat_cfg.audio_pkt << 5) |
 
850
                (repeat_cfg.audio_pkt_repeat << 4) |
 
851
                (repeat_cfg.avi_infoframe << 1) |
 
852
                (repeat_cfg.avi_infoframe_repeat));
 
853
 
 
854
        /* enable/repeat the packet */
 
855
        hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
 
856
                (repeat_cfg.gen_cntrl_pkt << 3) |
 
857
                (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
 
858
                (repeat_cfg.generic_pkt << 1) |
 
859
                (repeat_cfg.generic_pkt_repeat));
 
860
}
 
861
 
 
862
static void hdmi_wp_init(struct omap_video_timings *timings,
 
863
                        struct hdmi_video_format *video_fmt,
 
864
                        struct hdmi_video_interface *video_int)
 
865
{
 
866
        DSSDBG("Enter hdmi_wp_init\n");
 
867
 
 
868
        timings->hbp = 0;
 
869
        timings->hfp = 0;
 
870
        timings->hsw = 0;
 
871
        timings->vbp = 0;
 
872
        timings->vfp = 0;
 
873
        timings->vsw = 0;
 
874
 
 
875
        video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
 
876
        video_fmt->y_res = 0;
 
877
        video_fmt->x_res = 0;
 
878
 
 
879
        video_int->vsp = 0;
 
880
        video_int->hsp = 0;
 
881
 
 
882
        video_int->interlacing = 0;
 
883
        video_int->tm = 0; /* HDMI_TIMING_SLAVE */
 
884
 
 
885
}
 
886
 
 
887
static void hdmi_wp_video_start(bool start)
 
888
{
 
889
        REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
 
890
}
 
891
 
 
892
static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
 
893
        struct omap_video_timings *timings, struct hdmi_config *param)
 
894
{
 
895
        DSSDBG("Enter hdmi_wp_video_init_format\n");
 
896
 
 
897
        video_fmt->y_res = param->timings.timings.y_res;
 
898
        video_fmt->x_res = param->timings.timings.x_res;
 
899
 
 
900
        timings->hbp = param->timings.timings.hbp;
 
901
        timings->hfp = param->timings.timings.hfp;
 
902
        timings->hsw = param->timings.timings.hsw;
 
903
        timings->vbp = param->timings.timings.vbp;
 
904
        timings->vfp = param->timings.timings.vfp;
 
905
        timings->vsw = param->timings.timings.vsw;
 
906
}
 
907
 
 
908
static void hdmi_wp_video_config_format(
 
909
                struct hdmi_video_format *video_fmt)
 
910
{
 
911
        u32 l = 0;
 
912
 
 
913
        REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
 
914
 
 
915
        l |= FLD_VAL(video_fmt->y_res, 31, 16);
 
916
        l |= FLD_VAL(video_fmt->x_res, 15, 0);
 
917
        hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
 
918
}
 
919
 
 
920
static void hdmi_wp_video_config_interface(
 
921
                struct hdmi_video_interface *video_int)
 
922
{
 
923
        u32 r;
 
924
        DSSDBG("Enter hdmi_wp_video_config_interface\n");
 
925
 
 
926
        r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
 
927
        r = FLD_MOD(r, video_int->vsp, 7, 7);
 
928
        r = FLD_MOD(r, video_int->hsp, 6, 6);
 
929
        r = FLD_MOD(r, video_int->interlacing, 3, 3);
 
930
        r = FLD_MOD(r, video_int->tm, 1, 0);
 
931
        hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
 
932
}
 
933
 
 
934
static void hdmi_wp_video_config_timing(
 
935
                struct omap_video_timings *timings)
 
936
{
 
937
        u32 timing_h = 0;
 
938
        u32 timing_v = 0;
 
939
 
 
940
        DSSDBG("Enter hdmi_wp_video_config_timing\n");
 
941
 
 
942
        timing_h |= FLD_VAL(timings->hbp, 31, 20);
 
943
        timing_h |= FLD_VAL(timings->hfp, 19, 8);
 
944
        timing_h |= FLD_VAL(timings->hsw, 7, 0);
 
945
        hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
 
946
 
 
947
        timing_v |= FLD_VAL(timings->vbp, 31, 20);
 
948
        timing_v |= FLD_VAL(timings->vfp, 19, 8);
 
949
        timing_v |= FLD_VAL(timings->vsw, 7, 0);
 
950
        hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
 
951
}
 
952
 
 
953
static void hdmi_basic_configure(struct hdmi_config *cfg)
 
954
{
 
955
        /* HDMI */
 
956
        struct omap_video_timings video_timing;
 
957
        struct hdmi_video_format video_format;
 
958
        struct hdmi_video_interface video_interface;
 
959
        /* HDMI core */
 
960
        struct hdmi_core_infoframe_avi avi_cfg;
 
961
        struct hdmi_core_video_config v_core_cfg;
 
962
        struct hdmi_core_packet_enable_repeat repeat_cfg;
 
963
 
 
964
        hdmi_wp_init(&video_timing, &video_format,
 
965
                &video_interface);
 
966
 
 
967
        hdmi_core_init(&v_core_cfg,
 
968
                &avi_cfg,
 
969
                &repeat_cfg);
 
970
 
 
971
        hdmi_wp_video_init_format(&video_format,
 
972
                        &video_timing, cfg);
 
973
 
 
974
        hdmi_wp_video_config_timing(&video_timing);
 
975
 
 
976
        /* video config */
 
977
        video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
 
978
 
 
979
        hdmi_wp_video_config_format(&video_format);
 
980
 
 
981
        video_interface.vsp = cfg->timings.vsync_pol;
 
982
        video_interface.hsp = cfg->timings.hsync_pol;
 
983
        video_interface.interlacing = cfg->interlace;
 
984
        video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
 
985
 
 
986
        hdmi_wp_video_config_interface(&video_interface);
 
987
 
 
988
        /*
 
989
         * configure core video part
 
990
         * set software reset in the core
 
991
         */
 
992
        hdmi_core_swreset_assert();
 
993
 
 
994
        /* power down off */
 
995
        hdmi_core_powerdown_disable();
 
996
 
 
997
        v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
 
998
        v_core_cfg.hdmi_dvi = cfg->cm.mode;
 
999
 
 
1000
        hdmi_core_video_config(&v_core_cfg);
 
1001
 
 
1002
        /* release software reset in the core */
 
1003
        hdmi_core_swreset_release();
 
1004
 
 
1005
        /*
 
1006
         * configure packet
 
1007
         * info frame video see doc CEA861-D page 65
 
1008
         */
 
1009
        avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
 
1010
        avi_cfg.db1_active_info =
 
1011
                HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
 
1012
        avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
 
1013
        avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
 
1014
        avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
 
1015
        avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
 
1016
        avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
 
1017
        avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
 
1018
        avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
 
1019
        avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
 
1020
        avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
 
1021
        avi_cfg.db4_videocode = cfg->cm.code;
 
1022
        avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
 
1023
        avi_cfg.db6_7_line_eoftop = 0;
 
1024
        avi_cfg.db8_9_line_sofbottom = 0;
 
1025
        avi_cfg.db10_11_pixel_eofleft = 0;
 
1026
        avi_cfg.db12_13_pixel_sofright = 0;
 
1027
 
 
1028
        hdmi_core_aux_infoframe_avi_config(avi_cfg);
 
1029
 
 
1030
        /* enable/repeat the infoframe */
 
1031
        repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
 
1032
        repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
 
1033
        /* wakeup */
 
1034
        repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
 
1035
        repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
 
1036
        hdmi_core_av_packet_config(repeat_cfg);
 
1037
}
 
1038
 
 
1039
static void update_hdmi_timings(struct hdmi_config *cfg,
 
1040
                struct omap_video_timings *timings, int code)
 
1041
{
 
1042
        cfg->timings.timings.x_res = timings->x_res;
 
1043
        cfg->timings.timings.y_res = timings->y_res;
 
1044
        cfg->timings.timings.hbp = timings->hbp;
 
1045
        cfg->timings.timings.hfp = timings->hfp;
 
1046
        cfg->timings.timings.hsw = timings->hsw;
 
1047
        cfg->timings.timings.vbp = timings->vbp;
 
1048
        cfg->timings.timings.vfp = timings->vfp;
 
1049
        cfg->timings.timings.vsw = timings->vsw;
 
1050
        cfg->timings.timings.pixel_clock = timings->pixel_clock;
 
1051
        cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
 
1052
        cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
 
1053
}
 
1054
 
 
1055
static void hdmi_compute_pll(unsigned long clkin, int phy,
 
1056
        int n, struct hdmi_pll_info *pi)
 
1057
{
 
1058
        unsigned long refclk;
 
1059
        u32 mf;
 
1060
 
 
1061
        /*
 
1062
         * Input clock is predivided by N + 1
 
1063
         * out put of which is reference clk
 
1064
         */
 
1065
        refclk = clkin / (n + 1);
 
1066
        pi->regn = n;
 
1067
 
 
1068
        /*
 
1069
         * multiplier is pixel_clk/ref_clk
 
1070
         * Multiplying by 100 to avoid fractional part removal
 
1071
         */
 
1072
        pi->regm = (phy * 100/(refclk))/100;
 
1073
        pi->regm2 = 1;
 
1074
 
 
1075
        /*
 
1076
         * fractional multiplier is remainder of the difference between
 
1077
         * multiplier and actual phy(required pixel clock thus should be
 
1078
         * multiplied by 2^18(262144) divided by the reference clock
 
1079
         */
 
1080
        mf = (phy - pi->regm * refclk) * 262144;
 
1081
        pi->regmf = mf/(refclk);
 
1082
 
 
1083
        /*
 
1084
         * Dcofreq should be set to 1 if required pixel clock
 
1085
         * is greater than 1000MHz
 
1086
         */
 
1087
        pi->dcofreq = phy > 1000 * 100;
 
1088
        pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
 
1089
 
 
1090
        DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
 
1091
        DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
 
1092
}
 
1093
 
 
1094
static void hdmi_enable_clocks(int enable)
 
1095
{
 
1096
        if (enable)
 
1097
                dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
 
1098
                                DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
 
1099
        else
 
1100
                dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
 
1101
                                DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
 
1102
}
 
1103
 
 
1104
static int hdmi_power_on(struct omap_dss_device *dssdev)
 
1105
{
 
1106
        int r, code = 0;
 
1107
        struct hdmi_pll_info pll_data;
 
1108
        struct omap_video_timings *p;
 
1109
        int clkin, n, phy;
 
1110
 
 
1111
        hdmi_enable_clocks(1);
 
1112
 
 
1113
        dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
 
1114
 
 
1115
        p = &dssdev->panel.timings;
 
1116
 
 
1117
        DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
 
1118
                dssdev->panel.timings.x_res,
 
1119
                dssdev->panel.timings.y_res);
 
1120
 
 
1121
        if (!hdmi.custom_set) {
 
1122
                DSSDBG("Read EDID as no EDID is not set on poweron\n");
 
1123
                hdmi_read_edid(p);
 
1124
        }
 
1125
        code = get_timings_index();
 
1126
        dssdev->panel.timings = cea_vesa_timings[code].timings;
 
1127
        update_hdmi_timings(&hdmi.cfg, p, code);
 
1128
 
 
1129
        clkin = 3840; /* 38.4 MHz */
 
1130
        n = 15; /* this is a constant for our math */
 
1131
        phy = p->pixel_clock;
 
1132
 
 
1133
        hdmi_compute_pll(clkin, phy, n, &pll_data);
 
1134
 
 
1135
        hdmi_wp_video_start(0);
 
1136
 
 
1137
        /* config the PLL and PHY first */
 
1138
        r = hdmi_pll_program(&pll_data);
 
1139
        if (r) {
 
1140
                DSSDBG("Failed to lock PLL\n");
 
1141
                goto err;
 
1142
        }
 
1143
 
 
1144
        r = hdmi_phy_init();
 
1145
        if (r) {
 
1146
                DSSDBG("Failed to start PHY\n");
 
1147
                goto err;
 
1148
        }
 
1149
 
 
1150
        hdmi.cfg.cm.mode = hdmi.mode;
 
1151
        hdmi.cfg.cm.code = hdmi.code;
 
1152
        hdmi_basic_configure(&hdmi.cfg);
 
1153
 
 
1154
        /* Make selection of HDMI in DSS */
 
1155
        dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
 
1156
 
 
1157
        /* Select the dispc clock source as PRCM clock, to ensure that it is not
 
1158
         * DSI PLL source as the clock selected by DSI PLL might not be
 
1159
         * sufficient for the resolution selected / that can be changed
 
1160
         * dynamically by user. This can be moved to single location , say
 
1161
         * Boardfile.
 
1162
         */
 
1163
        dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
 
1164
 
 
1165
        /* bypass TV gamma table */
 
1166
        dispc_enable_gamma_table(0);
 
1167
 
 
1168
        /* tv size */
 
1169
        dispc_set_digit_size(dssdev->panel.timings.x_res,
 
1170
                        dssdev->panel.timings.y_res);
 
1171
 
 
1172
        dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
 
1173
 
 
1174
        hdmi_wp_video_start(1);
 
1175
 
 
1176
        return 0;
 
1177
err:
 
1178
        hdmi_enable_clocks(0);
 
1179
        return -EIO;
 
1180
}
 
1181
 
 
1182
static void hdmi_power_off(struct omap_dss_device *dssdev)
 
1183
{
 
1184
        dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
 
1185
 
 
1186
        hdmi_wp_video_start(0);
 
1187
        hdmi_phy_off();
 
1188
        hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
 
1189
        hdmi_enable_clocks(0);
 
1190
 
 
1191
        hdmi.edid_set = 0;
 
1192
}
 
1193
 
 
1194
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 
1195
                                        struct omap_video_timings *timings)
 
1196
{
 
1197
        struct hdmi_cm cm;
 
1198
 
 
1199
        cm = hdmi_get_code(timings);
 
1200
        if (cm.code == -1) {
 
1201
                DSSERR("Invalid timing entered\n");
 
1202
                return -EINVAL;
 
1203
        }
 
1204
 
 
1205
        return 0;
 
1206
 
 
1207
}
 
1208
 
 
1209
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 
1210
{
 
1211
        struct hdmi_cm cm;
 
1212
 
 
1213
        hdmi.custom_set = 1;
 
1214
        cm = hdmi_get_code(&dssdev->panel.timings);
 
1215
        hdmi.code = cm.code;
 
1216
        hdmi.mode = cm.mode;
 
1217
        omapdss_hdmi_display_enable(dssdev);
 
1218
        hdmi.custom_set = 0;
 
1219
}
 
1220
 
 
1221
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 
1222
{
 
1223
        int r = 0;
 
1224
 
 
1225
        DSSDBG("ENTER hdmi_display_enable\n");
 
1226
 
 
1227
        mutex_lock(&hdmi.lock);
 
1228
 
 
1229
        r = omap_dss_start_device(dssdev);
 
1230
        if (r) {
 
1231
                DSSERR("failed to start device\n");
 
1232
                goto err0;
 
1233
        }
 
1234
 
 
1235
        if (dssdev->platform_enable) {
 
1236
                r = dssdev->platform_enable(dssdev);
 
1237
                if (r) {
 
1238
                        DSSERR("failed to enable GPIO's\n");
 
1239
                        goto err1;
 
1240
                }
 
1241
        }
 
1242
 
 
1243
        r = hdmi_power_on(dssdev);
 
1244
        if (r) {
 
1245
                DSSERR("failed to power on device\n");
 
1246
                goto err2;
 
1247
        }
 
1248
 
 
1249
        mutex_unlock(&hdmi.lock);
 
1250
        return 0;
 
1251
 
 
1252
err2:
 
1253
        if (dssdev->platform_disable)
 
1254
                dssdev->platform_disable(dssdev);
 
1255
err1:
 
1256
        omap_dss_stop_device(dssdev);
 
1257
err0:
 
1258
        mutex_unlock(&hdmi.lock);
 
1259
        return r;
 
1260
}
 
1261
 
 
1262
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
 
1263
{
 
1264
        DSSDBG("Enter hdmi_display_disable\n");
 
1265
 
 
1266
        mutex_lock(&hdmi.lock);
 
1267
 
 
1268
        hdmi_power_off(dssdev);
 
1269
 
 
1270
        if (dssdev->platform_disable)
 
1271
                dssdev->platform_disable(dssdev);
 
1272
 
 
1273
        omap_dss_stop_device(dssdev);
 
1274
 
 
1275
        mutex_unlock(&hdmi.lock);
 
1276
}
 
1277
 
 
1278
/* HDMI HW IP initialisation */
 
1279
static int omapdss_hdmihw_probe(struct platform_device *pdev)
 
1280
{
 
1281
        struct resource *hdmi_mem;
 
1282
 
 
1283
        hdmi.pdata = pdev->dev.platform_data;
 
1284
        hdmi.pdev = pdev;
 
1285
 
 
1286
        mutex_init(&hdmi.lock);
 
1287
 
 
1288
        hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
 
1289
        if (!hdmi_mem) {
 
1290
                DSSERR("can't get IORESOURCE_MEM HDMI\n");
 
1291
                return -EINVAL;
 
1292
        }
 
1293
 
 
1294
        /* Base address taken from platform */
 
1295
        hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
 
1296
        if (!hdmi.base_wp) {
 
1297
                DSSERR("can't ioremap WP\n");
 
1298
                return -ENOMEM;
 
1299
        }
 
1300
 
 
1301
        hdmi_panel_init();
 
1302
 
 
1303
        return 0;
 
1304
}
 
1305
 
 
1306
static int omapdss_hdmihw_remove(struct platform_device *pdev)
 
1307
{
 
1308
        hdmi_panel_exit();
 
1309
 
 
1310
        iounmap(hdmi.base_wp);
 
1311
 
 
1312
        return 0;
 
1313
}
 
1314
 
 
1315
static struct platform_driver omapdss_hdmihw_driver = {
 
1316
        .probe          = omapdss_hdmihw_probe,
 
1317
        .remove         = omapdss_hdmihw_remove,
 
1318
        .driver         = {
 
1319
                .name   = "omapdss_hdmi",
 
1320
                .owner  = THIS_MODULE,
 
1321
        },
 
1322
};
 
1323
 
 
1324
int hdmi_init_platform_driver(void)
 
1325
{
 
1326
        return platform_driver_register(&omapdss_hdmihw_driver);
 
1327
}
 
1328
 
 
1329
void hdmi_uninit_platform_driver(void)
 
1330
{
 
1331
        return platform_driver_unregister(&omapdss_hdmihw_driver);
 
1332
}