1/* 2 * 3 * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450. 4 * 5 * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz> 6 * 7 * Portions Copyright (c) 2001 Matrox Graphics Inc. 8 * 9 * Version: 1.62 2001/11/29 10 * 11 * See matroxfb_base.c for contributors. 12 * 13 */ 14 15#include "matroxfb_g450.h" 16#include "matroxfb_misc.h" 17#include "matroxfb_DAC1064.h" 18#include "g450_pll.h" 19#include <linux/matroxfb.h> 20#include <asm/uaccess.h> 21 22static int matroxfb_g450_compute(void* md, struct my_timming* mt) { 23#define m2info ((struct matroxfb_g450_info*)md) 24#define minfo (m2info->primary_dev) 25 ACCESS_FBINFO(hw).vidclk = mt->pixclock; 26#undef minfo 27#undef m2info 28 return 0; 29} 30 31static int matroxfb_g450_program(void* md) { 32#define m2info ((struct matroxfb_g450_info*)md) 33#define minfo (m2info->primary_dev) 34 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(hw).vidclk, M_VIDEO_PLL); 35#undef minfo 36#undef m2info 37 return 0; 38} 39 40static int matroxfb_g450_start(void* md) { 41 return 0; 42} 43 44static void matroxfb_g450_incuse(void* md) { 45 MOD_INC_USE_COUNT; 46} 47 48static void matroxfb_g450_decuse(void* md) { 49 MOD_DEC_USE_COUNT; 50} 51 52static int matroxfb_g450_set_mode(void* md, u_int32_t arg) { 53 if (arg == MATROXFB_OUTPUT_MODE_MONITOR) { 54 return 1; 55 } 56 return -EINVAL; 57} 58 59static int matroxfb_g450_get_mode(void* md, u_int32_t* arg) { 60 *arg = MATROXFB_OUTPUT_MODE_MONITOR; 61 return 0; 62} 63 64static struct matrox_altout matroxfb_g450_altout = { 65 matroxfb_g450_compute, 66 matroxfb_g450_program, 67 matroxfb_g450_start, 68 matroxfb_g450_incuse, 69 matroxfb_g450_decuse, 70 matroxfb_g450_set_mode, 71 matroxfb_g450_get_mode 72}; 73 74static int matroxfb_g450_connect(struct matroxfb_g450_info* m2info) { 75 MINFO_FROM(m2info->primary_dev); 76 77 down_write(&ACCESS_FBINFO(altout.lock)); 78 ACCESS_FBINFO(altout.device) = m2info; 79 ACCESS_FBINFO(altout.output) = &matroxfb_g450_altout; 80 up_write(&ACCESS_FBINFO(altout.lock)); 81 ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY; 82 matroxfb_switch(ACCESS_FBINFO(currcon), (struct fb_info*)MINFO); 83 return 0; 84} 85 86static void matroxfb_g450_shutdown(struct matroxfb_g450_info* m2info) { 87 MINFO_FROM(m2info->primary_dev); 88 89 if (MINFO) { 90 ACCESS_FBINFO(output.all) &= ~MATROXFB_OUTPUT_CONN_SECONDARY; 91 ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_SECONDARY; 92 ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_SECONDARY; 93 down_write(&ACCESS_FBINFO(altout.lock)); 94 ACCESS_FBINFO(altout.device) = NULL; 95 ACCESS_FBINFO(altout.output) = NULL; 96 up_write(&ACCESS_FBINFO(altout.lock)); 97 m2info->primary_dev = NULL; 98 } 99} 100 101/* we do not have __setup() yet */ 102static void* matroxfb_g450_probe(struct matrox_fb_info* minfo) { 103 struct matroxfb_g450_info* m2info; 104 105 /* hardware is not G450... */ 106 if (!ACCESS_FBINFO(devflags.g450dac)) 107 return NULL; 108 m2info = (struct matroxfb_g450_info*)kmalloc(sizeof(*m2info), GFP_KERNEL); 109 if (!m2info) { 110 printk(KERN_ERR "matroxfb_g450: Not enough memory for G450 DAC control structs\n"); 111 return NULL; 112 } 113 memset(m2info, 0, sizeof(*m2info)); 114 m2info->primary_dev = MINFO; 115 if (matroxfb_g450_connect(m2info)) { 116 kfree(m2info); 117 printk(KERN_ERR "matroxfb_g450: G450 DAC failed to initialize\n"); 118 return NULL; 119 } 120 return m2info; 121} 122 123static void matroxfb_g450_remove(struct matrox_fb_info* minfo, void* g450) { 124 matroxfb_g450_shutdown(g450); 125 kfree(g450); 126} 127 128static struct matroxfb_driver g450 = { 129 name: "Matrox G450 output #2", 130 probe: matroxfb_g450_probe, 131 remove: matroxfb_g450_remove }; 132 133static int matroxfb_g450_init(void) { 134 matroxfb_register_driver(&g450); 135 return 0; 136} 137 138static void matroxfb_g450_exit(void) { 139 matroxfb_unregister_driver(&g450); 140} 141 142MODULE_AUTHOR("(c) 2000-2001 Petr Vandrovec <vandrove@vc.cvut.cz>"); 143MODULE_DESCRIPTION("Matrox G450 secondary output driver"); 144MODULE_LICENSE("GPL"); 145module_init(matroxfb_g450_init); 146module_exit(matroxfb_g450_exit); 147