Date:2011-06-06 05:41:21 (9 years 3 months ago)
Author:Maarten ter Huurne
Commit:da764510a60b020cb0cffb219e18778c7befb29a
Message:MIPS: JZ4740: SLCD framebufer driver.

This driver sends the frame buffer to a smart LCD controller, that is a controller with its own video memory.
It is a squashed version of development done in the jz-2.6.38 branch.
Files: arch/mips/include/asm/mach-jz4740/gpio.h (2 diffs)
arch/mips/include/asm/mach-jz4740/jz4740_fb.h (2 diffs)
drivers/video/Kconfig (1 diff)
drivers/video/Makefile (1 diff)
drivers/video/jz4740_fb.c (1 diff)
drivers/video/jz4740_lcd.h (1 diff)
drivers/video/jz4740_slcd.h (1 diff)
drivers/video/jz4740_slcd_fb.c (1 diff)
drivers/video/jz4740_slcd_panels.c (1 diff)

Change Details

arch/mips/include/asm/mach-jz4740/gpio.h
253253#define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27)
254254#define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28)
255255#define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29)
256/* Pins have different assignment in SLCD mode */
257#define JZ_GPIO_SLCD_RS JZ_GPIO_PORTC(19)
258#define JZ_GPIO_SLCD_CS JZ_GPIO_PORTC(20)
256259
257260#define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1
258261#define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1
...... 
284287#define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1
285288#define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1
286289#define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1
290#define JZ_GPIO_FUNC_SLCD_RS JZ_GPIO_FUNC1
291#define JZ_GPIO_FUNC_SLCD_CS JZ_GPIO_FUNC1
287292
288293
289294#define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22)
arch/mips/include/asm/mach-jz4740/jz4740_fb.h
3030    JZ_LCD_TYPE_DUAL_COLOR_STN = 10,
3131    JZ_LCD_TYPE_DUAL_MONOCHROME_STN = 11,
3232    JZ_LCD_TYPE_8BIT_SERIAL = 12,
33    JZ_LCD_TYPE_SMART_PARALLEL_8_BIT = 1 | (1 << 5),
34    JZ_LCD_TYPE_SMART_PARALLEL_16_BIT = 0 | (1 << 5),
35    JZ_LCD_TYPE_SMART_PARALLEL_18_BIT = 2 | (1 << 5),
36    JZ_LCD_TYPE_SMART_SERIAL_8_BIT = 1 | (3 << 5),
37    JZ_LCD_TYPE_SMART_SERIAL_16_BIT = 0 | (3 << 5),
38    JZ_LCD_TYPE_SMART_SERIAL_18_BIT = 2 | (3 << 5),
3339};
3440
3541#define JZ4740_FB_SPECIAL_TFT_CONFIG(start, stop) (((start) << 16) | (stop))
...... 
6268
6369    unsigned pixclk_falling_edge:1;
6470    unsigned date_enable_active_low:1;
71    unsigned chip_select_active_low:1;
72    unsigned register_select_active_low:1;
6573};
6674
6775#endif
drivers/video/Kconfig
23212321    help
23222322      Framebuffer support for the JZ4740 SoC.
23232323
2324config FB_JZ4740_SLCD
2325    tristate "JZ4740 Smart LCD framebuffer support"
2326    depends on FB && MACH_JZ4740
2327    select FB_SYS_FILLRECT
2328    select FB_SYS_COPYAREA
2329    select FB_SYS_IMAGEBLIT
2330    help
2331      This is the frame buffer device driver for the JZ4740 Smart LCD controller.
2332      If you say Y here, please say N to 'JZ4740 LCD framebuffer support'.
2333
2334config JZ_SLCD_ILI9325
2335    bool "ILI9325 Smart LCD panel"
2336    depends on FB_JZ4740_SLCD
2337
2338config JZ_SLCD_ILI9331
2339    bool "ILI9331 Smart LCD panel"
2340    depends on FB_JZ4740_SLCD
2341
2342config JZ_SLCD_ILI9338
2343    bool "ILI9338 Smart LCD panel"
2344    depends on FB_JZ4740_SLCD
2345
2346config JZ_SLCD_LGDP4551
2347    bool "LG LGDP4551 Smart LCD panel"
2348    depends on FB_JZ4740_SLCD
2349
2350config JZ_SLCD_SPFD5420A
2351    bool "SPFD5420A Smart LCD panel"
2352    depends on FB_JZ4740_SLCD
2353
23242354config FB_MXS
23252355    tristate "MXS LCD framebuffer support"
23262356    depends on FB && ARCH_MXS
drivers/video/Makefile
139139obj-$(CONFIG_FB_MSM) += msm/
140140obj-$(CONFIG_FB_NUC900) += nuc900fb.o
141141obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
142obj-$(CONFIG_FB_JZ4740_SLCD) += jz4740_slcd_fb.o jz4740_slcd_panels.o
142143obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
143144
144145# Platform or fallback drivers go here
drivers/video/jz4740_fb.c
2929#include <asm/mach-jz4740/jz4740_fb.h>
3030#include <asm/mach-jz4740/gpio.h>
3131
32#define JZ_REG_LCD_CFG 0x00
33#define JZ_REG_LCD_VSYNC 0x04
34#define JZ_REG_LCD_HSYNC 0x08
35#define JZ_REG_LCD_VAT 0x0C
36#define JZ_REG_LCD_DAH 0x10
37#define JZ_REG_LCD_DAV 0x14
38#define JZ_REG_LCD_PS 0x18
39#define JZ_REG_LCD_CLS 0x1C
40#define JZ_REG_LCD_SPL 0x20
41#define JZ_REG_LCD_REV 0x24
42#define JZ_REG_LCD_CTRL 0x30
43#define JZ_REG_LCD_STATE 0x34
44#define JZ_REG_LCD_IID 0x38
45#define JZ_REG_LCD_DA0 0x40
46#define JZ_REG_LCD_SA0 0x44
47#define JZ_REG_LCD_FID0 0x48
48#define JZ_REG_LCD_CMD0 0x4C
49#define JZ_REG_LCD_DA1 0x50
50#define JZ_REG_LCD_SA1 0x54
51#define JZ_REG_LCD_FID1 0x58
52#define JZ_REG_LCD_CMD1 0x5C
53
54#define JZ_LCD_CFG_SLCD BIT(31)
55#define JZ_LCD_CFG_PS_DISABLE BIT(23)
56#define JZ_LCD_CFG_CLS_DISABLE BIT(22)
57#define JZ_LCD_CFG_SPL_DISABLE BIT(21)
58#define JZ_LCD_CFG_REV_DISABLE BIT(20)
59#define JZ_LCD_CFG_HSYNCM BIT(19)
60#define JZ_LCD_CFG_PCLKM BIT(18)
61#define JZ_LCD_CFG_INV BIT(17)
62#define JZ_LCD_CFG_SYNC_DIR BIT(16)
63#define JZ_LCD_CFG_PS_POLARITY BIT(15)
64#define JZ_LCD_CFG_CLS_POLARITY BIT(14)
65#define JZ_LCD_CFG_SPL_POLARITY BIT(13)
66#define JZ_LCD_CFG_REV_POLARITY BIT(12)
67#define JZ_LCD_CFG_HSYNC_ACTIVE_LOW BIT(11)
68#define JZ_LCD_CFG_PCLK_FALLING_EDGE BIT(10)
69#define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9)
70#define JZ_LCD_CFG_VSYNC_ACTIVE_LOW BIT(8)
71#define JZ_LCD_CFG_18_BIT BIT(7)
72#define JZ_LCD_CFG_PDW (BIT(5) | BIT(4))
73#define JZ_LCD_CFG_MODE_MASK 0xf
74
75#define JZ_LCD_CTRL_BURST_4 (0x0 << 28)
76#define JZ_LCD_CTRL_BURST_8 (0x1 << 28)
77#define JZ_LCD_CTRL_BURST_16 (0x2 << 28)
78#define JZ_LCD_CTRL_RGB555 BIT(27)
79#define JZ_LCD_CTRL_OFUP BIT(26)
80#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24)
81#define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24)
82#define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24)
83#define JZ_LCD_CTRL_PDD_MASK (0xff << 16)
84#define JZ_LCD_CTRL_EOF_IRQ BIT(13)
85#define JZ_LCD_CTRL_SOF_IRQ BIT(12)
86#define JZ_LCD_CTRL_OFU_IRQ BIT(11)
87#define JZ_LCD_CTRL_IFU0_IRQ BIT(10)
88#define JZ_LCD_CTRL_IFU1_IRQ BIT(9)
89#define JZ_LCD_CTRL_DD_IRQ BIT(8)
90#define JZ_LCD_CTRL_QDD_IRQ BIT(7)
91#define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6)
92#define JZ_LCD_CTRL_LSB_FISRT BIT(5)
93#define JZ_LCD_CTRL_DISABLE BIT(4)
94#define JZ_LCD_CTRL_ENABLE BIT(3)
95#define JZ_LCD_CTRL_BPP_1 0x0
96#define JZ_LCD_CTRL_BPP_2 0x1
97#define JZ_LCD_CTRL_BPP_4 0x2
98#define JZ_LCD_CTRL_BPP_8 0x3
99#define JZ_LCD_CTRL_BPP_15_16 0x4
100#define JZ_LCD_CTRL_BPP_18_24 0x5
101
102#define JZ_LCD_CMD_SOF_IRQ BIT(15)
103#define JZ_LCD_CMD_EOF_IRQ BIT(16)
104#define JZ_LCD_CMD_ENABLE_PAL BIT(12)
105
106#define JZ_LCD_SYNC_MASK 0x3ff
107
108#define JZ_LCD_STATE_DISABLED BIT(0)
32#include "jz4740_lcd.h"
10933
11034struct jzfb_framedesc {
11135    uint32_t next;
drivers/video/jz4740_lcd.h
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4720/JZ4740 SoC LCD framebuffer driver
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#ifndef __JZ4740_LCD_H__
17#define __JZ4740_LCD_H__
18
19#include <linux/bitops.h>
20
21#define JZ_REG_LCD_CFG 0x00
22#define JZ_REG_LCD_VSYNC 0x04
23#define JZ_REG_LCD_HSYNC 0x08
24#define JZ_REG_LCD_VAT 0x0C
25#define JZ_REG_LCD_DAH 0x10
26#define JZ_REG_LCD_DAV 0x14
27#define JZ_REG_LCD_PS 0x18
28#define JZ_REG_LCD_CLS 0x1C
29#define JZ_REG_LCD_SPL 0x20
30#define JZ_REG_LCD_REV 0x24
31#define JZ_REG_LCD_CTRL 0x30
32#define JZ_REG_LCD_STATE 0x34
33#define JZ_REG_LCD_IID 0x38
34#define JZ_REG_LCD_DA0 0x40
35#define JZ_REG_LCD_SA0 0x44
36#define JZ_REG_LCD_FID0 0x48
37#define JZ_REG_LCD_CMD0 0x4C
38#define JZ_REG_LCD_DA1 0x50
39#define JZ_REG_LCD_SA1 0x54
40#define JZ_REG_LCD_FID1 0x58
41#define JZ_REG_LCD_CMD1 0x5C
42
43#define JZ_LCD_CFG_SLCD BIT(31)
44#define JZ_LCD_CFG_PS_DISABLE BIT(23)
45#define JZ_LCD_CFG_CLS_DISABLE BIT(22)
46#define JZ_LCD_CFG_SPL_DISABLE BIT(21)
47#define JZ_LCD_CFG_REV_DISABLE BIT(20)
48#define JZ_LCD_CFG_HSYNCM BIT(19)
49#define JZ_LCD_CFG_PCLKM BIT(18)
50#define JZ_LCD_CFG_INV BIT(17)
51#define JZ_LCD_CFG_SYNC_DIR BIT(16)
52#define JZ_LCD_CFG_PS_POLARITY BIT(15)
53#define JZ_LCD_CFG_CLS_POLARITY BIT(14)
54#define JZ_LCD_CFG_SPL_POLARITY BIT(13)
55#define JZ_LCD_CFG_REV_POLARITY BIT(12)
56#define JZ_LCD_CFG_HSYNC_ACTIVE_LOW BIT(11)
57#define JZ_LCD_CFG_PCLK_FALLING_EDGE BIT(10)
58#define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9)
59#define JZ_LCD_CFG_VSYNC_ACTIVE_LOW BIT(8)
60#define JZ_LCD_CFG_18_BIT BIT(7)
61#define JZ_LCD_CFG_PDW (BIT(5) | BIT(4))
62#define JZ_LCD_CFG_MODE_MASK 0xf
63
64#define JZ_LCD_CTRL_BURST_4 (0x0 << 28)
65#define JZ_LCD_CTRL_BURST_8 (0x1 << 28)
66#define JZ_LCD_CTRL_BURST_16 (0x2 << 28)
67#define JZ_LCD_CTRL_RGB555 BIT(27)
68#define JZ_LCD_CTRL_OFUP BIT(26)
69#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24)
70#define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24)
71#define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24)
72#define JZ_LCD_CTRL_PDD_MASK (0xff << 16)
73#define JZ_LCD_CTRL_EOF_IRQ BIT(13)
74#define JZ_LCD_CTRL_SOF_IRQ BIT(12)
75#define JZ_LCD_CTRL_OFU_IRQ BIT(11)
76#define JZ_LCD_CTRL_IFU0_IRQ BIT(10)
77#define JZ_LCD_CTRL_IFU1_IRQ BIT(9)
78#define JZ_LCD_CTRL_DD_IRQ BIT(8)
79#define JZ_LCD_CTRL_QDD_IRQ BIT(7)
80#define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6)
81#define JZ_LCD_CTRL_LSB_FISRT BIT(5)
82#define JZ_LCD_CTRL_DISABLE BIT(4)
83#define JZ_LCD_CTRL_ENABLE BIT(3)
84#define JZ_LCD_CTRL_BPP_1 0x0
85#define JZ_LCD_CTRL_BPP_2 0x1
86#define JZ_LCD_CTRL_BPP_4 0x2
87#define JZ_LCD_CTRL_BPP_8 0x3
88#define JZ_LCD_CTRL_BPP_15_16 0x4
89#define JZ_LCD_CTRL_BPP_18_24 0x5
90
91#define JZ_LCD_CMD_SOF_IRQ BIT(15)
92#define JZ_LCD_CMD_EOF_IRQ BIT(16)
93#define JZ_LCD_CMD_ENABLE_PAL BIT(12)
94
95#define JZ_LCD_SYNC_MASK 0x3ff
96
97#define JZ_LCD_STATE_DISABLED BIT(0)
98
99#endif /*__JZ4740_LCD_H__*/
drivers/video/jz4740_slcd.h
1/*
2 * linux/drivers/video/jz4740_slcd.h
3 * -- LCD panel definitions for Ingenic On-Chip SLCD frame buffer device
4 *
5 * Copyright (C) 2005-2007, Ingenic Semiconductor Inc.
6 * Copyright (C) 2010, Maarten ter Huurne <maarten@treewalker.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#ifndef __JZ4740_SLCD_H__
15#define __JZ4740_SLCD_H__
16
17#include <asm/mach-jz4740/base.h>
18#include <linux/gpio.h>
19#include <linux/mutex.h>
20#include <linux/workqueue.h>
21
22/*************************************************************************
23 * SLCD (Smart LCD Controller)
24 *************************************************************************/
25
26#define JZ_REG_SLCD_CFG 0xA0 /* SLCD Configure Register */
27#define JZ_REG_SLCD_CTRL 0xA4 /* SLCD Control Register */
28#define JZ_REG_SLCD_STATE 0xA8 /* SLCD Status Register */
29#define JZ_REG_SLCD_DATA 0xAC /* SLCD Data Register */
30#define JZ_REG_SLCD_FIFO 0xB0 /* SLCD FIFO Register */
31
32/* SLCD Configure Register */
33#define SLCD_CFG_BURST_BIT 14
34#define SLCD_CFG_BURST_MASK (0x3 << SLCD_CFG_BURST_BIT)
35  #define SLCD_CFG_BURST_4_WORD (0 << SLCD_CFG_BURST_BIT)
36  #define SLCD_CFG_BURST_8_WORD (1 << SLCD_CFG_BURST_BIT)
37#define SLCD_CFG_DWIDTH_BIT 10
38#define SLCD_CFG_DWIDTH_MASK (0x7 << SLCD_CFG_DWIDTH_BIT)
39  #define SLCD_CFG_DWIDTH_18 (0 << SLCD_CFG_DWIDTH_BIT)
40  #define SLCD_CFG_DWIDTH_16 (1 << SLCD_CFG_DWIDTH_BIT)
41  #define SLCD_CFG_DWIDTH_8_x3 (2 << SLCD_CFG_DWIDTH_BIT)
42  #define SLCD_CFG_DWIDTH_8_x2 (3 << SLCD_CFG_DWIDTH_BIT)
43  #define SLCD_CFG_DWIDTH_8_x1 (4 << SLCD_CFG_DWIDTH_BIT)
44  #define SLCD_CFG_DWIDTH_9_x2 (7 << SLCD_CFG_DWIDTH_BIT)
45#define SLCD_CFG_CWIDTH_BIT 8
46#define SLCD_CFG_CWIDTH_MASK (0x3 << SLCD_CFG_CWIDTH_BIT)
47  #define SLCD_CFG_CWIDTH_16BIT (0 << SLCD_CFG_CWIDTH_BIT)
48  #define SLCD_CFG_CWIDTH_8BIT (1 << SLCD_CFG_CWIDTH_BIT)
49  #define SLCD_CFG_CWIDTH_18BIT (2 << SLCD_CFG_CWIDTH_BIT)
50#define SLCD_CFG_CS_ACTIVE_LOW (0 << 4)
51#define SLCD_CFG_CS_ACTIVE_HIGH (1 << 4)
52#define SLCD_CFG_RS_CMD_LOW (0 << 3)
53#define SLCD_CFG_RS_CMD_HIGH (1 << 3)
54#define SLCD_CFG_CLK_ACTIVE_FALLING (0 << 1)
55#define SLCD_CFG_CLK_ACTIVE_RISING (1 << 1)
56#define SLCD_CFG_TYPE_PARALLEL (0 << 0)
57#define SLCD_CFG_TYPE_SERIAL (1 << 0)
58
59/* SLCD Control Register */
60#define SLCD_CTRL_DMA_EN (1 << 0)
61
62/* SLCD Status Register */
63#define SLCD_STATE_BUSY (1 << 0)
64
65/* SLCD Data Register */
66#define SLCD_DATA_RS_DATA (0 << 31)
67#define SLCD_DATA_RS_COMMAND (1 << 31)
68
69/* SLCD FIFO Register */
70#define SLCD_FIFO_RS_DATA (0 << 31)
71#define SLCD_FIFO_RS_COMMAND (1 << 31)
72
73/*************************************************************************/
74
75struct jzfb {
76    struct fb_info *fb;
77    struct platform_device *pdev;
78    void __iomem *base;
79    struct resource *mem;
80    struct jz4740_fb_platform_data *pdata;
81    const struct jz_slcd_panel *panel;
82
83    size_t vidmem_size;
84    void *vidmem;
85    dma_addr_t vidmem_phys;
86    struct jzfb_framedesc *framedesc;
87    dma_addr_t framedesc_phys;
88    struct jz4740_dma_chan *dma;
89
90    struct clk *ldclk;
91    struct clk *lpclk;
92
93    unsigned is_enabled:1;
94    struct mutex lock; /* Protecting against running enable/disable in paralell */
95
96    struct delayed_work refresh_work;
97
98    uint32_t pseudo_palette[16];
99};
100
101struct jz_slcd_panel {
102    /* request and configure GPIO pins */
103    int (*init)(struct jzfb *jzfb);
104    /* free GPIO pins */
105    void (*exit)(struct jzfb *jzfb);
106    /* activate, reset and initialize */
107    void (*enable)(struct jzfb *jzfb);
108    /* deactivate */
109    void (*disable)(struct jzfb *jzfb);
110};
111
112const struct jz_slcd_panel *jz_slcd_panels_probe(struct jzfb *jzfb);
113
114#endif /*__JZ4740_SLCD_H__*/
drivers/video/jz4740_slcd_fb.c
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * Copyright (C) 2010, Maarten ter Huurne <maarten@treewalker.org>
4 * JZ4720/JZ4740 SoC LCD framebuffer driver
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, write to the Free Software Foundation, Inc.,
13 * 675 Mass Ave, Cambridge, MA 02139, USA.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/mutex.h>
20#include <linux/platform_device.h>
21
22#include <linux/clk.h>
23#include <linux/delay.h>
24
25#include <linux/console.h>
26#include <linux/fb.h>
27
28#include <linux/dma-mapping.h>
29
30#include <asm/mach-jz4740/dma.h>
31#include <asm/mach-jz4740/gpio.h>
32#include <asm/mach-jz4740/jz4740_fb.h>
33
34#include "jz4740_lcd.h"
35#include "jz4740_slcd.h"
36
37struct jzfb_framedesc {
38    uint32_t next;
39    uint32_t addr;
40    uint32_t id;
41    uint32_t cmd;
42} __attribute__((packed));
43
44static struct fb_fix_screeninfo jzfb_fix __devinitdata = {
45    .id = "JZ4740 SLCD FB",
46    .type = FB_TYPE_PACKED_PIXELS,
47    .visual = FB_VISUAL_TRUECOLOR,
48    .xpanstep = 0,
49    .ypanstep = 1,
50    .ywrapstep = 0,
51    .accel = FB_ACCEL_NONE,
52};
53
54const static struct jz_gpio_bulk_request jz_slcd_ctrl_pins[] = {
55    JZ_GPIO_BULK_PIN(LCD_PCLK),
56    JZ_GPIO_BULK_PIN(SLCD_RS),
57    JZ_GPIO_BULK_PIN(SLCD_CS),
58};
59
60const static struct jz_gpio_bulk_request jz_slcd_data_pins[] = {
61    JZ_GPIO_BULK_PIN(LCD_DATA0),
62    JZ_GPIO_BULK_PIN(LCD_DATA1),
63    JZ_GPIO_BULK_PIN(LCD_DATA2),
64    JZ_GPIO_BULK_PIN(LCD_DATA3),
65    JZ_GPIO_BULK_PIN(LCD_DATA4),
66    JZ_GPIO_BULK_PIN(LCD_DATA5),
67    JZ_GPIO_BULK_PIN(LCD_DATA6),
68    JZ_GPIO_BULK_PIN(LCD_DATA7),
69    JZ_GPIO_BULK_PIN(LCD_DATA8),
70    JZ_GPIO_BULK_PIN(LCD_DATA9),
71    JZ_GPIO_BULK_PIN(LCD_DATA10),
72    JZ_GPIO_BULK_PIN(LCD_DATA11),
73    JZ_GPIO_BULK_PIN(LCD_DATA12),
74    JZ_GPIO_BULK_PIN(LCD_DATA13),
75    JZ_GPIO_BULK_PIN(LCD_DATA14),
76    JZ_GPIO_BULK_PIN(LCD_DATA15),
77    JZ_GPIO_BULK_PIN(LCD_DATA16),
78    JZ_GPIO_BULK_PIN(LCD_DATA17),
79};
80
81static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb)
82{
83    return ARRAY_SIZE(jz_slcd_ctrl_pins);
84}
85
86static unsigned int jzfb_num_data_pins(struct jzfb *jzfb)
87{
88    switch (jzfb->pdata->lcd_type) {
89    case JZ_LCD_TYPE_SMART_PARALLEL_8_BIT:
90        return 8;
91    case JZ_LCD_TYPE_SMART_PARALLEL_16_BIT:
92        return 16;
93    case JZ_LCD_TYPE_SMART_PARALLEL_18_BIT:
94        return 18;
95    default:
96        return 0;
97    }
98}
99
100static void jzfb_free_gpio_pins(struct jzfb *jzfb)
101{
102    jz_gpio_bulk_free(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
103    if (jzfb->pdata->lcd_type & (1 << 6)) {
104        /* serial */
105        jz_gpio_bulk_free(&jz_slcd_data_pins[15], 1);
106    } else {
107        /* parallel */
108        jz_gpio_bulk_free(jz_slcd_data_pins,
109                  jzfb_num_data_pins(jzfb));
110    }
111}
112
113static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green,
114            unsigned blue, unsigned transp, struct fb_info *fb)
115{
116    if (regno >= 16)
117        return -EINVAL;
118
119    red = (red * ((1 << fb->var.red.length ) - 1)) / ((1 << 16) - 1);
120    green = (green * ((1 << fb->var.green.length) - 1)) / ((1 << 16) - 1);
121    blue = (blue * ((1 << fb->var.blue.length ) - 1)) / ((1 << 16) - 1);
122
123    ((uint32_t *)fb->pseudo_palette)[regno] =
124        (red << fb->var.red.offset ) |
125        (green << fb->var.green.offset) |
126        (blue << fb->var.blue.offset );
127
128    return 0;
129}
130
131static int jzfb_get_controller_bpp(struct jzfb *jzfb)
132{
133    switch (jzfb->pdata->bpp) {
134    case 18:
135    case 24:
136        return 32;
137    case 15:
138        return 16;
139    default:
140        return jzfb->pdata->bpp;
141    }
142}
143
144static struct fb_videomode *jzfb_get_mode(struct jzfb *jzfb, struct fb_var_screeninfo *var)
145{
146    size_t i;
147    struct fb_videomode *mode = jzfb->pdata->modes;
148
149    for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
150        if (mode->xres == var->xres && mode->yres == var->yres)
151            return mode;
152    }
153
154    return NULL;
155}
156
157static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
158{
159    struct jzfb *jzfb = fb->par;
160    struct fb_videomode *mode;
161
162    if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
163        var->bits_per_pixel != jzfb->pdata->bpp)
164        return -EINVAL;
165
166    mode = jzfb_get_mode(jzfb, var);
167    if (mode == NULL)
168        return -EINVAL;
169
170    fb_videomode_to_var(var, mode);
171
172    /* Reserve space for double buffering. */
173    var->yres_virtual = var->yres * 2;
174
175    switch (jzfb->pdata->bpp) {
176    case 8:
177        break;
178    case 15:
179        var->red.offset = 10;
180        var->red.length = 5;
181        var->green.offset = 5;
182        var->green.length = 5;
183        var->blue.offset = 0;
184        var->blue.length = 5;
185        break;
186    case 16:
187        var->red.offset = 11;
188        var->red.length = 5;
189        var->green.offset = 5;
190        var->green.length = 6;
191        var->blue.offset = 0;
192        var->blue.length = 5;
193        break;
194    case 18:
195        var->red.offset = 16;
196        var->red.length = 6;
197        var->green.offset = 8;
198        var->green.length = 6;
199        var->blue.offset = 0;
200        var->blue.length = 6;
201        var->bits_per_pixel = 32;
202        break;
203    case 32:
204    case 24:
205        var->transp.offset = 24;
206        var->transp.length = 8;
207        var->red.offset = 16;
208        var->red.length = 8;
209        var->green.offset = 8;
210        var->green.length = 8;
211        var->blue.offset = 0;
212        var->blue.length = 8;
213        var->bits_per_pixel = 32;
214        break;
215    default:
216        break;
217    }
218
219    return 0;
220}
221
222static void jzfb_disable_dma(struct jzfb *jzfb)
223{
224    jz4740_dma_disable(jzfb->dma);
225    while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
226    writeb(readb(jzfb->base + JZ_REG_SLCD_CTRL) & ~SLCD_CTRL_DMA_EN,
227        jzfb->base + JZ_REG_SLCD_CTRL);
228}
229
230static struct jz4740_dma_config jzfb_slcd_dma_config = {
231    .src_width = JZ4740_DMA_WIDTH_32BIT,
232    .dst_width = JZ4740_DMA_WIDTH_16BIT,
233    .transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE,
234    .request_type = JZ4740_DMA_TYPE_SLCD,
235    .flags = JZ4740_DMA_SRC_AUTOINC,
236    .mode = JZ4740_DMA_MODE_BLOCK,
237};
238
239static void jzfb_upload_frame_dma(struct jzfb *jzfb)
240{
241    struct fb_info *fb = jzfb->fb;
242    struct fb_videomode *mode = fb->mode;
243    __u32 bytes_per_line = fb->fix.line_length;
244
245    jz4740_dma_set_src_addr(jzfb->dma, jzfb->vidmem_phys +
246                       bytes_per_line * fb->var.yoffset);
247    jz4740_dma_set_dst_addr(jzfb->dma,
248                CPHYSADDR(jzfb->base + JZ_REG_SLCD_FIFO));
249    jz4740_dma_set_transfer_count(jzfb->dma, bytes_per_line * mode->yres);
250
251    while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
252    writeb(readb(jzfb->base + JZ_REG_SLCD_CTRL) | SLCD_CTRL_DMA_EN,
253        jzfb->base + JZ_REG_SLCD_CTRL);
254    jz4740_dma_enable(jzfb->dma);
255}
256
257static void jzfb_upload_frame_cpu(struct jzfb *jzfb)
258{
259    const int num_pixels = jzfb->fb->mode->xres * jzfb->fb->mode->yres;
260    uint16_t *p = jzfb->vidmem;
261    int i;
262
263    jzfb_disable_dma(jzfb);
264    for (i = 0; i < num_pixels; i++) {
265        uint16_t rgb = *p++;
266        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
267        writel(SLCD_DATA_RS_DATA | rgb, jzfb->base + JZ_REG_SLCD_DATA);
268    }
269}
270
271static void jzfb_refresh_work(struct work_struct *work)
272{
273    struct jzfb *jzfb = container_of(work, struct jzfb, refresh_work.work);
274
275    mutex_lock(&jzfb->lock);
276    if (jzfb->is_enabled) {
277        if (1) {
278            jzfb_upload_frame_dma(jzfb);
279            /* The DMA complete callback will reschedule. */
280        } else {
281            jzfb_upload_frame_cpu(jzfb);
282            schedule_delayed_work(&jzfb->refresh_work, HZ / 10);
283        }
284    }
285    mutex_unlock(&jzfb->lock);
286}
287
288static void jzfb_refresh_work_complete(
289        struct jz4740_dma_chan *dma, int res, void *dev)
290{
291    struct jzfb *jzfb = dev_get_drvdata(dev);
292    // TODO: Stick to refresh rate in mode description.
293    int interval = HZ / 60;
294
295    schedule_delayed_work(&jzfb->refresh_work, interval);
296}
297
298static int jzfb_set_par(struct fb_info *info)
299{
300    struct jzfb *jzfb = info->par;
301    struct fb_var_screeninfo *var = &info->var;
302    struct fb_videomode *mode;
303    uint16_t slcd_cfg;
304
305    mode = jzfb_get_mode(jzfb, var);
306    if (mode == NULL)
307        return -EINVAL;
308
309    info->mode = mode;
310
311    slcd_cfg = SLCD_CFG_BURST_8_WORD;
312    /* command size */
313    slcd_cfg |= (jzfb->pdata->lcd_type & 3) << SLCD_CFG_CWIDTH_BIT;
314    /* data size */
315    if (jzfb->pdata->lcd_type & (1 << 6)) {
316        /* serial */
317        unsigned int num_bits;
318        switch (jzfb->pdata->lcd_type) {
319        case JZ_LCD_TYPE_SMART_SERIAL_8_BIT:
320            slcd_cfg |= SLCD_CFG_DWIDTH_8_x1;
321            num_bits = 8;
322            break;
323        case JZ_LCD_TYPE_SMART_SERIAL_16_BIT:
324            slcd_cfg |= SLCD_CFG_DWIDTH_16;
325            num_bits = 16;
326            break;
327        case JZ_LCD_TYPE_SMART_SERIAL_18_BIT:
328            slcd_cfg |= SLCD_CFG_DWIDTH_18;
329            num_bits = 18;
330            break;
331        default:
332            num_bits = 0;
333            break;
334        }
335        if (num_bits != jzfb->pdata->bpp) {
336            dev_err(&jzfb->pdev->dev,
337                "Data size (%d) does not match bpp (%d)\n",
338                num_bits, jzfb->pdata->bpp);
339        }
340        slcd_cfg |= SLCD_CFG_TYPE_SERIAL;
341    } else {
342        /* parallel */
343        switch (jzfb->pdata->bpp) {
344        case 8:
345            slcd_cfg |= SLCD_CFG_DWIDTH_8_x1;
346            break;
347        case 15:
348        case 16:
349            switch (jzfb->pdata->lcd_type) {
350            case JZ_LCD_TYPE_SMART_PARALLEL_8_BIT:
351                slcd_cfg |= SLCD_CFG_DWIDTH_8_x2;
352                break;
353            default:
354                slcd_cfg |= SLCD_CFG_DWIDTH_16;
355                break;
356            }
357            break;
358        case 18:
359            switch (jzfb->pdata->lcd_type) {
360            case JZ_LCD_TYPE_SMART_PARALLEL_8_BIT:
361                slcd_cfg |= SLCD_CFG_DWIDTH_8_x3;
362                break;
363            case JZ_LCD_TYPE_SMART_PARALLEL_16_BIT:
364                slcd_cfg |= SLCD_CFG_DWIDTH_9_x2;
365                break;
366            case JZ_LCD_TYPE_SMART_PARALLEL_18_BIT:
367                slcd_cfg |= SLCD_CFG_DWIDTH_18;
368                break;
369            default:
370                break;
371            }
372            break;
373        case 24:
374            slcd_cfg |= SLCD_CFG_DWIDTH_8_x3;
375            break;
376        default:
377            dev_err(&jzfb->pdev->dev,
378                "Unsupported value for bpp: %d\n",
379                jzfb->pdata->bpp);
380        }
381        slcd_cfg |= SLCD_CFG_TYPE_PARALLEL;
382    }
383    if (!jzfb->pdata->chip_select_active_low)
384        slcd_cfg |= SLCD_CFG_CS_ACTIVE_HIGH;
385    if (!jzfb->pdata->register_select_active_low)
386        slcd_cfg |= SLCD_CFG_RS_CMD_HIGH;
387    if (!jzfb->pdata->pixclk_falling_edge)
388        slcd_cfg |= SLCD_CFG_CLK_ACTIVE_RISING;
389
390#if 0
391    // TODO(MtH): Compute rate from refresh or vice versa.
392    if (mode->pixclock) {
393        rate = PICOS2KHZ(mode->pixclock) * 1000;
394        mode->refresh = rate / vt / ht;
395    } else {
396        if (jzfb->pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL)
397            rate = mode->refresh * (vt + 2 * mode->xres) * ht;
398        else
399            rate = mode->refresh * vt * ht;
400
401        mode->pixclock = KHZ2PICOS(rate / 1000);
402    }
403#endif
404
405    mutex_lock(&jzfb->lock);
406    if (!jzfb->is_enabled)
407        clk_enable(jzfb->ldclk);
408
409    // TODO(MtH): We should not change config while DMA might be running.
410    writew(slcd_cfg, jzfb->base + JZ_REG_SLCD_CFG);
411
412    if (!jzfb->is_enabled)
413        clk_disable(jzfb->ldclk);
414    mutex_unlock(&jzfb->lock);
415
416    // TODO(MtH): Use maximum transfer speed that panel can handle.
417    // ILI9325 can do 10 MHz.
418    clk_set_rate(jzfb->lpclk, 12000000);
419    clk_set_rate(jzfb->ldclk, 42000000);
420
421    return 0;
422}
423
424static void jzfb_enable(struct jzfb *jzfb)
425{
426    uint32_t ctrl;
427
428    clk_enable(jzfb->ldclk);
429
430    jz_gpio_bulk_resume(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
431    if (jzfb->pdata->lcd_type & (1 << 6)) {
432        /* serial */
433        jz_gpio_bulk_resume(&jz_slcd_data_pins[15], 1);
434    } else {
435        /* parallel */
436        jz_gpio_bulk_resume(jz_slcd_data_pins,
437                    jzfb_num_data_pins(jzfb));
438    }
439    jzfb_disable_dma(jzfb);
440    jzfb->panel->enable(jzfb);
441
442    ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
443    ctrl |= JZ_LCD_CTRL_ENABLE;
444    ctrl &= ~JZ_LCD_CTRL_DISABLE;
445    writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
446
447    schedule_delayed_work(&jzfb->refresh_work, 0);
448}
449
450static void jzfb_disable(struct jzfb *jzfb)
451{
452    /* It is safe but wasteful to call refresh_work() while disabled. */
453    cancel_delayed_work(&jzfb->refresh_work);
454
455    /* Abort any DMA transfer that might be in progress and allow direct
456       writes to the panel. */
457    jzfb_disable_dma(jzfb);
458
459    jzfb->panel->disable(jzfb);
460    jz_gpio_bulk_suspend(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
461    if (jzfb->pdata->lcd_type & (1 << 6)) {
462        /* serial */
463        jz_gpio_bulk_suspend(&jz_slcd_data_pins[15], 1);
464    } else {
465        /* parallel */
466        jz_gpio_bulk_suspend(jz_slcd_data_pins,
467                     jzfb_num_data_pins(jzfb));
468    }
469
470    clk_disable(jzfb->ldclk);
471}
472
473static int jzfb_blank(int blank_mode, struct fb_info *info)
474{
475    struct jzfb* jzfb = info->par;
476    int ret = 0;
477    int new_enabled = (blank_mode == FB_BLANK_UNBLANK);
478
479    mutex_lock(&jzfb->lock);
480    if (new_enabled) {
481        if (!jzfb->is_enabled)
482            jzfb_enable(jzfb);
483    } else {
484        if (jzfb->is_enabled) {
485            /* No sleep in TV-out mode. */
486            if (readl(jzfb->base + JZ_REG_LCD_CFG) & JZ_LCD_CFG_SLCD)
487                jzfb_disable(jzfb);
488            else
489                ret = -EBUSY;
490        }
491    }
492    if (!ret)
493        jzfb->is_enabled = new_enabled;
494    mutex_unlock(&jzfb->lock);
495
496    return ret;
497}
498
499static int jzfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
500{
501    info->var.yoffset = var->yoffset;
502    return 0;
503}
504
505static int jzfb_alloc_devmem(struct jzfb *jzfb)
506{
507    int max_framesize = 0;
508    struct fb_videomode *mode = jzfb->pdata->modes;
509    void *page;
510    int i;
511
512    for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
513        if (max_framesize < mode->xres * mode->yres)
514            max_framesize = mode->xres * mode->yres;
515    }
516
517    max_framesize *= jzfb_get_controller_bpp(jzfb) >> 3;
518
519    jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
520                    sizeof(*jzfb->framedesc),
521                    &jzfb->framedesc_phys, GFP_KERNEL);
522
523    if (!jzfb->framedesc)
524        return -ENOMEM;
525
526    /* reserve memory for two frames to allow double buffering */
527    jzfb->vidmem_size = PAGE_ALIGN(max_framesize * 2);
528    jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
529                        jzfb->vidmem_size,
530                        &jzfb->vidmem_phys, GFP_KERNEL);
531
532    if (!jzfb->vidmem)
533        goto err_free_framedesc;
534
535    for (page = jzfb->vidmem;
536         page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
537         page += PAGE_SIZE) {
538        SetPageReserved(virt_to_page(page));
539    }
540
541    jzfb->framedesc->next = jzfb->framedesc_phys;
542    jzfb->framedesc->addr = jzfb->vidmem_phys;
543    jzfb->framedesc->id = 0xdeafbead;
544    jzfb->framedesc->cmd = 0;
545    jzfb->framedesc->cmd |= max_framesize / 4;
546
547    return 0;
548
549err_free_framedesc:
550    dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
551                jzfb->framedesc, jzfb->framedesc_phys);
552    return -ENOMEM;
553}
554
555static void jzfb_free_devmem(struct jzfb *jzfb)
556{
557    dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
558                jzfb->vidmem, jzfb->vidmem_phys);
559    dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
560                jzfb->framedesc, jzfb->framedesc_phys);
561}
562
563#include "jz4740_lcd.h"
564
565#define FBIOA320TVOUT 0x46F0
566#define FB_A320TV_OFF 0
567#define FB_A320TV_NTSC 1
568#define FB_A320TV_PAL 2
569
570static void jzfb_tv_out(struct jzfb *jzfb, unsigned int mode)
571{
572    int blank = jzfb->is_enabled ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
573    struct fb_event event = {
574        .info = jzfb->fb,
575        .data = &blank,
576    };
577
578    printk("A320 TV out: %d\n", mode);
579
580    if (mode != FB_A320TV_OFF) {
581        cancel_delayed_work(&jzfb->refresh_work);
582        /* Abort any DMA transfer that might be in progress and
583           allow direct writes to the panel. */
584        jzfb_disable_dma(jzfb);
585        jzfb->panel->disable(jzfb);
586
587        /* set up LCD controller for TV output */
588
589        writel(JZ_LCD_CFG_HSYNC_ACTIVE_LOW |
590               JZ_LCD_CFG_VSYNC_ACTIVE_LOW,
591               jzfb->base + JZ_REG_LCD_CFG);
592
593        /* V-Sync pulse end position */
594        writel(10, jzfb->base + JZ_REG_LCD_VSYNC);
595
596        if (mode == FB_A320TV_PAL) {
597            /* PAL */
598            /* H-Sync pulse start position */
599            writel(125, jzfb->base + JZ_REG_LCD_HSYNC);
600            /* virtual area size */
601            writel(0x036c0112, jzfb->base + JZ_REG_LCD_VAT);
602            /* horizontal start/end point */
603            writel(0x02240364, jzfb->base + JZ_REG_LCD_DAH);
604            /* vertical start/end point */
605            writel(0x1b010b, jzfb->base + JZ_REG_LCD_DAV);
606        }
607        else {
608            /* NTSC */
609            writel(0x3c, jzfb->base + JZ_REG_LCD_HSYNC);
610            writel(0x02e00110, jzfb->base + JZ_REG_LCD_VAT);
611            writel(0x019902d9, jzfb->base + JZ_REG_LCD_DAH);
612            writel(0x1d010d, jzfb->base + JZ_REG_LCD_DAV);
613        }
614        writel(0, jzfb->base + JZ_REG_LCD_PS);
615        writel(0, jzfb->base + JZ_REG_LCD_CLS);
616        writel(0, jzfb->base + JZ_REG_LCD_SPL);
617        writel(0, jzfb->base + JZ_REG_LCD_REV);
618        /* reset status register */
619        writel(0, jzfb->base + JZ_REG_LCD_STATE);
620
621        /* tell LCDC about the frame descriptor address */
622        writel(jzfb->framedesc_phys, jzfb->base + JZ_REG_LCD_DA0);
623
624        writel(JZ_LCD_CTRL_BURST_16 | JZ_LCD_CTRL_ENABLE |
625               JZ_LCD_CTRL_BPP_15_16,
626               jzfb->base + JZ_REG_LCD_CTRL);
627    }
628    else {
629        /* disable LCD controller and re-enable SLCD */
630        writel(JZ_LCD_CFG_SLCD, jzfb->base + JZ_REG_LCD_CFG);
631        jzfb->panel->enable(jzfb);
632        schedule_delayed_work(&jzfb->refresh_work, 0);
633    }
634
635    /* reaffirm the current blanking state, to trigger a backlight update */
636    fb_notifier_call_chain(FB_EVENT_BLANK, &event);
637}
638
639static int jzfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
640{
641    struct jzfb *jzfb = info->par;
642    switch (cmd) {
643        case FBIOA320TVOUT:
644            /* No TV-out mode while sleeping. */
645            if (!jzfb->is_enabled)
646                return -EBUSY;
647
648            jzfb_tv_out(jzfb, arg);
649            break;
650        default:
651            return -EINVAL;
652    }
653    return 0;
654}
655
656static struct fb_ops jzfb_ops = {
657    .owner = THIS_MODULE,
658    .fb_check_var = jzfb_check_var,
659    .fb_set_par = jzfb_set_par,
660    .fb_setcolreg = jzfb_setcolreg,
661    .fb_blank = jzfb_blank,
662    .fb_pan_display = jzfb_pan_display,
663    .fb_fillrect = sys_fillrect,
664    .fb_copyarea = sys_copyarea,
665    .fb_imageblit = sys_imageblit,
666    .fb_ioctl = jzfb_ioctl,
667};
668
669static int __devinit jzfb_probe(struct platform_device *pdev)
670{
671    int ret;
672    struct jzfb *jzfb;
673    struct fb_info *fb;
674    struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
675    struct resource *mem;
676
677    if (!pdata) {
678        dev_err(&pdev->dev, "Missing platform data\n");
679        return -ENOENT;
680    }
681
682    mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
683
684    if (!mem) {
685        dev_err(&pdev->dev, "Failed to get register memory resource\n");
686        return -ENOENT;
687    }
688
689    mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
690
691    if (!mem) {
692        dev_err(&pdev->dev, "Failed to request register memory region\n");
693        return -EBUSY;
694    }
695
696    fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
697
698    if (!fb) {
699        dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
700        ret = -ENOMEM;
701        goto err_release_mem_region;
702    }
703
704    fb->fbops = &jzfb_ops;
705    fb->flags = FBINFO_DEFAULT;
706
707    jzfb = fb->par;
708    jzfb->pdev = pdev;
709    jzfb->pdata = pdata;
710    jzfb->mem = mem;
711
712    jzfb->dma = jz4740_dma_request(&pdev->dev, dev_name(&pdev->dev));
713    if (!jzfb->dma) {
714        dev_err(&pdev->dev, "Failed to get DMA channel\n");
715        ret = -EBUSY;
716        goto err_framebuffer_release;
717    }
718    jz4740_dma_configure(jzfb->dma, &jzfb_slcd_dma_config);
719    jz4740_dma_set_complete_cb(jzfb->dma, &jzfb_refresh_work_complete);
720
721    jzfb->ldclk = clk_get(&pdev->dev, "lcd");
722    if (IS_ERR(jzfb->ldclk)) {
723        ret = PTR_ERR(jzfb->ldclk);
724        dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
725        goto err_free_dma;
726    }
727
728    jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
729    if (IS_ERR(jzfb->lpclk)) {
730        ret = PTR_ERR(jzfb->lpclk);
731        dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
732        goto err_put_ldclk;
733    }
734
735    jzfb->base = ioremap(mem->start, resource_size(mem));
736
737    if (!jzfb->base) {
738        dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
739        ret = -EBUSY;
740        goto err_put_lpclk;
741    }
742
743    platform_set_drvdata(pdev, jzfb);
744
745    fb_videomode_to_modelist(pdata->modes, pdata->num_modes,
746                 &fb->modelist);
747    fb->mode = pdata->modes;
748
749    fb_videomode_to_var(&fb->var, fb->mode);
750    fb->var.bits_per_pixel = pdata->bpp;
751    jzfb_check_var(&fb->var, fb);
752
753    ret = jzfb_alloc_devmem(jzfb);
754    if (ret) {
755        dev_err(&pdev->dev, "Failed to allocate video memory\n");
756        goto err_iounmap;
757    }
758
759    fb->fix = jzfb_fix;
760    fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
761    fb->fix.mmio_start = mem->start;
762    fb->fix.mmio_len = resource_size(mem);
763    fb->fix.smem_start = jzfb->vidmem_phys;
764    fb->fix.smem_len = fb->fix.line_length * fb->var.yres_virtual;
765    fb->screen_base = jzfb->vidmem;
766    fb->pseudo_palette = jzfb->pseudo_palette;
767
768    fb_alloc_cmap(&fb->cmap, 256, 0);
769
770    mutex_init(&jzfb->lock);
771
772    clk_enable(jzfb->ldclk);
773    jzfb->is_enabled = 1;
774
775    writel(JZ_LCD_CFG_SLCD, jzfb->base + JZ_REG_LCD_CFG);
776    writeb(0, jzfb->base + JZ_REG_SLCD_CTRL);
777
778    jzfb_set_par(fb);
779
780    jz_gpio_bulk_request(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
781    if (jzfb->pdata->lcd_type & (1 << 6)) {
782        /* serial */
783        jz_gpio_bulk_request(&jz_slcd_data_pins[15], 1);
784    } else {
785        /* parallel */
786        jz_gpio_bulk_request(jz_slcd_data_pins,
787                     jzfb_num_data_pins(jzfb));
788    }
789
790    jzfb->panel = jz_slcd_panels_probe(jzfb);
791    if (!jzfb->panel) {
792        dev_err(&pdev->dev, "Failed to find panel driver\n");
793        ret = -ENOENT;
794        goto err_free_devmem;
795    }
796    jzfb_disable_dma(jzfb);
797    jzfb->panel->init(jzfb);
798    jzfb->panel->enable(jzfb);
799
800    ret = register_framebuffer(fb);
801    if (ret) {
802        dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
803        goto err_free_panel;
804    }
805
806    jzfb->fb = fb;
807
808    INIT_DELAYED_WORK(&jzfb->refresh_work, jzfb_refresh_work);
809    schedule_delayed_work(&jzfb->refresh_work, 0);
810
811    return 0;
812
813err_free_panel:
814    jzfb->panel->exit(jzfb);
815err_free_devmem:
816    jzfb_free_gpio_pins(jzfb);
817
818    fb_dealloc_cmap(&fb->cmap);
819    jzfb_free_devmem(jzfb);
820err_iounmap:
821    iounmap(jzfb->base);
822err_put_lpclk:
823    clk_put(jzfb->lpclk);
824err_put_ldclk:
825    clk_put(jzfb->ldclk);
826err_free_dma:
827    jz4740_dma_free(jzfb->dma);
828err_framebuffer_release:
829    framebuffer_release(fb);
830err_release_mem_region:
831    release_mem_region(mem->start, resource_size(mem));
832    return ret;
833}
834
835static int __devexit jzfb_remove(struct platform_device *pdev)
836{
837    struct jzfb *jzfb = platform_get_drvdata(pdev);
838
839    jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
840
841    /* Blanking will prevent future refreshes from behind scheduled.
842       Now wait for a possible refresh in progress to finish. */
843    cancel_delayed_work_sync(&jzfb->refresh_work);
844
845    jzfb->panel->exit(jzfb);
846
847    jzfb_free_gpio_pins(jzfb);
848
849    jz4740_dma_free(jzfb->dma);
850
851    iounmap(jzfb->base);
852    release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
853
854    fb_dealloc_cmap(&jzfb->fb->cmap);
855    jzfb_free_devmem(jzfb);
856
857    platform_set_drvdata(pdev, NULL);
858
859    clk_put(jzfb->lpclk);
860    clk_put(jzfb->ldclk);
861
862    framebuffer_release(jzfb->fb);
863
864    return 0;
865}
866
867#ifdef CONFIG_PM
868
869static int jzfb_suspend(struct device *dev)
870{
871    struct jzfb *jzfb = dev_get_drvdata(dev);
872
873    console_lock();
874    fb_set_suspend(jzfb->fb, 1);
875    console_unlock();
876
877    mutex_lock(&jzfb->lock);
878    if (jzfb->is_enabled)
879        jzfb_disable(jzfb);
880    mutex_unlock(&jzfb->lock);
881
882    return 0;
883}
884
885static int jzfb_resume(struct device *dev)
886{
887    struct jzfb *jzfb = dev_get_drvdata(dev);
888    clk_enable(jzfb->ldclk);
889
890    mutex_lock(&jzfb->lock);
891    if (jzfb->is_enabled)
892        jzfb_enable(jzfb);
893    mutex_unlock(&jzfb->lock);
894
895    console_lock();
896    fb_set_suspend(jzfb->fb, 0);
897    console_unlock();
898
899    return 0;
900}
901
902static const struct dev_pm_ops jzfb_pm_ops = {
903    .suspend = jzfb_suspend,
904    .resume = jzfb_resume,
905    .poweroff = jzfb_suspend,
906    .restore = jzfb_resume,
907};
908
909#define JZFB_PM_OPS (&jzfb_pm_ops)
910
911#else
912#define JZFB_PM_OPS NULL
913#endif
914
915static struct platform_driver jzfb_driver = {
916    .probe = jzfb_probe,
917    .remove = __devexit_p(jzfb_remove),
918    .driver = {
919        .name = "jz4740-fb",
920        .pm = JZFB_PM_OPS,
921    },
922};
923
924static int __init jzfb_init(void)
925{
926    return platform_driver_register(&jzfb_driver);
927}
928module_init(jzfb_init);
929
930static void __exit jzfb_exit(void)
931{
932    platform_driver_unregister(&jzfb_driver);
933}
934module_exit(jzfb_exit);
935
936MODULE_LICENSE("GPL");
937MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>, Maarten ter Huurne <maarten@treewalker.org>");
938MODULE_DESCRIPTION("JZ4740 SoC SLCD framebuffer driver");
939MODULE_ALIAS("platform:jz4740-fb");
drivers/video/jz4740_slcd_panels.c
1/*
2 * linux/drivers/video/jz4740_slcd_panels.c
3 * -- LCD panel definitions for Ingenic On-Chip SLCD frame buffer device
4 *
5 * Copyright (C) 2005-2007, Ingenic Semiconductor Inc.
6 * Copyright (C) 2009, Ignacio Garcia Perez <iggarpe@gmail.com>
7 * Copyright (C) 2010, Maarten ter Huurne <maarten@treewalker.org>
8 * Copyright (C) 2011, ChinaChip
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <asm/io.h>
17#include <asm/mach-jz4740/gpio.h>
18#include <asm/mach-jz4740/jz4740_fb.h>
19#include <linux/delay.h>
20#include <linux/gpio.h>
21#include <linux/kernel.h>
22#include <linux/platform_device.h>
23
24#include "jz4740_slcd.h"
25
26/* Send a command without data. */
27static void send_panel_command(struct jzfb *jzfb, u32 cmd) {
28    u16 slcd_cfg = readw(jzfb->base + JZ_REG_SLCD_CFG);
29    switch (slcd_cfg & SLCD_CFG_CWIDTH_MASK) {
30    case SLCD_CFG_CWIDTH_8BIT:
31        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
32        writel(SLCD_DATA_RS_COMMAND | ((cmd&0xff00) >> 8), jzfb->base + JZ_REG_SLCD_DATA);
33        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
34        writel(SLCD_DATA_RS_COMMAND | ((cmd&0xff) >> 0), jzfb->base + JZ_REG_SLCD_DATA);
35        break;
36    case SLCD_CFG_CWIDTH_16BIT:
37        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
38        writel(SLCD_DATA_RS_COMMAND | (cmd&0xffff), jzfb->base + JZ_REG_SLCD_DATA);
39        break;
40    case SLCD_CFG_CWIDTH_18BIT:
41        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
42        writel(SLCD_DATA_RS_COMMAND | ((cmd&0xff00) << 2) | ((cmd&0xff) << 1), jzfb->base + JZ_REG_SLCD_DATA);
43        break;
44    default:
45        break;
46    }
47}
48
49/* Send data without command. */
50static void send_panel_data(struct jzfb *jzfb, u32 data)
51{
52    u16 slcd_cfg = readw(jzfb->base + JZ_REG_SLCD_CFG);
53    switch (slcd_cfg & SLCD_CFG_DWIDTH_MASK) {
54    case SLCD_CFG_DWIDTH_18:
55        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
56        data = ((data & 0xff) << 1) | ((data & 0xff00) << 2);
57        writel(SLCD_DATA_RS_DATA | ((data<<6)&0xfc0000)|((data<<4)&0xfc00) | ((data<<2)&0xfc), jzfb->base + JZ_REG_SLCD_DATA);
58        break;
59    case SLCD_CFG_DWIDTH_16:
60        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
61        writel(SLCD_DATA_RS_DATA | (data&0xffff), jzfb->base + JZ_REG_SLCD_DATA);
62        break;
63    case SLCD_CFG_DWIDTH_9_x2:
64        data = ((data & 0xff) << 1) | ((data & 0xff00) << 2);
65        data = ((data << 6) & 0xfc0000) | ((data << 4) & 0xfc00) | ((data << 2) & 0xfc);
66        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
67        writel(SLCD_DATA_RS_DATA | data, jzfb->base + JZ_REG_SLCD_DATA);
68        break;
69    default:
70        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
71        writel(SLCD_DATA_RS_DATA | (data&0xffff), jzfb->base + JZ_REG_SLCD_DATA);
72        break;
73    }
74}
75
76/* Send command and data. */
77static void set_panel_reg(struct jzfb *jzfb, u32 cmd, u32 data)
78{
79    send_panel_command(jzfb, cmd);
80    send_panel_data(jzfb, data);
81}
82
83#ifdef CONFIG_JZ_SLCD_ILI9325
84
85// TODO(MtH): GPIO assignments belong in the board definition, since two
86// boards using the same panel controller could still use different
87// GPIO assignments.
88// TODO(MtH): CS mismatch: B17 (A320) vs C20 (standard).
89#define ILI9325_GPIO_CS_N JZ_GPIO_PORTB(17) /* Chip select */
90#define ILI9325_GPIO_RESET_N JZ_GPIO_PORTB(18) /* LCD reset */
91
92static int ili9325_init(struct jzfb *jzfb)
93{
94    struct device *dev = &jzfb->pdev->dev;
95    int ret;
96
97    ret = gpio_request(ILI9325_GPIO_CS_N, dev_name(dev));
98    if (ret)
99        goto err_cs;
100    gpio_direction_output(ILI9325_GPIO_CS_N, 1);
101
102    ret = gpio_request(ILI9325_GPIO_RESET_N, dev_name(dev));
103    if (ret)
104        goto err_reset;
105    gpio_direction_output(ILI9325_GPIO_RESET_N, 0);
106
107    mdelay(100);
108    return 0;
109
110err_reset:
111    gpio_free(ILI9325_GPIO_CS_N);
112err_cs:
113    dev_err(dev, "Could not reserve GPIO pins for ILI9325 panel driver\n");
114    return ret;
115}
116
117static void ili9325_exit(struct jzfb *jzfb)
118{
119    gpio_free(ILI9325_GPIO_CS_N);
120    gpio_free(ILI9325_GPIO_RESET_N);
121}
122
123static void ili9325_enable(struct jzfb *jzfb)
124{
125    /* RESET pulse */
126    gpio_set_value(ILI9325_GPIO_RESET_N, 0);
127    mdelay(10);
128    gpio_set_value(ILI9325_GPIO_RESET_N, 1);
129    mdelay(50);
130
131    /* Enable chip select */
132    gpio_set_value(ILI9325_GPIO_CS_N, 0);
133
134    /* Black magic */
135    set_panel_reg(jzfb, 0xE3, 0x3008);
136    set_panel_reg(jzfb, 0xE7, 0x0012);
137    set_panel_reg(jzfb, 0xEF, 0x1231);
138    set_panel_reg(jzfb, 0x01, 0x0100);
139    set_panel_reg(jzfb, 0x02, 0x0700);
140    set_panel_reg(jzfb, 0x03, 0x1098);
141    set_panel_reg(jzfb, 0x04, 0x0000);
142    set_panel_reg(jzfb, 0x08, 0x0207);
143    set_panel_reg(jzfb, 0x09, 0x0000);
144    set_panel_reg(jzfb, 0x0A, 0x0000);
145    set_panel_reg(jzfb, 0x0C, 0x0000);
146    set_panel_reg(jzfb, 0x0D, 0x0000);
147    set_panel_reg(jzfb, 0x0F, 0x0000);
148    set_panel_reg(jzfb, 0x10, 0x0000);
149    set_panel_reg(jzfb, 0x11, 0x0007);
150    set_panel_reg(jzfb, 0x12, 0x0000);
151    set_panel_reg(jzfb, 0x13, 0x0000);
152    mdelay(200);
153    set_panel_reg(jzfb, 0x10, 0x1290);
154    set_panel_reg(jzfb, 0x11, 0x0227);
155    mdelay(50);
156    set_panel_reg(jzfb, 0x12, 0x001B);
157    mdelay(50);
158    set_panel_reg(jzfb, 0x13, 0x0500);
159    set_panel_reg(jzfb, 0x29, 0x000C);
160    set_panel_reg(jzfb, 0x2B, 0x000D);
161    mdelay(50);
162    set_panel_reg(jzfb, 0x20, 0x0000);
163    set_panel_reg(jzfb, 0x21, 0x0000);
164    set_panel_reg(jzfb, 0x30, 0x0000);
165    set_panel_reg(jzfb, 0x31, 0x0204);
166    set_panel_reg(jzfb, 0x32, 0x0200);
167    set_panel_reg(jzfb, 0x35, 0x0007);
168    set_panel_reg(jzfb, 0x36, 0x1404);
169    set_panel_reg(jzfb, 0x37, 0x0705);
170    set_panel_reg(jzfb, 0x38, 0x0305);
171    set_panel_reg(jzfb, 0x39, 0x0707);
172    set_panel_reg(jzfb, 0x3C, 0x0701);
173    set_panel_reg(jzfb, 0x3D, 0x000E);
174    set_panel_reg(jzfb, 0x50, 0x0000);
175    set_panel_reg(jzfb, 0x51, 0x00EF);
176    set_panel_reg(jzfb, 0x52, 0x0000);
177    set_panel_reg(jzfb, 0x53, 0x013F);
178    set_panel_reg(jzfb, 0x60, 0xA700);
179    set_panel_reg(jzfb, 0x61, 0x0001);
180    set_panel_reg(jzfb, 0x6A, 0x0000);
181    set_panel_reg(jzfb, 0x80, 0x0000);
182    set_panel_reg(jzfb, 0x81, 0x0000);
183    set_panel_reg(jzfb, 0x82, 0x0000);
184    set_panel_reg(jzfb, 0x83, 0x0000);
185    set_panel_reg(jzfb, 0x84, 0x0000);
186    set_panel_reg(jzfb, 0x85, 0x0000);
187    set_panel_reg(jzfb, 0x90, 0x0010);
188    set_panel_reg(jzfb, 0x92, 0x0600);
189    mdelay(50);
190    set_panel_reg(jzfb, 0x07, 0x0133);
191    mdelay(50);
192    send_panel_command(jzfb, 0x22);
193}
194
195/* TODO(IGP): make sure LCD power consumption is low in these conditions */
196static void ili9325_disable(struct jzfb *jzfb)
197{
198    /* Keep chip select disabled */
199    gpio_set_value(ILI9325_GPIO_CS_N, 1);
200    /* Keep RESET active */
201    gpio_set_value(ILI9325_GPIO_RESET_N, 0);
202}
203
204#endif
205
206#ifdef CONFIG_JZ_SLCD_ILI9331
207
208#define ILI9331_GPIO_CS_N JZ_GPIO_PORTB(17) /* Chip select */
209#define ILI9331_GPIO_RESET_N JZ_GPIO_PORTB(18) /* LCD reset */
210
211static int ili9331_init(struct jzfb *jzfb)
212{
213    struct device *dev = &jzfb->pdev->dev;
214    int ret;
215
216    ret = gpio_request(ILI9331_GPIO_CS_N, dev_name(dev));
217    if (ret)
218        goto err_cs;
219    gpio_direction_output(ILI9331_GPIO_CS_N, 1);
220
221    ret = gpio_request(ILI9331_GPIO_RESET_N, dev_name(dev));
222    if (ret)
223        goto err_reset;
224    gpio_direction_output(ILI9331_GPIO_RESET_N, 0);
225
226    mdelay(100);
227    return 0;
228
229err_reset:
230    gpio_free(ILI9331_GPIO_CS_N);
231err_cs:
232    dev_err(dev, "Could not reserve GPIO pins for ILI9331 panel driver\n");
233    return ret;
234}
235
236static void ili9331_exit(struct jzfb *jzfb)
237{
238    gpio_free(ILI9331_GPIO_CS_N);
239    gpio_free(ILI9331_GPIO_RESET_N);
240}
241
242static void ili9331_enable(struct jzfb *jzfb)
243{
244    /* RESET pulse */
245    gpio_set_value(ILI9331_GPIO_RESET_N, 0);
246    mdelay(10);
247    gpio_set_value(ILI9331_GPIO_RESET_N, 1);
248    mdelay(50);
249
250    /* Enable chip select */
251    gpio_set_value(ILI9331_GPIO_CS_N, 0);
252
253    /* Black magic */
254    set_panel_reg(jzfb, 0xE7, 0x1014);
255    set_panel_reg(jzfb, 0x01, 0x0000);
256    set_panel_reg(jzfb, 0x02, 0x0200);
257    set_panel_reg(jzfb, 0x03, 0x1048);
258    set_panel_reg(jzfb, 0x08, 0x0202);
259    set_panel_reg(jzfb, 0x09, 0x0000);
260    set_panel_reg(jzfb, 0x0A, 0x0000);
261    set_panel_reg(jzfb, 0x0C, 0x0000);
262    set_panel_reg(jzfb, 0x0D, 0x0000);
263    set_panel_reg(jzfb, 0x0F, 0x0000);
264    set_panel_reg(jzfb, 0x10, 0x0000);
265    set_panel_reg(jzfb, 0x11, 0x0007);
266    set_panel_reg(jzfb, 0x12, 0x0000);
267    set_panel_reg(jzfb, 0x13, 0x0000);
268    mdelay(100);
269    set_panel_reg(jzfb, 0x10, 0x1690);
270    set_panel_reg(jzfb, 0x11, 0x0224);
271    mdelay(50);
272    set_panel_reg(jzfb, 0x12, 0x001F);
273    mdelay(50);
274    set_panel_reg(jzfb, 0x13, 0x0500);
275    set_panel_reg(jzfb, 0x29, 0x000C);
276    set_panel_reg(jzfb, 0x2B, 0x000D);
277    mdelay(50);
278    set_panel_reg(jzfb, 0x30, 0x0000);
279    set_panel_reg(jzfb, 0x31, 0x0106);
280    set_panel_reg(jzfb, 0x32, 0x0000);
281    set_panel_reg(jzfb, 0x35, 0x0204);
282    set_panel_reg(jzfb, 0x36, 0x160A);
283    set_panel_reg(jzfb, 0x37, 0x0707);
284    set_panel_reg(jzfb, 0x38, 0x0106);
285    set_panel_reg(jzfb, 0x39, 0x0706);
286    set_panel_reg(jzfb, 0x3C, 0x0402);
287    set_panel_reg(jzfb, 0x3D, 0x0C0F);
288    set_panel_reg(jzfb, 0x50, 0x0000);
289    set_panel_reg(jzfb, 0x51, 0x00EF);
290    set_panel_reg(jzfb, 0x52, 0x0000);
291    set_panel_reg(jzfb, 0x53, 0x013F);
292    set_panel_reg(jzfb, 0x20, 0x0000);
293    set_panel_reg(jzfb, 0x21, 0x0000);
294    set_panel_reg(jzfb, 0x60, 0x2700);
295    set_panel_reg(jzfb, 0x61, 0x0001);
296    set_panel_reg(jzfb, 0x6A, 0x0000);
297    set_panel_reg(jzfb, 0x80, 0x0000);
298    set_panel_reg(jzfb, 0x81, 0x0000);
299    set_panel_reg(jzfb, 0x82, 0x0000);
300    set_panel_reg(jzfb, 0x83, 0x0000);
301    set_panel_reg(jzfb, 0x84, 0x0000);
302    set_panel_reg(jzfb, 0x85, 0x0000);
303    set_panel_reg(jzfb, 0x20, 0x00EF);
304    set_panel_reg(jzfb, 0x21, 0x0190);
305    set_panel_reg(jzfb, 0x90, 0x0010);
306    set_panel_reg(jzfb, 0x92, 0x0600);
307    set_panel_reg(jzfb, 0x07, 0x0133);
308    send_panel_command(jzfb, 0x22);
309}
310
311/* TODO(IGP): make sure LCD power consumption is low in these conditions */
312static void ili9331_disable(struct jzfb *jzfb)
313{
314    /* Keep chip select disabled */
315    gpio_set_value(ILI9331_GPIO_CS_N, 1);
316    /* Keep RESET active */
317    gpio_set_value(ILI9331_GPIO_RESET_N, 0);
318}
319
320#endif
321
322#ifdef CONFIG_JZ_SLCD_ILI9338
323
324#define ILI9338_GPIO_CS_N JZ_GPIO_PORTB(17) /* Chip select */
325#define ILI9338_GPIO_RESET_N JZ_GPIO_PORTB(18) /* LCD reset */
326
327static int ili9338_init(struct jzfb *jzfb)
328{
329    struct device *dev = &jzfb->pdev->dev;
330    int ret;
331
332    ret = gpio_request(ILI9338_GPIO_CS_N, dev_name(dev));
333    if (ret)
334        goto err_cs;
335    gpio_direction_output(ILI9338_GPIO_CS_N, 1);
336
337    ret = gpio_request(ILI9338_GPIO_RESET_N, dev_name(dev));
338    if (ret)
339        goto err_reset;
340    gpio_direction_output(ILI9338_GPIO_RESET_N, 0);
341
342    mdelay(100);
343    return 0;
344
345err_reset:
346    gpio_free(ILI9338_GPIO_CS_N);
347err_cs:
348    dev_err(dev, "Could not reserve GPIO pins for ILI9338 panel driver\n");
349    return ret;
350}
351
352static void ili9338_exit(struct jzfb *jzfb)
353{
354    gpio_free(ILI9338_GPIO_CS_N);
355    gpio_free(ILI9338_GPIO_RESET_N);
356}
357
358static void ili9338_enable(struct jzfb *jzfb)
359{
360    /* RESET pulse */
361    gpio_set_value(ILI9338_GPIO_RESET_N, 0);
362    mdelay(10);
363    gpio_set_value(ILI9338_GPIO_RESET_N, 1);
364    mdelay(50);
365
366    /* Enable chip select */
367    gpio_set_value(ILI9338_GPIO_CS_N, 0);
368
369    /* Black magic */
370    send_panel_command(jzfb, 0x11);
371    mdelay(100);
372
373    send_panel_command(jzfb, 0xCB);
374    send_panel_data(jzfb, 0x01);
375
376    send_panel_command(jzfb, 0xC0);
377    send_panel_data(jzfb, 0x26);
378    send_panel_data(jzfb, 0x01);
379    send_panel_command(jzfb, 0xC1);
380    send_panel_data(jzfb, 0x10);
381    send_panel_command(jzfb, 0xC5);
382    send_panel_data(jzfb, 0x10);
383    send_panel_data(jzfb, 0x52);
384
385    send_panel_command(jzfb, 0x26);
386    send_panel_data(jzfb, 0x01);
387    send_panel_command(jzfb, 0xE0);
388    send_panel_data(jzfb, 0x10);
389    send_panel_data(jzfb, 0x10);
390    send_panel_data(jzfb, 0x10);
391    send_panel_data(jzfb, 0x08);
392    send_panel_data(jzfb, 0x0E);
393    send_panel_data(jzfb, 0x06);
394    send_panel_data(jzfb, 0x42);
395    send_panel_data(jzfb, 0x28);
396    send_panel_data(jzfb, 0x36);
397    send_panel_data(jzfb, 0x03);
398    send_panel_data(jzfb, 0x0E);
399    send_panel_data(jzfb, 0x04);
400    send_panel_data(jzfb, 0x13);
401    send_panel_data(jzfb, 0x0E);
402    send_panel_data(jzfb, 0x0C);
403    send_panel_command(jzfb, 0XE1);
404    send_panel_data(jzfb, 0x0C);
405    send_panel_data(jzfb, 0x23);
406    send_panel_data(jzfb, 0x26);
407    send_panel_data(jzfb, 0x04);
408    send_panel_data(jzfb, 0x0C);
409    send_panel_data(jzfb, 0x04);
410    send_panel_data(jzfb, 0x39);
411    send_panel_data(jzfb, 0x24);
412    send_panel_data(jzfb, 0x4B);
413    send_panel_data(jzfb, 0x03);
414    send_panel_data(jzfb, 0x0B);
415    send_panel_data(jzfb, 0x0B);
416    send_panel_data(jzfb, 0x33);
417    send_panel_data(jzfb, 0x37);
418    send_panel_data(jzfb, 0x0F);
419
420    send_panel_command(jzfb, 0x2a);
421    send_panel_data(jzfb, 0x00);
422    send_panel_data(jzfb, 0x00);
423    send_panel_data(jzfb, 0x01);
424    send_panel_data(jzfb, 0x3f);
425
426    send_panel_command(jzfb, 0x2b);
427    send_panel_data(jzfb, 0x00);
428    send_panel_data(jzfb, 0x00);
429    send_panel_data(jzfb, 0x00);
430    send_panel_data(jzfb, 0xef);
431
432    send_panel_command(jzfb, 0x36);
433    send_panel_data(jzfb, 0xe8);
434
435    send_panel_command(jzfb, 0x3A);
436    send_panel_data(jzfb, 0x05);
437
438    send_panel_command(jzfb, 0x29);
439
440    send_panel_command(jzfb, 0x2c);
441}
442
443/* TODO(IGP): make sure LCD power consumption is low in these conditions */
444static void ili9338_disable(struct jzfb *jzfb)
445{
446    /* Keep chip select disabled */
447    gpio_set_value(ILI9338_GPIO_CS_N, 1);
448    /* Keep RESET active */
449    gpio_set_value(ILI9338_GPIO_RESET_N, 0);
450}
451
452#endif
453
454#ifdef CONFIG_JZ_SLCD_LGDP4551
455
456#define LGDP4551_GPIO_CS_N JZ_GPIO_PORTC(18) /* Chip select */
457#define LGDP4551_GPIO_RESET_N JZ_GPIO_PORTC(21) /* LCD reset */
458
459/* Set the start address of screen, for example (0, 0) */
460static void lgdp4551_set_addr(struct jzfb *jzfb, u16 x, u16 y)
461{
462    set_panel_reg(jzfb, 0x20, x);
463    udelay(1);
464    set_panel_reg(jzfb, 0x21, y);
465    udelay(1);
466    send_panel_command(jzfb, 0x22);
467}
468
469static int lgdp4551_init(struct jzfb *jzfb)
470{
471    struct device *dev = &jzfb->pdev->dev;
472    int ret;
473
474    ret = gpio_request(LGDP4551_GPIO_CS_N, dev_name(dev));
475    if (ret)
476        goto err_cs;
477    gpio_direction_output(LGDP4551_GPIO_CS_N, 0);
478
479    ret = gpio_request(LGDP4551_GPIO_RESET_N, dev_name(dev));
480    if (ret)
481        goto err_reset;
482    gpio_direction_output(LGDP4551_GPIO_RESET_N, 1);
483
484    mdelay(100);
485    return 0;
486
487err_reset:
488    gpio_free(LGDP4551_GPIO_CS_N);
489err_cs:
490    dev_err(dev, "Could not reserve GPIO pins for LGDP4551 panel\n");
491    return ret;
492}
493
494static void lgdp4551_exit(struct jzfb *jzfb)
495{
496    gpio_free(LGDP4551_GPIO_CS_N);
497    gpio_free(LGDP4551_GPIO_RESET_N);
498}
499
500static void lgdp4551_enable(struct jzfb *jzfb)
501{
502    /* RESET# */
503    gpio_set_value(LGDP4551_GPIO_RESET_N, 1);
504    mdelay(10);
505    gpio_set_value(LGDP4551_GPIO_RESET_N, 0);
506    mdelay(10);
507    gpio_set_value(LGDP4551_GPIO_RESET_N, 1);
508    mdelay(100);
509    set_panel_reg(jzfb, 0x0015, 0x0050);
510    set_panel_reg(jzfb, 0x0011, 0x0000);
511    set_panel_reg(jzfb, 0x0010, 0x3628);
512    set_panel_reg(jzfb, 0x0012, 0x0002);
513    set_panel_reg(jzfb, 0x0013, 0x0E47);
514    udelay(100);
515    set_panel_reg(jzfb, 0x0012, 0x0012);
516    udelay(100);
517    set_panel_reg(jzfb, 0x0010, 0x3620);
518    set_panel_reg(jzfb, 0x0013, 0x2E47);
519    udelay(50);
520    set_panel_reg(jzfb, 0x0030, 0x0000);
521    set_panel_reg(jzfb, 0x0031, 0x0502);
522    set_panel_reg(jzfb, 0x0032, 0x0307);
523    set_panel_reg(jzfb, 0x0033, 0x0304);
524    set_panel_reg(jzfb, 0x0034, 0x0004);
525    set_panel_reg(jzfb, 0x0035, 0x0401);
526    set_panel_reg(jzfb, 0x0036, 0x0707);
527    set_panel_reg(jzfb, 0x0037, 0x0303);
528    set_panel_reg(jzfb, 0x0038, 0x1E02);
529    set_panel_reg(jzfb, 0x0039, 0x1E02);
530    set_panel_reg(jzfb, 0x0001, 0x0000);
531    set_panel_reg(jzfb, 0x0002, 0x0300);
532    if (jzfb->pdata->bpp == 16)
533        set_panel_reg(jzfb, 0x0003, 0x10B8); /*8-bit system interface two transfers
534                          up:0x10B8 down:0x1088 left:0x1090 right:0x10a0*/
535    else if (jzfb->pdata->bpp == 32)
536        set_panel_reg(jzfb, 0x0003, 0xD0B8);/*8-bit system interface three transfers,666
537                           up:0xD0B8 down:0xD088 left:0xD090 right:0xD0A0*/
538    set_panel_reg(jzfb, 0x0008, 0x0204);
539    set_panel_reg(jzfb, 0x000A, 0x0008);
540    set_panel_reg(jzfb, 0x0060, 0x3100);
541    set_panel_reg(jzfb, 0x0061, 0x0001);
542    set_panel_reg(jzfb, 0x0090, 0x0052);
543    set_panel_reg(jzfb, 0x0092, 0x000F);
544    set_panel_reg(jzfb, 0x0093, 0x0001);
545    set_panel_reg(jzfb, 0x009A, 0x0008);
546    set_panel_reg(jzfb, 0x00A3, 0x0010);
547    set_panel_reg(jzfb, 0x0050, 0x0000);
548    set_panel_reg(jzfb, 0x0051, 0x00EF);
549    set_panel_reg(jzfb, 0x0052, 0x0000);
550    set_panel_reg(jzfb, 0x0053, 0x018F);
551    /*===Display_On_Function=== */
552    set_panel_reg(jzfb, 0x0007, 0x0001);
553    set_panel_reg(jzfb, 0x0007, 0x0021);
554    set_panel_reg(jzfb, 0x0007, 0x0023);
555    set_panel_reg(jzfb, 0x0007, 0x0033);
556    set_panel_reg(jzfb, 0x0007, 0x0133);
557    send_panel_command(jzfb, 0x0022); /* Write Data to GRAM. */
558    udelay(1);
559    lgdp4551_set_addr(jzfb, 0, 0);
560    mdelay(100);
561}
562
563static void lgdp4551_disable(struct jzfb *jzfb)
564{
565}
566
567#endif
568
569#ifdef CONFIG_JZ_SLCD_SPFD5420A
570
571#define SPFD5420A_GPIO_CS_N JZ_GPIO_PORTC(22) /* Chip select */
572#define SPFD5420A_GPIO_RESET_N JZ_GPIO_PORTB(18) /* LCD reset */
573#define SPFD5420A_GPIO_POWER_N JZ_GPIO_PORTD(0) /* Power off */
574#define SPFD5420A_GPIO_FMARK_N JZ_GPIO_PORTD(1) /* fmark */
575
576/* Set the start address of screen, for example (0, 0) */
577static void spfd5420a_set_addr(struct jzfb *jzfb, u32 x, u32 y)
578{
579    set_panel_reg(jzfb, 0x200, x);
580    udelay(1);
581    set_panel_reg(jzfb, 0x201, y);
582    udelay(1);
583    send_panel_command(jzfb, 0x202);
584}
585
586static int spfd5420a_init(struct jzfb *jzfb)
587{
588    struct device *dev = &jzfb->pdev->dev;
589    int ret;
590
591    ret = gpio_request(SPFD5420A_GPIO_CS_N, dev_name(dev));
592    if (ret)
593        goto err_cs;
594    gpio_direction_output(SPFD5420A_GPIO_CS_N, 0);
595
596    ret = gpio_request(SPFD5420A_GPIO_RESET_N, dev_name(dev));
597    if (ret)
598        goto err_reset;
599    gpio_direction_output(SPFD5420A_GPIO_RESET_N, 1);
600
601    ret = gpio_request(SPFD5420A_GPIO_POWER_N, dev_name(dev));
602    if (ret)
603        goto err_power;
604    gpio_direction_output(SPFD5420A_GPIO_POWER_N, 0);
605
606    mdelay(100);
607    return 0;
608
609err_power:
610    gpio_free(SPFD5420A_GPIO_RESET_N);
611err_reset:
612    gpio_free(SPFD5420A_GPIO_CS_N);
613err_cs:
614    dev_err(dev, "Could not reserve GPIO pins for SPFD5420A panel\n");
615    return ret;
616}
617
618static void spfd5420a_exit(struct jzfb *jzfb)
619{
620    gpio_free(SPFD5420A_GPIO_CS_N);
621    gpio_free(SPFD5420A_GPIO_RESET_N);
622    gpio_free(SPFD5420A_GPIO_POWER_N);
623}
624
625static void spfd5420a_init_gamma(struct jzfb *jzfb)
626{
627    set_panel_reg(jzfb, 0x0300, 0x0101);
628    set_panel_reg(jzfb, 0x0301, 0x0b27);
629    set_panel_reg(jzfb, 0x0302, 0x132a);
630    set_panel_reg(jzfb, 0x0303, 0x2a13);
631    set_panel_reg(jzfb, 0x0304, 0x270b);
632    set_panel_reg(jzfb, 0x0305, 0x0101);
633    set_panel_reg(jzfb, 0x0306, 0x1205);
634    set_panel_reg(jzfb, 0x0307, 0x0512);
635    set_panel_reg(jzfb, 0x0308, 0x0005);
636    set_panel_reg(jzfb, 0x0309, 0x0003);
637    set_panel_reg(jzfb, 0x030a, 0x0f04);
638    set_panel_reg(jzfb, 0x030b, 0x0f00);
639    set_panel_reg(jzfb, 0x030c, 0x000f);
640    set_panel_reg(jzfb, 0x030d, 0x040f);
641    set_panel_reg(jzfb, 0x030e, 0x0300);
642    set_panel_reg(jzfb, 0x030f, 0x0500);
643    /*** secorrect gamma2 ***/
644    set_panel_reg(jzfb, 0x0400, 0x3500);
645    set_panel_reg(jzfb, 0x0401, 0x0001);
646    set_panel_reg(jzfb, 0x0404, 0x0000);
647    set_panel_reg(jzfb, 0x0500, 0x0000);
648    set_panel_reg(jzfb, 0x0501, 0x0000);
649    set_panel_reg(jzfb, 0x0502, 0x0000);
650    set_panel_reg(jzfb, 0x0503, 0x0000);
651    set_panel_reg(jzfb, 0x0504, 0x0000);
652    set_panel_reg(jzfb, 0x0505, 0x0000);
653    set_panel_reg(jzfb, 0x0600, 0x0000);
654    set_panel_reg(jzfb, 0x0606, 0x0000);
655    set_panel_reg(jzfb, 0x06f0, 0x0000);
656    set_panel_reg(jzfb, 0x07f0, 0x5420);
657    set_panel_reg(jzfb, 0x07f3, 0x288a);
658    set_panel_reg(jzfb, 0x07f4, 0x0022);
659    set_panel_reg(jzfb, 0x07f5, 0x0001);
660    set_panel_reg(jzfb, 0x07f0, 0x0000);
661}
662
663static void spfd5420a_enable(struct jzfb *jzfb)
664{
665    gpio_set_value(SPFD5420A_GPIO_RESET_N, 1);
666    mdelay(10);
667    gpio_set_value(SPFD5420A_GPIO_RESET_N, 0);
668    mdelay(10);
669    gpio_set_value(SPFD5420A_GPIO_RESET_N, 1);
670    mdelay(100);
671    if (jzfb->pdata->lcd_type == JZ_LCD_TYPE_SMART_PARALLEL_18_BIT) {
672        set_panel_reg(jzfb, 0x0606, 0x0000);
673        udelay(10);
674        set_panel_reg(jzfb, 0x0007, 0x0001);
675        udelay(10);
676        set_panel_reg(jzfb, 0x0110, 0x0001);
677        udelay(10);
678        set_panel_reg(jzfb, 0x0100, 0x17b0);
679        set_panel_reg(jzfb, 0x0101, 0x0147);
680        set_panel_reg(jzfb, 0x0102, 0x019d);
681        set_panel_reg(jzfb, 0x0103, 0x8600);
682        set_panel_reg(jzfb, 0x0281, 0x0010);
683        udelay(10);
684        set_panel_reg(jzfb, 0x0102, 0x01bd);
685        udelay(10);
686        /************initial************/
687        set_panel_reg(jzfb, 0x0000, 0x0000);
688        set_panel_reg(jzfb, 0x0001, 0x0000);
689        set_panel_reg(jzfb, 0x0002, 0x0400);
690        set_panel_reg(jzfb, 0x0003, 0x1288); /*up:0x1288 down:0x12B8 left:0x1290 right:0x12A0*/
691        set_panel_reg(jzfb, 0x0006, 0x0000);
692        set_panel_reg(jzfb, 0x0008, 0x0503);
693        set_panel_reg(jzfb, 0x0009, 0x0001);
694        set_panel_reg(jzfb, 0x000b, 0x0010);
695        set_panel_reg(jzfb, 0x000c, 0x0000);
696        set_panel_reg(jzfb, 0x000f, 0x0000);
697        set_panel_reg(jzfb, 0x0007, 0x0001);
698        set_panel_reg(jzfb, 0x0010, 0x0010);
699        set_panel_reg(jzfb, 0x0011, 0x0202);
700        set_panel_reg(jzfb, 0x0012, 0x0300);
701        set_panel_reg(jzfb, 0x0020, 0x021e);
702        set_panel_reg(jzfb, 0x0021, 0x0202);
703        set_panel_reg(jzfb, 0x0022, 0x0100);
704        set_panel_reg(jzfb, 0x0090, 0x0000);
705        set_panel_reg(jzfb, 0x0092, 0x0000);
706        set_panel_reg(jzfb, 0x0100, 0x16b0);
707        set_panel_reg(jzfb, 0x0101, 0x0147);
708        set_panel_reg(jzfb, 0x0102, 0x01bd);
709        set_panel_reg(jzfb, 0x0103, 0x2c00);
710        set_panel_reg(jzfb, 0x0107, 0x0000);
711        set_panel_reg(jzfb, 0x0110, 0x0001);
712        set_panel_reg(jzfb, 0x0210, 0x0000);
713        set_panel_reg(jzfb, 0x0211, 0x00ef);
714        set_panel_reg(jzfb, 0x0212, 0x0000);
715        set_panel_reg(jzfb, 0x0213, 0x018f);
716        set_panel_reg(jzfb, 0x0280, 0x0000);
717        set_panel_reg(jzfb, 0x0281, 0x0001);
718        set_panel_reg(jzfb, 0x0282, 0x0000);
719        spfd5420a_init_gamma(jzfb);
720        set_panel_reg(jzfb, 0x0007, 0x0173);
721    } else {
722        set_panel_reg(jzfb, 0x0600, 0x0001); /*soft reset*/
723        mdelay(10);
724        set_panel_reg(jzfb, 0x0600, 0x0000); /*soft reset*/
725        mdelay(10);
726        set_panel_reg(jzfb, 0x0606, 0x0000); /*i80-i/F Endian Control*/
727        /*===User setting=== */
728        set_panel_reg(jzfb, 0x0001, 0x0000);/* Driver Output Control-----0x0100 SM(bit10) | 0x400*/
729        set_panel_reg(jzfb, 0x0002, 0x0100); /*LCD Driving Wave Control 0x0100 */
730        if (jzfb->pdata->bpp == 16)
731            set_panel_reg(jzfb, 0x0003, 0x50A8);/*Entry Mode 0x1030*/
732        else /*bpp = 18*/
733            set_panel_reg(jzfb, 0x0003, 0x1010 | 0xC8); /*Entry Mode 0x1030*/
734        set_panel_reg(jzfb, 0x0006, 0x0000); /*Outline Sharpening Control*/
735        set_panel_reg(jzfb, 0x0008, 0x0808); /*Sets the number of lines for front/back porch period*/
736        set_panel_reg(jzfb, 0x0009, 0x0001); /*Display Control 3 */
737        set_panel_reg(jzfb, 0x000B, 0x0010); /*Low Power Control*/
738        set_panel_reg(jzfb, 0x000C, 0x0000); /*External Display Interface Control 1 0x0001 */
739        set_panel_reg(jzfb, 0x000F, 0x0000); /*External Display Interface Control 2 */
740        set_panel_reg(jzfb, 0x0400, 0xB104); /*Base Image Number of Line---GS(bit15) | 0x8000*/
741        set_panel_reg(jzfb, 0x0401, 0x0001); /*Base Image Display 0x0001*/
742        set_panel_reg(jzfb, 0x0404, 0x0000); /*Base Image Vertical Scroll Control 0x0000*/
743        set_panel_reg(jzfb, 0x0500, 0x0000); /*Partial Image 1: Display Position*/
744        set_panel_reg(jzfb, 0x0501, 0x0000); /*RAM Address (Start Line Address) */
745        set_panel_reg(jzfb, 0x0502, 0x018f); /*RAM Address (End Line Address) */
746        set_panel_reg(jzfb, 0x0503, 0x0000); /*Partial Image 2: Display Position RAM Address*/
747        set_panel_reg(jzfb, 0x0504, 0x0000); /*RAM Address (Start Line Address) */
748        set_panel_reg(jzfb, 0x0505, 0x0000); /*RAM Address (End Line Address)*/
749        /*Panel interface control===*/
750        set_panel_reg(jzfb, 0x0010, 0x0011); /*Division Ratio,Clocks per Line 14 */
751        mdelay(10);
752        set_panel_reg(jzfb, 0x0011, 0x0202); /*Division Ratio,Clocks per Line*/
753        set_panel_reg(jzfb, 0x0012, 0x0300); /*Sets low power VCOM drive period. */
754        mdelay(10);
755        set_panel_reg(jzfb, 0x0020, 0x021e); /*Panel Interface Control 4 */
756        set_panel_reg(jzfb, 0x0021, 0x0202); /*Panel Interface Control 5 */
757        set_panel_reg(jzfb, 0x0022, 0x0100); /*Panel Interface Control 6*/
758        set_panel_reg(jzfb, 0x0090, 0x0000); /*Frame Marker Control */
759        set_panel_reg(jzfb, 0x0092, 0x0000); /*MDDI Sub-display Control */
760        /*===Gamma setting=== */
761        set_panel_reg(jzfb, 0x0300, 0x0101); /*γ Control*/
762        set_panel_reg(jzfb, 0x0301, 0x0000); /*γ Control*/
763        set_panel_reg(jzfb, 0x0302, 0x0016); /*γ Control*/
764        set_panel_reg(jzfb, 0x0303, 0x2913); /*γ Control*/
765        set_panel_reg(jzfb, 0x0304, 0x260B); /*γ Control*/
766        set_panel_reg(jzfb, 0x0305, 0x0101); /*γ Control*/
767        set_panel_reg(jzfb, 0x0306, 0x1204); /*γ Control*/
768        set_panel_reg(jzfb, 0x0307, 0x0415); /*γ Control*/
769        set_panel_reg(jzfb, 0x0308, 0x0205); /*γ Control*/
770        set_panel_reg(jzfb, 0x0309, 0x0303); /*γ Control*/
771        set_panel_reg(jzfb, 0x030a, 0x0E05); /*γ Control*/
772        set_panel_reg(jzfb, 0x030b, 0x0D01); /*γ Control*/
773        set_panel_reg(jzfb, 0x030c, 0x010D); /*γ Control*/
774        set_panel_reg(jzfb, 0x030d, 0x050E); /*γ Control*/
775        set_panel_reg(jzfb, 0x030e, 0x0303); /*γ Control*/
776        set_panel_reg(jzfb, 0x030f, 0x0502); /*γ Control*/
777        /*===Power on sequence===*/
778        set_panel_reg(jzfb, 0x0007, 0x0001); /*Display Control 1*/
779        set_panel_reg(jzfb, 0x0110, 0x0001); /*Power supply startup enable bit*/
780        set_panel_reg(jzfb, 0x0112, 0x0060); /*Power Control 7*/
781        set_panel_reg(jzfb, 0x0100, 0x16B0); /*Power Control 1 */
782        set_panel_reg(jzfb, 0x0101, 0x0115); /*Power Control 2*/
783        set_panel_reg(jzfb, 0x0102, 0x0119); /*Starts VLOUT3,Sets the VREG1OUT.*/
784        mdelay(50);
785        set_panel_reg(jzfb, 0x0103, 0x2E00); /*set the amplitude of VCOM*/
786        mdelay(50);
787        set_panel_reg(jzfb, 0x0282, 0x0093); /*VCOMH voltage, alt: 0x008E, 0x0093*/
788        set_panel_reg(jzfb, 0x0281, 0x000A); /*Selects the factor of VREG1OUT to generate VCOMH. */
789        set_panel_reg(jzfb, 0x0102, 0x01BE); /*Starts VLOUT3,Sets the VREG1OUT.*/
790        mdelay(10);
791        /*Address */
792        set_panel_reg(jzfb, 0x0210, 0x0000); /*Window Horizontal RAM Address Start*/
793        set_panel_reg(jzfb, 0x0211, 0x00ef); /*Window Horizontal RAM Address End*/
794        set_panel_reg(jzfb, 0x0212, 0x0000); /*Window Vertical RAM Address Start*/
795        set_panel_reg(jzfb, 0x0213, 0x018f); /*Window Vertical RAM Address End */
796        set_panel_reg(jzfb, 0x0200, 0x0000); /*RAM Address Set (Horizontal Address)*/
797        set_panel_reg(jzfb, 0x0201, 0x018f); /*RAM Address Set (Vertical Address)*/
798        /*===Display_On_Function===*/
799        set_panel_reg(jzfb, 0x0007, 0x0021); /*Display Control 1 */
800        mdelay(50); /*40*/
801        set_panel_reg(jzfb, 0x0007, 0x0061); /*Display Control 1 */
802        mdelay(50); /*100*/
803        set_panel_reg(jzfb, 0x0007, 0x0173); /*Display Control 1 */
804        mdelay(50); /*300*/
805    }
806    send_panel_command(jzfb, 0x0202); /*Write Data to GRAM */
807    udelay(10);
808    spfd5420a_set_addr(jzfb, 0, 0);
809    udelay(100);
810}
811
812static void spfd5420a_disable(struct jzfb *jzfb)
813{
814}
815
816#endif
817
818static const struct jz_slcd_panel jz_slcd_panels[] = {
819#ifdef CONFIG_JZ_SLCD_ILI9325
820    {
821        ili9325_init, ili9325_exit,
822        ili9325_enable, ili9325_disable,
823    },
824#endif
825#ifdef CONFIG_JZ_SLCD_ILI9331
826    {
827        ili9331_init, ili9331_exit,
828        ili9331_enable, ili9331_disable,
829    },
830#endif
831#ifdef CONFIG_JZ_SLCD_ILI9338
832    {
833        ili9338_init, ili9338_exit,
834        ili9338_enable, ili9338_disable,
835    },
836#endif
837#ifdef CONFIG_JZ_SLCD_LGDP4551
838    {
839        lgdp4551_init, lgdp4551_exit,
840        lgdp4551_enable, lgdp4551_disable,
841    },
842#endif
843#ifdef CONFIG_JZ_SLCD_SPFD5420A
844    {
845        spfd5420a_init, spfd5420a_exit,
846        spfd5420a_enable, spfd5420a_disable,
847    },
848#endif
849};
850
851const struct jz_slcd_panel *jz_slcd_panels_probe(struct jzfb *jzfb)
852{
853    switch (ARRAY_SIZE(jz_slcd_panels)) {
854    case 0:
855        return NULL;
856    case 1:
857        return &jz_slcd_panels[0];
858    default:
859        dev_warn(&jzfb->pdev->dev,
860            "SLCD panel selection not implemented yet; "
861            "picking first panel\n");
862        return &jz_slcd_panels[0];
863    }
864}

Archive Download the corresponding diff file



interactive