2 * SMedia Glamo 336x/337x display
4 * Copyright (C) 2008-2009 Thomas White <taw@bitwiz.org.uk>
6 * Based on glamo-fb.c (C) 2007-2008 by Openmoko, Inc.
7 * Author: Harald Welte <laforge@openmoko.org>
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 * Based on intel_display.c and intel_crt.c from drivers/gpu/drm/i915
27 * to which the following licence applies:
29 * Copyright © 2006-2007 Intel Corporation
31 * Permission is hereby granted, free of charge, to any person obtaining a
32 * copy of this software and associated documentation files (the "Software"),
33 * to deal in the Software without restriction, including without limitation
34 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35 * and/or sell copies of the Software, and to permit persons to whom the
36 * Software is furnished to do so, subject to the following conditions:
38 * The above copyright notice and this permission notice (including the next
39 * paragraph) shall be included in all copies or substantial portions of the
42 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
45 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
47 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
48 * DEALINGS IN THE SOFTWARE.
51 * Eric Anholt <eric@anholt.net>
58 #include <drm/glamo_drm.h>
59 #include <drm/drm_crtc_helper.h>
60 #include <drm/drm_crtc.h>
62 #include "glamo-core.h"
63 #include "glamo-drm-private.h"
64 #include "glamo-regs.h"
65 #include "glamo-kms-fb.h"
66 #include <linux/glamofb.h>
69 #define GLAMO_LCD_WIDTH_MASK 0x03FF
70 #define GLAMO_LCD_HEIGHT_MASK 0x03FF
71 #define GLAMO_LCD_PITCH_MASK 0x07FE
72 #define GLAMO_LCD_HV_TOTAL_MASK 0x03FF
73 #define GLAMO_LCD_HV_RETR_START_MASK 0x03FF
74 #define GLAMO_LCD_HV_RETR_END_MASK 0x03FF
75 #define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF
76 #define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF
80 struct drm_device *dev;
81 struct drm_display_mode *our_mode;
82 struct glamo_framebuffer *glamo_fb;
84 /* crtc currently bound to this */
89 static int reg_read_lcd(struct glamodrm_handle *gdrm, u_int16_t reg)
93 for (i = 0; i != 2; i++)
96 return ioread16(gdrm->lcd_base + reg);
100 static void reg_write_lcd(struct glamodrm_handle *gdrm,
101 u_int16_t reg, u_int16_t val)
105 for (i = 0; i != 2; i++)
108 iowrite16(val, gdrm->lcd_base + reg);
112 static void reg_set_bit_mask_lcd(struct glamodrm_handle *gdrm,
113 u_int16_t reg, u_int16_t mask,
120 tmp = reg_read_lcd(gdrm, reg);
123 reg_write_lcd(gdrm, reg, tmp);
127 /* Note that this has nothing at all to do with the engine command queue
129 static inline int glamo_lcd_cmdq_empty(struct glamodrm_handle *gdrm)
131 /* DGCMdQempty -- 1 == command queue is empty */
132 return reg_read_lcd(gdrm, GLAMO_REG_LCD_STATUS1) & (1 << 15);
136 /* call holding gfb->lock_cmd when locking, until you unlock */
137 int glamo_lcd_cmd_mode(struct glamodrm_handle *gdrm, int on)
139 int timeout = 2000000;
141 if (gdrm->glamo_core->suspending) {
142 dev_err(&gdrm->glamo_core->pdev->dev,
143 "IGNORING glamofb_cmd_mode while"
148 dev_dbg(gdrm->dev, "glamofb_cmd_mode(on=%d)\n", on);
151 while ((!glamo_lcd_cmdq_empty(gdrm)) && (timeout--))
154 printk(KERN_ERR "*************"
155 " LCD command queue never got empty "
160 /* display the entire frame then switch to command */
161 reg_write_lcd(gdrm, GLAMO_REG_LCD_COMMAND1,
162 GLAMO_LCD_CMD_TYPE_DISP |
163 GLAMO_LCD_CMD_DATA_FIRE_VSYNC);
165 /* wait until lcd idle */
167 while ((!reg_read_lcd(gdrm, GLAMO_REG_LCD_STATUS2) & (1 << 12))
171 printk(KERN_ERR"*************"
180 /* RGB interface needs vsync/hsync */
182 mode = reg_read_lcd(gdrm, GLAMO_REG_LCD_MODE3);
183 if ( mode & GLAMO_LCD_MODE3_RGB)
184 reg_write_lcd(gdrm, GLAMO_REG_LCD_COMMAND1,
185 GLAMO_LCD_CMD_TYPE_DISP |
186 GLAMO_LCD_CMD_DATA_DISP_SYNC);
188 reg_write_lcd(gdrm, GLAMO_REG_LCD_COMMAND1,
189 GLAMO_LCD_CMD_TYPE_DISP |
190 GLAMO_LCD_CMD_DATA_DISP_FIRE);
197 static struct glamo_script lcd_init_script[] = {
198 { GLAMO_REG_LCD_MODE1, 0x0020 },
199 /* no display rotation, no hardware cursor, no dither, no gamma,
200 * no retrace flip, vsync low-active, hsync low active,
201 * no TVCLK, no partial display, hw dest color from fb,
202 * no partial display mode, LCD1, software flip, */
203 { GLAMO_REG_LCD_MODE2, 0x9020 },
204 /* video flip, no ptr, no ptr, dhclk off,
205 * normal mode, no cpuif,
206 * res, serial msb first, single fb, no fr ctrl,
207 * cpu if bits all zero, no crc
208 * 0000 0000 0010 0000 */
209 { GLAMO_REG_LCD_MODE3, 0x0b40 },
210 /* src data rgb565, res, 18bit rgb666
211 * 000 01 011 0100 0000 */
212 { GLAMO_REG_LCD_POLARITY, 0x440c },
213 /* DE high active, no cpu/lcd if, cs0 force low, a0 low active,
214 * np cpu if, 9bit serial data, sclk rising edge latch data
215 * 01 00 0 100 0 000 01 0 0 */
216 /* The following values assume 640*480@16bpp */
217 { GLAMO_REG_LCD_A_BASE1, 0x0000 }, /* display A base address 15:0 */
218 { GLAMO_REG_LCD_A_BASE2, 0x0000 }, /* display A base address 22:16 */
219 { GLAMO_REG_LCD_B_BASE1, 0x6000 }, /* display B base address 15:0 */
220 { GLAMO_REG_LCD_B_BASE2, 0x0009 }, /* display B base address 22:16 */
221 { GLAMO_REG_LCD_CURSOR_BASE1, 0xC000 }, /* cursor base address 15:0 */
222 { GLAMO_REG_LCD_CURSOR_BASE2, 0x0012 }, /* cursor base address 22:16 */
223 { GLAMO_REG_LCD_COMMAND2, 0x0000 }, /* display page A */
227 static int glamo_run_lcd_script(struct glamodrm_handle *gdrm,
228 struct glamo_script *script, int len)
232 for (i = 0; i < len; i++) {
233 struct glamo_script *line = &script[i];
235 if (line->reg == 0xffff)
237 else if (line->reg == 0xfffe)
240 reg_write_lcd(gdrm, script[i].reg, script[i].val);
248 static void notify_blank(struct drm_crtc *crtc, int mode)
250 struct fb_event event;
253 event.data = &blank_mode;
254 fb_notifier_call_chain(FB_EVENT_CONBLANK, &event);
259 extern void jbt6k74_action(int val);
263 static void glamo_crtc_dpms(struct drm_crtc *crtc, int mode)
265 struct glamodrm_handle *gdrm;
266 struct glamo_crtc *glamo_crtc = to_glamo_crtc(crtc);
268 printk(KERN_CRIT "glamo_crtc_dpms(%u)\n", mode);
269 gdrm = glamo_crtc->gdrm;
272 case DRM_MODE_DPMS_OFF:
273 /* LCM need notification before pixel clock is stopped */
276 /* disable the pixel clock */
277 // glamo_engine_clkreg_set(gdrm->glamo_core, GLAMO_ENGINE_LCD,
278 // GLAMO_CLOCK_LCD_EN_DCLK, 0);
279 glamo_crtc->blank_mode = mode;
281 case DRM_MODE_DPMS_ON:
282 /* enable the pixel clock if off */
283 if (glamo_crtc->blank_mode == DRM_MODE_DPMS_OFF)
284 glamo_engine_clkreg_set(gdrm->glamo_core,
286 GLAMO_CLOCK_LCD_EN_DCLK,
287 GLAMO_CLOCK_LCD_EN_DCLK);
290 glamo_crtc->blank_mode = mode;
296 static bool glamo_crtc_mode_fixup(struct drm_crtc *crtc,
297 struct drm_display_mode *mode,
298 struct drm_display_mode *adjusted_mode)
300 printk(KERN_CRIT "glamo_crtc_mode_fixup\n");
305 static void glamo_crtc_mode_set(struct drm_crtc *crtc,
306 struct drm_display_mode *mode,
307 struct drm_display_mode *adjusted_mode,
309 struct drm_framebuffer *old_fb)
311 struct glamodrm_handle *gdrm;
312 struct glamo_crtc *gcrtc;
313 int retr_start, retr_end, disp_start, disp_end;
315 printk(KERN_CRIT "glamo_crtc_mode_set\n");
317 /* Dig out our handle */
318 gcrtc = to_glamo_crtc(crtc);
319 gdrm = gcrtc->gdrm; /* Here it is! */
321 glamo_lcd_cmd_mode(gdrm, 1);
322 glamo_engine_reclock(gdrm->glamo_core, GLAMO_ENGINE_LCD, mode->clock);
324 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_WIDTH,
325 GLAMO_LCD_WIDTH_MASK, mode->hdisplay);
326 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HEIGHT,
327 GLAMO_LCD_HEIGHT_MASK, mode->vdisplay);
328 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_PITCH,
329 GLAMO_LCD_PITCH_MASK, mode->hdisplay*2);
331 /* Convert "X modeline timings" into "Glamo timings" */
333 retr_end = retr_start + mode->hsync_end - mode->hsync_start;
334 disp_start = mode->htotal - mode->hsync_start;
335 disp_end = disp_start + mode->hdisplay;
336 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_TOTAL,
337 GLAMO_LCD_HV_TOTAL_MASK, mode->htotal);
338 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_START,
339 GLAMO_LCD_HV_RETR_START_MASK, retr_start);
340 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_END,
341 GLAMO_LCD_HV_RETR_END_MASK, retr_end);
342 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_START,
343 GLAMO_LCD_HV_RETR_DISP_START_MASK, disp_start);
344 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_END,
345 GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end);
347 /* The same in the vertical direction */
349 retr_end = retr_start + mode->vsync_end - mode->vsync_start;
350 disp_start = mode->vtotal - mode->vsync_start;
351 disp_end = disp_start + mode->vdisplay;
352 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_TOTAL,
353 GLAMO_LCD_HV_TOTAL_MASK, mode->vtotal);
354 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_START,
355 GLAMO_LCD_HV_RETR_START_MASK, retr_start);
356 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_END,
357 GLAMO_LCD_HV_RETR_END_MASK, retr_end);
358 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_START,
359 GLAMO_LCD_HV_RETR_DISP_START_MASK, disp_start);
360 reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_END,
361 GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end);
363 glamo_lcd_cmd_mode(gdrm, 0);
367 static void glamo_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
368 struct drm_framebuffer *old_fb)
370 printk(KERN_CRIT "glamo_crtc_mode_set_base\n");
374 static void glamo_crtc_prepare(struct drm_crtc *crtc)
376 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
377 printk(KERN_CRIT "glamo_crtc_prepare\n");
378 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
382 static void glamo_crtc_commit(struct drm_crtc *crtc)
384 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
385 printk(KERN_CRIT "glamo_crtc_commit\n");
386 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
390 static int glamo_crtc_cursor_set(struct drm_crtc *crtc,
391 struct drm_file *file_priv,
393 uint32_t width, uint32_t height)
395 printk(KERN_CRIT "glamo_crtc_cursor_set\n");
400 static int glamo_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
402 printk(KERN_CRIT "glamo_crtc_cursor_move\n");
407 static void glamo_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
408 u16 *blue, uint32_t size)
410 printk(KERN_CRIT "glamo_crtc_gamma_set\n");
414 static void glamo_crtc_destroy(struct drm_crtc *crtc)
416 struct glamo_crtc *glamo_crtc = to_glamo_crtc(crtc);
417 printk(KERN_CRIT "glamo_crtc_destroy\n");
418 drm_crtc_cleanup(crtc);
423 static enum drm_connector_status
424 glamo_connector_detect(struct drm_connector *connector)
426 /* One hopes it hasn't been de-soldered... */
427 printk(KERN_CRIT "glamo_connector_detect\n");
428 return connector_status_connected;
432 static void glamo_connector_destroy(struct drm_connector *connector)
434 printk(KERN_CRIT "glamo_connector_destroy\n");
435 drm_sysfs_connector_remove(connector);
436 drm_connector_cleanup(connector);
441 static int glamo_connector_get_modes(struct drm_connector *connector)
443 struct drm_display_mode *mode;
444 struct glamofb_platform_data *mach_info;
445 struct glamo_output *goutput = to_glamo_output(connector);
446 struct glamodrm_handle *gdrm = goutput->gdrm;
448 /* Dig out the record which will tell us about the hardware */
449 mach_info = gdrm->glamo_core->pdev->dev.platform_data;
451 printk(KERN_CRIT "glamo_connector_get_modes\n");
453 mode = drm_mode_create(connector->dev);
456 /* Fill in 'mode' here */
457 mode->type = DRM_MODE_TYPE_DEFAULT | DRM_MODE_TYPE_PREFERRED;
459 /* Convert framebuffer timings into KMS timings */
460 mode->clock = 1000000 / mach_info->pixclock; /* ps -> Hz */
461 mode->hdisplay = mach_info->xres.defval;
462 mode->hsync_start = mach_info->right_margin + mode->hdisplay;
463 mode->hsync_end = mode->hsync_start + mach_info->hsync_len;
464 mode->htotal = mode->hsync_end + mach_info->left_margin;
467 mode->vdisplay = mach_info->yres.defval;
468 mode->vsync_start = mach_info->lower_margin + mode->vdisplay;
469 mode->vsync_end = mode->vsync_start + mach_info->vsync_len;
470 mode->vtotal = mode->vsync_end + mach_info->upper_margin;
473 mode->width_mm = mach_info->width;
474 mode->height_mm = mach_info->height;
476 printk(KERN_CRIT "Modeline \"%ix%i\" %i %i %i %i %i %i %i %i %i\n",
477 mode->hdisplay, mode->vdisplay, mode->clock,
478 mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
479 mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal);
481 drm_mode_set_name(mode);
482 drm_mode_probed_add(connector, mode);
484 return 1; /* one mode, for now */
488 static int glamo_connector_set_property(struct drm_connector *connector,
489 struct drm_property *property,
492 printk(KERN_CRIT "glamo_connector_set_property\n");
497 static int glamo_connector_mode_valid(struct drm_connector *connector,
498 struct drm_display_mode *mode)
500 printk(KERN_CRIT "glamo_connector_mode_valid\n");
501 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
502 return MODE_NO_DBLESCAN;
509 glamo_connector_best_encoder(struct drm_connector *connector)
511 struct glamo_output *glamo_output = to_glamo_output(connector);
512 printk(KERN_CRIT "glamo_connector_best_encoder\n");
513 return &glamo_output->enc;
517 static void glamo_encoder_dpms(struct drm_encoder *encoder, int mode)
519 printk(KERN_CRIT "glamo_encoder_dpms\n");
523 static bool glamo_encoder_mode_fixup(struct drm_encoder *encoder,
524 struct drm_display_mode *mode,
525 struct drm_display_mode *adjusted_mode)
527 printk(KERN_CRIT "glamo_encoder_mode_fixup\n");
532 void glamo_encoder_prepare(struct drm_encoder *encoder)
534 printk(KERN_CRIT "glamo_encoder_prepare\n");
538 void glamo_encoder_commit(struct drm_encoder *encoder)
540 printk(KERN_CRIT "glamo_encoder_commit\n");
544 static void glamo_encoder_mode_set(struct drm_encoder *encoder,
545 struct drm_display_mode *mode,
546 struct drm_display_mode *adjusted_mode)
548 printk(KERN_CRIT "glamo_encoder_mode_set\n");
552 static void glamo_encoder_destroy(struct drm_encoder *encoder)
554 printk(KERN_CRIT "glamo_encoder_destroy\n");
555 drm_encoder_cleanup(encoder);
559 static void glamo_framebuffer_destroy(struct drm_framebuffer *fb)
561 struct glamo_framebuffer *glamo_fb = to_glamo_framebuffer(fb);
562 struct drm_device *dev = fb->dev;
563 printk(KERN_CRIT "glamo_user_framebuffer_destroy\n");
565 drm_framebuffer_cleanup(fb);
566 mutex_lock(&dev->struct_mutex);
567 drm_gem_object_unreference(glamo_fb->obj);
568 mutex_unlock(&dev->struct_mutex);
573 static int glamo_framebuffer_create_handle(struct drm_framebuffer *fb,
574 struct drm_file *file_priv,
575 unsigned int *handle)
577 struct glamo_framebuffer *glamo_fb = to_glamo_framebuffer(fb);
578 struct drm_gem_object *object = glamo_fb->obj;
579 printk(KERN_CRIT "glamo_user_framebuffer_create_handle\n");
581 return drm_gem_handle_create(file_priv, object, handle);
585 static const struct drm_framebuffer_funcs glamo_fb_funcs = {
586 .destroy = glamo_framebuffer_destroy,
587 .create_handle = glamo_framebuffer_create_handle,
591 int glamo_framebuffer_create(struct drm_device *dev,
592 struct drm_mode_fb_cmd *mode_cmd,
593 struct drm_framebuffer **fb,
594 struct drm_gem_object *obj)
596 struct glamo_framebuffer *glamo_fb;
599 printk(KERN_CRIT "glamo_framebuffer_create\n");
600 glamo_fb = kzalloc(sizeof(*glamo_fb), GFP_KERNEL);
604 ret = drm_framebuffer_init(dev, &glamo_fb->base, &glamo_fb_funcs);
606 DRM_ERROR("framebuffer init failed %d\n", ret);
610 drm_helper_mode_fill_fb_struct(&glamo_fb->base, mode_cmd);
614 *fb = &glamo_fb->base;
620 static struct drm_framebuffer *
621 glamo_user_framebuffer_create(struct drm_device *dev,
622 struct drm_file *filp,
623 struct drm_mode_fb_cmd *mode_cmd)
625 struct drm_gem_object *obj;
626 struct drm_framebuffer *fb;
628 printk(KERN_CRIT "glamo_user_framebuffer_create\n");
630 obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
634 ret = glamo_framebuffer_create(dev, mode_cmd, &fb, obj);
636 drm_gem_object_unreference(obj);
644 int glamo_fbchanged(struct drm_device *dev)
646 printk(KERN_CRIT "glamo_fb_changed\n");
652 static const struct drm_crtc_funcs glamo_crtc_funcs = {
653 .cursor_set = glamo_crtc_cursor_set,
654 .cursor_move = glamo_crtc_cursor_move,
655 .gamma_set = glamo_crtc_gamma_set,
656 .set_config = drm_crtc_helper_set_config,
657 .destroy = glamo_crtc_destroy,
661 /* CRTC helper functions */
662 static const struct drm_crtc_helper_funcs glamo_crtc_helper_funcs = {
663 .dpms = glamo_crtc_dpms,
664 .mode_fixup = glamo_crtc_mode_fixup,
665 .mode_set = glamo_crtc_mode_set,
666 .mode_set_base = glamo_crtc_mode_set_base,
667 .prepare = glamo_crtc_prepare,
668 .commit = glamo_crtc_commit,
672 /* Connector functions */
673 static const struct drm_connector_funcs glamo_connector_funcs = {
674 .detect = glamo_connector_detect,
675 .fill_modes = drm_helper_probe_single_connector_modes,
676 .destroy = glamo_connector_destroy,
677 .set_property = glamo_connector_set_property,
681 /* Connector helper functions */
682 static const struct drm_connector_helper_funcs glamo_connector_helper_funcs = {
683 .mode_valid = glamo_connector_mode_valid,
684 .get_modes = glamo_connector_get_modes,
685 .best_encoder = glamo_connector_best_encoder,
689 /* Encoder functions */
690 static const struct drm_encoder_funcs glamo_encoder_funcs = {
691 .destroy = glamo_encoder_destroy,
695 /* Encoder helper functions */
696 static const struct drm_encoder_helper_funcs glamo_encoder_helper_funcs = {
697 .dpms = glamo_encoder_dpms,
698 .mode_fixup = glamo_encoder_mode_fixup,
699 .prepare = glamo_encoder_prepare,
700 .commit = glamo_encoder_commit,
701 .mode_set = glamo_encoder_mode_set,
706 static const struct drm_mode_config_funcs glamo_mode_funcs = {
707 .fb_create = glamo_user_framebuffer_create,
708 .fb_changed = glamo_fbchanged
712 static struct drm_mode_set kernelfb_mode;
715 /* Restore's the kernel's fbcon mode, used for panic path */
716 void glamo_display_restore(void)
718 drm_crtc_helper_set_config(&kernelfb_mode);
722 static int glamo_display_panic(struct notifier_block *n, unsigned long ununsed,
725 DRM_ERROR("panic occurred, switching back to text console\n");
727 glamo_display_restore();
732 static struct notifier_block paniced = {
733 .notifier_call = glamo_display_panic,
737 int glamo_display_init(struct drm_device *dev)
739 struct glamodrm_handle *gdrm;
740 struct glamo_crtc *glamo_crtc;
741 struct glamo_output *glamo_output;
742 struct drm_connector *connector;
743 struct glamo_framebuffer *glamo_fb;
744 struct fb_info *info;
745 struct glamofb_par *par;
746 struct drm_mode_set *modeset;
748 gdrm = dev->dev_private;
750 printk(KERN_CRIT "glamo_display_init\n");
752 glamo_engine_enable(gdrm->glamo_core, GLAMO_ENGINE_LCD);
753 glamo_engine_reset(gdrm->glamo_core, GLAMO_ENGINE_LCD);
755 drm_mode_config_init(dev);
757 dev->mode_config.min_width = 0;
758 dev->mode_config.min_height = 0;
760 dev->mode_config.funcs = (void *)&glamo_mode_funcs;
762 /* Initialise our CRTC object.
763 * Only one connector per CRTC. We know this: it's kind of soldered. */
764 glamo_crtc = kzalloc(sizeof(struct glamo_crtc)
765 + sizeof(struct drm_connector *), GFP_KERNEL);
766 if (glamo_crtc == NULL) return 1;
767 glamo_crtc->gdrm = gdrm;
768 glamo_crtc->blank_mode = DRM_MODE_DPMS_OFF;
769 drm_crtc_init(dev, &glamo_crtc->base, &glamo_crtc_funcs);
770 drm_crtc_helper_add(&glamo_crtc->base, &glamo_crtc_helper_funcs);
772 glamo_crtc->mode_set.crtc = &glamo_crtc->base;
773 glamo_crtc->mode_set.connectors =
774 (struct drm_connector **)(glamo_crtc + 1);
775 glamo_crtc->mode_set.num_connectors = 0;
777 /* Create our "output" object: consists of an output and an encoder */
778 glamo_output = kzalloc(sizeof(struct glamo_output), GFP_KERNEL);
779 if (glamo_output == NULL) return 1;
780 connector = &glamo_output->base;
781 glamo_output->gdrm = gdrm;
783 /* Initialise the connector */
784 drm_connector_init(dev, connector, &glamo_connector_funcs,
785 DRM_MODE_CONNECTOR_Unknown);
786 drm_sysfs_connector_add(connector);
787 connector->interlace_allowed = 0;
788 connector->doublescan_allowed = 0;
790 /* Initialise the encoder */
791 drm_encoder_init(dev, &glamo_output->enc, &glamo_encoder_funcs,
792 DRM_MODE_ENCODER_DAC);
793 glamo_output->enc.possible_crtcs = 1 << 0;
794 drm_mode_connector_attach_encoder(&glamo_output->base,
797 drm_encoder_helper_add(&glamo_output->enc, &glamo_encoder_helper_funcs);
798 drm_connector_helper_add(connector, &glamo_connector_helper_funcs);
800 drm_helper_initial_config(dev, false);
802 /* Initial setup of the LCD controller */
803 glamo_run_lcd_script(gdrm, lcd_init_script,
804 ARRAY_SIZE(lcd_init_script));
806 if (list_empty(&dev->mode_config.fb_kernel_list)) {
808 ret = glamofb_create(dev, 480, 640, 480, 640, &glamo_fb);
809 if (ret) return -EINVAL;
812 info = glamo_fb->base.fbdev;
815 modeset = &glamo_crtc->mode_set;
816 modeset->fb = &glamo_fb->base;
817 modeset->connectors[0] = connector;
819 par->crtc_ids[0] = glamo_crtc->base.base.id;
821 modeset->num_connectors = 1;
822 modeset->mode = modeset->crtc->desired_mode;
826 if (register_framebuffer(info) < 0)
829 printk(KERN_INFO "[glamo-drm] fb%d: %s frame buffer device\n",
830 info->node, info->fix.id);
832 /* Switch back to kernel console on panic */
833 kernelfb_mode = *modeset;
834 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
835 printk(KERN_INFO "[glamo-drm] registered panic notifier\n");