12ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior/* 22ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * Frame buffer driver for the Carmine GPU. 32ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * 42ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * The driver configures the GPU as follows 52ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * - FB0 is display 0 with unique memory area 62ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * - FB1 is display 1 with unique memory area 72ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * - both display use 32 bit colors 82ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior */ 92ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#include <linux/delay.h> 102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#include <linux/errno.h> 112ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#include <linux/fb.h> 122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#include <linux/interrupt.h> 132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#include <linux/pci.h> 145a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 15355b200bacdb6017669cdc5bc9e7b1037aac42a2Paul Gortmaker#include <linux/module.h> 162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#include "carminefb.h" 182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#include "carminefb_regs.h" 192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) 212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#error "The endianness of the target host has not been defined." 222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#endif 232ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior/* 252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * The initial video mode can be supplied via two different ways: 262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * - as a string that is passed to fb_find_mode() (module option fb_mode_str) 272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * - as an integer that picks the video mode from carmine_modedb[] (module 282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * option fb_mode) 292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * 302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * If nothing is used than the initial video mode will be the 312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * CARMINEFB_DEFAULT_VIDEO_MODE member of the carmine_modedb[]. 322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior */ 332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#define CARMINEFB_DEFAULT_VIDEO_MODE 1 342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE; 36c84c14224bbca6ec60d5851fcc87be0e34df2f44Jean Delvaremodule_param(fb_mode, uint, 0444); 372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian SiewiorMODULE_PARM_DESC(fb_mode, "Initial video mode as integer."); 382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic char *fb_mode_str; 40c84c14224bbca6ec60d5851fcc87be0e34df2f44Jean Delvaremodule_param(fb_mode_str, charp, 0444); 412ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian SiewiorMODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters."); 422ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior/* 442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * Carminefb displays: 452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * 0b000 None 462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * 0b001 Display 0 472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * 0b010 Display 1 482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior */ 492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1; 50c84c14224bbca6ec60d5851fcc87be0e34df2f44Jean Delvaremodule_param(fb_displays, int, 0444); 512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian SiewiorMODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used"); 522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 532ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstruct carmine_hw { 542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior void __iomem *v_regs; 552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior void __iomem *screen_mem; 562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct fb_info *fb[MAX_DISPLAY]; 572ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstruct carmine_resolution { 602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 htp; 612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 hsp; 622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 hsw; 632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 hdp; 642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 vtr; 652ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 vsp; 662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 vsw; 672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 vdp; 682ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 disp_mode; 692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstruct carmine_fb { 722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior void __iomem *display_reg; 732ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior void __iomem *screen_base; 742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 smem_offset; 752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 cur_mode; 762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 new_mode; 772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct carmine_resolution *res; 782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 pseudo_palette[16]; 792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 8148c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic struct fb_fix_screeninfo carminefb_fix = { 822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .id = "Carmine", 832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .type = FB_TYPE_PACKED_PIXELS, 842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .visual = FB_VISUAL_TRUECOLOR, 852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .accel = FB_ACCEL_NONE, 862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 882ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic const struct fb_videomode carmine_modedb[] = { 892ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior { 902ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .name = "640x480", 912ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .xres = 640, 922ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .yres = 480, 932ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior }, { 942ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .name = "800x600", 952ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .xres = 800, 962ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .yres = 600, 972ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior }, 982ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 992ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1002ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic struct carmine_resolution car_modes[] = { 1012ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior { 1022ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* 640x480 */ 1032ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .htp = 800, 1042ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .hsp = 672, 1052ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .hsw = 96, 1062ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .hdp = 640, 1072ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vtr = 525, 1082ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vsp = 490, 1092ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vsw = 2, 1102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vdp = 480, 1112ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .disp_mode = 0x1400, 1122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior }, 1132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior { 1142ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* 800x600 */ 1152ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .htp = 1060, 1162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .hsp = 864, 1172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .hsw = 72, 1182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .hdp = 800, 1192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vtr = 628, 1202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vsp = 601, 1212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vsw = 2, 1222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .vdp = 600, 1232ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .disp_mode = 0x0d00, 1242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 1252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 1262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic int carmine_find_mode(const struct fb_var_screeninfo *var) 1282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 1292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior int i; 1302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior for (i = 0; i < ARRAY_SIZE(car_modes); i++) 1322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (car_modes[i].hdp == var->xres && 1332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior car_modes[i].vdp == var->yres) 1342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return i; 1352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return -EINVAL; 1362ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 1372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic void c_set_disp_reg(const struct carmine_fb *par, 1392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 offset, u32 val) 1402ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 1412ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior writel(val, par->display_reg + offset); 1422ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 1432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic u32 c_get_disp_reg(const struct carmine_fb *par, 1452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 offset) 1462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 1472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return readl(par->display_reg + offset); 1482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 1492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1502ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic void c_set_hw_reg(const struct carmine_hw *hw, 1512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 offset, u32 val) 1522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 1532ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior writel(val, hw->v_regs + offset); 1542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 1552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic u32 c_get_hw_reg(const struct carmine_hw *hw, 1572ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 offset) 1582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 1592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return readl(hw->v_regs + offset); 1602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 1612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic int carmine_setcolreg(unsigned regno, unsigned red, unsigned green, 1632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior unsigned blue, unsigned transp, struct fb_info *info) 1642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 1652ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (regno >= 16) 1662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return 1; 1672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1682ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior red >>= 8; 1692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior green >>= 8; 1702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior blue >>= 8; 1712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior transp >>= 8; 1722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 17308cc6341cc04fad45c28995db796317b5b413045Harvey Harrison ((__be32 *)info->pseudo_palette)[regno] = cpu_to_be32(transp << 24 | 1742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior red << 0 | green << 8 | blue << 16); 1752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return 0; 1762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 1772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic int carmine_check_var(struct fb_var_screeninfo *var, 1792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct fb_info *info) 1802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 1812ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior int ret; 1822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = carmine_find_mode(var); 1842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret < 0) 1852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return ret; 1862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (var->grayscale || var->rotate || var->nonstd) 1882ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return -EINVAL; 1892ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1902ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->xres_virtual = var->xres; 1912ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->yres_virtual = var->yres; 1922ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1932ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->bits_per_pixel = 32; 1942ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 1952ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#ifdef __BIG_ENDIAN 1962ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->transp.offset = 24; 1972ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->red.offset = 0; 1982ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->green.offset = 8; 1992ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->blue.offset = 16; 2002ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#else 2012ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->transp.offset = 24; 2022ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->red.offset = 16; 2032ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->green.offset = 8; 2042ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->blue.offset = 0; 2052ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#endif 2062ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2072ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->red.length = 8; 2082ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->green.length = 8; 2092ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->blue.length = 8; 2102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->transp.length = 8; 2112ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->red.msb_right = 0; 2132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->green.msb_right = 0; 2142ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->blue.msb_right = 0; 2152ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior var->transp.msb_right = 0; 2162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return 0; 2172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 2182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic void carmine_init_display_param(struct carmine_fb *par) 2202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 2212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 width; 2222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 height; 2232ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 param; 2242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 window_size; 2252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 soffset = par->smem_offset; 2262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_C_TRANS, 0); 2282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_MLMR_TRANS, 0); 2292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_CURSOR_MODE, 2302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_CURSOR0_PRIORITY_MASK | 2312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_CURSOR1_PRIORITY_MASK | 2322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_CURSOR_CUTZ_MASK); 2332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default cursor position */ 2352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_CUR1_POS, 0 << 16 | 0); 2362ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_CUR2_POS, 0 << 16 | 0); 2372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default display mode */ 2392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_EXT_MODE, CARMINE_WINDOW_MODE | 2402ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2412ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L1_EXT_MODE, 2422ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_EXT_MODE, CARMINE_EXTEND_MODE | 2442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_EXT_MODE, CARMINE_EXTEND_MODE | 2462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_EXT_MODE, CARMINE_EXTEND_MODE | 2482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_EXT_MODE, CARMINE_EXTEND_MODE | 2502ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_EXT_MODE, CARMINE_EXTEND_MODE | 2522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2532ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_EXT_MODE, CARMINE_EXTEND_MODE | 2542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_EXT_CMODE_DIRECT24_RGBA); 2552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default frame size to layer mode register */ 2572ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior width = par->res->hdp * 4 / CARMINE_DISP_WIDTH_UNIT; 2582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior width = width << CARMINE_DISP_WIDTH_SHIFT; 2592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior height = par->res->vdp - 1; 2612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior param = width | height; 2622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_MODE_W_H, param); 2642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L1_WIDTH, width); 2652ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_MODE_W_H, param); 2662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_MODE_W_H, param); 2672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_MODE_W_H, param); 2682ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_MODE_W_H, param); 2692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_MODE_W_H, param); 2702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_MODE_W_H, param); 2712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default pos and size */ 2732ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior window_size = (par->res->vdp - 1) << CARMINE_DISP_WIN_H_SHIFT; 2742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior window_size |= par->res->hdp; 2752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_WIN_POS, 0); 2772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_WIN_SIZE, window_size); 2782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L1_WIN_POS, 0); 2792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L1_WIN_SIZE, window_size); 2802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_WIN_POS, 0); 2812ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_WIN_SIZE, window_size); 2822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_WIN_POS, 0); 2832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_WIN_SIZE, window_size); 2842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_WIN_POS, 0); 2852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_WIN_SIZE, window_size); 2862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_WIN_POS, 0); 2872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_WIN_SIZE, window_size); 2882ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_WIN_POS, 0); 2892ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_WIN_SIZE, window_size); 2902ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_WIN_POS, 0); 2912ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_WIN_SIZE, window_size); 2922ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 2932ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default origin address */ 2942ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_ORG_ADR, soffset); 2952ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L1_ORG_ADR, soffset); 2962ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_ORG_ADR1, soffset); 2972ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_ORG_ADR1, soffset); 2982ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_ORG_ADR1, soffset); 2992ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_ORG_ADR1, soffset); 3002ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_ORG_ADR1, soffset); 3012ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_ORG_ADR1, soffset); 3022ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3032ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default display address */ 3042ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_DISP_ADR, soffset); 3052ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_DISP_ADR1, soffset); 3062ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_DISP_ADR1, soffset); 3072ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_DISP_ADR1, soffset); 3082ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_DISP_ADR1, soffset); 3092ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_DISP_ADR0, soffset); 3102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_DISP_ADR0, soffset); 3112ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default display position */ 3132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_DISP_POS, 0); 3142ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_DISP_POS, 0); 3152ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_DISP_POS, 0); 3162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_DISP_POS, 0); 3172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_DISP_POS, 0); 3182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_DISP_POS, 0); 3192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_DISP_POS, 0); 3202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default blend mode */ 3222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L0, 0); 3232ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L1, 0); 3242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L2, 0); 3252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L3, 0); 3262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L4, 0); 3272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L5, 0); 3282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L6, 0); 3292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L7, 0); 3302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* default transparency mode */ 3322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0_TRANS, 0); 3332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L1_TRANS, 0); 3342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2_TRANS, 0); 3352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3_TRANS, 0); 3362ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4_TRANS, 0); 3372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5_TRANS, 0); 3382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6_TRANS, 0); 3392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7_TRANS, 0); 3402ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3412ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set default read skip parameter */ 3422ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0RM, 0); 3432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2RM, 0); 3442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3RM, 0); 3452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4RM, 0); 3462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5RM, 0); 3472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6RM, 0); 3482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7RM, 0); 3492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3502ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0PX, 0); 3512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2PX, 0); 3522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3PX, 0); 3532ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4PX, 0); 3542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5PX, 0); 3552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6PX, 0); 3562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7PX, 0); 3572ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L0PY, 0); 3592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L2PY, 0); 3602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L3PY, 0); 3612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L4PY, 0); 3622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L5PY, 0); 3632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L6PY, 0); 3642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_L7PY, 0); 3652ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 3662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic void set_display_parameters(struct carmine_fb *par) 3682ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 3692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 mode; 3702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 hdp, vdp, htp, hsp, hsw, vtr, vsp, vsw; 3712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* 3732ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * display timing. Parameters are decreased by one because hardware 3742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * spec is 0 to (n - 1) 3752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * */ 3762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hdp = par->res->hdp - 1; 3772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior vdp = par->res->vdp - 1; 3782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior htp = par->res->htp - 1; 3792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hsp = par->res->hsp - 1; 3802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hsw = par->res->hsw - 1; 3812ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior vtr = par->res->vtr - 1; 3822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior vsp = par->res->vsp - 1; 3832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior vsw = par->res->vsw - 1; 3842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_H_TOTAL, 3862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior htp << CARMINE_DISP_HTP_SHIFT); 3872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_H_PERIOD, 3882ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior (hdp << CARMINE_DISP_HDB_SHIFT) | hdp); 3892ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_V_H_W_H_POS, 3902ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior (vsw << CARMINE_DISP_VSW_SHIFT) | 3912ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior (hsw << CARMINE_DISP_HSW_SHIFT) | 3922ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior (hsp)); 3932ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_V_TOTAL, 3942ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior vtr << CARMINE_DISP_VTR_SHIFT); 3952ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_V_PERIOD_POS, 3962ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior (vdp << CARMINE_DISP_VDP_SHIFT) | vsp); 3972ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 3982ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* clock */ 3992ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior mode = c_get_disp_reg(par, CARMINE_DISP_REG_DCM1); 4002ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior mode = (mode & ~CARMINE_DISP_DCM_MASK) | 4012ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior (par->res->disp_mode & CARMINE_DISP_DCM_MASK); 4022ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* enable video output and layer 0 */ 4032ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior mode |= CARMINE_DEN | CARMINE_L0E; 4042ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_disp_reg(par, CARMINE_DISP_REG_DCM1, mode); 4052ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 4062ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4072ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic int carmine_set_par(struct fb_info *info) 4082ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 4092ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct carmine_fb *par = info->par; 4102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior int ret; 4112ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = carmine_find_mode(&info->var); 4132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret < 0) 4142ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return ret; 4152ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior par->new_mode = ret; 4172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (par->cur_mode != par->new_mode) { 4182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior par->cur_mode = par->new_mode; 4202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior par->res = &car_modes[par->new_mode]; 4212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carmine_init_display_param(par); 4232ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior set_display_parameters(par); 4242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 4252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8; 4272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return 0; 4282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 4292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic int init_hardware(struct carmine_hw *hw) 4312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 4322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 flags; 4332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 loops; 4342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior u32 ret; 4352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 436421f91d21ad6f799dc7b489bb33cc560ccc56f98Uwe Kleine-König /* Initialize Carmine */ 4372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Sets internal clock */ 4382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE, 4392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_CLOCK_ENABLE); 4402ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4412ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Video signal output is turned off */ 4422ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DISP0_REG + CARMINE_DISP_REG_DCM1, 0); 4432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DISP1_REG + CARMINE_DISP_REG_DCM1, 0); 4442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Software reset */ 4462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_SOFTWARE_RESET, 1); 4472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_SOFTWARE_RESET, 0); 4482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* I/O mode settings */ 4502ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_IO_CONT1 << 16 | 4512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_DCTL_IO_CONT0; 4522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_IOCONT1_IOCONT0, 4532ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags); 4542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* DRAM initial sequence */ 4562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_MODE << 16 | CARMINE_DFLT_IP_DCTL_ADD; 4572ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_MODE_ADD, 4582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags); 4592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_SET_TIME1 << 16 | 4612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_DCTL_EMODE; 4622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_SETTIME1_EMODE, 4632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags); 4642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4652ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_REFRESH << 16 | 4662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_DCTL_SET_TIME2; 4672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_REFRESH_SETTIME2, 4682ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags); 4692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_RESERVE2 << 16 | 4712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_DCTL_FIFO_DEPTH; 4722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_RSV2_RSV1, flags); 4732ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_DDRIF2 << 16 | CARMINE_DFLT_IP_DCTL_DDRIF1; 4752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_DDRIF2_DDRIF1, 4762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags); 4772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_RESERVE0 << 16 | 4792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_DCTL_STATES; 4802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_RSV0_STATES, 4812ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags); 4822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Executes DLL reset */ 4842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (CARMINE_DCTL_DLL_RESET) { 4852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior for (loops = 0; loops < CARMINE_DCTL_INIT_WAIT_LIMIT; loops++) { 4862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = c_get_hw_reg(hw, CARMINE_DCTL_REG + 4882ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DCTL_REG_RSV0_STATES); 4892ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret &= CARMINE_DCTL_REG_STATES_MASK; 4902ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!ret) 4912ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior break; 4922ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4932ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior mdelay(CARMINE_DCTL_INIT_WAIT_INTERVAL); 4942ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 4952ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 4962ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (loops >= CARMINE_DCTL_INIT_WAIT_LIMIT) { 4972ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior printk(KERN_ERR "DRAM init failed\n"); 4982ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return -EIO; 4992ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 5002ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 5012ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5022ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_MODE_AFT_RST << 16 | 5032ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_DCTL_ADD; 5042ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_MODE_ADD, flags); 5052ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5062ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags = CARMINE_DFLT_IP_DCTL_RESERVE0 << 16 | 5072ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_DFLT_IP_DCTL_STATES_AFT_RST; 5082ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_RSV0_STATES, 5092ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior flags); 5102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5112ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Initialize the write back register */ 5122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_WB_REG + CARMINE_WB_REG_WBM, 5132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_WB_REG_WBM_DEFAULT); 5142ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5152ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Initialize the Kottos registers */ 5162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_VRINTM, 0); 5172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_VRERRM, 0); 5182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* Set DC offsets */ 5202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_PX, 0); 5212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_PY, 0); 5222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_LX, 0); 5232ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_LY, 0); 5242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_TX, 0); 5252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_TY, 0); 5262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return 0; 5272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 5282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic struct fb_ops carminefb_ops = { 5302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .owner = THIS_MODULE, 5312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .fb_fillrect = cfb_fillrect, 5322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .fb_copyarea = cfb_copyarea, 5332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .fb_imageblit = cfb_imageblit, 5342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .fb_check_var = carmine_check_var, 5362ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .fb_set_par = carmine_set_par, 5372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .fb_setcolreg = carmine_setcolreg, 5382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 5392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 54048c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base, 54148c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartman int smem_offset, struct device *device, 54248c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartman struct fb_info **rinfo) 5432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 5442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior int ret; 5452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct fb_info *info; 5462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct carmine_fb *par; 5472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info = framebuffer_alloc(sizeof *par, device); 5492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!info) 5502ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return -ENOMEM; 5512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior par = info->par; 5532ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior par->display_reg = regs; 5542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior par->smem_offset = smem_offset; 5552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info->screen_base = smem_base + smem_offset; 5572ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info->screen_size = CARMINE_DISPLAY_MEM; 5582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info->fbops = &carminefb_ops; 5592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info->fix = carminefb_fix; 5612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info->pseudo_palette = par->pseudo_palette; 5622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info->flags = FBINFO_DEFAULT; 5632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = fb_alloc_cmap(&info->cmap, 256, 1); 5652ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret < 0) 5662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_free_fb; 5672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 568493f139ecf9ee72f73ccbabd016325a145e884eeRoel Kluin if (fb_mode >= ARRAY_SIZE(carmine_modedb)) 5692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE; 5702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior par->cur_mode = par->new_mode = ~0; 5722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5732ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = fb_find_mode(&info->var, info, fb_mode_str, carmine_modedb, 5742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ARRAY_SIZE(carmine_modedb), 5752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior &carmine_modedb[fb_mode], 32); 5762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!ret || ret == 4) { 5772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = -EINVAL; 5782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_dealloc_cmap; 5792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 5802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5812ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior fb_videomode_to_modelist(carmine_modedb, ARRAY_SIZE(carmine_modedb), 5822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior &info->modelist); 5832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = register_framebuffer(info); 5852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret < 0) 5862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_dealloc_cmap; 5872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 58831b6780c15a4e3a90fe260e977f5186772ce7afbJoe Perches fb_info(info, "%s frame buffer device\n", info->fix.id); 5892ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5902ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior *rinfo = info; 5912ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return 0; 5922ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 5932ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_dealloc_cmap: 5942ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior fb_dealloc_cmap(&info->cmap); 5952ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_free_fb: 5962ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior framebuffer_release(info); 5972ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return ret; 5982ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 5992ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6002ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic void cleanup_fb_device(struct fb_info *info) 6012ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 6022ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (info) { 6032ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior unregister_framebuffer(info); 6042ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior fb_dealloc_cmap(&info->cmap); 6052ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior framebuffer_release(info); 6062ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6072ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 6082ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 60948c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int carminefb_probe(struct pci_dev *dev, const struct pci_device_id *ent) 6102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 6112ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct carmine_hw *hw; 6122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct device *device = &dev->dev; 6132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct fb_info *info; 6142ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior int ret; 6152ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = pci_enable_device(dev); 6172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret) 6182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return ret; 6192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = -ENOMEM; 6212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hw = kzalloc(sizeof *hw, GFP_KERNEL); 6222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!hw) 6232ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_enable_pci; 6242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.mmio_start = pci_resource_start(dev, CARMINE_CONFIG_BAR); 6262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.mmio_len = pci_resource_len(dev, CARMINE_CONFIG_BAR); 6272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!request_mem_region(carminefb_fix.mmio_start, 6292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.mmio_len, 6302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior "carminefb regbase")) { 6312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior printk(KERN_ERR "carminefb: Can't reserve regbase.\n"); 6322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = -EBUSY; 6332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_free_hw; 6342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hw->v_regs = ioremap_nocache(carminefb_fix.mmio_start, 6362ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.mmio_len); 6372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!hw->v_regs) { 6382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior printk(KERN_ERR "carminefb: Can't remap %s register.\n", 6392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.id); 6402ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_free_reg_mmio; 6412ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6422ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.smem_start = pci_resource_start(dev, CARMINE_MEMORY_BAR); 6442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.smem_len = pci_resource_len(dev, CARMINE_MEMORY_BAR); 6452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* The memory area tends to be very large (256 MiB). Remap only what 6472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * is required for that largest resolution to avoid remaps at run 6482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior * time 6492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior */ 6502ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (carminefb_fix.smem_len > CARMINE_TOTAL_DIPLAY_MEM) 6512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.smem_len = CARMINE_TOTAL_DIPLAY_MEM; 6522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6532ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior else if (carminefb_fix.smem_len < CARMINE_TOTAL_DIPLAY_MEM) { 6542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior printk(KERN_ERR "carminefb: Memory bar is only %d bytes, %d " 6552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior "are required.", carminefb_fix.smem_len, 6562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior CARMINE_TOTAL_DIPLAY_MEM); 657e045da7d835a28950543f5f10f0cb1905ca9bbafJulia Lawall goto err_unmap_vregs; 6582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!request_mem_region(carminefb_fix.smem_start, 6612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.smem_len, "carminefb smem")) { 6622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior printk(KERN_ERR "carminefb: Can't reserve smem.\n"); 6632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_unmap_vregs; 6642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6652ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hw->screen_mem = ioremap_nocache(carminefb_fix.smem_start, 6672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior carminefb_fix.smem_len); 6682ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!hw->screen_mem) { 6692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior printk(KERN_ERR "carmine: Can't ioremap smem area.\n"); 6702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_reg_smem; 6712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6732ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = init_hardware(hw); 6742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret) 6752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_unmap_screen; 6762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info = NULL; 6782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (fb_displays & CARMINE_USE_DISPLAY0) { 6792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = alloc_carmine_fb(hw->v_regs + CARMINE_DISP0_REG, 6802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hw->screen_mem, CARMINE_DISPLAY_MEM * 0, 6812ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior device, &info); 6822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret) 6832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_deinit_hw; 6842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hw->fb[0] = info; 6872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6882ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info = NULL; 6892ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (fb_displays & CARMINE_USE_DISPLAY1) { 6902ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior ret = alloc_carmine_fb(hw->v_regs + CARMINE_DISP1_REG, 6912ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hw->screen_mem, CARMINE_DISPLAY_MEM * 1, 6922ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior device, &info); 6932ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (ret) 6942ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior goto err_cleanup_fb0; 6952ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 6962ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 6972ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior hw->fb[1] = info; 6982ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior info = NULL; 6992ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7002ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior pci_set_drvdata(dev, hw); 7012ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return 0; 7022ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7032ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_cleanup_fb0: 7042ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior cleanup_fb_device(hw->fb[0]); 7052ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_deinit_hw: 7062ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* disable clock, etc */ 7072ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE, 0); 7082ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_unmap_screen: 7092ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior iounmap(hw->screen_mem); 7102ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_reg_smem: 711e045da7d835a28950543f5f10f0cb1905ca9bbafJulia Lawall release_mem_region(carminefb_fix.smem_start, carminefb_fix.smem_len); 7122ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_unmap_vregs: 7132ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior iounmap(hw->v_regs); 7142ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_free_reg_mmio: 7152ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior release_mem_region(carminefb_fix.mmio_start, carminefb_fix.mmio_len); 7162ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_free_hw: 7172ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior kfree(hw); 7182ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorerr_enable_pci: 7192ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior pci_disable_device(dev); 7202ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return ret; 7212ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 7222ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 72348c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic void carminefb_remove(struct pci_dev *dev) 7242ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 7252ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct carmine_hw *hw = pci_get_drvdata(dev); 7262ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior struct fb_fix_screeninfo fix; 7272ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior int i; 7282ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7292ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* in case we use only fb1 and not fb1 */ 7302ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (hw->fb[0]) 7312ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior fix = hw->fb[0]->fix; 7322ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior else 7332ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior fix = hw->fb[1]->fix; 7342ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7352ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior /* deactivate display(s) and switch clocks */ 7362ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DISP0_REG + CARMINE_DISP_REG_DCM1, 0); 7372ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_DISP1_REG + CARMINE_DISP_REG_DCM1, 0); 7382ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE, 0); 7392ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7402ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior for (i = 0; i < MAX_DISPLAY; i++) 7412ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior cleanup_fb_device(hw->fb[i]); 7422ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7432ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior iounmap(hw->screen_mem); 7442ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior release_mem_region(fix.smem_start, fix.smem_len); 7452ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior iounmap(hw->v_regs); 7462ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior release_mem_region(fix.mmio_start, fix.mmio_len); 7472ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7482ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior pci_disable_device(dev); 7492ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior kfree(hw); 7502ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 7512ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7522ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior#define PCI_VENDOR_ID_FUJITU_LIMITED 0x10cf 75348c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic struct pci_device_id carmine_devices[] = { 7542ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 7552ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior PCI_DEVICE(PCI_VENDOR_ID_FUJITU_LIMITED, 0x202b)}, 7562ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior {0, 0, 0, 0, 0, 0, 0} 7572ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 7582ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7592ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian SiewiorMODULE_DEVICE_TABLE(pci, carmine_devices); 7602ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7612ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic struct pci_driver carmine_pci_driver = { 7622ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .name = "carminefb", 7632ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .id_table = carmine_devices, 7642ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior .probe = carminefb_probe, 76548c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartman .remove = carminefb_remove, 7662ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior}; 7672ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7682ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic int __init carminefb_init(void) 7692ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 7702ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior if (!(fb_displays & 7712ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior (CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1))) { 7722ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior printk(KERN_ERR "If you disable both displays than you don't " 7732ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior "need the driver at all\n"); 7742ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return -EINVAL; 7752ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior } 7762ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior return pci_register_driver(&carmine_pci_driver); 7772ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 7782ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiormodule_init(carminefb_init); 7792ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7802ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiorstatic void __exit carminefb_cleanup(void) 7812ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior{ 7822ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior pci_unregister_driver(&carmine_pci_driver); 7832ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior} 7842ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewiormodule_exit(carminefb_cleanup); 7852ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian Siewior 7862ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian SiewiorMODULE_AUTHOR("Sebastian Siewior <bigeasy@linutronix.de>"); 7872ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian SiewiorMODULE_DESCRIPTION("Framebuffer driver for Fujitsu Carmine based devices"); 7882ece5f43b041b96fa2a05107a10a6b0ea0c03a3bSebastian SiewiorMODULE_LICENSE("GPL v2"); 789