Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright © 2011 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Permission is hereby granted, free of charge, to any person obtaining a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * copy of this software and associated documentation files (the "Software"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * to deal in the Software without restriction, including without limitation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * and/or sell copies of the Software, and to permit persons to whom the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Software is furnished to do so, subject to the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * The above copyright notice and this permission notice (including the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * paragraph) shall be included in all copies or substantial portions of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * DEALINGS IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <asm/intel_scu_ipc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "mdfld_dsi_dpi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include "mdfld_dsi_pkg_sender.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include "mdfld_output.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include "tc35876x-dsi-lvds.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static struct i2c_client *tc35876x_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static struct i2c_client *cmi_lcd_i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) /* Panel GPIOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static struct gpio_desc *bridge_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static struct gpio_desc *bridge_bl_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static struct gpio_desc *backlight_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << (end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /* DSI D-PHY Layer Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define D0W_DPHYCONTTX		0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define CLW_DPHYCONTRX		0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define D0W_DPHYCONTRX		0x0024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define D1W_DPHYCONTRX		0x0028
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define D2W_DPHYCONTRX		0x002C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define D3W_DPHYCONTRX		0x0030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define COM_DPHYCONTRX		0x0038
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define CLW_CNTRL		0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define D0W_CNTRL		0x0044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define D1W_CNTRL		0x0048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define D2W_CNTRL		0x004C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define D3W_CNTRL		0x0050
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define DFTMODE_CNTRL		0x0054
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /* DSI PPI Layer Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define PPI_STARTPPI		0x0104
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define PPI_BUSYPPI		0x0108
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define PPI_LINEINITCNT		0x0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define PPI_LPTXTIMECNT		0x0114
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define PPI_LANEENABLE		0x0134
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define PPI_TX_RX_TA		0x013C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define PPI_CLS_ATMR		0x0140
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define PPI_D0S_ATMR		0x0144
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define PPI_D1S_ATMR		0x0148
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define PPI_D2S_ATMR		0x014C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define PPI_D3S_ATMR		0x0150
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define PPI_D0S_CLRSIPOCOUNT	0x0164
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define PPI_D1S_CLRSIPOCOUNT	0x0168
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define PPI_D2S_CLRSIPOCOUNT	0x016C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define PPI_D3S_CLRSIPOCOUNT	0x0170
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define CLS_PRE			0x0180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define D0S_PRE			0x0184
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define D1S_PRE			0x0188
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define D2S_PRE			0x018C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define D3S_PRE			0x0190
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define CLS_PREP		0x01A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define D0S_PREP		0x01A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define D1S_PREP		0x01A8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define D2S_PREP		0x01AC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define D3S_PREP		0x01B0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define CLS_ZERO		0x01C0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #define D0S_ZERO		0x01C4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define D1S_ZERO		0x01C8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define D2S_ZERO		0x01CC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define D3S_ZERO		0x01D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define PPI_CLRFLG		0x01E0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define PPI_CLRSIPO		0x01E4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define HSTIMEOUT		0x01F0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define HSTIMEOUTENABLE		0x01F4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /* DSI Protocol Layer Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define DSI_STARTDSI		0x0204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define DSI_BUSYDSI		0x0208
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define DSI_LANEENABLE		0x0210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define DSI_LANESTATUS0		0x0214
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define DSI_LANESTATUS1		0x0218
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define DSI_INTSTATUS		0x0220
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define DSI_INTMASK		0x0224
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define DSI_INTCLR		0x0228
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define DSI_LPTXTO		0x0230
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* DSI General Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define DSIERRCNT		0x0300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* DSI Application Layer Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define APLCTRL			0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define RDPKTLN			0x0404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Video Path Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define VPCTRL			0x0450
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define HTIM1			0x0454
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define HTIM2			0x0458
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define VTIM1			0x045C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define VTIM2			0x0460
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define VFUEN			0x0464
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* LVDS Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define LVMX0003		0x0480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define LVMX0407		0x0484
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define LVMX0811		0x0488
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define LVMX1215		0x048C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define LVMX1619		0x0490
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define LVMX2023		0x0494
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define LVMX2427		0x0498
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define LVCFG			0x049C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define LVPHY0			0x04A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define LVPHY1			0x04A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* System Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SYSSTAT			0x0500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define SYSRST			0x0504
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* GPIO Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*#define GPIOC			0x0520*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define GPIOO			0x0524
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define GPIOI			0x0528
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* I2C Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define I2CTIMCTRL		0x0540
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define I2CMADDR		0x0544
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define WDATAQ			0x0548
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define RDATAQ			0x054C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* Chip/Rev Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define IDREG			0x0580
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Debug Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define DEBUG00			0x05A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define DEBUG01			0x05A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Panel CABC registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define PANEL_PWM_CONTROL	0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define PANEL_FREQ_DIVIDER_HI	0x91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define PANEL_FREQ_DIVIDER_LO	0x92
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define PANEL_DUTY_CONTROL	0x93
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define PANEL_MODIFY_RGB	0x94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define PANEL_FRAMERATE_CONTROL	0x96
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define PANEL_PWM_MIN		0x97
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define PANEL_PWM_REF		0x98
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define PANEL_PWM_MAX		0x99
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define PANEL_ALLOW_DISTORT	0x9A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define PANEL_BYPASS_PWMI	0x9B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Panel color management registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define PANEL_CM_ENABLE		0x700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define PANEL_CM_HUE		0x701
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define PANEL_CM_SATURATION	0x702
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define PANEL_CM_INTENSITY	0x703
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define PANEL_CM_BRIGHTNESS	0x704
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define PANEL_CM_CE_ENABLE	0x705
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define PANEL_CM_PEAK_EN	0x710
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define PANEL_CM_GAIN		0x711
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define PANEL_CM_HUETABLE_START	0x730
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define PANEL_CM_HUETABLE_END	0x747 /* inclusive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Input muxing for registers LVMX0003...LVMX2427 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	INPUT_R0,	/* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	INPUT_R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	INPUT_R2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	INPUT_R3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	INPUT_R4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	INPUT_R5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	INPUT_R6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	INPUT_R7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	INPUT_G0,	/* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	INPUT_G1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	INPUT_G2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	INPUT_G3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	INPUT_G4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	INPUT_G5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	INPUT_G6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	INPUT_G7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	INPUT_B0,	/* 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	INPUT_B1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	INPUT_B2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	INPUT_B3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	INPUT_B4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	INPUT_B5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	INPUT_B6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	INPUT_B7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	INPUT_HSYNC,	/* 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	INPUT_VSYNC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	INPUT_DE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	LOGIC_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	/* 28...31 undefined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define INPUT_MUX(lvmx03, lvmx02, lvmx01, lvmx00)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	(FLD_VAL(lvmx03, 29, 24) | FLD_VAL(lvmx02, 20, 16) |	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	FLD_VAL(lvmx01, 12, 8) | FLD_VAL(lvmx00, 4, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  * tc35876x_regw - Write DSI-LVDS bridge register using I2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * @client: struct i2c_client to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * @reg: register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * @value: value to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * Returns 0 on success, or a negative error value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int tc35876x_regw(struct i2c_client *client, u16 reg, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	u8 tx_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		/* NOTE: Register address big-endian, data little-endian. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		(reg >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		reg & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		value & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		(value >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		(value >> 16) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		(value >> 24) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	struct i2c_msg msgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			.addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			.buf = tx_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			.len = ARRAY_SIZE(tx_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			__func__, reg, value, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (r < ARRAY_SIZE(msgs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x msgs %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			__func__, reg, value, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	dev_dbg(&client->dev, "%s: reg 0x%04x val 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			__func__, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  * tc35876x_regr - Read DSI-LVDS bridge register using I2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * @client: struct i2c_client to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * @reg: register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  * @value: pointer for storing the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * Returns 0 on success, or a negative error value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	u8 tx_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		(reg >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		reg & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	u8 rx_data[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	struct i2c_msg msgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			.addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			.buf = tx_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			.len = ARRAY_SIZE(tx_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			.addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			.flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			.buf = rx_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			.len = ARRAY_SIZE(rx_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		dev_err(&client->dev, "%s: reg 0x%04x error %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			reg, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (r < ARRAY_SIZE(msgs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		dev_err(&client->dev, "%s: reg 0x%04x msgs %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			reg, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	*value = rx_data[0] << 24 | rx_data[1] << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		rx_data[2] << 8 | rx_data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	dev_dbg(&client->dev, "%s: reg 0x%04x value 0x%08x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		reg, *value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (!bridge_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		gpiod_set_value_cansleep(bridge_reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		/* Pull MIPI Bridge reset pin to Low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		gpiod_set_value_cansleep(bridge_reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		mdelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		/* Pull MIPI Bridge reset pin to High */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		gpiod_set_value_cansleep(bridge_reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		mdelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void tc35876x_configure_lvds_bridge(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	struct i2c_client *i2c = tc35876x_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	u32 ppi_lptxtimecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	u32 txtagocnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	u32 txtasurecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	u32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (!tc35876x_regr(i2c, IDREG, &id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		dev_info(&tc35876x_client->dev, "tc35876x ID 0x%08x\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		dev_err(&tc35876x_client->dev, "Cannot read ID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	ppi_lptxtimecnt = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	txtagocnt = (5 * ppi_lptxtimecnt - 3) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	txtasurecnt = 3 * ppi_lptxtimecnt / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	tc35876x_regw(i2c, PPI_TX_RX_TA, FLD_VAL(txtagocnt, 26, 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		FLD_VAL(txtasurecnt, 10, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	tc35876x_regw(i2c, PPI_LPTXTIMECNT, FLD_VAL(ppi_lptxtimecnt, 10, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	tc35876x_regw(i2c, PPI_D0S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	tc35876x_regw(i2c, PPI_D1S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	tc35876x_regw(i2c, PPI_D2S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	tc35876x_regw(i2c, PPI_D3S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	/* Enabling MIPI & PPI lanes, Enable 4 lanes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	tc35876x_regw(i2c, PPI_LANEENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	tc35876x_regw(i2c, DSI_LANEENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	tc35876x_regw(i2c, PPI_STARTPPI, BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	tc35876x_regw(i2c, DSI_STARTDSI, BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	/* Setting LVDS output frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	tc35876x_regw(i2c, LVPHY0, FLD_VAL(1, 20, 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		FLD_VAL(2, 15, 14) | FLD_VAL(6, 4, 0)); /* 0x00048006 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	/* Setting video panel control register,0x00000120 VTGen=ON ?!?!? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	tc35876x_regw(i2c, VPCTRL, BIT(8) | BIT(5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	/* Horizontal back porch and horizontal pulse width. 0x00280028 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	tc35876x_regw(i2c, HTIM1, FLD_VAL(40, 24, 16) | FLD_VAL(40, 8, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	/* Horizontal front porch and horizontal active video size. 0x00500500*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	tc35876x_regw(i2c, HTIM2, FLD_VAL(80, 24, 16) | FLD_VAL(1280, 10, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	/* Vertical back porch and vertical sync pulse width. 0x000e000a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	tc35876x_regw(i2c, VTIM1, FLD_VAL(14, 23, 16) | FLD_VAL(10, 7, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	/* Vertical front porch and vertical display size. 0x000e0320 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	tc35876x_regw(i2c, VTIM2, FLD_VAL(14, 23, 16) | FLD_VAL(800, 10, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	/* Set above HTIM1, HTIM2, VTIM1, and VTIM2 at next VSYNC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	tc35876x_regw(i2c, VFUEN, BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	/* Soft reset LCD controller. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	tc35876x_regw(i2c, SYSRST, BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	/* LVDS-TX input muxing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	tc35876x_regw(i2c, LVMX0003,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		INPUT_MUX(INPUT_R5, INPUT_R4, INPUT_R3, INPUT_R2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	tc35876x_regw(i2c, LVMX0407,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		INPUT_MUX(INPUT_G2, INPUT_R7, INPUT_R1, INPUT_R6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	tc35876x_regw(i2c, LVMX0811,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		INPUT_MUX(INPUT_G1, INPUT_G0, INPUT_G4, INPUT_G3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	tc35876x_regw(i2c, LVMX1215,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		INPUT_MUX(INPUT_B2, INPUT_G7, INPUT_G6, INPUT_G5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	tc35876x_regw(i2c, LVMX1619,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		INPUT_MUX(INPUT_B4, INPUT_B3, INPUT_B1, INPUT_B0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	tc35876x_regw(i2c, LVMX2023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		INPUT_MUX(LOGIC_0,  INPUT_B7, INPUT_B6, INPUT_B5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	tc35876x_regw(i2c, LVMX2427,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		INPUT_MUX(INPUT_R0, INPUT_DE, INPUT_VSYNC, INPUT_HSYNC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	/* Enable LVDS transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	tc35876x_regw(i2c, LVCFG, BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	/* Clear notifications. Don't write reserved bits. Was write 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	 * to 0x0288, must be in error?! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	tc35876x_regw(i2c, DSI_INTCLR, FLD_MASK(31, 30) | FLD_MASK(22, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) #define GPIOPWMCTRL	0x38F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) #define PWM0CLKDIV0	0x62 /* low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #define PWM0CLKDIV1	0x61 /* high byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #define SYSTEMCLK	19200000UL /* 19.2 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #define PWM_FREQUENCY	9600 /* Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* f = baseclk / (clkdiv + 1) => clkdiv = (baseclk - f) / f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static inline u16 calc_clkdiv(unsigned long baseclk, unsigned int f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	return (baseclk - f) / f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static void tc35876x_brightness_init(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	u8 pwmctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	u16 clkdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	/* Make sure the PWM reference is the 19.2 MHz system clock. Read first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	 * instead of setting directly to catch potential conflicts between PWM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	 * users. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	ret = intel_scu_ipc_ioread8(GPIOPWMCTRL, &pwmctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	if (ret || pwmctrl != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			dev_err(&dev->pdev->dev, "GPIOPWMCTRL read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			dev_warn(&dev->pdev->dev, "GPIOPWMCTRL was not set to system clock (pwmctrl = 0x%02x)\n", pwmctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		ret = intel_scu_ipc_iowrite8(GPIOPWMCTRL, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			dev_err(&dev->pdev->dev, "GPIOPWMCTRL set failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	clkdiv = calc_clkdiv(SYSTEMCLK, PWM_FREQUENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	ret = intel_scu_ipc_iowrite8(PWM0CLKDIV1, (clkdiv >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		ret = intel_scu_ipc_iowrite8(PWM0CLKDIV0, clkdiv & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		dev_err(&dev->pdev->dev, "PWM0CLKDIV set failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		dev_dbg(&dev->pdev->dev, "PWM0CLKDIV set to 0x%04x (%d Hz)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			clkdiv, PWM_FREQUENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #define PWM0DUTYCYCLE			0x67
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) void tc35876x_brightness_control(struct drm_device *dev, int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	u8 duty_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	u8 panel_duty_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	level = clamp(level, 0, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	/* PWM duty cycle 0x00...0x63 corresponds to 0...99% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	duty_val = level * 0x63 / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	/* I won't pretend to understand this formula. The panel spec is quite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	 * bad engrish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	panel_duty_val = (2 * level - 100) * 0xA9 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			 MDFLD_DSI_BRIGHTNESS_MAX_LEVEL + 0x56;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	ret = intel_scu_ipc_iowrite8(PWM0DUTYCYCLE, duty_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		dev_err(&tc35876x_client->dev, "%s: ipc write fail\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	if (cmi_lcd_i2c_client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 						PANEL_PWM_MAX, panel_duty_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			dev_err(&cmi_lcd_i2c_client->dev, "%s: i2c write failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	if (bridge_bl_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		gpiod_set_value_cansleep(bridge_bl_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	if (backlight_voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		gpiod_set_value_cansleep(backlight_voltage, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	struct drm_psb_private *dev_priv = dev->dev_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	if (backlight_voltage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		gpiod_set_value_cansleep(backlight_voltage, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		msleep(260);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	if (cmi_lcd_i2c_client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		dev_dbg(&cmi_lcd_i2c_client->dev, "setting TCON\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		/* Bit 4 is average_saving. Setting it to 1, the brightness is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		 * referenced to the average of the frame content. 0 means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		 * reference to the maximum of frame contents. Bits 3:0 are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		 * allow_distort. When set to a nonzero value, all color values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		 * between 255-allow_distort*2 and 255 are mapped to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		 * 255-allow_distort*2 value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 						PANEL_ALLOW_DISTORT, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			dev_err(&cmi_lcd_i2c_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 				"i2c write failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 						PANEL_BYPASS_PWMI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			dev_err(&cmi_lcd_i2c_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 				"i2c write failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		/* Set minimum brightness value - this is tunable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 						PANEL_PWM_MIN, 0x35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			dev_err(&cmi_lcd_i2c_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 				"i2c write failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (bridge_bl_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		gpiod_set_value_cansleep(bridge_bl_enable, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	tc35876x_brightness_control(dev, dev_priv->brightness_adjusted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static struct drm_display_mode *tc35876x_get_config_mode(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	struct drm_display_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	dev_dbg(&dev->pdev->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	if (!mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	/* FIXME: do this properly. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	mode->hdisplay = 1280;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	mode->vdisplay = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	mode->hsync_start = 1360;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	mode->hsync_end = 1400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	mode->htotal = 1440;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	mode->vsync_start = 814;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	mode->vsync_end = 824;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	mode->vtotal = 838;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	mode->clock = 33324 << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	dev_info(&dev->pdev->dev, "hdisplay(w) = %d\n", mode->hdisplay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	dev_info(&dev->pdev->dev, "vdisplay(h) = %d\n", mode->vdisplay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	dev_info(&dev->pdev->dev, "HSS = %d\n", mode->hsync_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	dev_info(&dev->pdev->dev, "HSE = %d\n", mode->hsync_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	dev_info(&dev->pdev->dev, "htotal = %d\n", mode->htotal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	dev_info(&dev->pdev->dev, "VSS = %d\n", mode->vsync_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	dev_info(&dev->pdev->dev, "VSE = %d\n", mode->vsync_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	dev_info(&dev->pdev->dev, "vtotal = %d\n", mode->vtotal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	dev_info(&dev->pdev->dev, "clock = %d\n", mode->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	drm_mode_set_name(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	drm_mode_set_crtcinfo(mode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	mode->type |= DRM_MODE_TYPE_PREFERRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* DV1 Active area 216.96 x 135.6 mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) #define DV1_PANEL_WIDTH 217
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #define DV1_PANEL_HEIGHT 136
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static int tc35876x_get_panel_info(struct drm_device *dev, int pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 				struct panel_info *pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	if (!dev || !pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	pi->width_mm = DV1_PANEL_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	pi->height_mm = DV1_PANEL_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static int tc35876x_bridge_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 				const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	dev_info(&client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		dev_err(&client->dev, "%s: i2c_check_functionality() failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	bridge_reset = devm_gpiod_get_optional(&client->dev, "bridge-reset", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	if (IS_ERR(bridge_reset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		return PTR_ERR(bridge_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	if (bridge_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		gpiod_set_consumer_name(bridge_reset, "tc35876x bridge reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	bridge_bl_enable = devm_gpiod_get_optional(&client->dev, "bl-en", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	if (IS_ERR(bridge_bl_enable))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		return PTR_ERR(bridge_bl_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	if (bridge_bl_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		gpiod_set_consumer_name(bridge_bl_enable, "tc35876x panel bl en");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	backlight_voltage = devm_gpiod_get_optional(&client->dev, "vadd", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	if (IS_ERR(backlight_voltage))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		return PTR_ERR(backlight_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	if (backlight_voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		gpiod_set_consumer_name(backlight_voltage, "tc35876x panel vadd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	tc35876x_client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int tc35876x_bridge_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	dev_dbg(&client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	tc35876x_client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static const struct i2c_device_id tc35876x_bridge_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	{ "i2c_disp_brig", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) MODULE_DEVICE_TABLE(i2c, tc35876x_bridge_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static struct i2c_driver tc35876x_bridge_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		.name = "i2c_disp_brig",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	.id_table = tc35876x_bridge_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	.probe = tc35876x_bridge_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	.remove = tc35876x_bridge_remove,
^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) /* LCD panel I2C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int cmi_lcd_i2c_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 			     const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	dev_info(&client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		dev_err(&client->dev, "%s: i2c_check_functionality() failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	cmi_lcd_i2c_client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static int cmi_lcd_i2c_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	dev_dbg(&client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	cmi_lcd_i2c_client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static const struct i2c_device_id cmi_lcd_i2c_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	{ "cmi-lcd", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) MODULE_DEVICE_TABLE(i2c, cmi_lcd_i2c_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static struct i2c_driver cmi_lcd_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		.name = "cmi-lcd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	.id_table = cmi_lcd_i2c_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	.probe = cmi_lcd_i2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	.remove = cmi_lcd_i2c_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /* HACK to create I2C device while it's not created by platform code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #define CMI_LCD_I2C_ADAPTER	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) #define CMI_LCD_I2C_ADDR	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int cmi_lcd_hack_create_device(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	struct i2c_adapter *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	struct i2c_board_info info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 		.type = "cmi-lcd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		.addr = CMI_LCD_I2C_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	adapter = i2c_get_adapter(CMI_LCD_I2C_ADAPTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	if (!adapter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		pr_err("%s: i2c_get_adapter(%d) failed\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 			CMI_LCD_I2C_ADAPTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	client = i2c_new_client_device(adapter, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	if (IS_ERR(client)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		pr_err("%s: creating I2C device failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		i2c_put_adapter(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		return PTR_ERR(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static const struct drm_encoder_helper_funcs tc35876x_encoder_helper_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	.dpms = mdfld_dsi_dpi_dpms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	.mode_fixup = mdfld_dsi_dpi_mode_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	.prepare = mdfld_dsi_dpi_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	.mode_set = mdfld_dsi_dpi_mode_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	.commit = mdfld_dsi_dpi_commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) const struct panel_funcs mdfld_tc35876x_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	.encoder_helper_funcs = &tc35876x_encoder_helper_funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	.get_config_mode = tc35876x_get_config_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	.get_panel_info = tc35876x_get_panel_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) void tc35876x_init(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	dev_dbg(&dev->pdev->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	cmi_lcd_hack_create_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	r = i2c_add_driver(&cmi_lcd_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		dev_err(&dev->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 			"%s: i2c_add_driver() for %s failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 			__func__, cmi_lcd_i2c_driver.driver.name, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	r = i2c_add_driver(&tc35876x_bridge_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		dev_err(&dev->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 			"%s: i2c_add_driver() for %s failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 			__func__, tc35876x_bridge_i2c_driver.driver.name, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	tc35876x_brightness_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) void tc35876x_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	i2c_del_driver(&tc35876x_bridge_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	if (cmi_lcd_i2c_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 		i2c_del_driver(&cmi_lcd_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }