• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2008, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <boot/boot.h>
30 #include <boot/board.h>
31 #include <msm7k/mddi.h>
32 
33 unsigned fb_width = 0;
34 unsigned fb_height = 0;
35 
36 static unsigned short *FB;
37 static mddi_llentry *mlist;
38 
wr32(void * _dst,unsigned n)39 void wr32(void *_dst, unsigned n)
40 {
41     unsigned char *src = (unsigned char*) &n;
42     unsigned char *dst = _dst;
43 
44     dst[0] = src[0];
45     dst[1] = src[1];
46     dst[2] = src[2];
47     dst[3] = src[3];
48 };
49 
printcaps(mddi_client_caps * c)50 void printcaps(mddi_client_caps *c)
51 {
52     if((c->length != 0x4a) || (c->type != 0x42)) {
53         dprintf("bad caps header\n");
54         memset(c, 0, sizeof(*c));
55         return;
56     }
57 
58     dprintf("mddi: bm: %d,%d win %d,%d rgb %x\n",
59             c->bitmap_width, c->bitmap_height,
60             c->display_window_width, c->display_window_height,
61             c->rgb_cap);
62     dprintf("mddi: vend %x prod %x\n",
63             c->manufacturer_name, c->product_code);
64 
65     fb_width = c->bitmap_width;
66     fb_height = c->bitmap_height;
67 
68     panel_init(c);
69 }
70 
71 mddi_llentry *mlist_remote_write = 0;
72 
mddi_remote_write(unsigned val,unsigned reg)73 void mddi_remote_write(unsigned val, unsigned reg)
74 {
75     mddi_llentry *ll;
76     mddi_register_access *ra;
77     unsigned s;
78 
79     if(mlist_remote_write == 0) {
80         mlist_remote_write = alloc(sizeof(mddi_llentry));
81     }
82 
83     ll = mlist_remote_write;
84 
85     ra = &(ll->u.r);
86     ra->length = 14 + 4;
87     ra->type = TYPE_REGISTER_ACCESS;
88     ra->client_id = 0;
89     ra->rw_info = MDDI_WRITE | 1;
90     ra->crc = 0;
91 
92     wr32(&ra->reg_addr, reg);
93     wr32(&ra->reg_data, val);
94 
95     ll->flags = 1;
96     ll->header_count = 14;
97     ll->data_count = 4;
98     wr32(&ll->data, (unsigned) &ra->reg_data);
99     wr32(&ll->next, 0);
100     ll->reserved = 0;
101 
102     writel((unsigned) ll, MDDI_PRI_PTR);
103 
104     s = readl(MDDI_STAT);
105     while((s & 0x20) == 0){
106         s = readl(MDDI_STAT);
107     }
108 }
109 
mddi_start_update(void)110 void mddi_start_update(void)
111 {
112     writel((unsigned) mlist, MDDI_PRI_PTR);
113 }
114 
mddi_update_done(void)115 int mddi_update_done(void)
116 {
117     return !!(readl(MDDI_STAT) & MDDI_STAT_PRI_LINK_LIST_DONE);
118 }
119 
mddi_do_cmd(unsigned cmd)120 void mddi_do_cmd(unsigned cmd)
121 {
122     writel(cmd, MDDI_CMD);
123 
124     while (!(readl(MDDI_INT) & MDDI_INT_NO_REQ_PKTS_PENDING)) ;
125 }
126 
127 unsigned char *rev_pkt_buf;
128 
mddi_get_caps(void)129 void mddi_get_caps(void)
130 {
131     unsigned timeout = 100000;
132     unsigned n;
133 
134     memset(rev_pkt_buf, 0xee, 256);
135 
136 //    writel(CMD_HIBERNATE, MDDI_CMD);
137 //    writel(CMD_LINK_ACTIVE, MDDI_CMD);
138 
139     writel(256, MDDI_REV_SIZE);
140     writel((unsigned) rev_pkt_buf, MDDI_REV_PTR);
141     mddi_do_cmd(CMD_FORCE_NEW_REV_PTR);
142 
143         /* sometimes this will fail -- do it three times for luck... */
144     mddi_do_cmd(CMD_RTD_MEASURE);
145     mdelay(1);
146 
147     mddi_do_cmd(CMD_RTD_MEASURE);
148     mdelay(1);
149 
150     mddi_do_cmd(CMD_RTD_MEASURE);
151     mdelay(1);
152 
153     mddi_do_cmd(CMD_GET_CLIENT_CAP);
154 
155     do {
156         n = readl(MDDI_INT);
157     } while(!(n & MDDI_INT_REV_DATA_AVAIL) && (--timeout));
158 
159     if(timeout == 0) dprintf("timeout\n");
160     printcaps((mddi_client_caps*) rev_pkt_buf);
161 }
162 
163 
mddi_init(void)164 void mddi_init(void)
165 {
166     unsigned n;
167 
168 //    dprintf("mddi_init()\n");
169 
170     rev_pkt_buf = alloc(256);
171 
172     mddi_do_cmd(CMD_RESET);
173 
174         /* disable periodic rev encap */
175     mddi_do_cmd(CMD_PERIODIC_REV_ENC | 0);
176 
177     writel(0x0001, MDDI_VERSION);
178     writel(0x3C00, MDDI_BPS);
179     writel(0x0003, MDDI_SPM);
180 
181     writel(0x0005, MDDI_TA1_LEN);
182     writel(0x000C, MDDI_TA2_LEN);
183     writel(0x0096, MDDI_DRIVE_HI);
184     writel(0x0050, MDDI_DRIVE_LO);
185     writel(0x003C, MDDI_DISP_WAKE);
186     writel(0x0002, MDDI_REV_RATE_DIV);
187 
188         /* needs to settle for 5uS */
189     if (readl(MDDI_PAD_CTL) == 0) {
190         writel(0x08000, MDDI_PAD_CTL);
191         udelay(5);
192     }
193 
194     writel(0xA850F, MDDI_PAD_CTL);
195     writel(0x60006, MDDI_DRIVER_START_CNT);
196 
197     writel((unsigned) rev_pkt_buf, MDDI_REV_PTR);
198     writel(256, MDDI_REV_SIZE);
199     writel(256, MDDI_REV_ENCAP_SZ);
200 
201     mddi_do_cmd(CMD_FORCE_NEW_REV_PTR);
202 
203         /* disable hibernate */
204     mddi_do_cmd(CMD_HIBERNATE | 0);
205 
206     panel_backlight(0);
207 
208     panel_poweron();
209 
210     mddi_do_cmd(CMD_LINK_ACTIVE);
211 
212     do {
213         n = readl(MDDI_STAT);
214     } while(!(n & MDDI_STAT_LINK_ACTIVE));
215 
216         /* v > 8?  v > 8 && < 0x19 ? */
217     writel(2, MDDI_TEST);
218 
219 //    writel(CMD_PERIODIC_REV_ENC | 0, MDDI_CMD); /* disable */
220 
221 	mddi_get_caps();
222 
223 #if 0
224     writel(0x5666, MDDI_MDP_VID_FMT_DES);
225     writel(0x00C3, MDDI_MDP_VID_PIX_ATTR);
226     writel(0x0000, MDDI_MDP_CLIENTID);
227 #endif
228 
229     dprintf("panel is %d x %d\n", fb_width, fb_height);
230 
231     FB = alloc(2 * fb_width * fb_height);
232     mlist = alloc(sizeof(mddi_llentry) * (fb_height / 8));
233 
234 //    dprintf("FB @ %x  mlist @ %x\n", (unsigned) FB, (unsigned) mlist);
235 
236     for(n = 0; n < (fb_height / 8); n++) {
237         unsigned y = n * 8;
238         unsigned pixels = fb_width * 8;
239         mddi_video_stream *vs = &(mlist[n].u.v);
240 
241         vs->length = sizeof(mddi_video_stream) - 2 + (pixels * 2);
242         vs->type = TYPE_VIDEO_STREAM;
243         vs->client_id = 0;
244         vs->format = 0x5565; // FORMAT_16BPP;
245         vs->pixattr = PIXATTR_BOTH_EYES | PIXATTR_TO_ALL;
246 
247         vs->left = 0;
248         vs->right = fb_width - 1;
249         vs->top = y;
250         vs->bottom = y + 7;
251 
252         vs->start_x = 0;
253         vs->start_y = y;
254 
255         vs->pixels = pixels;
256         vs->crc = 0;
257         vs->reserved = 0;
258 
259         mlist[n].header_count = sizeof(mddi_video_stream) - 2;
260         mlist[n].data_count = pixels * 2;
261         mlist[n].reserved = 0;
262         wr32(&mlist[n].data, ((unsigned) FB) + (y * fb_width * 2));
263 
264         mlist[n].flags = 0;
265         wr32(&mlist[n].next, (unsigned) (mlist + n + 1));
266     }
267 
268     mlist[n-1].flags = 1;
269     wr32(&mlist[n-1].next, 0);
270 
271     writel(CMD_HIBERNATE, MDDI_CMD);
272     writel(CMD_LINK_ACTIVE, MDDI_CMD);
273 
274     for(n = 0; n < (fb_width * fb_height); n++) FB[n] = 0;
275 
276     mddi_start_update();
277 
278     panel_backlight(1);
279 }
280 
mddi_framebuffer(void)281 void *mddi_framebuffer(void)
282 {
283     return FB;
284 }
285 
286