^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * BRIEF MODULE DESCRIPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Au1200 LCD Driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2004-2005 AMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: AMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Created 28 Dec 1997 by Geert Uytterhoeven
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * under the terms of the GNU General Public License as published by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Free Software Foundation; either version 2 of the License, or (at your
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * You should have received a copy of the GNU General Public License along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * with this program; if not, write to the Free Software Foundation, Inc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * 675 Mass Ave, Cambridge, MA 02139, USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <asm/mach-au1x00/au1000.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <asm/mach-au1x00/au1200fb.h> /* platform_data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "au1200fb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DRIVER_NAME "au1200fb"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define DRIVER_DESC "LCD controller driver for AU1200 processors"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define DEBUG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define print_dbg(f, arg...) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AU1200_LCD_FB_IOCTL 0x46FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define AU1200_LCD_SET_SCREEN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define AU1200_LCD_GET_SCREEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define AU1200_LCD_SET_WINDOW 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define AU1200_LCD_GET_WINDOW 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define AU1200_LCD_SET_PANEL 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define AU1200_LCD_GET_PANEL 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SCREEN_SIZE (1<< 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SCREEN_BACKCOLOR (1<< 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SCREEN_BRIGHTNESS (1<< 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SCREEN_COLORKEY (1<< 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SCREEN_MASK (1<< 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct au1200_lcd_global_regs_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned int xsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int ysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int backcolor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int colorkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned int panel_choice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) char panel_desc[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define WIN_POSITION (1<< 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define WIN_ALPHA_COLOR (1<< 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define WIN_ALPHA_MODE (1<< 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define WIN_PRIORITY (1<< 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define WIN_CHANNEL (1<< 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define WIN_BUFFER_FORMAT (1<< 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define WIN_COLOR_ORDER (1<< 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define WIN_PIXEL_ORDER (1<< 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define WIN_SIZE (1<< 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define WIN_COLORKEY_MODE (1<< 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define WIN_DOUBLE_BUFFER_MODE (1<< 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define WIN_RAM_ARRAY_MODE (1<< 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define WIN_BUFFER_SCALE (1<< 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define WIN_ENABLE (1<< 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct au1200_lcd_window_regs_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned int xpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned int ypos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned int alpha_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned int alpha_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned int channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned int buffer_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int color_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int pixel_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int xsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned int ysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int colorkey_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int double_buffer_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int ram_array_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned int xscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int yscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned int enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct au1200_lcd_iodata_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned int subcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct au1200_lcd_global_regs_t global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct au1200_lcd_window_regs_t window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #if defined(__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Private, per-framebuffer management information (independent of the panel itself) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct au1200fb_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct fb_info *fb_info; /* FB driver info record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct au1200fb_platdata *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned char* fb_mem; /* FrameBuffer memory map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned int fb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) dma_addr_t fb_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* LCD controller restrictions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define AU1200_LCD_MAX_XRES 1280
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define AU1200_LCD_MAX_YRES 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define AU1200_LCD_MAX_BPP 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define AU1200_LCD_NBR_PALETTE_ENTRIES 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Default number of visible screen buffer to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define AU1200FB_NBR_VIDEO_BUFFERS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Default maximum number of fb devices to create */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define MAX_DEVICE_COUNT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Default window configuration entry to use (see windows[]) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define DEFAULT_WINDOW_INDEX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int device_count = MAX_DEVICE_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int window_index = DEFAULT_WINDOW_INDEX; /* default is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int panel_index = 2; /* default is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static struct window_settings *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static struct panel_settings *panel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int noblanking = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int nohwcursor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct window_settings {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned char name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) uint32 mode_backcolor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) uint32 mode_colorkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) uint32 mode_colorkeymsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int xpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int ypos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) uint32 mode_winenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) } w[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #if defined(__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Default window configurations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static struct window_settings windows[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { /* Index 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* mode_backcolor */ 0x006600ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* mode_colorkey,msk*/ 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) LCD_WINCTRL1_PO_16BPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* mode_winenable*/ LCD_WINENABLE_WEN0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* xres, yres, xpos, ypos */ 100, 100, 100, 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) LCD_WINCTRL1_PO_16BPP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) LCD_WINCTRL1_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* mode_winenable*/ LCD_WINENABLE_WEN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) LCD_WINCTRL1_PO_16BPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* mode_winenable*/ 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) LCD_WINCTRL1_PO_16BPP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) LCD_WINCTRL1_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* mode_winenable*/ 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) { /* Index 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* mode_backcolor */ 0x006600ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* mode_colorkey,msk*/ 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* xres, yres, xpos, ypos */ 320, 240, 5, 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) LCD_WINCTRL1_PO_00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* mode_winenable*/ LCD_WINENABLE_WEN0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) | LCD_WINCTRL1_PO_16BPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* mode_winenable*/ 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* xres, yres, xpos, ypos */ 100, 100, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) LCD_WINCTRL1_PO_16BPP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) LCD_WINCTRL1_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* xres, yres, xpos, ypos */ 200, 25, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) LCD_WINCTRL1_PO_16BPP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) LCD_WINCTRL1_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* mode_winenable*/ 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { /* Index 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* mode_backcolor */ 0x006600ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* mode_colorkey,msk*/ 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) LCD_WINCTRL1_PO_16BPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* mode_winenable*/ LCD_WINENABLE_WEN0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) LCD_WINCTRL1_PO_16BPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* mode_winenable*/ 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) LCD_WINCTRL1_PO_16BPP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) LCD_WINCTRL1_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* mode_winenable*/ 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* Need VGA 640 @ 24bpp, @ 32bpp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* Need VGA 800 @ 24bpp, @ 32bpp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* Need VGA 1024 @ 24bpp, @ 32bpp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * Controller configurations for various panels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct panel_settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) const char name[25]; /* Full name <vendor>_<model> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct fb_monspecs monspecs; /* FB monitor specs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* panel timings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) uint32 mode_screen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) uint32 mode_horztiming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) uint32 mode_verttiming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) uint32 mode_clkcontrol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) uint32 mode_pwmdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) uint32 mode_pwmhi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) uint32 mode_outmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) uint32 mode_fifoctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) uint32 mode_backlight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) uint32 lcdclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define Xres min_xres
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #define Yres min_yres
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) u32 min_xres; /* Minimum horizontal resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u32 max_xres; /* Maximum horizontal resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u32 min_yres; /* Minimum vertical resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) u32 max_yres; /* Maximum vertical resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* List of panels known to work with the AU1200 LCD controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * To add a new panel, enter the same specifications as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * Generic_TFT one, and MAKE SURE that it doesn't conflicts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * with the controller restrictions. Restrictions are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * STN color panels: max_bpp <= 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * STN mono panels: max_bpp <= 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * TFT panels: max_bpp <= 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * max_xres <= 800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * max_yres <= 600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static struct panel_settings known_lcd_panels[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .name = "QVGA_320x240",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .mode_screen = LCD_SCREEN_SX_N(320) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) LCD_SCREEN_SY_N(240),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .mode_horztiming = 0x00c4623b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .mode_verttiming = 0x00502814,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .mode_clkcontrol = 0x00020002, /* /4=24Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .mode_pwmdiv = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .mode_pwmhi = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .mode_outmask = 0x00FFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .lcdclk = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 320, 320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 240, 240,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .name = "VGA_640x480",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .mode_screen = 0x13f9df80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) .mode_horztiming = 0x003c5859,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .mode_verttiming = 0x00741201,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .mode_pwmdiv = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .mode_pwmhi = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .mode_outmask = 0x00FFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .lcdclk = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 640, 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 640, 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .name = "SVGA_800x600",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .mode_screen = 0x18fa5780,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .mode_horztiming = 0x00dc7e77,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .mode_verttiming = 0x00584805,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .mode_clkcontrol = 0x00020000, /* /2=48Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .mode_pwmdiv = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .mode_pwmhi = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .mode_outmask = 0x00FFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .lcdclk = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 800, 800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 600, 600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .name = "XVGA_1024x768",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .mode_screen = 0x1ffaff80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .mode_horztiming = 0x007d0e57,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .mode_verttiming = 0x00740a01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .mode_clkcontrol = 0x000A0000, /* /1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .mode_pwmdiv = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .mode_pwmhi = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .mode_outmask = 0x00FFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .lcdclk = 72,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 1024, 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 768, 768,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .name = "XVGA_1280x1024",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .mode_screen = 0x27fbff80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .mode_horztiming = 0x00cdb2c7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .mode_verttiming = 0x00600002,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .mode_clkcontrol = 0x000A0000, /* /1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .mode_pwmdiv = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .mode_pwmhi = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .mode_outmask = 0x00FFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .lcdclk = 120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 1280, 1280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 1024, 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) [5] = { /* Samsung 1024x768 TFT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .name = "Samsung_1024x768_TFT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .mode_screen = 0x1ffaff80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .mode_horztiming = 0x018cc677,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .mode_verttiming = 0x00241217,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .mode_pwmhi = 0x03400000, /* SCB 0x0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .mode_outmask = 0x00FFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .lcdclk = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 1024, 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 768, 768,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) [6] = { /* Toshiba 640x480 TFT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .name = "Toshiba_640x480_TFT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .mode_screen = LCD_SCREEN_SX_N(640) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) LCD_SCREEN_SY_N(480),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .mode_horztiming = LCD_HORZTIMING_HPW_N(96) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .mode_clkcontrol = 0x00000000, /* /4=24Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .mode_pwmdiv = 0x8000063f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .mode_pwmhi = 0x03400000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .mode_outmask = 0x00fcfcfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .lcdclk = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 640, 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 640, 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) [7] = { /* Sharp 320x240 TFT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .name = "Sharp_320x240_TFT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .hfmin = 12500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .hfmax = 20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .vfmin = 38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .vfmax = 81,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .dclkmin = 4500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .dclkmax = 6800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .mode_screen = LCD_SCREEN_SX_N(320) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) LCD_SCREEN_SY_N(240),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .mode_horztiming = LCD_HORZTIMING_HPW_N(60) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .mode_pwmdiv = 0x8000063f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .mode_pwmhi = 0x03400000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .mode_outmask = 0x00fcfcfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .lcdclk = 96, /* 96MHz AUXPLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 320, 320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 240, 240,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .name = "Toppoly_TD070WGCB2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .mode_screen = LCD_SCREEN_SX_N(856) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) LCD_SCREEN_SY_N(480),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .mode_horztiming = LCD_HORZTIMING_HND2_N(43) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .mode_verttiming = LCD_VERTTIMING_VND2_N(20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) .mode_pwmdiv = 0x8000063f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .mode_pwmhi = 0x03400000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .mode_outmask = 0x00fcfcfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .lcdclk = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 856, 856,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 480, 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) [9] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .name = "DB1300_800x480",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .monspecs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .modedb = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .modedb_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .hfmin = 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .hfmax = 70000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) .vfmin = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .vfmax = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .dclkmin = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .dclkmax = 28000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) .input = FB_DISP_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .mode_screen = LCD_SCREEN_SX_N(800) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) LCD_SCREEN_SY_N(480),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .mode_horztiming = LCD_HORZTIMING_HPW_N(5) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) LCD_HORZTIMING_HND1_N(16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) LCD_HORZTIMING_HND2_N(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .mode_verttiming = LCD_VERTTIMING_VPW_N(4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) LCD_VERTTIMING_VND1_N(8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) LCD_VERTTIMING_VND2_N(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) LCD_CLKCONTROL_IV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) LCD_CLKCONTROL_IH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .mode_pwmdiv = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .mode_pwmhi = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .mode_outmask = 0x00FFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .mode_fifoctrl = 0x2f2f2f2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .mode_backlight = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .lcdclk = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 800, 800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 480, 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) #define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static int winbpp (unsigned int winctrl1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* how many bits are needed for each pixel format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) switch (winctrl1 & LCD_WINCTRL1_FRM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) case LCD_WINCTRL1_FRM_1BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) bits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) case LCD_WINCTRL1_FRM_2BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) bits = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case LCD_WINCTRL1_FRM_4BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) bits = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case LCD_WINCTRL1_FRM_8BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) case LCD_WINCTRL1_FRM_12BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case LCD_WINCTRL1_FRM_16BPP655:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) case LCD_WINCTRL1_FRM_16BPP565:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case LCD_WINCTRL1_FRM_16BPP556:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case LCD_WINCTRL1_FRM_16BPPI1555:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case LCD_WINCTRL1_FRM_16BPPI5551:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case LCD_WINCTRL1_FRM_16BPPA1555:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case LCD_WINCTRL1_FRM_16BPPA5551:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) bits = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) case LCD_WINCTRL1_FRM_24BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case LCD_WINCTRL1_FRM_32BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) bits = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int fbinfo2index (struct fb_info *fb_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) for (i = 0; i < device_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (fb_info == _au1200fb_infos[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) printk("au1200fb: ERROR: fbinfo2index failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int xpos, int ypos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int xsz, ysz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) winctrl0 = lcd->window[plane].winctrl0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) winctrl1 = lcd->window[plane].winctrl1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /* Check for off-screen adjustments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) xsz = win->w[plane].xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ysz = win->w[plane].yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if ((xpos + win->w[plane].xres) > panel->Xres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Off-screen to the right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) xsz = panel->Xres - xpos; /* off by 1 ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /*printk("off screen right\n");*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if ((ypos + win->w[plane].yres) > panel->Yres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /* Off-screen to the bottom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ysz = panel->Yres - ypos; /* off by 1 ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /*printk("off screen bottom\n");*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (xpos < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* Off-screen to the left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) xsz = win->w[plane].xres + xpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) xpos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /*printk("off screen left\n");*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (ypos < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /* Off-screen to the top */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ysz = win->w[plane].yres + ypos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ypos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*printk("off screen top\n");*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* record settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) win->w[plane].xpos = xpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) win->w[plane].ypos = ypos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) xsz -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ysz -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) winctrl0 |= (xpos << 21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) winctrl0 |= (ypos << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) winctrl1 |= (xsz << 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) winctrl1 |= (ysz << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /* Disable the window while making changes, then restore WINEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) winenable = lcd->winenable & (1 << plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) lcd->winenable &= ~(1 << plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) lcd->window[plane].winctrl0 = winctrl0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) lcd->window[plane].winctrl1 = winctrl1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) lcd->window[plane].winbuf0 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) lcd->window[plane].winbuf1 = fbdev->fb_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) lcd->winenable |= winenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static void au1200_setpanel(struct panel_settings *newpanel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct au1200fb_platdata *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * Perform global setup/init of LCD controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) uint32 winenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* Make sure all windows disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) winenable = lcd->winenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) lcd->winenable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * Ensure everything is disabled before reconfiguring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (lcd->screen & LCD_SCREEN_SEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* Wait for vertical sync period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) lcd->intstatus = LCD_INT_SS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) while ((lcd->intstatus & LCD_INT_SS) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) lcd->intstatus = lcd->intstatus; /*clear interrupts*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /*wait for controller to shut down*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) } while ((lcd->intstatus & LCD_INT_SD) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* Call shutdown of current panel (if up) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* this must occur last, because if an external clock is driving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) the controller, the clock cannot be turned off before first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) shutting down the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (pd->panel_shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) pd->panel_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* Newpanel == NULL indicates a shutdown operation only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (newpanel == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) panel = newpanel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct clk *c = clk_get(NULL, "lcd_intclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) long r, pc = panel->lcdclk * 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (!IS_ERR(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) r = clk_round_rate(c, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if ((pc - r) < (pc / 10)) { /* 10% slack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) clk_set_rate(c, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) clk_prepare_enable(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) clk_put(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * Configure panel timings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) lcd->screen = panel->mode_screen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) lcd->horztiming = panel->mode_horztiming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) lcd->verttiming = panel->mode_verttiming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) lcd->clkcontrol = panel->mode_clkcontrol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) lcd->pwmdiv = panel->mode_pwmdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) lcd->pwmhi = panel->mode_pwmhi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) lcd->outmask = panel->mode_outmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) lcd->fifoctrl = panel->mode_fifoctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* fixme: Check window settings to make sure still valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * for new geometry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) lcd->winenable = winenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * Re-enable screen now that it is configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) lcd->screen |= LCD_SCREEN_SEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* Call init of panel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (pd->panel_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) pd->panel_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* FIX!!!! not appropriate on panel change!!! Global setup/init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) lcd->intenable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) lcd->intstatus = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) lcd->backcolor = win->mode_backcolor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* Setup Color Key - FIX!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) lcd->colorkey = win->mode_colorkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) lcd->colorkeymsk = win->mode_colorkeymsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /* Setup HWCursor - FIX!!! Need to support this eventually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) lcd->hwc.cursorctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) lcd->hwc.cursorpos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) lcd->hwc.cursorcolor0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) lcd->hwc.cursorcolor1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) lcd->hwc.cursorcolor2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) lcd->hwc.cursorcolor3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) #define D(X) printk("%25s: %08X\n", #X, X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) D(lcd->screen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) D(lcd->horztiming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) D(lcd->verttiming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) D(lcd->clkcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) D(lcd->pwmdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) D(lcd->pwmhi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) D(lcd->outmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) D(lcd->fifoctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) D(lcd->window[0].winctrl0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) D(lcd->window[0].winctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) D(lcd->window[0].winctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) D(lcd->window[0].winbuf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) D(lcd->window[0].winbuf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) D(lcd->window[0].winbufctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) D(lcd->window[1].winctrl0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) D(lcd->window[1].winctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) D(lcd->window[1].winctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) D(lcd->window[1].winbuf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) D(lcd->window[1].winbuf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) D(lcd->window[1].winbufctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) D(lcd->window[2].winctrl0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) D(lcd->window[2].winctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) D(lcd->window[2].winctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) D(lcd->window[2].winbuf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) D(lcd->window[2].winbuf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) D(lcd->window[2].winbufctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) D(lcd->window[3].winctrl0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) D(lcd->window[3].winctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) D(lcd->window[3].winctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) D(lcd->window[3].winbuf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) D(lcd->window[3].winbuf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) D(lcd->window[3].winbufctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) D(lcd->winenable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) D(lcd->intenable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) D(lcd->intstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) D(lcd->backcolor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) D(lcd->winenable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) D(lcd->colorkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) D(lcd->colorkeymsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) D(lcd->hwc.cursorctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) D(lcd->hwc.cursorpos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) D(lcd->hwc.cursorcolor0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) D(lcd->hwc.cursorcolor1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) D(lcd->hwc.cursorcolor2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) D(lcd->hwc.cursorcolor3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static void au1200_setmode(struct au1200fb_device *fbdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) int plane = fbdev->plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /* Window/plane setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) lcd->window[plane].winctrl1 = ( 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) | LCD_WINCTRL1_PRI_N(plane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) lcd->window[plane].winctrl2 = ( 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) | LCD_WINCTRL2_CKMODE_00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) | LCD_WINCTRL2_DBM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) | LCD_WINCTRL2_SCX_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) | LCD_WINCTRL2_SCY_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) lcd->winenable |= win->w[plane].mode_winenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* Inline helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) #define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /* Bitfields format supported by the controller. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static struct fb_bitfield rgb_bitfields[][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) /* Red, Green, Blue, Transp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) [LCD_WINCTRL1_FRM_16BPP655 >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) [LCD_WINCTRL1_FRM_16BPP565 >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) [LCD_WINCTRL1_FRM_16BPP556 >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) [LCD_WINCTRL1_FRM_24BPP >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) [LCD_WINCTRL1_FRM_32BPP >> 25] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /* Helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static void au1200fb_update_fbinfo(struct fb_info *fbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* FIX!!!! This also needs to take the window pixel format into account!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* Update var-dependent FB info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (panel_is_color(panel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (fbi->var.bits_per_pixel <= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* palettized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) fbi->fix.line_length = fbi->var.xres_virtual /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) (8/fbi->var.bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /* non-palettized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) fbi->fix.visual = FB_VISUAL_TRUECOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* mono FIX!!! mono 8 and 4 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) fbi->fix.visual = FB_VISUAL_MONO10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) fbi->fix.line_length = fbi->var.xres_virtual / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) print_dbg("line length: %d\n", fbi->fix.line_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /* AU1200 framebuffer driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /* fb_check_var
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * Validate var settings with hardware restrictions and modify it if necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct fb_info *fbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct au1200fb_device *fbdev = fbi->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) u32 pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) int screen_size, plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) plane = fbdev->plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /* Make sure that the mode respect all LCD controller and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * panel restrictions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) var->xres = win->w[plane].xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) var->yres = win->w[plane].yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /* No need for virtual resolution support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) var->xres_virtual = var->xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) var->yres_virtual = var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) screen_size = var->xres_virtual * var->yres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) else screen_size /= (8/var->bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (fbdev->fb_len < screen_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return -EINVAL; /* Virtual screen is to big, abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * clock can only be obtain by dividing this value by an even integer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * Fallback to a slower pixel clock if necessary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) pixclock = min3(pixclock, fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (AU1200_LCD_MAX_CLK % pixclock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) int diff = AU1200_LCD_MAX_CLK % pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) pixclock -= diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) var->pixclock = KHZ2PICOS(pixclock/1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (!panel_is_active(panel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (!panel_is_color(panel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* STN 8bit mono panel support is up to 6MHz pixclock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) var->pixclock = KHZ2PICOS(6000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) } else if (!pcd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* Other STN panel support is up to 12MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) var->pixclock = KHZ2PICOS(12000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* Set bitfield accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) switch (var->bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /* 16bpp True color.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * These must be set to MATCH WINCTRL[FORM] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) var->red = rgb_bitfields[idx][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) var->green = rgb_bitfields[idx][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) var->blue = rgb_bitfields[idx][2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) var->transp = rgb_bitfields[idx][3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* 32bpp True color.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) * These must be set to MATCH WINCTRL[FORM] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) var->red = rgb_bitfields[idx][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) var->green = rgb_bitfields[idx][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) var->blue = rgb_bitfields[idx][2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) var->transp = rgb_bitfields[idx][3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /* fb_set_par
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * Set hardware with var settings. This will enable the controller with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * specific mode, normally validated with the fb_check_var method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static int au1200fb_fb_set_par(struct fb_info *fbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct au1200fb_device *fbdev = fbi->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) au1200fb_update_fbinfo(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) au1200_setmode(fbdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /* fb_setcolreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) * Set color in LCD palette.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) unsigned blue, unsigned transp, struct fb_info *fbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) volatile u32 *palette = lcd->palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (fbi->var.grayscale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /* Convert color to grayscale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) red = green = blue =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) (19595 * red + 38470 * green + 7471 * blue) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /* Place color in the pseudopalette */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (regno > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) palette = (u32*) fbi->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) red >>= (16 - fbi->var.red.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) green >>= (16 - fbi->var.green.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) blue >>= (16 - fbi->var.blue.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) value = (red << fbi->var.red.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) (green << fbi->var.green.offset)|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) (blue << fbi->var.blue.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) value &= 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /* COLOR TFT PALLETTIZED (use RGB 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) value = (red & 0xF800)|((green >> 5) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 0x07E0)|((blue >> 11) & 0x001F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) value &= 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) } else if (0 /*panel_is_color(fbdev->panel)*/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /* COLOR STN MODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) value = 0x1234;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) value &= 0xFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* MONOCHROME MODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) value = (green >> 12) & 0x000F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) value &= 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) palette[regno] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* fb_blank
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * Blank the screen. Depending on the mode, the screen will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * activated with the backlight color, or desactivated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct au1200fb_device *fbdev = fbi->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* Short-circuit screen blanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (noblanking)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) switch (blank_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) case FB_BLANK_UNBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) case FB_BLANK_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* printk("turn on panel\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) au1200_setpanel(panel, fbdev->pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) case FB_BLANK_VSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) case FB_BLANK_HSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) case FB_BLANK_POWERDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) /* printk("turn off panel\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) au1200_setpanel(NULL, fbdev->pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) /* FB_BLANK_NORMAL is a soft blank */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /* fb_mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * Map video memory in user space. We don't use the generic fb_mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * method mainly to allow the use of the TLB streaming flag (CCA=6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) struct au1200fb_device *fbdev = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return dma_mmap_attrs(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) fbdev->fb_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) unsigned int hi1, divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) /* SCREEN_SIZE: user cannot reset size, must switch panel choice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (pdata->flags & SCREEN_BACKCOLOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) lcd->backcolor = pdata->backcolor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (pdata->flags & SCREEN_BRIGHTNESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) // limit brightness pwm duty to >= 30/1600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (pdata->brightness < 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) pdata->brightness = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) divider = (lcd->pwmdiv & 0x3FFFF) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) lcd->pwmhi &= 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) lcd->pwmhi |= (hi1 << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (pdata->flags & SCREEN_COLORKEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) lcd->colorkey = pdata->colorkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (pdata->flags & SCREEN_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) lcd->colorkeymsk = pdata->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) unsigned int hi1, divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) pdata->backcolor = lcd->backcolor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) pdata->colorkey = lcd->colorkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) pdata->mask = lcd->colorkeymsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) // brightness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) hi1 = (lcd->pwmhi >> 16) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) divider = (lcd->pwmdiv & 0x3FFFF) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) pdata->brightness = ((hi1 << 8) / divider) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static void set_window(unsigned int plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct au1200_lcd_window_regs_t *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) unsigned int val, bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /* Window control register 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (pdata->flags & WIN_POSITION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) LCD_WINCTRL0_OY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) lcd->window[plane].winctrl0 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (pdata->flags & WIN_ALPHA_COLOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) lcd->window[plane].winctrl0 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (pdata->flags & WIN_ALPHA_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) lcd->window[plane].winctrl0 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /* Window control register 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (pdata->flags & WIN_PRIORITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) lcd->window[plane].winctrl1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (pdata->flags & WIN_CHANNEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) lcd->window[plane].winctrl1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (pdata->flags & WIN_BUFFER_FORMAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) lcd->window[plane].winctrl1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (pdata->flags & WIN_COLOR_ORDER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) lcd->window[plane].winctrl1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (pdata->flags & WIN_PIXEL_ORDER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) lcd->window[plane].winctrl1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (pdata->flags & WIN_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) LCD_WINCTRL1_SZY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) lcd->window[plane].winctrl1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /* program buffer line width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) bpp = winbpp(val) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) lcd->window[plane].winctrl2 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) /* Window control register 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (pdata->flags & WIN_COLORKEY_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) lcd->window[plane].winctrl2 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) lcd->window[plane].winctrl2 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (pdata->flags & WIN_RAM_ARRAY_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) lcd->window[plane].winctrl2 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) /* Buffer line width programmed with WIN_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (pdata->flags & WIN_BUFFER_SCALE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) LCD_WINCTRL2_SCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) lcd->window[plane].winctrl2 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (pdata->flags & WIN_ENABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) val = lcd->winenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) val &= ~(1<<plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) val |= (pdata->enable & 1) << plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) lcd->winenable = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static void get_window(unsigned int plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct au1200_lcd_window_regs_t *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) /* Window control register 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /* Window control register 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /* Window control register 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) pdata->enable = (lcd->winenable >> plane) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct au1200fb_device *fbdev = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) int plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) plane = fbinfo2index(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (cmd == AU1200_LCD_FB_IOCTL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) struct au1200_lcd_iodata_t iodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) print_dbg("FB IOCTL called\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) switch (iodata.subcmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case AU1200_LCD_SET_SCREEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) print_dbg("AU1200_LCD_SET_SCREEN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) set_global(cmd, &iodata.global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) case AU1200_LCD_GET_SCREEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) print_dbg("AU1200_LCD_GET_SCREEN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) get_global(cmd, &iodata.global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) case AU1200_LCD_SET_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) print_dbg("AU1200_LCD_SET_WINDOW\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) set_window(plane, &iodata.window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) case AU1200_LCD_GET_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) print_dbg("AU1200_LCD_GET_WINDOW\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) get_window(plane, &iodata.window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) case AU1200_LCD_SET_PANEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) print_dbg("AU1200_LCD_SET_PANEL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if ((iodata.global.panel_choice >= 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) (iodata.global.panel_choice <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) NUM_PANELS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) struct panel_settings *newpanel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) panel_index = iodata.global.panel_choice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) newpanel = &known_lcd_panels[panel_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) au1200_setpanel(newpanel, fbdev->pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) case AU1200_LCD_GET_PANEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) print_dbg("AU1200_LCD_GET_PANEL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) iodata.global.panel_choice = panel_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) print_dbg("error: could not copy %d bytes\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) static const struct fb_ops au1200fb_fb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) .fb_check_var = au1200fb_fb_check_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .fb_set_par = au1200fb_fb_set_par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .fb_setcolreg = au1200fb_fb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .fb_blank = au1200fb_fb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) .fb_fillrect = sys_fillrect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) .fb_copyarea = sys_copyarea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) .fb_imageblit = sys_imageblit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) .fb_read = fb_sys_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) .fb_write = fb_sys_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) .fb_sync = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .fb_ioctl = au1200fb_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) .fb_mmap = au1200fb_fb_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) /* Nothing to do for now, just clear any pending interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) lcd->intstatus = lcd->intstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /* AU1200 LCD device probe helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) struct fb_info *fbi = fbdev->fb_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) int bpp, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) fbi->fbops = &au1200fb_fb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) /* Copy monitor specs from panel data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /* fixme: we're setting up LCD controller windows, so these dont give a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) damn as to what the monitor specs are (the panel itself does, but that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) isn't done here...so maybe need a generic catchall monitor setting??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) /* We first try the user mode passed in argument. If that failed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * or if no one has been specified, we default to the first mode of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * panel list. Note that after this call, var data will be set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (!fb_find_mode(&fbi->var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) fbi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) NULL, /* drv_info.opt_mode, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) fbi->monspecs.modedb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) fbi->monspecs.modedb_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) fbi->monspecs.modedb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) bpp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) print_err("Cannot find valid mode for panel %s", panel->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) fbi->pseudo_palette = kcalloc(16, sizeof(u32), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (!fbi->pseudo_palette)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) ret = fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) print_err("Fail to allocate colormap (%d entries)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) AU1200_LCD_NBR_PALETTE_ENTRIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) fbi->fix.smem_start = fbdev->fb_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) fbi->fix.smem_len = fbdev->fb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) fbi->fix.type = FB_TYPE_PACKED_PIXELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) fbi->fix.xpanstep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) fbi->fix.ypanstep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) fbi->fix.mmio_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) fbi->fix.mmio_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) fbi->fix.accel = FB_ACCEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) fbi->screen_base = (char __iomem *) fbdev->fb_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) au1200fb_update_fbinfo(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) static int au1200fb_setup(struct au1200fb_platdata *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) char *options = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) char *this_opt, *endptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) int num_panels = ARRAY_SIZE(known_lcd_panels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) int panel_idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) fb_get_options(DRIVER_NAME, &options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (!options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) while ((this_opt = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /* Panel option - can be panel name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * "bs" for board-switch, or number/index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (!strncmp(this_opt, "panel:", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) long int li;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) char *endptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) this_opt += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* First check for index, which allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) * to short circuit this mess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) li = simple_strtol(this_opt, &endptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (*endptr == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) panel_idx = (int)li;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) else if (strcmp(this_opt, "bs") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) panel_idx = pd->panel_index();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) for (i = 0; i < num_panels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if (!strcmp(this_opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) known_lcd_panels[i].name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) panel_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if ((panel_idx < 0) || (panel_idx >= num_panels))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) print_warn("Panel %s not supported!", this_opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) panel_index = panel_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) } else if (strncmp(this_opt, "nohwcursor", 10) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) nohwcursor = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) else if (strncmp(this_opt, "devices:", 8) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) this_opt += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) device_count = simple_strtol(this_opt, &endptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if ((device_count < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) (device_count > MAX_DEVICE_COUNT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) device_count = MAX_DEVICE_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) } else if (strncmp(this_opt, "wincfg:", 7) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) this_opt += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) window_index = simple_strtol(this_opt, &endptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if ((window_index < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) (window_index >= ARRAY_SIZE(windows)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) window_index = DEFAULT_WINDOW_INDEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) } else if (strncmp(this_opt, "off", 3) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) print_warn("Unsupported option \"%s\"", this_opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) /* AU1200 LCD controller device driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) static int au1200fb_drv_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) struct au1200fb_device *fbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) struct au1200fb_platdata *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) struct fb_info *fbi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) int bpp, plane, ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) print_info("" DRIVER_DESC "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) pd = dev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (!pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) /* Setup driver with options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (au1200fb_setup(pd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /* Point to the panel selected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) panel = &known_lcd_panels[panel_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) win = &windows[window_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) for (plane = 0; plane < device_count; ++plane) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) bpp = winbpp(win->w[plane].mode_winctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (win->w[plane].xres == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) win->w[plane].xres = panel->Xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (win->w[plane].yres == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) win->w[plane].yres = panel->Yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) &dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (!fbi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) _au1200fb_infos[plane] = fbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) fbdev = fbi->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) fbdev->fb_info = fbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) fbdev->pd = pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) fbdev->dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) fbdev->plane = plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) /* Allocate the framebuffer to the maximum screen size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) fbdev->fb_mem = dmam_alloc_attrs(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) PAGE_ALIGN(fbdev->fb_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) &fbdev->fb_phys, GFP_KERNEL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (!fbdev->fb_mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) print_err("fail to allocate framebuffer (size: %dK))",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) fbdev->fb_len / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) /* Init FB data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) ret = au1200fb_init_fbinfo(fbdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) /* Register new framebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) ret = register_framebuffer(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) print_err("cannot register new framebuffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) au1200fb_fb_set_par(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (plane == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) /* Start display and show logo on boot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) fb_set_cmap(&fbi->cmap, fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) fb_show_logo(fbi, FB_ROTATE_UR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) /* Now hook interrupt too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) irq = platform_get_irq(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) ret = request_irq(irq, au1200fb_handle_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) IRQF_SHARED, "lcd", (void *)dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) print_err("fail to request interrupt line %d (err: %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) platform_set_drvdata(dev, pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* Kickstart the panel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) au1200_setpanel(panel, pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) for (plane = 0; plane < device_count; ++plane) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) fbi = _au1200fb_infos[plane];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (!fbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* Clean up all probe data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) unregister_framebuffer(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (fbi->cmap.len != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) fb_dealloc_cmap(&fbi->cmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) kfree(fbi->pseudo_palette);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) framebuffer_release(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) _au1200fb_infos[plane] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) static int au1200fb_drv_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) struct au1200fb_platdata *pd = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) struct fb_info *fbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) int plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) /* Turn off the panel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) au1200_setpanel(NULL, pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) for (plane = 0; plane < device_count; ++plane) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) fbi = _au1200fb_infos[plane];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) /* Clean up all probe data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) unregister_framebuffer(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (fbi->cmap.len != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) fb_dealloc_cmap(&fbi->cmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) kfree(fbi->pseudo_palette);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) framebuffer_release(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) _au1200fb_infos[plane] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) free_irq(platform_get_irq(dev, 0), (void *)dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) static int au1200fb_drv_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) struct au1200fb_platdata *pd = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) au1200_setpanel(NULL, pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) lcd->outmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) wmb(); /* drain writebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static int au1200fb_drv_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) struct au1200fb_platdata *pd = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) struct fb_info *fbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /* Kickstart the panel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) au1200_setpanel(panel, pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) for (i = 0; i < device_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) fbi = _au1200fb_infos[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) au1200fb_fb_set_par(fbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) static const struct dev_pm_ops au1200fb_pmops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) .suspend = au1200fb_drv_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) .resume = au1200fb_drv_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) .freeze = au1200fb_drv_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) .thaw = au1200fb_drv_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) #define AU1200FB_PMOPS (&au1200fb_pmops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) #define AU1200FB_PMOPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) static struct platform_driver au1200fb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) .name = "au1200-lcd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) .pm = AU1200FB_PMOPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) .probe = au1200fb_drv_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) .remove = au1200fb_drv_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) module_platform_driver(au1200fb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) MODULE_LICENSE("GPL");