cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fb_ili9325.c (8282B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * FB driver for the ILI9325 LCD Controller
      4 *
      5 * Copyright (C) 2013 Noralf Tronnes
      6 *
      7 * Based on ili9325.c by Jeroen Domburg
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/kernel.h>
     12#include <linux/init.h>
     13#include <linux/delay.h>
     14
     15#include "fbtft.h"
     16
     17#define DRVNAME		"fb_ili9325"
     18#define WIDTH		240
     19#define HEIGHT		320
     20#define BPP		16
     21#define FPS		20
     22#define DEFAULT_GAMMA	"0F 00 7 2 0 0 6 5 4 1\n" \
     23			"04 16 2 7 6 3 2 1 7 7"
     24
     25static unsigned int bt = 6; /* VGL=Vci*4 , VGH=Vci*4 */
     26module_param(bt, uint, 0000);
     27MODULE_PARM_DESC(bt, "Sets the factor used in the step-up circuits");
     28
     29static unsigned int vc = 0x03; /* Vci1=Vci*0.80 */
     30module_param(vc, uint, 0000);
     31MODULE_PARM_DESC(vc, "Sets the ratio factor of Vci to generate the reference voltages Vci1");
     32
     33static unsigned int vrh = 0x0d; /* VREG1OUT=Vci*1.85 */
     34module_param(vrh, uint, 0000);
     35MODULE_PARM_DESC(vrh, "Set the amplifying rate (1.6 ~ 1.9) of Vci applied to output the VREG1OUT");
     36
     37static unsigned int vdv = 0x12; /* VCOMH amplitude=VREG1OUT*0.98 */
     38module_param(vdv, uint, 0000);
     39MODULE_PARM_DESC(vdv, "Select the factor of VREG1OUT to set the amplitude of Vcom");
     40
     41static unsigned int vcm = 0x0a; /* VCOMH=VREG1OUT*0.735 */
     42module_param(vcm, uint, 0000);
     43MODULE_PARM_DESC(vcm, "Set the internal VcomH voltage");
     44
     45/*
     46 * Verify that this configuration is within the Voltage limits
     47 *
     48 * Display module configuration: Vcc = IOVcc = Vci = 3.3V
     49 *
     50 * Voltages
     51 * ----------
     52 * Vci                                =   3.3
     53 * Vci1           =  Vci * 0.80       =   2.64
     54 * DDVDH          =  Vci1 * 2         =   5.28
     55 * VCL            = -Vci1             =  -2.64
     56 * VREG1OUT       =  Vci * 1.85       =   4.88
     57 * VCOMH          =  VREG1OUT * 0.735 =   3.59
     58 * VCOM amplitude =  VREG1OUT * 0.98  =   4.79
     59 * VGH            =  Vci * 4          =  13.2
     60 * VGL            = -Vci * 4          = -13.2
     61 *
     62 * Limits
     63 * --------
     64 * Power supplies
     65 * 1.65 < IOVcc < 3.30   =>  1.65 < 3.3 < 3.30
     66 * 2.40 < Vcc   < 3.30   =>  2.40 < 3.3 < 3.30
     67 * 2.50 < Vci   < 3.30   =>  2.50 < 3.3 < 3.30
     68 *
     69 * Source/VCOM power supply voltage
     70 *  4.50 < DDVDH < 6.0   =>  4.50 <  5.28 <  6.0
     71 * -3.0  < VCL   < -2.0  =>  -3.0 < -2.64 < -2.0
     72 * VCI - VCL < 6.0       =>  5.94 < 6.0
     73 *
     74 * Gate driver output voltage
     75 *  10  < VGH   < 20     =>   10 <  13.2  < 20
     76 * -15  < VGL   < -5     =>  -15 < -13.2  < -5
     77 * VGH - VGL < 32        =>   26.4 < 32
     78 *
     79 * VCOM driver output voltage
     80 * VCOMH - VCOML < 6.0   =>  4.79 < 6.0
     81 */
     82
     83static int init_display(struct fbtft_par *par)
     84{
     85	par->fbtftops.reset(par);
     86
     87	bt &= 0x07;
     88	vc &= 0x07;
     89	vrh &= 0x0f;
     90	vdv &= 0x1f;
     91	vcm &= 0x3f;
     92
     93	/* Initialization sequence from ILI9325 Application Notes */
     94
     95	/* ----------- Start Initial Sequence ----------- */
     96	write_reg(par, 0x00E3, 0x3008); /* Set internal timing */
     97	write_reg(par, 0x00E7, 0x0012); /* Set internal timing */
     98	write_reg(par, 0x00EF, 0x1231); /* Set internal timing */
     99	write_reg(par, 0x0001, 0x0100); /* set SS and SM bit */
    100	write_reg(par, 0x0002, 0x0700); /* set 1 line inversion */
    101	write_reg(par, 0x0004, 0x0000); /* Resize register */
    102	write_reg(par, 0x0008, 0x0207); /* set the back porch and front porch */
    103	write_reg(par, 0x0009, 0x0000); /* set non-display area refresh cycle */
    104	write_reg(par, 0x000A, 0x0000); /* FMARK function */
    105	write_reg(par, 0x000C, 0x0000); /* RGB interface setting */
    106	write_reg(par, 0x000D, 0x0000); /* Frame marker Position */
    107	write_reg(par, 0x000F, 0x0000); /* RGB interface polarity */
    108
    109	/* ----------- Power On sequence ----------- */
    110	write_reg(par, 0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
    111	write_reg(par, 0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */
    112	write_reg(par, 0x0012, 0x0000); /* VREG1OUT voltage */
    113	write_reg(par, 0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
    114	mdelay(200); /* Dis-charge capacitor power voltage */
    115	write_reg(par, 0x0010, /* SAP, BT[3:0], AP, DSTB, SLP, STB */
    116		BIT(12) | (bt << 8) | BIT(7) | BIT(4));
    117	write_reg(par, 0x0011, 0x220 | vc); /* DC1[2:0], DC0[2:0], VC[2:0] */
    118	mdelay(50); /* Delay 50ms */
    119	write_reg(par, 0x0012, vrh); /* Internal reference voltage= Vci; */
    120	mdelay(50); /* Delay 50ms */
    121	write_reg(par, 0x0013, vdv << 8); /* Set VDV[4:0] for VCOM amplitude */
    122	write_reg(par, 0x0029, vcm); /* Set VCM[5:0] for VCOMH */
    123	write_reg(par, 0x002B, 0x000C); /* Set Frame Rate */
    124	mdelay(50); /* Delay 50ms */
    125	write_reg(par, 0x0020, 0x0000); /* GRAM horizontal Address */
    126	write_reg(par, 0x0021, 0x0000); /* GRAM Vertical Address */
    127
    128	/*------------------ Set GRAM area --------------- */
    129	write_reg(par, 0x0050, 0x0000); /* Horizontal GRAM Start Address */
    130	write_reg(par, 0x0051, 0x00EF); /* Horizontal GRAM End Address */
    131	write_reg(par, 0x0052, 0x0000); /* Vertical GRAM Start Address */
    132	write_reg(par, 0x0053, 0x013F); /* Vertical GRAM Start Address */
    133	write_reg(par, 0x0060, 0xA700); /* Gate Scan Line */
    134	write_reg(par, 0x0061, 0x0001); /* NDL,VLE, REV */
    135	write_reg(par, 0x006A, 0x0000); /* set scrolling line */
    136
    137	/*-------------- Partial Display Control --------- */
    138	write_reg(par, 0x0080, 0x0000);
    139	write_reg(par, 0x0081, 0x0000);
    140	write_reg(par, 0x0082, 0x0000);
    141	write_reg(par, 0x0083, 0x0000);
    142	write_reg(par, 0x0084, 0x0000);
    143	write_reg(par, 0x0085, 0x0000);
    144
    145	/*-------------- Panel Control ------------------- */
    146	write_reg(par, 0x0090, 0x0010);
    147	write_reg(par, 0x0092, 0x0600);
    148	write_reg(par, 0x0007, 0x0133); /* 262K color and display ON */
    149
    150	return 0;
    151}
    152
    153static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
    154{
    155	switch (par->info->var.rotate) {
    156	/* R20h = Horizontal GRAM Start Address */
    157	/* R21h = Vertical GRAM Start Address */
    158	case 0:
    159		write_reg(par, 0x0020, xs);
    160		write_reg(par, 0x0021, ys);
    161		break;
    162	case 180:
    163		write_reg(par, 0x0020, WIDTH - 1 - xs);
    164		write_reg(par, 0x0021, HEIGHT - 1 - ys);
    165		break;
    166	case 270:
    167		write_reg(par, 0x0020, WIDTH - 1 - ys);
    168		write_reg(par, 0x0021, xs);
    169		break;
    170	case 90:
    171		write_reg(par, 0x0020, ys);
    172		write_reg(par, 0x0021, HEIGHT - 1 - xs);
    173		break;
    174	}
    175	write_reg(par, 0x0022); /* Write Data to GRAM */
    176}
    177
    178static int set_var(struct fbtft_par *par)
    179{
    180	switch (par->info->var.rotate) {
    181	/* AM: GRAM update direction */
    182	case 0:
    183		write_reg(par, 0x03, 0x0030 | (par->bgr << 12));
    184		break;
    185	case 180:
    186		write_reg(par, 0x03, 0x0000 | (par->bgr << 12));
    187		break;
    188	case 270:
    189		write_reg(par, 0x03, 0x0028 | (par->bgr << 12));
    190		break;
    191	case 90:
    192		write_reg(par, 0x03, 0x0018 | (par->bgr << 12));
    193		break;
    194	}
    195
    196	return 0;
    197}
    198
    199/*
    200 * Gamma string format:
    201 *  VRP0 VRP1 RP0 RP1 KP0 KP1 KP2 KP3 KP4 KP5
    202 *  VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5
    203 */
    204#define CURVE(num, idx)  curves[(num) * par->gamma.num_values + (idx)]
    205static int set_gamma(struct fbtft_par *par, u32 *curves)
    206{
    207	static const unsigned long mask[] = {
    208		0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    209		0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    210	};
    211	int i, j;
    212
    213	/* apply mask */
    214	for (i = 0; i < 2; i++)
    215		for (j = 0; j < 10; j++)
    216			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
    217
    218	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
    219	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
    220	write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
    221	write_reg(par, 0x0035, CURVE(0, 3) << 8 | CURVE(0, 2));
    222	write_reg(par, 0x0036, CURVE(0, 1) << 8 | CURVE(0, 0));
    223
    224	write_reg(par, 0x0037, CURVE(1, 5) << 8 | CURVE(1, 4));
    225	write_reg(par, 0x0038, CURVE(1, 7) << 8 | CURVE(1, 6));
    226	write_reg(par, 0x0039, CURVE(1, 9) << 8 | CURVE(1, 8));
    227	write_reg(par, 0x003C, CURVE(1, 3) << 8 | CURVE(1, 2));
    228	write_reg(par, 0x003D, CURVE(1, 1) << 8 | CURVE(1, 0));
    229
    230	return 0;
    231}
    232
    233#undef CURVE
    234
    235static struct fbtft_display display = {
    236	.regwidth = 16,
    237	.width = WIDTH,
    238	.height = HEIGHT,
    239	.bpp = BPP,
    240	.fps = FPS,
    241	.gamma_num = 2,
    242	.gamma_len = 10,
    243	.gamma = DEFAULT_GAMMA,
    244	.fbtftops = {
    245		.init_display = init_display,
    246		.set_addr_win = set_addr_win,
    247		.set_var = set_var,
    248		.set_gamma = set_gamma,
    249	},
    250};
    251
    252FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9325", &display);
    253
    254MODULE_ALIAS("spi:" DRVNAME);
    255MODULE_ALIAS("platform:" DRVNAME);
    256MODULE_ALIAS("spi:ili9325");
    257MODULE_ALIAS("platform:ili9325");
    258
    259MODULE_DESCRIPTION("FB driver for the ILI9325 LCD Controller");
    260MODULE_AUTHOR("Noralf Tronnes");
    261MODULE_LICENSE("GPL");