mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
video: rockchip: remove unused transmitter driver
Change-Id: I01c7291b55c9183902ecb55c6b0b2e79d2aa3097 Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
@@ -1,87 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
menuconfig RK_TRSM
|
||||
bool "RockChip display transmitter support"
|
||||
depends on FB_ROCKCHIP || DRM_ROCKCHIP
|
||||
|
||||
config RK2928_LVDS
|
||||
bool "RK2928/RK2926 lvds transmitter support"
|
||||
depends on ARCH_RK2928 && RK_TRSM
|
||||
|
||||
config RK3026_LVDS
|
||||
depends on ARCH_RK3026 && RK_TRSM
|
||||
bool "RK3026/RK3028A lvds transmitter support"
|
||||
default y
|
||||
|
||||
config RK32_LVDS
|
||||
bool "RK32 lvds transmitter support"
|
||||
depends on RK_TRSM
|
||||
|
||||
config RK31XX_LVDS
|
||||
bool "RK312x/RK3190/3368 lvds transmitter support"
|
||||
depends on RK_TRSM
|
||||
help
|
||||
If use LVDS or RGB output interface,selete this module.
|
||||
|
||||
config RK610_LVDS
|
||||
bool "RK610(Jetta) lvds transmitter support"
|
||||
depends on MFD_RK610 && RK_TRSM
|
||||
help
|
||||
Support Jetta(RK610) to output LCD1 and LVDS.
|
||||
|
||||
config RK616_LVDS
|
||||
bool "RK616(JettaB) lvds,lcd,scaler vido interface support"
|
||||
depends on MFD_RK616 && RK_TRSM
|
||||
help
|
||||
RK616(Jetta B) LVDS,LCD,scaler transmitter support.
|
||||
|
||||
|
||||
config DP_ANX6345
|
||||
bool "RGB to DisplayPort transmitter anx6345,anx9804,anx9805 support"
|
||||
depends on RK_TRSM
|
||||
|
||||
config DP501
|
||||
bool"RGB to DisplayPort transmitter dp501 support"
|
||||
depends on RK_TRSM
|
||||
|
||||
config RK32_DP
|
||||
bool "RK32 RGB to DisplayPort transmitter support "
|
||||
depends on RK_TRSM
|
||||
|
||||
config RK_VGA
|
||||
bool "VGA support on RockChip platform"
|
||||
depends on RK_TRSM
|
||||
default y
|
||||
help
|
||||
say y here will enable VGA on RockChip platform
|
||||
|
||||
config MIPI_DSI
|
||||
depends on RK_TRSM
|
||||
bool "Rockchip MIPI DSI support"
|
||||
|
||||
config TC358768_RGB2MIPI
|
||||
tristate "toshiba TC358768 RGB to MIPI DSI"
|
||||
depends on MIPI_DSI
|
||||
help
|
||||
"a chip that change RGB interface parallel signal into DSI serial signal"
|
||||
|
||||
config SSD2828_RGB2MIPI
|
||||
tristate "solomon SSD2828 RGB to MIPI DSI"
|
||||
depends on MIPI_DSI
|
||||
help
|
||||
"a chip that change RGB interface parallel signal into DSI serial signal"
|
||||
|
||||
config RK32_MIPI_DSI
|
||||
tristate "rk32 mipi dsi support"
|
||||
depends on MIPI_DSI
|
||||
help
|
||||
Rockchip mipi dsi support.
|
||||
|
||||
|
||||
config RK616_MIPI_DSI_RST
|
||||
bool "Reset the rockchip mipi dsi"
|
||||
depends on MFD_RK616 && RK616_MIPI_DSI && RK616_USE_MCLK_12M
|
||||
default y
|
||||
help
|
||||
if you say y here: inset the hdmi, mipi lcd will be reset.
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Makefile for display transmitter like lvds edp mipi
|
||||
#
|
||||
obj-$(CONFIG_RK2928_LVDS) += rk2928_lvds.o
|
||||
obj-$(CONFIG_RK3026_LVDS) += rk3026_lvds.o
|
||||
obj-$(CONFIG_RK610_LVDS) += rk610_lcd.o
|
||||
obj-$(CONFIG_RK616_LVDS) += rk616_lvds.o
|
||||
obj-$(CONFIG_RK32_LVDS) += rk32_lvds.o
|
||||
obj-$(CONFIG_RK31XX_LVDS) += rk31xx_lvds.o
|
||||
obj-$(CONFIG_DP_ANX6345) += dp_anx6345.o
|
||||
obj-$(CONFIG_DP501) += dp501.o
|
||||
obj-$(CONFIG_RK32_DP) += rk32_dp.o rk32_dp_reg.o
|
||||
obj-$(CONFIG_MIPI_DSI) += mipi_dsi.o
|
||||
obj-$(CONFIG_RK616_MIPI_DSI) += rk616_mipi_dsi.o
|
||||
obj-$(CONFIG_RK32_MIPI_DSI) += rk32_mipi_dsi.o
|
||||
obj-$(CONFIG_TC358768_RGB2MIPI) += tc358768.o
|
||||
obj-$(CONFIG_SSD2828_RGB2MIPI) += ssd2828.o
|
||||
obj-$(CONFIG_RK_VGA) += vga.o
|
||||
|
||||
@@ -1,689 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ANX6345_H_
|
||||
#define __ANX6345_H_
|
||||
|
||||
#include<linux/rk_fb.h>
|
||||
#include "anx9805.h"
|
||||
|
||||
#define ANX6345_SCL_RATE (100*1000)
|
||||
|
||||
#define MAX_REG 0xf0
|
||||
#define MAX_BUF_CNT 6
|
||||
|
||||
|
||||
#define DP_TX_PORT0_ADDR 0x70
|
||||
#define HDMI_TX_PORT0_ADDR 0x72
|
||||
|
||||
#define DP_TIMEOUT_LOOP_CNT 100
|
||||
#define MAX_CR_LOOP 5
|
||||
#define MAX_EQ_LOOP 5
|
||||
|
||||
/***************************************************************/
|
||||
// DEV_ADDR = 0x7A or 0x7B , MIPI Rx Registers
|
||||
#define MIPI_ANALOG_PWD_CTRL0 0x00
|
||||
#define MIPI_ANALOG_PWD_CTRL1 0x01
|
||||
#define MIPI_ANALOG_PWD_CTRL2 0x02
|
||||
|
||||
#define MIPI_MISC_CTRL 0x03
|
||||
|
||||
#define MIPI_TIMING_REG0 0x04
|
||||
#define MIPI_TIMING_REG1 0x05
|
||||
#define MIPI_TIMING_REG2 0x06
|
||||
#define MIPI_TIMING_REG3 0x07
|
||||
#define MIPI_TIMING_REG4 0x08
|
||||
#define MIPI_TIMING_REG5 0x09
|
||||
#define MIPI_TIMING_REG6 0x0a
|
||||
|
||||
#define MIPI_HS_JITTER_REG 0x0B
|
||||
|
||||
#define MIPI_VID_STABLE_CNT 0x0C
|
||||
|
||||
#define MIPI_ANALOG_CTRL0 0x0D
|
||||
#define MIPI_ANALOG_CTRL1 0x0E
|
||||
#define MIPI_ANALOG_CTRL2 0x0F
|
||||
|
||||
#define MIPI_PRBS_REG 0x10
|
||||
#define MIPI_PROTOCOL_STATE 0x11
|
||||
|
||||
|
||||
//End for DEV_addr 0x7A/0x7E
|
||||
|
||||
/***************************************************************/
|
||||
// DEV_ADDR = 0x70 or 0x78 , Displayport mode and HDCP registers
|
||||
#define HDCP_STATUS 0x00
|
||||
#define HDCP_AUTH_PASS 0x02//bit position
|
||||
|
||||
#define HDCP_CONTROL_0_REG 0x01
|
||||
#define HDCP_CONTROL_0_STORE_AN 0x80//bit position
|
||||
#define HDCP_CONTROL_0_RX_REPEATER 0x40//bit position
|
||||
#define HDCP_CONTROL_0_RE_AUTH 0x20//bit position
|
||||
#define HDCP_CONTROL_0_SW_AUTH_OK 0x10//bit position
|
||||
#define HDCP_CONTROL_0_HARD_AUTH_EN 0x08//bit position
|
||||
#define HDCP_CONTROL_0_HDCP_ENC_EN 0x04//bit position
|
||||
#define HDCP_CONTROL_0_BKSV_SRM_PASS 0x02//bit position
|
||||
#define HDCP_CONTROL_0_KSVLIST_VLD 0x01//bit position
|
||||
|
||||
|
||||
#define HDCP_CONTROL_1_REG 0x02
|
||||
#define HDCP_CONTROL_1_DDC_NO_STOP 0x20//bit position
|
||||
#define HDCP_CONTROL_1_DDC_NO_ACK 0x10//bit position
|
||||
#define HDCP_CONTROL_1_EDDC_NO_ACK 0x08//bit position
|
||||
//#define HDCP_CONTROL_1_HDCP_EMB_SCREEN_EN 0x04//bit position
|
||||
#define HDCP_CONTROL_1_RCV_11_EN 0x02//bit position
|
||||
#define HDCP_CONTROL_1_HDCP_11_EN 0x01//bit position
|
||||
|
||||
#define HDCP_LINK_CHK_FRAME_NUM 0x03
|
||||
#define HDCP_CONTROL_2_REG 0x04
|
||||
|
||||
#define HDCP_AKSV0 0x05
|
||||
#define HDCP_AKSV1 0x06
|
||||
#define HDCP_AKSV2 0x07
|
||||
#define HDCP_AKSV3 0x08
|
||||
#define HDCP_AKSV4 0x09
|
||||
|
||||
//AKSV
|
||||
#define HDCP_AN0 0x0A
|
||||
#define HDCP_AN1 0x0B
|
||||
#define HDCP_AN2 0x0C
|
||||
#define HDCP_AN3 0x0D
|
||||
#define HDCP_AN4 0x0E
|
||||
#define HDCP_AN5 0x0F
|
||||
#define HDCP_AN6 0x10
|
||||
#define HDCP_AN7 0x11
|
||||
|
||||
//BKSV
|
||||
#define HDCP_BKSV0 0x12
|
||||
#define HDCP_BKSV1 0x13
|
||||
#define HDCP_BKSV2 0x14
|
||||
#define HDCP_BKSV3 0x15
|
||||
#define HDCP_BKSV4 0x16
|
||||
|
||||
#define HDCP_R0_L 0x17
|
||||
#define HDCP_R0_H 0x18
|
||||
|
||||
#define M_VID_0 0xC0
|
||||
#define M_VID_1 0xC1
|
||||
#define M_VID_2 0xC2
|
||||
#define N_VID_0 0xC3
|
||||
#define N_VID_1 0xC4
|
||||
#define N_VID_2 0xC5
|
||||
|
||||
#define HDCP_R0_WAIT_Timer 0x40
|
||||
|
||||
|
||||
|
||||
#define SYS_CTRL1_REG 0x80
|
||||
//#define SYS_CTRL1_PD_IO 0x80 // bit position
|
||||
//#define SYS_CTRL1_PD_VID 0x40 // bit position
|
||||
//#define SYS_CTRL1_PD_LINK 0x20 // bit position
|
||||
//#define SYS_CTRL1_PD_TOTAL 0x10 // bit position
|
||||
//#define SYS_CTRL1_MODE_SEL 0x08 // bit position
|
||||
#define SYS_CTRL1_DET_STA 0x04 // bit position
|
||||
#define SYS_CTRL1_FORCE_DET 0x02 // bit position
|
||||
#define SYS_CTRL1_DET_CTRL 0x01 // bit position
|
||||
|
||||
#define SYS_CTRL2_REG 0x81
|
||||
// #define SYS_CTRL2_ENHANCED 0x08 //bit position
|
||||
#define SYS_CTRL2_CHA_STA 0x04 // bit position
|
||||
#define SYS_CTRL2_FORCE_CHA 0x02 // bit position
|
||||
#define SYS_CTRL2_CHA_CTRL 0x01 // bit position
|
||||
|
||||
#define SYS_CTRL3_REG 0x82
|
||||
#define SYS_CTRL3_HPD_STATUS 0x40 // bit position
|
||||
#define SYS_CTRL3_F_HPD 0x20 // bit position
|
||||
#define SYS_CTRL3_HPD_CTRL 0x10 // bit position
|
||||
#define SYS_CTRL3_STRM_VALID 0x04 // bit position
|
||||
#define SYS_CTRL3_F_VALID 0x02 // bit position
|
||||
#define SYS_CTRL3_VALID_CTRL 0x01 // bit position
|
||||
|
||||
#define SYS_CTRL4_REG 0x83
|
||||
#define SYS_CTRL4_ENHANCED 0x08//bit position
|
||||
|
||||
#define VID_CTRL 0x84
|
||||
|
||||
#define AUD_CTRL 0x87
|
||||
#define AUD_CTRL_AUD_EN 0x01
|
||||
|
||||
|
||||
#define PKT_EN_REG 0x90
|
||||
#define PKT_AUD_UP 0x80 // bit position
|
||||
#define PKT_AVI_UD 0x40 // bit position
|
||||
#define PKT_MPEG_UD 0x20 // bit position
|
||||
#define PKT_SPD_UD 0x10 // bit position
|
||||
#define PKT_AUD_EN 0x08 // bit position=
|
||||
#define PKT_AVI_EN 0x04 // bit position
|
||||
#define PKT_MPEG_EN 0x02 // bit position
|
||||
#define PKT_SPD_EN 0x01 // bit position
|
||||
|
||||
|
||||
#define HDCP_CTRL 0x92
|
||||
|
||||
#define LINK_BW_SET_REG 0xA0
|
||||
#define LANE_COUNT_SET_REG 0xA1
|
||||
|
||||
#define TRAINING_PTN_SET_REG 0xA2
|
||||
#define SCRAMBLE_DISABLE 0x20//bit 5
|
||||
|
||||
#define TRAINING_LANE0_SET_REG 0xA3
|
||||
#define TRAINING_LANE0_SET_MAX_PRE_REACH 0x20 // bit position
|
||||
#define TRAINING_LANE0_SET_MAX_DRIVE_REACH 0x04 // bit position
|
||||
|
||||
#define TRAINING_LANE1_SET_REG 0xA4
|
||||
|
||||
|
||||
#define SSC_CTRL_REG1 0xA7
|
||||
#define SPREAD_AMP 0x10//bit 4
|
||||
#define MODULATION_FREQ 0x01//bit 0
|
||||
|
||||
|
||||
#define LINK_TRAINING_CTRL_REG 0xA8
|
||||
#define LINK_TRAINING_CTRL_EN 0x01 // bit position
|
||||
|
||||
|
||||
#define DEBUG_REG1 0xB0
|
||||
#define DEBUG_HPD_POLLING_DET 0x40//bit position
|
||||
#define DEBUG_HPD_POLLING_EN 0x20//bit position
|
||||
#define DEBUG_PLL_LOCK 0x10//bit position
|
||||
|
||||
|
||||
#define LINK_DEBUG_REG 0xB8
|
||||
#define LINK_DEBUG_INSERT_ER 0x02 // bit position
|
||||
#define LINK_DEBUG_PRBS31_EN 0x01 // bit position
|
||||
|
||||
#define SINK_COUNT_REG 0xB9
|
||||
|
||||
#define LINK_STATUS_REG1 0xBB
|
||||
|
||||
#define SINK_STATUS_REG 0xBE
|
||||
#define SINK_STATUS_SINK_STATUS_1 0x02 // bit position
|
||||
#define SINK_STATUS_SINK_STATUS_0 0x01 // bit position
|
||||
|
||||
|
||||
//#define LINK_TEST_COUNT 0xC0
|
||||
|
||||
|
||||
#define PLL_CTRL_REG 0xC7
|
||||
#define PLL_CTRL_PLL_PD 0x80 // bit position
|
||||
#define PLL_CTRL_PLL_RESET 0x40 // bit position
|
||||
//#define PLL_CTRL_CPREG_BLEED 0x08 // bit position
|
||||
|
||||
#define ANALOG_POWER_DOWN_REG 0xC8
|
||||
#define ANALOG_POWER_DOWN_MACRO_PD 0x20 // bit position
|
||||
#define ANALOG_POWER_DOWN_AUX_PD 0x10 // bit position
|
||||
//#define ANALOG_POWER_DOWN_CH3_PD 0x08 // bit position
|
||||
//#define ANALOG_POWER_DOWN_CH2_PD 0x04 // bit position
|
||||
#define ANALOG_POWER_DOWN_CH1_PD 0x02 // bit position
|
||||
#define ANALOG_POWER_DOWN_CH0_PD 0x01 // bit position
|
||||
|
||||
|
||||
#define ANALOG_TEST_REG 0xC9
|
||||
#define ANALOG_TEST_MACRO_RST 0x20 // bit position
|
||||
#define ANALOG_TEST_PLL_TEST 0x10 // bit position
|
||||
#define ANALOG_TEST_CH3_TEST 0x08 // bit position
|
||||
#define ANALOG_TEST_CH2_TEST 0x04 // bit position
|
||||
#define ANALOG_TEST_CH1_TEST 0x02 // bit position
|
||||
#define ANALOG_TEST_CH0_TEST 0x01 // bit position
|
||||
|
||||
#define GNS_CTRL_REG 0xCD
|
||||
#define SP_EQ_LOOP_CNT 0x40//bit position
|
||||
#define VIDEO_MAP_CTRL 0x02 // bit position
|
||||
#define RS_CTRL 0x01 // bit position
|
||||
|
||||
#define DOWN_SPREADING_CTRL1 0xD0 //guochuncheng
|
||||
#define DOWN_SPREADING_CTRL2 0xD1
|
||||
#define DOWN_SPREADING_CTRL3 0xD2
|
||||
#define SSC_D_CTRL 0x40 //bit position
|
||||
#define FS_CTRL_TH_CTRL 0x20 //bit position
|
||||
|
||||
#define M_CALCU_CTRL 0xD9
|
||||
#define M_GEN_CLK_SEL 0x01//bit 0
|
||||
|
||||
|
||||
#define EXTRA_ADDR_REG 0xCE
|
||||
#define I2C_STRETCH_CTRL_REG 0xDB
|
||||
#define AUX_STATUS 0xE0
|
||||
#define DEFER_CTRL_REG 0xE2
|
||||
#define SP_TXL_DEFER_CTRL_EN 0x80 // bit position
|
||||
|
||||
#define BUF_DATA_COUNT_REG 0xE4
|
||||
#define AUX_CTRL_REG 0xE5
|
||||
#define MOT_BIT 0x04//bit 2
|
||||
|
||||
#define AUX_ADDR_7_0_REG 0xE6
|
||||
#define AUX_ADDR_15_8_REG 0xE7
|
||||
#define AUX_ADDR_19_16_REG 0xE8
|
||||
|
||||
#define AUX_CTRL_REG2 0xE9
|
||||
#define ADDR_ONLY_BIT 0x02//bit 1
|
||||
|
||||
#define BUF_DATA_0_REG 0xf0
|
||||
#define BUF_DATA_1_REG 0xf1
|
||||
#define BUF_DATA_2_REG 0xf2
|
||||
#define BUF_DATA_3_REG 0xf3
|
||||
#define BUF_DATA_4_REG 0xf4
|
||||
#define BUF_DATA_5_REG 0xf5
|
||||
#define BUF_DATA_6_REG 0xf6
|
||||
#define BUF_DATA_7_REG 0xf7
|
||||
#define BUF_DATA_8_REG 0xf8
|
||||
#define BUF_DATA_9_REG 0xf9
|
||||
#define BUF_DATA_10_REG 0xfa
|
||||
#define BUF_DATA_11_REG 0xfb
|
||||
#define BUF_DATA_12_REG 0xfc
|
||||
#define BUF_DATA_13_REG 0xfd
|
||||
#define BUF_DATA_14_REG 0xfe
|
||||
#define BUF_DATA_15_REG 0xff
|
||||
|
||||
//End for Address 0x70 or 0x78
|
||||
|
||||
/***************************************************************/
|
||||
// DEV_ADDR = 0x72 or 0x76, System control registers
|
||||
#define VND_IDL_REG 0x00
|
||||
#define VND_IDH_REG 0x01
|
||||
#define DEV_IDL_REG 0x02
|
||||
#define DEV_IDH_REG 0x03
|
||||
#define DEV_REV_REG 0x04
|
||||
|
||||
#define SP_POWERD_CTRL_REG 0x05
|
||||
#define SP_POWERD_REGISTER_REG 0x80// bit position
|
||||
//#define SP_POWERD_MISC_REG 0x40// bit position
|
||||
#define SP_POWERD_IO_REG 0x20// bit position
|
||||
#define SP_POWERD_AUDIO_REG 0x10// bit position
|
||||
#define SP_POWERD_VIDEO_REG 0x08// bit position
|
||||
#define SP_POWERD_LINK_REG 0x04// bit position
|
||||
#define SP_POWERD_TOTAL_REG 0x02// bit position
|
||||
#define SP_MODE_SEL_REG 0x01// bit position
|
||||
|
||||
#define RST_CTRL_REG 0x06
|
||||
#define RST_MISC_REG 0x80 // bit position
|
||||
#define RST_VIDCAP_REG 0x40 // bit position
|
||||
#define RST_VIDFIF_REG 0x20 // bit position
|
||||
#define RST_AUDFIF_REG 0x10 // bit position
|
||||
#define RST_AUDCAP_REG 0x08 // bit position
|
||||
#define RST_HDCP_REG 0x04 // bit position
|
||||
#define RST_SW_RST 0x02 // bit position
|
||||
#define RST_HW_RST 0x01 // bit position
|
||||
|
||||
#define RST_CTRL2_REG 0x07
|
||||
#define RST_SSC 0x80//bit position
|
||||
#define AC_MODE 0x40//bit position
|
||||
//#define DDC_RST 0x10//bit position
|
||||
//#define TMDS_BIST_RST 0x08//bit position
|
||||
#define AUX_RST 0x04//bit position
|
||||
#define SERDES_FIFO_RST 0x02//bit position
|
||||
#define I2C_REG_RST 0x01//bit position
|
||||
|
||||
|
||||
#define VID_CTRL1_REG 0x08
|
||||
#define VID_CTRL1_VID_EN 0x80 // bit position
|
||||
#define VID_CTRL1_VID_MUTE 0x40 // bit position
|
||||
#define VID_CTRL1_DE_GEN 0x20 // bit position
|
||||
#define VID_CTRL1_DEMUX 0x10 // bit position
|
||||
#define VID_CTRL1_IN_BIT 0x04 // bit position
|
||||
#define VID_CTRL1_DDRCTRL 0x02 // bit position
|
||||
#define VID_CTRL1_EDGE 0x01 // bit position
|
||||
|
||||
#define VID_CTRL2_REG 0x09
|
||||
#define VID_CTRL1_YCBIT_SEL 0x04 // bit position
|
||||
|
||||
#define VID_CTRL3_REG 0x0A
|
||||
|
||||
#define VID_CTRL4_REG 0x0B
|
||||
#define VID_CTRL4_E_SYNC_EN 0x80 //bit position
|
||||
#define VID_CTRL4_EX_E_SYNC 0x40 // bit position
|
||||
#define VID_CTRL4_BIST 0x08 // bit position
|
||||
#define VID_CTRL4_BIST_WIDTH 0x04 // bit position
|
||||
|
||||
#define VID_CTRL5_REG 0x0C
|
||||
|
||||
#define VID_CTRL6_REG 0x0D
|
||||
#define VID_UPSAMPLE 0x02//bit position
|
||||
|
||||
#define VID_CTRL7_REG 0x0E
|
||||
#define VID_CTRL8_REG 0x0F
|
||||
#define VID_CTRL9_REG 0x10
|
||||
|
||||
#define VID_CTRL10_REG 0x11
|
||||
#define VID_CTRL10_INV_F 0x08 // bit position
|
||||
#define VID_CTRL10_I_SCAN 0x04 // bit position
|
||||
#define VID_CTRL10_VSYNC_POL 0x02 // bit position
|
||||
#define VID_CTRL10_HSYNC_POL 0x01 // bit position
|
||||
|
||||
#define TOTAL_LINEL_REG 0x12
|
||||
#define TOTAL_LINEH_REG 0x13
|
||||
#define ACT_LINEL_REG 0x14
|
||||
#define ACT_LINEH_REG 0x15
|
||||
#define VF_PORCH_REG 0x16
|
||||
#define VSYNC_CFG_REG 0x17
|
||||
#define VB_PORCH_REG 0x18
|
||||
#define TOTAL_PIXELL_REG 0x19
|
||||
#define TOTAL_PIXELH_REG 0x1A
|
||||
#define ACT_PIXELL_REG 0x1B
|
||||
#define ACT_PIXELH_REG 0x1C
|
||||
#define HF_PORCHL_REG 0x1D
|
||||
#define HF_PORCHH_REG 0x1E
|
||||
#define HSYNC_CFGL_REG 0x1F
|
||||
#define HSYNC_CFGH_REG 0x20
|
||||
#define HB_PORCHL_REG 0x21
|
||||
#define HB_PORCHH_REG 0x22
|
||||
|
||||
#define VID_STATUS 0x23
|
||||
|
||||
#define TOTAL_LINE_STA_L 0x24
|
||||
#define TOTAL_LINE_STA_H 0x25
|
||||
#define ACT_LINE_STA_L 0x26
|
||||
#define ACT_LINE_STA_H 0x27
|
||||
#define V_F_PORCH_STA 0x28
|
||||
#define V_SYNC_STA 0x29
|
||||
#define V_B_PORCH_STA 0x2A
|
||||
#define TOTAL_PIXEL_STA_L 0x2B
|
||||
#define TOTAL_PIXEL_STA_H 0x2C
|
||||
#define ACT_PIXEL_STA_L 0x2D
|
||||
#define ACT_PIXEL_STA_H 0x2E
|
||||
#define H_F_PORCH_STA_L 0x2F
|
||||
#define H_F_PORCH_STA_H 0x30
|
||||
#define H_SYNC_STA_L 0x31
|
||||
#define H_SYNC_STA_H 0x32
|
||||
#define H_B_PORCH_STA_L 0x33
|
||||
#define H_B_PORCH_STA_H 0x34
|
||||
|
||||
#define Video_Interface_BIST 0x35
|
||||
|
||||
#define SPDIF_AUDIO_CTRL0 0x36
|
||||
#define SPDIF_AUDIO_CTRL0_SPDIF_IN 0x80 // bit position
|
||||
|
||||
#define SPDIF_AUDIO_STATUS0 0x38
|
||||
#define SPDIF_AUDIO_STATUS0_CLK_DET 0x80
|
||||
#define SPDIF_AUDIO_STATUS0_AUD_DET 0x01
|
||||
|
||||
#define SPDIF_AUDIO_STATUS1 0x39
|
||||
|
||||
#define AUDIO_BIST_CTRL 0x3c
|
||||
#define AUDIO_BIST_EN 0x01
|
||||
|
||||
//#define AUDIO_BIST_CHANNEL_STATUS1 0xd0
|
||||
//#define AUDIO_BIST_CHANNEL_STATUS2 0xd1
|
||||
//#define AUDIO_BIST_CHANNEL_STATUS3 0xd2
|
||||
//#define AUDIO_BIST_CHANNEL_STATUS4 0xd3
|
||||
//#define AUDIO_BIST_CHANNEL_STATUS5 0xd4
|
||||
|
||||
#define VIDEO_BIT_CTRL_0_REG 0x40
|
||||
#define VIDEO_BIT_CTRL_1_REG 0x41
|
||||
#define VIDEO_BIT_CTRL_2_REG 0x42
|
||||
#define VIDEO_BIT_CTRL_3_REG 0x43
|
||||
#define VIDEO_BIT_CTRL_4_REG 0x44
|
||||
#define VIDEO_BIT_CTRL_5_REG 0x45
|
||||
#define VIDEO_BIT_CTRL_6_REG 0x46
|
||||
#define VIDEO_BIT_CTRL_7_REG 0x47
|
||||
#define VIDEO_BIT_CTRL_8_REG 0x48
|
||||
#define VIDEO_BIT_CTRL_9_REG 0x49
|
||||
#define VIDEO_BIT_CTRL_10_REG 0x4a
|
||||
#define VIDEO_BIT_CTRL_11_REG 0x4b
|
||||
#define VIDEO_BIT_CTRL_12_REG 0x4c
|
||||
#define VIDEO_BIT_CTRL_13_REG 0x4d
|
||||
#define VIDEO_BIT_CTRL_14_REG 0x4e
|
||||
#define VIDEO_BIT_CTRL_15_REG 0x4f
|
||||
#define VIDEO_BIT_CTRL_16_REG 0x50
|
||||
#define VIDEO_BIT_CTRL_17_REG 0x51
|
||||
#define VIDEO_BIT_CTRL_18_REG 0x52
|
||||
#define VIDEO_BIT_CTRL_19_REG 0x53
|
||||
#define VIDEO_BIT_CTRL_20_REG 0x54
|
||||
#define VIDEO_BIT_CTRL_21_REG 0x55
|
||||
#define VIDEO_BIT_CTRL_22_REG 0x56
|
||||
#define VIDEO_BIT_CTRL_23_REG 0x57
|
||||
#define VIDEO_BIT_CTRL_24_REG 0x58
|
||||
#define VIDEO_BIT_CTRL_25_REG 0x59
|
||||
#define VIDEO_BIT_CTRL_26_REG 0x5a
|
||||
#define VIDEO_BIT_CTRL_27_REG 0x5b
|
||||
#define VIDEO_BIT_CTRL_28_REG 0x5c
|
||||
#define VIDEO_BIT_CTRL_29_REG 0x5d
|
||||
#define VIDEO_BIT_CTRL_30_REG 0x5e
|
||||
#define VIDEO_BIT_CTRL_31_REG 0x5f
|
||||
#define VIDEO_BIT_CTRL_32_REG 0x60
|
||||
#define VIDEO_BIT_CTRL_33_REG 0x61
|
||||
#define VIDEO_BIT_CTRL_34_REG 0x62
|
||||
#define VIDEO_BIT_CTRL_35_REG 0x63
|
||||
#define VIDEO_BIT_CTRL_36_REG 0x64
|
||||
#define VIDEO_BIT_CTRL_37_REG 0x65
|
||||
#define VIDEO_BIT_CTRL_38_REG 0x66
|
||||
#define VIDEO_BIT_CTRL_39_REG 0x67
|
||||
#define VIDEO_BIT_CTRL_40_REG 0x68
|
||||
#define VIDEO_BIT_CTRL_41_REG 0x69
|
||||
#define VIDEO_BIT_CTRL_42_REG 0x6a
|
||||
#define VIDEO_BIT_CTRL_43_REG 0x6b
|
||||
#define VIDEO_BIT_CTRL_44_REG 0x6c
|
||||
#define VIDEO_BIT_CTRL_45_REG 0x6d
|
||||
#define VIDEO_BIT_CTRL_46_REG 0x6e
|
||||
#define VIDEO_BIT_CTRL_47_REG 0x6f
|
||||
|
||||
//AVI info frame
|
||||
#define AVI_TYPE 0x70
|
||||
#define AVI_VER 0x71
|
||||
#define AVI_LEN 0x72
|
||||
#define AVI_DB0 0x73
|
||||
#define AVI_DB1 0x74
|
||||
#define AVI_DB2 0x75
|
||||
#define AVI_DB3 0x76
|
||||
#define AVI_DB4 0x77
|
||||
#define AVI_DB5 0x78
|
||||
#define AVI_DB6 0x79
|
||||
#define AVI_DB7 0x7A
|
||||
#define AVI_DB8 0x7B
|
||||
#define AVI_DB9 0x7C
|
||||
#define AVI_DB10 0x7D
|
||||
#define AVI_DB11 0x7E
|
||||
#define AVI_DB12 0x7F
|
||||
#define AVI_DB13 0x80
|
||||
#define AVI_DB14 0x81
|
||||
#define AVI_DB15 0x82
|
||||
|
||||
//Audio info frame
|
||||
#define AUD_TYPE 0x83
|
||||
#define AUD_VER 0x84
|
||||
#define AUD_LEN 0x85
|
||||
#define AUD_DB0 0x86
|
||||
#define AUD_DB1 0x87
|
||||
#define AUD_DB2 0x88
|
||||
#define AUD_DB3 0x89
|
||||
#define AUD_DB4 0x8A
|
||||
#define AUD_DB5 0x8B
|
||||
#define AUD_DB6 0x8C
|
||||
#define AUD_DB7 0x8D
|
||||
#define AUD_DB8 0x8E
|
||||
#define AUD_DB9 0x8F
|
||||
#define AUD_DB10 0x90
|
||||
|
||||
//SPD info frame
|
||||
#define SPD_TYPE 0x91
|
||||
#define SPD_VER 0x92
|
||||
#define SPD_LEN 0x93
|
||||
#define SPD_DATA0 0x94
|
||||
#define SPD_DATA1 0x95
|
||||
#define SPD_DATA2 0x96
|
||||
#define SPD_DATA3 0x97
|
||||
#define SPD_DATA4 0x98
|
||||
#define SPD_DATA5 0x99
|
||||
#define SPD_DATA6 0x9A
|
||||
#define SPD_DATA7 0x9B
|
||||
#define SPD_DATA8 0x9C
|
||||
#define SPD_DATA9 0x9D
|
||||
#define SPD_DATA10 0x9E
|
||||
#define SPD_DATA11 0x9F
|
||||
#define SPD_DATA12 0xA0
|
||||
#define SPD_DATA13 0xA1
|
||||
#define SPD_DATA14 0xA2
|
||||
#define SPD_DATA15 0xA3
|
||||
#define SPD_DATA16 0xA4
|
||||
#define SPD_DATA17 0xA5
|
||||
#define SPD_DATA18 0xA6
|
||||
#define SPD_DATA19 0xA7
|
||||
#define SPD_DATA20 0xA8
|
||||
#define SPD_DATA21 0xA9
|
||||
#define SPD_DATA22 0xAA
|
||||
#define SPD_DATA23 0xAB
|
||||
#define SPD_DATA24 0xAC
|
||||
#define SPD_DATA25 0xAD
|
||||
#define SPD_DATA26 0xAE
|
||||
#define SPD_DATA27 0xAF
|
||||
|
||||
//Mpeg source info frame
|
||||
#define MPEG_TYPE 0xB0
|
||||
#define MPEG_VER 0xB1
|
||||
#define MPEG_LEN 0xB2
|
||||
#define MPEG_DATA0 0xB3
|
||||
#define MPEG_DATA1 0xB4
|
||||
#define MPEG_DATA2 0xB5
|
||||
#define MPEG_DATA3 0xB6
|
||||
#define MPEG_DATA4 0xB7
|
||||
#define MPEG_DATA5 0xB8
|
||||
#define MPEG_DATA6 0xB9
|
||||
#define MPEG_DATA7 0xBA
|
||||
#define MPEG_DATA8 0xBB
|
||||
#define MPEG_DATA9 0xBC
|
||||
#define MPEG_DATA10 0xBD
|
||||
#define MPEG_DATA11 0xBE
|
||||
#define MPEG_DATA12 0xBF
|
||||
#define MPEG_DATA13 0xC0
|
||||
#define MPEG_DATA14 0xC1
|
||||
#define MPEG_DATA15 0xC2
|
||||
#define MPEG_DATA16 0xC3
|
||||
#define MPEG_DATA17 0xC4
|
||||
#define MPEG_DATA18 0xC5
|
||||
#define MPEG_DATA19 0xC6
|
||||
#define MPEG_DATA20 0xC7
|
||||
#define MPEG_DATA21 0xC8
|
||||
#define MPEG_DATA22 0xC9
|
||||
#define MPEG_DATA23 0xCA
|
||||
#define MPEG_DATA24 0xCB
|
||||
#define MPEG_DATA25 0xCC
|
||||
#define MPEG_DATA26 0xCD
|
||||
#define MPEG_DATA27 0xCE
|
||||
|
||||
//#define GNSS_CTRL_REG 0xCD
|
||||
//#define ENABLE_SSC_FILTER 0x80//bit
|
||||
|
||||
//#define SSC_D_VALUE 0xD0
|
||||
//#define SSC_CTRL_REG2 0xD1
|
||||
|
||||
#define ANALOG_DEBUG_REG1 0xDC
|
||||
#define ANALOG_SEL_BG 0x40//bit 4
|
||||
#define ANALOG_SWING_A_30PER 0x08//bit 3
|
||||
|
||||
#define ANALOG_DEBUG_REG2 0xDD
|
||||
#define ANALOG_24M_SEL 0x08//bit 3
|
||||
//#define ANALOG_FILTER_ENABLED 0x10//bit 4
|
||||
|
||||
|
||||
#define ANALOG_DEBUG_REG3 0xDE
|
||||
|
||||
#define PLL_FILTER_CTRL1 0xDF
|
||||
#define PD_RING_OSC 0x40//bit 6
|
||||
|
||||
#define PLL_FILTER_CTRL2 0xE0
|
||||
#define PLL_FILTER_CTRL3 0xE1
|
||||
#define PLL_FILTER_CTRL4 0xE2
|
||||
#define PLL_FILTER_CTRL5 0xE3
|
||||
#define PLL_FILTER_CTRL6 0xE4
|
||||
|
||||
#define I2S_CTRL 0xE6
|
||||
#define I2S_FMT 0xE7
|
||||
#define I2S_CH_Status1 0xD0
|
||||
#define I2S_CH_Status2 0xD1
|
||||
#define I2S_CH_Status3 0xD2
|
||||
#define I2S_CH_Status4 0xD3
|
||||
#define I2S_CH_Status5 0xD4
|
||||
|
||||
//interrupt
|
||||
#define SP_COMMON_INT_STATUS1 0xF1
|
||||
#define SP_COMMON_INT1_PLL_LOCK_CHG 0x40//bit position
|
||||
#define SP_COMMON_INT1_VIDEO_FORMAT_CHG 0x08//bit position
|
||||
#define SP_COMMON_INT1_AUDIO_CLK_CHG 0x04//bit position
|
||||
#define SP_COMMON_INT1_VIDEO_CLOCK_CHG 0x02//bit position
|
||||
|
||||
|
||||
#define SP_COMMON_INT_STATUS2 0xF2
|
||||
#define SP_COMMON_INT2_AUTHCHG 0x02 //bit position
|
||||
#define SP_COMMON_INT2_AUTHDONE 0x01 //bit position
|
||||
|
||||
#define SP_COMMON_INT_STATUS3 0xF3
|
||||
#define SP_COMMON_INT3_AFIFO_UNDER 0x80//bit position
|
||||
#define SP_COMMON_INT3_AFIFO_OVER 0x40//bit position
|
||||
|
||||
#define SP_COMMON_INT_STATUS4 0xF4
|
||||
#define SP_COMMON_INT4_PLUG 0x01 // bit position
|
||||
#define SP_COMMON_INT4_ESYNC_ERR 0x10 // bit position
|
||||
#define SP_COMMON_INT4_HPDLOST 0x02 //bit position
|
||||
#define SP_COMMON_INT4_HPD_CHANGE 0x04 //bit position
|
||||
|
||||
|
||||
#define INT_STATUS1 0xF7
|
||||
#define INT_STATUS1_HPD 0x40 //bit position
|
||||
#define INT_STATUS1_TRAINING_Finish 0x20 // bit position
|
||||
#define INT_STATUS1_POLLING_ERR 0x10 // bit position
|
||||
|
||||
#define INT_SINK_CHG 0x08//bit position
|
||||
|
||||
|
||||
#define AUX_CH_STA 0xe0
|
||||
#define AUX_BUSY (0x1 << 4)
|
||||
#define AUX_STATUS_MASK (0xf << 0)
|
||||
#define DP_AUX_RX_COMM 0xe3
|
||||
#define BUF_DATA_CTL 0xe4
|
||||
#define BUF_CLR (0x1 << 7)
|
||||
#define DP_AUX_CH_CTL_1 0xe5
|
||||
#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4)
|
||||
#define AUX_TX_COMM_MASK (0xf << 0)
|
||||
#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3)
|
||||
#define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3)
|
||||
#define AUX_TX_COMM_MOT (0x1 << 2)
|
||||
#define AUX_TX_COMM_WRITE (0x0 << 0)
|
||||
#define AUX_TX_COMM_READ (0x1 << 0)
|
||||
|
||||
#define DP_AUX_ADDR_7_0 0xe6
|
||||
#define DP_AUX_ADDR_15_8 0xe7
|
||||
#define DP_AUX_ADDR_19_16 0xe8
|
||||
|
||||
#define DP_AUX_CH_CTL_2 0xe9
|
||||
#define ADDR_ONLY (0x1 << 1)
|
||||
#define AUX_EN (0x1 << 0)
|
||||
|
||||
#define BUF_DATA_0 0xf0
|
||||
|
||||
#define DP_INT_STA 0xf7
|
||||
#define RPLY_RECEIV (0x1 << 1)
|
||||
#define AUX_ERR (0x1 << 0)
|
||||
#define SP_COMMON_INT_MASK1 0xF8
|
||||
#define SP_COMMON_INT_MASK2 0xF9
|
||||
#define SP_COMMON_INT_MASK3 0xFA
|
||||
#define SP_COMMON_INT_MASK4 0xFB
|
||||
#define SP_INT_MASK 0xFE
|
||||
#define INT_CTRL_REG 0xFF
|
||||
//End for dev_addr 0x72 or 0x76
|
||||
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
|
||||
struct anx6345_platform_data {
|
||||
unsigned int dvdd33_en_pin;
|
||||
int dvdd33_en_val;
|
||||
unsigned int dvdd18_en_pin;
|
||||
int dvdd18_en_val;
|
||||
unsigned int edp_rst_pin;
|
||||
int (*power_ctl)(struct anx6345_platform_data *pdata);
|
||||
bool pwron;
|
||||
};
|
||||
|
||||
struct edp_anx6345 {
|
||||
struct i2c_client *client;
|
||||
struct anx6345_platform_data *pdata;
|
||||
struct rk_screen screen;
|
||||
struct fb_monspecs specs;
|
||||
struct dentry *debugfs_dir;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
int (*edp_anx_init)(struct i2c_client *client);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,114 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _DP_ANX9805_H_
|
||||
#define _DP_ANX9805_H_
|
||||
/**************register define for anx9805 anx9804********/
|
||||
|
||||
#define DP_TX_VND_IDL_REG 0x00
|
||||
#define DP_TX_VND_IDH_REG 0x01
|
||||
#define DP_TX_DEV_IDL_REG 0x02
|
||||
#define DP_TX_DEV_IDH_REG 0x03
|
||||
#define DP_POWERD_CTRL_REG 0x05
|
||||
|
||||
#define DP_TX_VID_CTRL1_REG 0x08
|
||||
#define DP_TX_VID_CTRL1_VID_EN 0x80 // bit position
|
||||
#define DP_POWERD_TOTAL_REG 0x02// bit position
|
||||
#define DP_POWERD_AUDIO_REG 0x10// bit position
|
||||
|
||||
#define DP_TX_RST_CTRL_REG 0x06
|
||||
#define DP_TX_RST_CTRL2_REG 0x07
|
||||
#define DP_TX_RST_HW_RST 0x01 // bit position
|
||||
#define DP_TX_AUX_RST 0x04//bit position
|
||||
#define DP_TX_RST_SW_RST 0x02 // bit position
|
||||
#define DP_TX_PLL_CTRL_REG 0xC7
|
||||
#define DP_TX_EXTRA_ADDR_REG 0xCE
|
||||
#define DP_TX_PLL_FILTER_CTRL3 0xE1
|
||||
#define DP_TX_PLL_CTRL3 0xE6
|
||||
#define DP_TX_AC_MODE 0x40//bit position
|
||||
#define ANALOG_DEBUG_REG1 0xDC
|
||||
#define ANALOG_DEBUG_REG3 0xDE
|
||||
#define DP_TX_PLL_FILTER_CTRL1 0xDF
|
||||
#define DP_TX_PLL_FILTER_CTRL3 0xE1
|
||||
#define DP_TX_PLL_FILTER_CTRL 0xE2
|
||||
#define DP_TX_LINK_DEBUG_REG 0xB8
|
||||
#define DP_TX_GNS_CTRL_REG 0xCD
|
||||
#define DP_TX_AUX_CTRL_REG2 0xE9
|
||||
#define DP_TX_BUF_DATA_COUNT_REG 0xE4
|
||||
#define DP_TX_AUX_CTRL_REG 0xE5
|
||||
#define DP_TX_AUX_ADDR_7_0_REG 0xE6
|
||||
#define DP_TX_AUX_ADDR_15_8_REG 0xE7
|
||||
#define DP_TX_AUX_ADDR_19_16_REG 0xE8
|
||||
#define DP_TX_BUF_DATA_0_REG 0xf0
|
||||
#define DP_TX_SYS_CTRL4_REG 0x83
|
||||
#define DP_TX_SYS_CTRL4_ENHANCED 0x08//bit position
|
||||
#define DP_TX_LINK_BW_SET_REG 0xA0
|
||||
#define DP_TX_LANE_COUNT_SET_REG 0xA1
|
||||
#define DP_TX_LINK_TRAINING_CTRL_REG 0xA8
|
||||
#define DP_TX_LINK_TRAINING_CTRL_EN 0x01// bit position
|
||||
#define DP_TX_TRAINING_LANE0_SET_REG 0xA3
|
||||
#define DP_TX_TRAINING_LANE1_SET_REG 0xA4
|
||||
#define DP_TX_TRAINING_LANE2_SET_REG 0xA5
|
||||
#define DP_TX_TRAINING_LANE3_SET_REG 0xA6
|
||||
#define DP_TX_SYS_CTRL1_REG 0x80
|
||||
#define DP_TX_SYS_CTRL1_DET_STA 0x04// bit position
|
||||
#define DP_TX_SYS_CTRL2_REG 0x81
|
||||
#define DP_TX_SYS_CTRL3_REG 0x82
|
||||
#define DP_TX_SYS_CTRL2_CHA_STA 0x04// bit position
|
||||
#define DP_TX_VID_CTRL2_REG 0x09
|
||||
#define DP_TX_TOTAL_LINEL_REG 0x12
|
||||
#define DP_TX_TOTAL_LINEH_REG 0x13
|
||||
#define DP_TX_ACT_LINEL_REG 0x14
|
||||
#define DP_TX_ACT_LINEH_REG 0x15
|
||||
#define DP_TX_VF_PORCH_REG 0x16
|
||||
#define DP_TX_VSYNC_CFG_REG 0x17
|
||||
#define DP_TX_VB_PORCH_REG 0x18
|
||||
#define DP_TX_TOTAL_PIXELL_REG 0x19
|
||||
#define DP_TX_TOTAL_PIXELH_REG 0x1A
|
||||
#define DP_TX_ACT_PIXELL_REG 0x1B
|
||||
#define DP_TX_ACT_PIXELH_REG 0x1C
|
||||
#define DP_TX_HF_PORCHL_REG 0x1D
|
||||
#define DP_TX_HF_PORCHH_REG 0x1E
|
||||
#define DP_TX_HSYNC_CFGL_REG 0x1F
|
||||
#define DP_TX_HSYNC_CFGH_REG 0x20
|
||||
#define DP_TX_HB_PORCHL_REG 0x21
|
||||
#define DP_TX_HB_PORCHH_REG 0x22
|
||||
#define DP_TX_VID_CTRL10_REG 0x11
|
||||
#define DP_TX_VID_CTRL4_REG 0x0B
|
||||
#define DP_TX_VID_CTRL4_E_SYNC_EN 0x80//bit position
|
||||
#define DP_TX_VID_CTRL10_I_SCAN 0x04// bit position
|
||||
#define DP_TX_VID_CTRL10_VSYNC_POL 0x02// bit position
|
||||
#define DP_TX_VID_CTRL10_HSYNC_POL 0x01// bit position
|
||||
#define DP_TX_VID_CTRL4_BIST_WIDTH 0x04// bit position
|
||||
#define DP_TX_VID_CTRL4_BIST 0x08// bit position
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COLOR_6,
|
||||
COLOR_8,
|
||||
COLOR_10,
|
||||
COLOR_12
|
||||
}VIP_COLOR_DEPTH;
|
||||
|
||||
struct rk_edp_platform_data {
|
||||
unsigned int dvdd33_en_pin;
|
||||
int dvdd33_en_val;
|
||||
unsigned int dvdd18_en_pin;
|
||||
int dvdd18_en_val;
|
||||
unsigned int edp_rst_pin;
|
||||
int (*power_ctl)(void);
|
||||
};
|
||||
|
||||
struct rk_edp {
|
||||
struct i2c_client *client;
|
||||
struct rk_edp_platform_data *pdata;
|
||||
struct rk_screen screen;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,295 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/dp501.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
|
||||
|
||||
static int dp501_write_reg(struct i2c_client *client,char index,char reg,char val)
|
||||
{
|
||||
int ret;
|
||||
if(index == 0) //page 0
|
||||
{
|
||||
client->addr = (DP501_P0_ADDR >> 1);
|
||||
}
|
||||
else if(index == 1) //page1
|
||||
{
|
||||
client->addr = (DP501_P1_ADDR >> 1);
|
||||
}
|
||||
else if(index == 2) //page 2
|
||||
{
|
||||
client->addr = (DP501_P2_ADDR >> 1);
|
||||
}
|
||||
else if(index == 3)
|
||||
{
|
||||
client->addr = (DP501_P3_ADDR >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev_err(&client->dev,"invalid page number\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = i2c_master_reg8_send(client, reg, &val, 1,DP501_SCL_RATE);
|
||||
if(ret < 0)
|
||||
{
|
||||
|
||||
dev_err(&client->dev,"%s page%d:0x%x err\n",__func__,index,reg);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static char dp501_read_reg(struct i2c_client *client,char index,char reg)
|
||||
{
|
||||
int ret;
|
||||
char val;
|
||||
if(index == 0) //page 0
|
||||
{
|
||||
client->addr = (DP501_P0_ADDR >> 1);
|
||||
}
|
||||
else if(index == 1) //page1
|
||||
{
|
||||
client->addr = (DP501_P1_ADDR>>1);
|
||||
}
|
||||
else if(index == 2) //page 2
|
||||
{
|
||||
client->addr = (DP501_P2_ADDR>>1);
|
||||
}
|
||||
else if(index == 3)
|
||||
{
|
||||
client->addr = (DP501_P3_ADDR>>1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev_err(&client->dev,"invalid page number\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
ret = i2c_master_reg8_recv(client, reg, &val, 1, DP501_SCL_RATE);
|
||||
if(ret < 0)
|
||||
{
|
||||
dev_err(&client->dev,"%s page%d:0x%x err\n",__func__,index,reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
static int get_dp_chip_id(struct i2c_client *client)
|
||||
{
|
||||
char c1,c2;
|
||||
int id;
|
||||
c1 = dp501_read_reg(client,2,CHIP_ID_L);
|
||||
c2 = dp501_read_reg(client,2,CHIP_ID_H);
|
||||
id = c2;
|
||||
return (id<<8)|c1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dp501_init(struct i2c_client *client)
|
||||
{
|
||||
char val,val1;
|
||||
|
||||
dp501_write_reg(client,2,0x00,0x6C);
|
||||
dp501_write_reg(client,2,0x01,0x68);
|
||||
dp501_write_reg(client,2,0x02,0x28);
|
||||
dp501_write_reg(client,2,0x03,0x2A);
|
||||
dp501_write_reg(client,2,0x16,0x50);
|
||||
dp501_write_reg(client,2,0x24,0x22);
|
||||
dp501_write_reg(client,2,0x25,0x04);
|
||||
dp501_write_reg(client,2,0x26,0x10); //PIO setting
|
||||
|
||||
dp501_write_reg(client,0,0x0a,0x0c); //block 74 & 76
|
||||
dp501_write_reg(client,0,0x20,0x00);
|
||||
dp501_write_reg(client,0,0x27,0x30); //auto detect CRTC
|
||||
dp501_write_reg(client,0,0x2f,0x82); //reset tpfifo at v blank
|
||||
dp501_write_reg(client,0,0x24,0xc0); //DVO mapping ; crtc follow mode
|
||||
dp501_write_reg(client,0,0x28,0x07); //crtc follow mode
|
||||
dp501_write_reg(client,0,0x87,0x7f); //aux retry
|
||||
dp501_write_reg(client,0,0x88,0x1e); //aux retry
|
||||
dp501_write_reg(client,0,0xbb,0x06); //aux retry
|
||||
dp501_write_reg(client,0,0x72,0xa9); //DPCD readable
|
||||
dp501_write_reg(client,0,0x60,0x00); //Scramble on
|
||||
dp501_write_reg(client,0,0x8f,0x02); //debug select, read P0.0x8d[2] can check HPD
|
||||
|
||||
|
||||
//second, set up training
|
||||
dp501_write_reg(client,0,0x5d,0x06); //training link rate(2.7Gbps)
|
||||
dp501_write_reg(client,0,0x5e,0x84); //training lane count(4Lanes),
|
||||
dp501_write_reg(client,0,0x74,0x00); //idle pattern
|
||||
dp501_write_reg(client,0,0x5f,0x0d); //trigger training
|
||||
mdelay(100); //delay 100ms
|
||||
|
||||
//then, check training result
|
||||
val = dp501_read_reg(client,0,0x63);
|
||||
val1 = dp501_read_reg(client,0,0x64); //Each 4bits stand for one lane, 0x77/0x77 means training succeed with 4Lanes.
|
||||
dev_info(&client->dev,"training result:>>val:0x%x>>val1:0x%x\n",val,val1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int edp_reg_show(struct seq_file *s, void *v)
|
||||
{
|
||||
int i = 0;
|
||||
char val;
|
||||
struct dp501 *dp501= s->private;
|
||||
|
||||
seq_printf(s,"page 0:\n");
|
||||
for(i=0;i< MAX_REG;i++)
|
||||
{
|
||||
val = dp501_read_reg(dp501->client,0,i);
|
||||
seq_printf(s,"0x%02x>>0x%02x\n",i,val);
|
||||
}
|
||||
|
||||
seq_printf(s,"page 1:\n");
|
||||
for(i=0;i< MAX_REG;i++)
|
||||
{
|
||||
val = dp501_read_reg(dp501->client,1,i);
|
||||
seq_printf(s,"0x%02x>>0x%02x\n",i,val);
|
||||
}
|
||||
|
||||
seq_printf(s,"page 2:\n");
|
||||
for(i=0;i< MAX_REG;i++)
|
||||
{
|
||||
val = dp501_read_reg(dp501->client,0,i);
|
||||
seq_printf(s,"0x%02x>>0x%02x\n",2,val);
|
||||
}
|
||||
|
||||
seq_printf(s,"page 3:\n");
|
||||
for(i=0;i< MAX_REG;i++)
|
||||
{
|
||||
val = dp501_read_reg(dp501->client,3,i);
|
||||
seq_printf(s,"0x%02x>>0x%02x\n",i,val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int edp_reg_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dp501 *dp501 = inode->i_private;
|
||||
return single_open(file,edp_reg_show,dp501);
|
||||
}
|
||||
|
||||
static const struct file_operations edp_reg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = edp_reg_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void dp501_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct dp501 *dp501 = container_of(h, struct dp501, early_suspend);
|
||||
gpio_set_value(dp501->pdata->dvdd33_en_pin,!dp501->pdata->dvdd33_en_val);
|
||||
gpio_set_value(dp501->pdata->dvdd18_en_pin,!dp501->pdata->dvdd18_en_val);
|
||||
|
||||
}
|
||||
|
||||
static void dp501_late_resume(struct early_suspend *h)
|
||||
{
|
||||
struct dp501 *dp501 = container_of(h, struct dp501, early_suspend);
|
||||
gpio_set_value(dp501->pdata->dvdd33_en_pin,dp501->pdata->dvdd33_en_val);
|
||||
gpio_set_value(dp501->pdata->dvdd18_en_pin,dp501->pdata->dvdd18_en_val);
|
||||
gpio_set_value(dp501->pdata->edp_rst_pin,0);
|
||||
msleep(10);
|
||||
gpio_set_value(dp501->pdata->edp_rst_pin,1);
|
||||
dp501->edp_init(dp501->client);
|
||||
}
|
||||
#endif
|
||||
static int dp501_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
struct dp501 *dp501 = NULL;
|
||||
int chip_id;
|
||||
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
{
|
||||
dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
|
||||
ret = -ENODEV;
|
||||
}
|
||||
dp501 = kzalloc(sizeof(struct dp501), GFP_KERNEL);
|
||||
if (dp501 == NULL)
|
||||
{
|
||||
dev_err(&client->dev,"alloc for struct dp501 fail\n");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
dp501->client = client;
|
||||
dp501->pdata = client->dev.platform_data;
|
||||
i2c_set_clientdata(client,dp501);
|
||||
if(dp501->pdata->power_ctl)
|
||||
dp501->pdata->power_ctl();
|
||||
|
||||
debugfs_create_file("edp-reg", S_IRUSR,NULL,dp501,&edp_reg_fops);
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
dp501->early_suspend.suspend = dp501_early_suspend;
|
||||
dp501->early_suspend.resume = dp501_late_resume;
|
||||
dp501->early_suspend.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING;
|
||||
register_early_suspend(&dp501->early_suspend);
|
||||
#endif
|
||||
|
||||
chip_id = get_dp_chip_id(client);
|
||||
dp501->edp_init = dp501_init;
|
||||
dp501->edp_init(client);
|
||||
|
||||
|
||||
printk("edp dp%x probe ok\n",chip_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit dp501_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct i2c_device_id id_table[] = {
|
||||
{"dp501", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver dp501_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "dp501",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = &dp501_i2c_probe,
|
||||
.remove = &dp501_i2c_remove,
|
||||
.id_table = id_table,
|
||||
};
|
||||
|
||||
|
||||
static int __init dp501_module_init(void)
|
||||
{
|
||||
return i2c_add_driver(&dp501_i2c_driver);
|
||||
}
|
||||
|
||||
static void __exit dp501_module_exit(void)
|
||||
{
|
||||
i2c_del_driver(&dp501_i2c_driver);
|
||||
}
|
||||
|
||||
fs_initcall_sync(dp501_module_init);
|
||||
module_exit(dp501_module_exit);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,136 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DPCD_EDID_H
|
||||
#define __DPCD_EDID_H
|
||||
#include "../../fbdev/edid.h"
|
||||
|
||||
#define DPCD_REV 0x00
|
||||
#define DPCD_MAX_LINK_RATE 0x01
|
||||
#define DPCD_MAX_LANE_CNT 0x02
|
||||
|
||||
#define DPCD_MAX_DOWNSPREAD 0x03
|
||||
#define DPCD_NORP 0x04
|
||||
#define DPCD_DOWNSTREAMPORT_PRESENT 0x05
|
||||
|
||||
#define DPCD_RECEIVE_PORT0_CAP_0 0x08
|
||||
#define DPCD_RECEIVE_PORT0_CAP_1 0x09
|
||||
#define DPCD_RECEIVE_PORT0_CAP_2 0x0a
|
||||
#define DPCD_RECEIVE_PORT0_CAP_3 0x0b
|
||||
|
||||
#define DPCD_LINK_BW_SET 0x100
|
||||
#define DPCD_LANE_CNT_SET 0x101
|
||||
#define DPCD_TRAINING_PATTERN_SET 0x102
|
||||
#define DPCD_TRAINING_LANE0_SET 0x103
|
||||
#define DPCD_TRAINING_LANE1_SET 0x104
|
||||
#define DPCD_TRAINING_LANE2_SET 0x105
|
||||
#define DPCD_TRAINING_LANE3_SET 0x106
|
||||
#define DPCD_DOWNSPREAD_CTRL 0x107
|
||||
|
||||
#define DPCD_SINK_COUNT 0x200
|
||||
#define DPCD_DEVICE_SERVICE_IRQ_VECTOR 0x201
|
||||
#define DPCD_LANE0_1_STATUS 0x202
|
||||
#define DPCD_LANE2_3_STATUS 0x203
|
||||
#define DPCD_LANE_ALIGN_STATUS_UPDATED 0x204
|
||||
#define DPCD_SINK_STATUS 0x205
|
||||
#define DPCD_ADJUST_REQUEST_LANE0_1 0x206
|
||||
#define DPCD_ADJUST_REQUEST_LANE2_3 0x207
|
||||
#define DPCD_TRAINING_SCORE_LANE0 0x208
|
||||
#define DPCD_TRAINING_SCORE_LANE1 0x209
|
||||
#define DPCD_TRAINING_SCORE_LANE2 0x20a
|
||||
#define DPCD_TRAINING_SCORE_LANE3 0x20b
|
||||
#define DPCD_SYMBOL_ERR_CONUT_LANE0 0x210
|
||||
#define DPCD_SINK_POWER_STATE 0x0600
|
||||
|
||||
/* DPCD_ADDR_MAX_LANE_COUNT */
|
||||
#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
|
||||
#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
|
||||
|
||||
/* DPCD_ADDR_LANE_COUNT_SET */
|
||||
#define DPCD_ENHANCED_FRAME_EN (0x1 << 7)
|
||||
#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
|
||||
|
||||
/* DPCD_ADDR_TRAINING_PATTERN_SET */
|
||||
#define DPCD_SCRAMBLING_DISABLED (0x1 << 5)
|
||||
#define DPCD_SCRAMBLING_ENABLED (0x0 << 5)
|
||||
#define DPCD_TRAINING_PATTERN_2 (0x2 << 0)
|
||||
#define DPCD_TRAINING_PATTERN_1 (0x1 << 0)
|
||||
#define DPCD_TRAINING_PATTERN_DISABLED (0x0 << 0)
|
||||
|
||||
/* DPCD_ADDR_TRAINING_LANE0_SET */
|
||||
#define DPCD_MAX_PRE_EMPHASIS_REACHED (0x1 << 5)
|
||||
#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
|
||||
#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
|
||||
#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 (0x0 << 3)
|
||||
#define DPCD_MAX_SWING_REACHED (0x1 << 2)
|
||||
#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
|
||||
#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
|
||||
#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0 (0x0 << 0)
|
||||
|
||||
/* DPCD_ADDR_LANE0_1_STATUS */
|
||||
#define DPCD_LANE_SYMBOL_LOCKED (0x1 << 2)
|
||||
#define DPCD_LANE_CHANNEL_EQ_DONE (0x1 << 1)
|
||||
#define DPCD_LANE_CR_DONE (0x1 << 0)
|
||||
#define DPCD_CHANNEL_EQ_BITS (DPCD_LANE_CR_DONE| \
|
||||
DPCD_LANE_CHANNEL_EQ_DONE|\
|
||||
DPCD_LANE_SYMBOL_LOCKED)
|
||||
|
||||
#define DPCD_TEST_REQUEST 0x218
|
||||
#define DPCD_TEST_LINK_RATE 0x219
|
||||
|
||||
#define DPCD_TEST_LANE_COUNT 0x220
|
||||
#define DPCD_TEST_RESPONSE 0x260
|
||||
#define DPCD_TEST_EDID_CHECKSUM 0x261
|
||||
#define TEST_ACK 0x01
|
||||
#define DPCD_TEST_EDID_Checksum_Write 0x04//bit position
|
||||
|
||||
#define DPCD_TEST_EDID_Checksum 0x261
|
||||
|
||||
|
||||
#define DPCD_SPECIFIC_INTERRUPT 0x10
|
||||
#define DPCD_USER_COMM1 0x22//define for downstream HDMI Rx sense detection
|
||||
|
||||
#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff)
|
||||
#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff)
|
||||
#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f)
|
||||
|
||||
#define AUX_RX_COMM_I2C_DEFER (0x2 << 2)
|
||||
#define AUX_RX_COMM_AUX_DEFER (0x2 << 0)
|
||||
|
||||
/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */
|
||||
#define DPCD_LINK_STATUS_UPDATED (0x1 << 7)
|
||||
#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED (0x1 << 6)
|
||||
#define DPCD_INTERLANE_ALIGN_DONE (0x1 << 0)
|
||||
|
||||
/* DPCD_ADDR_TEST_REQUEST */
|
||||
#define DPCD_TEST_EDID_READ (0x1 << 2)
|
||||
|
||||
/* DPCD_ADDR_TEST_RESPONSE */
|
||||
#define DPCD_TEST_EDID_CHECKSUM_WRITE (0x1 << 2)
|
||||
|
||||
/* DPCD_ADDR_SINK_POWER_STATE */
|
||||
#define DPCD_SET_POWER_STATE_D0 (0x1 << 0)
|
||||
#define DPCD_SET_POWER_STATE_D4 (0x2 << 0)
|
||||
|
||||
|
||||
/*
|
||||
* EDID device address is 0x50.
|
||||
* However, if necessary, you must have set upper address
|
||||
* into E-EDID in I2C device, 0x30.
|
||||
*/
|
||||
|
||||
#define EDID_ADDR 0x50
|
||||
#define E_EDID_ADDR 0x30
|
||||
#define EDID_EXTENSION_FLAG 0x7e
|
||||
#define EDID_CHECKSUM 0x7f
|
||||
|
||||
static unsigned char inline edp_calc_edid_check_sum(unsigned char *edid_data)
|
||||
{
|
||||
int i;
|
||||
unsigned char sum = 0;
|
||||
|
||||
for (i = 0; i < EDID_LENGTH; i++)
|
||||
sum = sum + edid_data[i];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 ROCKCHIP, Inc.
|
||||
* drivers/video/display/transmitter/mipi_dsi.c
|
||||
* author: hhb@rock-chips.com
|
||||
* create date: 2013-01-17
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#ifndef CONFIG_MIPI_DSI
|
||||
#include <common.h>
|
||||
#endif
|
||||
#ifdef CONFIG_RK_3288_DSI_UBOOT
|
||||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/rkplat.h>
|
||||
#include <lcd.h>
|
||||
#include "mipi_dsi.h"
|
||||
#else
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
/* #include <asm/system.h> */
|
||||
#include <linux/fb.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include <linux/rk_screen.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
#include "mipi_dsi.h"
|
||||
#endif
|
||||
|
||||
#define MAX_DSI_CHIPS 5
|
||||
|
||||
/*
|
||||
* Driver Version Note
|
||||
*
|
||||
*v1.0 : this driver is a top level architecture of mipi dsi driver;
|
||||
*v1.1 : add struct mipi_dsi_screen
|
||||
*v1.2 : add id argument to identify different dsi
|
||||
*v1.3 : fix send commad's methods
|
||||
*/
|
||||
#define MIPI_DSI_VERSION_AND_TIME "mipi_dsi v1.3 2014-04-17"
|
||||
#ifdef CONFIG_RK_3288_DSI_UBOOT
|
||||
#define printk(x...) printf(x)
|
||||
#endif
|
||||
|
||||
|
||||
static struct mipi_dsi_ops *dsi_ops[MAX_DSI_CHIPS] = {NULL};
|
||||
//static struct mipi_dsi_ops *cur_dsi_ops;
|
||||
|
||||
int register_dsi_ops(unsigned int id, struct mipi_dsi_ops *ops) {
|
||||
|
||||
//int i = 0;
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
dsi_ops[id] = ops;
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(register_dsi_ops);
|
||||
#endif
|
||||
|
||||
int del_dsi_ops(struct mipi_dsi_ops *ops) {
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < MAX_DSI_CHIPS; i++) {
|
||||
if(dsi_ops[i] == ops) {
|
||||
dsi_ops[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == MAX_DSI_CHIPS) {
|
||||
printk("dsi ops not found\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(del_dsi_ops);
|
||||
#endif
|
||||
|
||||
int dsi_probe_current_chip(unsigned int id) {
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
id = ops->get_id(ops->dsi);
|
||||
|
||||
return id;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_probe_current_chip);
|
||||
#endif
|
||||
int dsi_power_up(unsigned int id) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
if(ops->power_up)
|
||||
ops->power_up(ops->dsi);
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_power_up);
|
||||
#endif
|
||||
|
||||
int dsi_power_off(unsigned int id) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->power_down)
|
||||
ops->power_down(ops->dsi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_power_off);
|
||||
#endif
|
||||
int dsi_set_regs(unsigned int id, void *array, u32 n) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_set_regs)
|
||||
ops->dsi_set_regs(ops->dsi, array, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_set_regs);
|
||||
#endif
|
||||
int dsi_init(unsigned int id, u32 n) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_init)
|
||||
ops->dsi_init(ops->dsi, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_init);
|
||||
#endif
|
||||
int dsi_enable_video_mode(unsigned int id, u32 enable) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_enable_video_mode)
|
||||
ops->dsi_enable_video_mode(ops->dsi, enable);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_enable_video_mode);
|
||||
#endif
|
||||
int dsi_enable_command_mode(unsigned int id, u32 enable) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_enable_command_mode)
|
||||
ops->dsi_enable_command_mode(ops->dsi, enable);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_enable_command_mode);
|
||||
#endif
|
||||
int dsi_enable_hs_clk(unsigned int id, u32 enable) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_enable_hs_clk)
|
||||
ops->dsi_enable_hs_clk(ops->dsi, enable);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_enable_hs_clk);
|
||||
#endif
|
||||
int dsi_is_active(unsigned int id) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_is_active)
|
||||
return ops->dsi_is_active(ops->dsi);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_is_active);
|
||||
#endif
|
||||
int dsi_is_enable(unsigned int id, u32 enable){
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_is_enable)
|
||||
ops->dsi_is_enable(ops->dsi, enable);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_is_enable);
|
||||
#endif
|
||||
int dsi_send_dcs_packet(unsigned int id, unsigned char *packet, u32 n) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
//printk("dsi_send_dcs_packet-------id=%d\n",id);
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_send_dcs_packet)
|
||||
ops->dsi_send_dcs_packet(ops->dsi, packet, n);
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_send_dcs_packet);
|
||||
#endif
|
||||
|
||||
int dsi_read_dcs_packet(unsigned int id, unsigned char *packet, u32 n) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_read_dcs_packet)
|
||||
ops->dsi_read_dcs_packet(ops->dsi, packet, n);
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_read_dcs_packet);
|
||||
#endif
|
||||
|
||||
int dsi_send_packet(unsigned int id, unsigned char *packet, u32 n) {
|
||||
|
||||
struct mipi_dsi_ops *ops = NULL;
|
||||
|
||||
if(id > (MAX_DSI_CHIPS - 1))
|
||||
return -EINVAL;
|
||||
|
||||
ops = dsi_ops[id];
|
||||
|
||||
if(!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(ops->dsi_send_packet)
|
||||
ops->dsi_send_packet(ops->dsi, packet, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_MIPI_DSI
|
||||
EXPORT_SYMBOL(dsi_send_packet);
|
||||
#endif
|
||||
@@ -1,308 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
drivers/video/rockchip/transmitter/mipi_dsi.h
|
||||
*/
|
||||
#ifndef MIPI_DSI_H_
|
||||
#define MIPI_DSI_H_
|
||||
|
||||
#ifdef CONFIG_MIPI_DSI_FT
|
||||
#include "..\..\common\config.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#endif
|
||||
#ifdef CONFIG_RK_3288_DSI_UBOOT
|
||||
#include <linux/list.h>
|
||||
#endif
|
||||
|
||||
|
||||
//DSI DATA TYPE
|
||||
#define DTYPE_DCS_SWRITE_0P 0x05
|
||||
#define DTYPE_DCS_SWRITE_1P 0x15
|
||||
#define DTYPE_DCS_LWRITE 0x39
|
||||
#define DTYPE_GEN_LWRITE 0x29
|
||||
#define DTYPE_GEN_SWRITE_2P 0x23
|
||||
#define DTYPE_GEN_SWRITE_1P 0x13
|
||||
#define DTYPE_GEN_SWRITE_0P 0x03
|
||||
|
||||
//command transmit mode
|
||||
#define HSDT 0x00
|
||||
#define LPDT 0x01
|
||||
|
||||
//DSI DATA TYPE FLAG
|
||||
#define DATA_TYPE_DCS 0x00
|
||||
#define DATA_TYPE_GEN 0x01
|
||||
|
||||
|
||||
//Video Mode
|
||||
#define VM_NBMWSP 0x00 //Non burst mode with sync pulses
|
||||
#define VM_NBMWSE 0x01 //Non burst mode with sync events
|
||||
#define VM_BM 0x02 //Burst mode
|
||||
|
||||
//Video Pixel Format
|
||||
#define VPF_16BPP 0x00
|
||||
#define VPF_18BPP 0x01 //packed
|
||||
#define VPF_18BPPL 0x02 //loosely packed
|
||||
#define VPF_24BPP 0x03
|
||||
|
||||
//Display Command Set
|
||||
#define dcs_enter_idle_mode 0x39
|
||||
#define dcs_enter_invert_mode 0x21
|
||||
#define dcs_enter_normal_mode 0x13
|
||||
#define dcs_enter_partial_mode 0x12
|
||||
#define dcs_enter_sleep_mode 0x10
|
||||
#define dcs_exit_idle_mode 0x38
|
||||
#define dcs_exit_invert_mode 0x20
|
||||
#define dcs_exit_sleep_mode 0x11
|
||||
#define dcs_get_address_mode 0x0b
|
||||
#define dcs_get_blue_channel 0x08
|
||||
#define dcs_get_diagnostic_result 0x0f
|
||||
#define dcs_get_display_mode 0x0d
|
||||
#define dcs_get_green_channel 0x07
|
||||
#define dcs_get_pixel_format 0x0c
|
||||
#define dcs_get_power_mode 0x0a
|
||||
#define dcs_get_red_channel 0x06
|
||||
#define dcs_get_scanline 0x45
|
||||
#define dcs_get_signal_mode 0x0e
|
||||
#define dcs_nop 0x00
|
||||
#define dcs_read_DDB_continue 0xa8
|
||||
#define dcs_read_DDB_start 0xa1
|
||||
#define dcs_read_memory_continue 0x3e
|
||||
#define dcs_read_memory_start 0x2e
|
||||
#define dcs_set_address_mode 0x36
|
||||
#define dcs_set_column_address 0x2a
|
||||
#define dcs_set_display_off 0x28
|
||||
#define dcs_set_display_on 0x29
|
||||
#define dcs_set_gamma_curve 0x26
|
||||
#define dcs_set_page_address 0x2b
|
||||
#define dcs_set_partial_area 0x30
|
||||
#define dcs_set_pixel_format 0x3a
|
||||
#define dcs_set_scroll_area 0x33
|
||||
#define dcs_set_scroll_start 0x37
|
||||
#define dcs_set_tear_off 0x34
|
||||
#define dcs_set_tear_on 0x35
|
||||
#define dcs_set_tear_scanline 0x44
|
||||
#define dcs_soft_reset 0x01
|
||||
#define dcs_write_LUT 0x2d
|
||||
#define dcs_write_memory_continue 0x3c
|
||||
#define dcs_write_memory_start 0x2c
|
||||
|
||||
#ifndef MHz
|
||||
#define MHz 1000000
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
typedef signed char s8;
|
||||
typedef unsigned char u8;
|
||||
|
||||
typedef signed short s16;
|
||||
typedef unsigned short u16;
|
||||
|
||||
typedef signed int s32;
|
||||
typedef unsigned int u32;
|
||||
|
||||
typedef signed long s64;
|
||||
typedef unsigned long u64;
|
||||
#endif
|
||||
|
||||
|
||||
//iomux
|
||||
#define OLD_RK_IOMUX 0
|
||||
|
||||
struct spi_t {
|
||||
u32 cs;
|
||||
#if OLD_RK_IOMUX
|
||||
char* cs_mux_name;
|
||||
#endif
|
||||
int sck;
|
||||
#if OLD_RK_IOMUX
|
||||
char* sck_mux_name;
|
||||
#endif
|
||||
int miso;
|
||||
#if OLD_RK_IOMUX
|
||||
char* miso_mux_name;
|
||||
#endif
|
||||
int mosi;
|
||||
#if OLD_RK_IOMUX
|
||||
char* mosi_mux_name;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct power_t {
|
||||
int enable_pin; //gpio that control power
|
||||
#if OLD_RK_IOMUX
|
||||
char* mux_name;
|
||||
u32 mux_mode;
|
||||
#endif
|
||||
u32 effect_value;
|
||||
|
||||
char *name;
|
||||
u32 voltage;
|
||||
int (*enable)(void *);
|
||||
int (*disable)(void *);
|
||||
};
|
||||
|
||||
struct reset_t {
|
||||
int reset_pin; //gpio that control reset
|
||||
#if OLD_RK_IOMUX
|
||||
char* mux_name;
|
||||
u32 mux_mode;
|
||||
#endif
|
||||
u32 effect_value;
|
||||
|
||||
u32 time_before_reset; //ms
|
||||
u32 time_after_reset;
|
||||
|
||||
int (*do_reset)(void *);
|
||||
};
|
||||
|
||||
struct tc358768_t {
|
||||
u32 id;
|
||||
struct reset_t reset;
|
||||
struct power_t vddc;
|
||||
struct power_t vddio;
|
||||
struct power_t vdd_mipi;
|
||||
struct i2c_client *client;
|
||||
int (*gpio_init)(void *);
|
||||
int (*gpio_deinit)(void *);
|
||||
int (*power_up)(void);
|
||||
int (*power_down)(void);
|
||||
};
|
||||
|
||||
|
||||
struct ssd2828_t {
|
||||
u32 id;
|
||||
struct reset_t reset;
|
||||
struct power_t shut;
|
||||
struct power_t vddio;
|
||||
struct power_t vdd_mipi;
|
||||
|
||||
struct spi_t spi;
|
||||
int (*gpio_init)(void *);
|
||||
int (*gpio_deinit)(void *);
|
||||
int (*power_up)(void);
|
||||
int (*power_down)(void);
|
||||
};
|
||||
|
||||
struct mipi_dsi_ops {
|
||||
u32 id;
|
||||
char name[32];
|
||||
void *dsi;
|
||||
int (*get_id)(void *);
|
||||
int (*dsi_init)(void *, u32 n);
|
||||
int (*dsi_set_regs)(void *, void *, u32 n);
|
||||
int (*dsi_enable_video_mode)(void *, u32 enable);
|
||||
int (*dsi_enable_command_mode)(void *, u32 enable);
|
||||
int (*dsi_enable_hs_clk)(void *, u32 enable);
|
||||
int (*dsi_send_dcs_packet)(void *, unsigned char *, u32 n);
|
||||
int (*dsi_read_dcs_packet)(void *, unsigned char *, u32 n);
|
||||
int (*dsi_send_packet)(void *, unsigned char *, u32 n);
|
||||
int (*dsi_is_enable)(void *, u32 enable);
|
||||
int (*dsi_is_active)(void *);
|
||||
int (*power_up)(void *);
|
||||
int (*power_down)(void *);
|
||||
};
|
||||
|
||||
/* Screen description */
|
||||
struct mipi_dsi_screen {
|
||||
|
||||
u16 type;
|
||||
u16 face;
|
||||
u8 lcdc_id;
|
||||
u8 screen_id;
|
||||
|
||||
/* Timing */
|
||||
u32 pixclock;
|
||||
u16 left_margin;
|
||||
u16 right_margin;
|
||||
u16 hsync_len;
|
||||
u16 upper_margin;
|
||||
u16 lower_margin;
|
||||
u16 vsync_len;
|
||||
|
||||
/* Screen size */
|
||||
u16 x_res;
|
||||
u16 y_res;
|
||||
u16 width;
|
||||
u16 height;
|
||||
/* Pin polarity */
|
||||
u8 pin_hsync;
|
||||
u8 pin_vsync;
|
||||
u8 pin_den;
|
||||
u8 pin_dclk;
|
||||
|
||||
/* MIPI DSI */
|
||||
u8 dsi_lane;
|
||||
u16 refresh_mode;
|
||||
u32 hs_tx_clk;
|
||||
struct rk_screen *screen;
|
||||
|
||||
/* Operation function*/
|
||||
int (*init)(void);
|
||||
int (*standby)(u8 enable);
|
||||
|
||||
};
|
||||
|
||||
#define INVALID_GPIO -1
|
||||
|
||||
struct dcs_cmd {
|
||||
u8 type;
|
||||
u8 dtype;
|
||||
u8 dsi_id;
|
||||
u8 cmd_len;
|
||||
int *cmds;
|
||||
int delay;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
struct mipi_dcs_cmd_ctr_list {
|
||||
struct list_head list;
|
||||
struct dcs_cmd dcs_cmd;
|
||||
};
|
||||
|
||||
enum {
|
||||
VIDEO_MODE = 0,
|
||||
COMMAND_MODE,
|
||||
};
|
||||
|
||||
struct mipi_screen
|
||||
{
|
||||
u8 screen_init;
|
||||
u8 mipi_dsi_num;
|
||||
u8 lcd_rst_atv_val;
|
||||
u8 lcd_en_atv_val;
|
||||
u8 dsi_lane;
|
||||
u8 dsi_operate_mode;
|
||||
u32 hs_tx_clk;
|
||||
u32 lcd_en_gpio;
|
||||
u32 lcd_en_delay;
|
||||
u32 lcd_rst_gpio;
|
||||
u32 lcd_rst_delay;
|
||||
|
||||
struct list_head cmdlist_head;
|
||||
};
|
||||
|
||||
int register_dsi_ops(unsigned int id, struct mipi_dsi_ops *ops);
|
||||
int del_dsi_ops(struct mipi_dsi_ops *ops);
|
||||
int dsi_power_up(unsigned int id);
|
||||
int dsi_power_off(unsigned int id);
|
||||
int dsi_probe_current_chip(unsigned int id);
|
||||
int dsi_init(unsigned int id, u32 n);
|
||||
int dsi_is_active(unsigned int id);
|
||||
int dsi_enable_video_mode(unsigned int id, u32 enable);
|
||||
int dsi_enable_command_mode(unsigned int id, u32 enable);
|
||||
int dsi_enable_hs_clk(unsigned int id, u32 enable);
|
||||
int dsi_set_virtual_channel(unsigned int id, u32 channel);
|
||||
|
||||
int dsi_set_regs(unsigned int id, void *array, u32 n);
|
||||
int dsi_send_dcs_packet(unsigned int id, unsigned char *packet, u32 n);
|
||||
int dsi_read_dcs_packet(unsigned int id, unsigned char *packet, u32 n);
|
||||
int dsi_send_packet(unsigned int id, unsigned char *packet, u32 n);
|
||||
int dsi_is_enable(unsigned int id, u32 enable);
|
||||
|
||||
#endif /* end of MIPI_DSI_H_ */
|
||||
@@ -1,64 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/io.h>
|
||||
#include <linux/rk_screen.h>
|
||||
#include "rk2928_lvds.h"
|
||||
|
||||
static void rk_output_lvds(rk_screen *screen)
|
||||
{
|
||||
LVDSWrReg(m_PDN_CBG(1)|m_PD_PLL(0)|m_PDN(1)|m_OEN(0) \
|
||||
|m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB) \
|
||||
|m_OUT_FORMAT(screen->lvds_format) \
|
||||
|m_LCDC_SEL(screen->lcdc_id));
|
||||
|
||||
printk("%s>>connect to lcdc output interface%d\n",__func__,screen->lcdc_id);
|
||||
}
|
||||
|
||||
static void rk_output_lvttl(rk_screen *screen)
|
||||
{
|
||||
LVDSWrReg(m_PDN_CBG(0)|m_PD_PLL(1)|m_PDN(0)|m_OEN(1) \
|
||||
|m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB) \
|
||||
|m_OUT_FORMAT(screen->lvds_format) \
|
||||
|m_LCDC_SEL(screen->lcdc_id));
|
||||
printk("%s>>connect to lcdc output interface%d\n",__func__,screen->lcdc_id);
|
||||
}
|
||||
|
||||
static void rk_output_disable(void)
|
||||
{
|
||||
LVDSWrReg(m_PDN_CBG(0)|m_PD_PLL(1)|m_PDN(0)|m_OEN(0));
|
||||
printk("%s: reg = 0x%x\n", __func__, LVDSRdReg());
|
||||
}
|
||||
|
||||
static int rk_lvds_set_param(rk_screen *screen,bool enable )
|
||||
{
|
||||
if(OUT_ENABLE == enable){
|
||||
switch(screen->type){
|
||||
case SCREEN_LVDS:
|
||||
rk_output_lvds(screen);
|
||||
|
||||
break;
|
||||
case SCREEN_RGB:
|
||||
rk_output_lvttl(screen);
|
||||
break;
|
||||
default:
|
||||
printk("%s>>>>LVDS not support this screen type %d,power down LVDS\n",__func__,screen->type);
|
||||
rk_output_disable();
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
rk_output_disable();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rk_lvds_register(rk_screen *screen)
|
||||
{
|
||||
if(screen->sscreen_set == NULL)
|
||||
screen->sscreen_set = rk_lvds_set_param;
|
||||
|
||||
rk_lvds_set_param(screen , OUT_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef RK_LVDS_H_
|
||||
#define RK_LVDS_H
|
||||
|
||||
#define LVDS_CON0_OFFSET 0x150
|
||||
#define LVDS_CON0_REG (RK2928_GRF_BASE + LVDS_CON0_OFFSET)
|
||||
|
||||
#define LVDSRdReg() __raw_readl(LVDS_CON0_REG)
|
||||
#define LVDSWrReg(val) __raw_writel( val ,LVDS_CON0_REG)
|
||||
|
||||
#define m_value(x,offset,mask) \
|
||||
((mask<<(offset+16)) | (x&mask)<<offset)
|
||||
|
||||
#define OEN (1<<9)
|
||||
#define m_OEN(x) m_value(x,9,1)
|
||||
#define PD_PLL (1<<8)
|
||||
#define m_PD_PLL(x) m_value(x,8,1)
|
||||
#define PDN_CBG (1<<7)
|
||||
#define m_PDN_CBG(x) m_value(x,7,1)
|
||||
#define PDN (1<<6)
|
||||
#define m_PDN(x) m_value(x,6,1)
|
||||
#define DS (3<<4)
|
||||
#define m_DS(x) m_value(x,4,3)
|
||||
#define MSBSEL (1<<3)
|
||||
#define m_MSBSEL(x) m_value(x,3,1)
|
||||
#define OUT_FORMAT (3<<1)
|
||||
#define m_OUT_FORMAT(x) m_value(x,1,3)
|
||||
#define LCDC_SEL (1<<0)
|
||||
#define m_LCDC_SEL(x) m_value(x,0,1)
|
||||
|
||||
enum{
|
||||
OUT_DISABLE=0,
|
||||
OUT_ENABLE,
|
||||
};
|
||||
|
||||
//DS
|
||||
#define DS_3PF 0
|
||||
#define DS_7PF 0
|
||||
#define DS_5PF 0
|
||||
#define DS_10PF 0
|
||||
|
||||
//LVDS lane input format
|
||||
#define DATA_D0_MSB 0
|
||||
#define DATA_D7_MSB 1
|
||||
//LVDS input source
|
||||
#define FROM_LCDC0 0
|
||||
#define FROM_LCDC1 1
|
||||
|
||||
extern int rk_lvds_register(rk_screen *screen);
|
||||
#endif
|
||||
@@ -1,147 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/io.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
#include "rk3026_lvds.h"
|
||||
|
||||
#define lvds_readl(offset) readl_relaxed(RK30_GRF_BASE + offset)
|
||||
#define lvds_writel(v,offset) do{ writel_relaxed(v, RK30_GRF_BASE + offset);dsb();} while (0)
|
||||
|
||||
static void rk3026_output_lvds(rk_screen *screen)
|
||||
{
|
||||
u32 val =0;
|
||||
|
||||
#if defined(CONFIG_LCDC0_RK3188)
|
||||
val |= LVDS_DATA_SEL(0);
|
||||
#else
|
||||
val |= LVDS_DATA_SEL(1);
|
||||
#endif
|
||||
|
||||
if(screen->lvds_format == 0 || screen->lvds_format == 1)
|
||||
val |= LVDS_CBS_COL_SEL(2); //24bit lvds
|
||||
else
|
||||
val |= LVDS_CBS_COL_SEL(1); //16bit lvds
|
||||
|
||||
val |= ((LVDS_OUTPUT_FORMAT(screen->lvds_format))|LVDS_INPUT_FORMAT(1)|LVDS_OUTPUT_LOAD_SEL(0)|
|
||||
LVDS_CBG_PWD_EN(1)|LVDS_PLL_PWD_EN(0)|LVDS_OUTPUT_EN(0)|LVDS_SWING_SEL(0));
|
||||
|
||||
val |= ((m_DATA_SEL|m_CBS_COL_SEL|m_OUTPUT_FORMAT|m_INPUT_FORMAT|m_OUTPUT_LOAD_SEL|
|
||||
m_CBG_PWD_EN|m_PLL_PWD_EN|m_OUTPUT_EN|m_SWING_SEL)<<16);
|
||||
|
||||
lvds_writel(val,CRU_LVDS_CON0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void rk3026_output_lvttl(rk_screen *screen)
|
||||
{
|
||||
|
||||
u32 val =0;
|
||||
|
||||
val |= (LVDS_CBG_PWD_EN(0)|LVDS_PLL_PWD_EN(1)|LVDS_OUTPUT_EN(1));
|
||||
val |= ((m_CBG_PWD_EN|m_PLL_PWD_EN|m_OUTPUT_EN)<<16);
|
||||
|
||||
lvds_writel(val,CRU_LVDS_CON0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void rk3026_output_disable(void)
|
||||
{
|
||||
|
||||
u32 val =0;
|
||||
|
||||
val |= (LVDS_CBG_PWD_EN(1)|LVDS_PLL_PWD_EN(0)|LVDS_OUTPUT_EN(0)|LVDS_CBS_COL_SEL(0));
|
||||
val |= ((m_CBG_PWD_EN|m_PLL_PWD_EN|m_OUTPUT_EN|m_CBS_COL_SEL)<<16);
|
||||
|
||||
lvds_writel(val,CRU_LVDS_CON0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int rk3026_lvds_set_param(rk_screen *screen,bool enable)
|
||||
{
|
||||
|
||||
if(OUT_ENABLE == enable){
|
||||
switch(screen->type){
|
||||
case SCREEN_LVDS:
|
||||
rk3026_output_lvds(screen);
|
||||
break;
|
||||
case SCREEN_RGB:
|
||||
rk3026_output_lvttl(screen);
|
||||
break;
|
||||
default:
|
||||
printk("%s>>>>LVDS not support this screen type %d,power down LVDS\n",__func__,screen->type);
|
||||
rk3026_output_disable();
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
rk3026_output_disable();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int rk3026_lvds_probe(struct platform_device *pdev)
|
||||
{
|
||||
rk_screen *screen = NULL;
|
||||
screen = rk_fb_get_prmry_screen();
|
||||
if(!screen)
|
||||
{
|
||||
dev_err(&pdev->dev,"the fb prmry screen is null!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rk3026_lvds_set_param(screen,OUT_ENABLE);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int rk3026_lvds_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk3026_lvds_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_driver rk3026_lvds_driver = {
|
||||
.driver = {
|
||||
.name = "rk3026-lvds",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = rk3026_lvds_probe,
|
||||
.remove = rk3026_lvds_remove,
|
||||
.shutdown = rk3026_lvds_shutdown,
|
||||
};
|
||||
|
||||
static int __init rk3026_lvds_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk3026_lvds_driver);
|
||||
}
|
||||
fs_initcall(rk3026_lvds_init);
|
||||
static void __exit rk3026_lvds_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk3026_lvds_driver);
|
||||
}
|
||||
module_exit(rk3026_lvds_exit);
|
||||
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include<linux/rk_screen.h>
|
||||
|
||||
|
||||
#define CRU_LVDS_CON0 0x0150
|
||||
#define LVDS_SWING_SEL(x) (((x)&1)<<12)//0:250mv-450mv;1:150mv-250mv
|
||||
#define LVDS_CBS_COL_SEL(x) (((x)&3)<<10)// 1:18-bit lvds 2:24-bit lvds; 3:all lvds power down
|
||||
#define LVDS_OUTPUT_EN(x) (((x)&1)<<9) //0:lvds; 1:lvttl
|
||||
#define LVDS_PLL_PWD_EN(x) (((x)&1)<<8) //0:enable; 1:disable
|
||||
#define LVDS_CBG_PWD_EN(x) (((x)&1)<<7) //0:disable; 1:enable
|
||||
#define LVDS_OUTPUT_LOAD_SEL(X) (((X)&3)<<4) //0:3pf; 1:6pf; 2:10pf; 3:15pf
|
||||
#define LVDS_INPUT_FORMAT(x) (((x)&1)<<3) //0:MSB is on D7; 1:MSB is on D0;
|
||||
#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<1) //0:LVDS_8BIT_1; 1:LVDS_8BIT_2; 2:LVDS_8BIT_3; 3:LVDS_6BIT
|
||||
#define LVDS_DATA_SEL(x) (((x)&1)<<0) //0:from lcdc; 1:from ebc;
|
||||
|
||||
|
||||
#define m_SWING_SEL (1<<12)
|
||||
#define m_CBS_COL_SEL (3<<10)
|
||||
#define m_OUTPUT_EN (1<<9)
|
||||
#define m_PLL_PWD_EN (1<<8)
|
||||
#define m_CBG_PWD_EN (1<<7)
|
||||
#define m_OUTPUT_LOAD_SEL (3<<4)
|
||||
#define m_INPUT_FORMAT (1<<3)
|
||||
#define m_OUTPUT_FORMAT (3<<1)
|
||||
#define m_DATA_SEL (1<<0)
|
||||
|
||||
|
||||
enum{
|
||||
OUT_DISABLE=0,
|
||||
OUT_ENABLE,
|
||||
};
|
||||
|
||||
@@ -1,544 +0,0 @@
|
||||
/*
|
||||
* drivers/video/rockchip/transmitter/rk31xx_lvds.c
|
||||
*
|
||||
* Copyright (C) 2014 ROCKCHIP, Inc.
|
||||
* Author: zhuangwenlong<zwl@rock-chips.com>
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rockchip/iomap.h>
|
||||
#include <linux/rockchip/grf.h>
|
||||
#include "rk31xx_lvds.h"
|
||||
|
||||
|
||||
#define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset)
|
||||
#define grf_writel(v,offset) \
|
||||
do { \
|
||||
writel_relaxed(v, RK_GRF_VIRT + offset); \
|
||||
dsb(sy); \
|
||||
} while (0)
|
||||
|
||||
|
||||
static struct rk_lvds_device *rk31xx_lvds;
|
||||
|
||||
static int rk31xx_lvds_clk_init(struct rk_lvds_device *lvds)
|
||||
{
|
||||
lvds->pclk = devm_clk_get(lvds->dev, "pclk_lvds");
|
||||
if (IS_ERR(lvds->pclk)) {
|
||||
dev_err(lvds->dev, "get pclk failed\n");
|
||||
return PTR_ERR(lvds->pclk);
|
||||
}
|
||||
|
||||
lvds->ctrl_pclk = devm_clk_get(lvds->dev, "pclk_lvds_ctl");
|
||||
if (IS_ERR(lvds->ctrl_pclk)) {
|
||||
dev_err(lvds->dev, "get ctrl pclk failed\n");
|
||||
return PTR_ERR(lvds->ctrl_pclk);
|
||||
}
|
||||
|
||||
if (lvds->data->soc_type == LVDS_SOC_RK312X) {
|
||||
lvds->ctrl_hclk = devm_clk_get(lvds->dev, "hclk_vio_h2p");
|
||||
if (IS_ERR(lvds->ctrl_hclk)) {
|
||||
dev_err(lvds->dev, "get ctrl hclk failed\n");
|
||||
return PTR_ERR(lvds->ctrl_hclk);
|
||||
}
|
||||
} else {
|
||||
lvds->pd = devm_clk_get(lvds->dev, "pd_lvds");
|
||||
if (IS_ERR(lvds->pd)) {
|
||||
dev_err(lvds->dev, "get pd_lvds failed\n");
|
||||
lvds->pd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk31xx_lvds_clk_enable(struct rk_lvds_device *lvds)
|
||||
{
|
||||
if (!lvds->clk_on) {
|
||||
clk_prepare_enable(lvds->pclk);
|
||||
clk_prepare_enable(lvds->ctrl_pclk);
|
||||
if (lvds->data->soc_type == LVDS_SOC_RK312X)
|
||||
clk_prepare_enable(lvds->ctrl_hclk);
|
||||
if (lvds->pd)
|
||||
clk_prepare_enable(lvds->pd);
|
||||
lvds->clk_on = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk31xx_lvds_clk_disable(struct rk_lvds_device *lvds)
|
||||
{
|
||||
if (lvds->clk_on) {
|
||||
clk_disable_unprepare(lvds->pclk);
|
||||
if (lvds->data->soc_type == LVDS_SOC_RK312X)
|
||||
clk_disable_unprepare(lvds->ctrl_hclk);
|
||||
if (lvds->pd)
|
||||
clk_disable_unprepare(lvds->pd);
|
||||
clk_disable_unprepare(lvds->ctrl_pclk);
|
||||
lvds->clk_on = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk31xx_lvds_pwr_on(void)
|
||||
{
|
||||
struct rk_lvds_device *lvds = rk31xx_lvds;
|
||||
|
||||
if (lvds->screen.type == SCREEN_LVDS) {
|
||||
/* set VOCM 900 mv and V-DIFF 350 mv */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REGE4, m_VOCM | m_DIFF_V,
|
||||
v_VOCM(0) | v_DIFF_V(2));
|
||||
|
||||
/* power up lvds pll and ldo */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REG1,
|
||||
m_SYNC_RST | m_LDO_PWR_DOWN | m_PLL_PWR_DOWN,
|
||||
v_SYNC_RST(0) | v_LDO_PWR_DOWN(0) | v_PLL_PWR_DOWN(0));
|
||||
|
||||
/* enable lvds lane and power on pll */
|
||||
lvds_writel(lvds, MIPIPHY_REGEB,
|
||||
v_LANE0_EN(1) | v_LANE1_EN(1) | v_LANE2_EN(1) |
|
||||
v_LANE3_EN(1) | v_LANECLK_EN(1) | v_PLL_PWR_OFF(0));
|
||||
|
||||
/* enable lvds */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REGE3,
|
||||
m_MIPI_EN | m_LVDS_EN | m_TTL_EN,
|
||||
v_MIPI_EN(0) | v_LVDS_EN(1) | v_TTL_EN(0));
|
||||
} else {
|
||||
lvds_msk_reg(lvds, MIPIPHY_REGE3,
|
||||
m_MIPI_EN | m_LVDS_EN | m_TTL_EN,
|
||||
v_MIPI_EN(0) | v_LVDS_EN(0) | v_TTL_EN(1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk31xx_lvds_pwr_off(void)
|
||||
{
|
||||
struct rk_lvds_device *lvds = rk31xx_lvds;
|
||||
|
||||
/* disable lvds lane and power off pll */
|
||||
lvds_writel(lvds, MIPIPHY_REGEB,
|
||||
v_LANE0_EN(0) | v_LANE1_EN(0) | v_LANE2_EN(0) |
|
||||
v_LANE3_EN(0) | v_LANECLK_EN(0) | v_PLL_PWR_OFF(1));
|
||||
|
||||
/* power down lvds pll and bandgap */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REG1,
|
||||
m_SYNC_RST | m_LDO_PWR_DOWN | m_PLL_PWR_DOWN,
|
||||
v_SYNC_RST(1) | v_LDO_PWR_DOWN(1) | v_PLL_PWR_DOWN(1));
|
||||
|
||||
/* disable lvds */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REGE3, m_LVDS_EN | m_TTL_EN,
|
||||
v_LVDS_EN(0) | v_TTL_EN(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk31xx_lvds_disable(void)
|
||||
{
|
||||
struct rk_lvds_device *lvds = rk31xx_lvds;
|
||||
u32 val;
|
||||
|
||||
if (unlikely(!lvds) || !lvds->sys_state)
|
||||
return 0;
|
||||
if (lvds->data->soc_type == LVDS_SOC_RK3368) {
|
||||
val = v_RK3368_LVDSMODE_EN(0) | v_RK3368_MIPIPHY_TTL_EN(0);
|
||||
lvds_grf_writel(lvds, RK3368_GRF_SOC_CON7_LVDS, val);
|
||||
} else {
|
||||
grf_writel(v_LVDSMODE_EN(0) | v_MIPIPHY_TTL_EN(0), RK312X_GRF_LVDS_CON0);
|
||||
}
|
||||
|
||||
rk31xx_lvds_pwr_off();
|
||||
rk31xx_lvds_clk_disable(lvds);
|
||||
|
||||
#if !defined(CONFIG_RK_FPGA)
|
||||
#ifdef CONFIG_PINCTRL
|
||||
if (lvds->screen.type == SCREEN_RGB) {
|
||||
if (lvds->dev->pins) {
|
||||
pinctrl_select_state(lvds->dev->pins->p,
|
||||
lvds->dev->pins->sleep_state);
|
||||
} else if (lvds->pins && !IS_ERR(lvds->pins->sleep_state)) {
|
||||
pinctrl_select_state(lvds->pins->p,
|
||||
lvds->pins->sleep_state);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
lvds->sys_state = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk31xx_output_lvds(struct rk_lvds_device *lvds,
|
||||
struct rk_screen *screen)
|
||||
{
|
||||
u32 val = 0;
|
||||
u32 delay_times = 20;
|
||||
|
||||
/* if LVDS transmitter source from VOP, vop_dclk need get invert
|
||||
* set iomux in dts pinctrl
|
||||
*/
|
||||
if ((lvds->data->soc_type == LVDS_SOC_RK3368) ||
|
||||
(lvds->data->soc_type == LVDS_SOC_RK3366)) {
|
||||
/* enable lvds mode */
|
||||
val |= v_RK3368_LVDSMODE_EN(1) | v_RK3368_MIPIPHY_TTL_EN(0);
|
||||
/* config data source */
|
||||
/*val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC); */
|
||||
/* config lvds_format */
|
||||
val |= v_RK3368_LVDS_OUTPUT_FORMAT(screen->lvds_format);
|
||||
/* LSB receive mode */
|
||||
val |= v_RK3368_LVDS_MSBSEL(LVDS_MSB_D7);
|
||||
val |= v_RK3368_MIPIPHY_LANE0_EN(1) |
|
||||
v_RK3368_MIPIDPI_FORCEX_EN(1);
|
||||
/*rk3368 RK3368_GRF_SOC_CON7 = 0X0041C*/
|
||||
/*grf_writel(val, 0x0041C);*/
|
||||
if (lvds->data->soc_type == LVDS_SOC_RK3368)
|
||||
lvds_grf_writel(lvds, RK3368_GRF_SOC_CON7_LVDS, val);
|
||||
else
|
||||
lvds_grf_writel(lvds, RK3366_GRF_SOC_CON5_LVDS, val);
|
||||
} else {
|
||||
/* enable lvds mode */
|
||||
val |= v_LVDSMODE_EN(1) | v_MIPIPHY_TTL_EN(0);
|
||||
/* config data source */
|
||||
val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC);
|
||||
/* config lvds_format */
|
||||
val |= v_LVDS_OUTPUT_FORMAT(screen->lvds_format);
|
||||
/* LSB receive mode */
|
||||
val |= v_LVDS_MSBSEL(LVDS_MSB_D7);
|
||||
val |= v_MIPIPHY_LANE0_EN(1) | v_MIPIDPI_FORCEX_EN(1);
|
||||
/*rk312x RK312X_GRF_LVDS_CON0 = 0X00150*/
|
||||
grf_writel(val, 0X00150);
|
||||
}
|
||||
/* digital internal disable */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REGE1, m_DIG_INTER_EN, v_DIG_INTER_EN(0));
|
||||
|
||||
/* set pll prediv and fbdiv */
|
||||
lvds_writel(lvds, MIPIPHY_REG3, v_PREDIV(2) | v_FBDIV_MSB(0));
|
||||
lvds_writel(lvds, MIPIPHY_REG4, v_FBDIV_LSB(28));
|
||||
|
||||
lvds_writel(lvds, MIPIPHY_REGE8, 0xfc);
|
||||
|
||||
/* set lvds mode and reset phy config */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REGE0,
|
||||
m_MSB_SEL | m_DIG_INTER_RST,
|
||||
v_MSB_SEL(1) | v_DIG_INTER_RST(1));
|
||||
|
||||
/* power on pll and enable lane */
|
||||
rk31xx_lvds_pwr_on();
|
||||
|
||||
/* delay for waitting pll lock on */
|
||||
while (delay_times--) {
|
||||
if (lvds_phy_lockon(lvds)) {
|
||||
msleep(1);
|
||||
break;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
/* digital internal enable */
|
||||
lvds_msk_reg(lvds, MIPIPHY_REGE1, m_DIG_INTER_EN, v_DIG_INTER_EN(1));
|
||||
|
||||
#if 0
|
||||
lvds_writel(lvds, MIPIPHY_REGE2, 0xa0); /* timing */
|
||||
lvds_writel(lvds, MIPIPHY_REGE7, 0xfc); /* phase */
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void rk31xx_output_lvttl(struct rk_lvds_device *lvds,
|
||||
struct rk_screen *screen)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if ((lvds->data->soc_type == LVDS_SOC_RK3368) ||
|
||||
(lvds->data->soc_type == LVDS_SOC_RK3366)) {
|
||||
/* iomux to lcdc */
|
||||
#ifdef CONFIG_PINCTRL
|
||||
if (lvds->pins && !IS_ERR(lvds->pins->default_state))
|
||||
pinctrl_select_state(lvds->pins->p,
|
||||
lvds->pins->default_state);
|
||||
#endif
|
||||
lvds_dsi_writel(lvds, 0x0, 0x4);/*set clock lane enable*/
|
||||
/* enable lvds mode */
|
||||
val |= v_RK3368_LVDSMODE_EN(0) | v_RK3368_MIPIPHY_TTL_EN(1) |
|
||||
v_RK3368_MIPIPHY_LANE0_EN(1) |
|
||||
v_RK3368_MIPIDPI_FORCEX_EN(1);
|
||||
if (lvds->data->soc_type == LVDS_SOC_RK3368) {
|
||||
lvds_grf_writel(lvds, RK3368_GRF_SOC_CON7_LVDS, val);
|
||||
val = v_RK3368_FORCE_JETAG(0);
|
||||
lvds_grf_writel(lvds, RK3368_GRF_SOC_CON15_LVDS, val);
|
||||
} else {
|
||||
lvds_grf_writel(lvds, RK3366_GRF_SOC_CON5_LVDS, val);
|
||||
val = v_RK3368_FORCE_JETAG(0);
|
||||
lvds_grf_writel(lvds, RK3366_GRF_SOC_CON6_LVDS, val);
|
||||
}
|
||||
/*val = v_MIPITTL_CLK_EN(1) | v_MIPITTL_LANE0_EN(1) |
|
||||
v_MIPITTL_LANE1_EN(1) | v_MIPITTL_LANE2_EN(1) |
|
||||
v_MIPITTL_LANE3_EN(1);
|
||||
grf_writel(val, RK312X_GRF_SOC_CON1);*/
|
||||
} else {
|
||||
/* iomux to lcdc */
|
||||
#if defined(CONFIG_RK_FPGA)
|
||||
grf_writel(0xffff5555, RK312X_GRF_GPIO2B_IOMUX);
|
||||
grf_writel(0x00ff0055, RK312X_GRF_GPIO2C_IOMUX);
|
||||
grf_writel(0x77771111, 0x00e8); /* RK312X_GRF_GPIO2C_IOMUX2 */
|
||||
grf_writel(0x700c1004, RK312X_GRF_GPIO2D_IOMUX);
|
||||
#else
|
||||
#ifdef CONFIG_PINCTRL
|
||||
if (lvds->pins && !IS_ERR(lvds->pins->default_state))
|
||||
pinctrl_select_state(lvds->pins->p,
|
||||
lvds->pins->default_state);
|
||||
#endif
|
||||
#endif
|
||||
/* enable lvds mode */
|
||||
val |= v_LVDSMODE_EN(0) | v_MIPIPHY_TTL_EN(1);
|
||||
/* config data source */
|
||||
val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC);
|
||||
grf_writel(0xffff0380, RK312X_GRF_LVDS_CON0);
|
||||
|
||||
val = v_MIPITTL_CLK_EN(1) | v_MIPITTL_LANE0_EN(1) |
|
||||
v_MIPITTL_LANE1_EN(1) | v_MIPITTL_LANE2_EN(1) |
|
||||
v_MIPITTL_LANE3_EN(1);
|
||||
grf_writel(val, RK312X_GRF_SOC_CON1);
|
||||
}
|
||||
/* enable lane */
|
||||
lvds_writel(lvds, MIPIPHY_REG0, 0x7f);
|
||||
val = v_LANE0_EN(1) | v_LANE1_EN(1) | v_LANE2_EN(1) | v_LANE3_EN(1) |
|
||||
v_LANECLK_EN(1) | v_PLL_PWR_OFF(1);
|
||||
lvds_writel(lvds, MIPIPHY_REGEB, val);
|
||||
|
||||
/* set ttl mode and reset phy config */
|
||||
val = v_LVDS_MODE_EN(0) | v_TTL_MODE_EN(1) | v_MIPI_MODE_EN(0) |
|
||||
v_MSB_SEL(1) | v_DIG_INTER_RST(1);
|
||||
lvds_writel(lvds, MIPIPHY_REGE0, val);
|
||||
|
||||
rk31xx_lvds_pwr_on();
|
||||
|
||||
}
|
||||
|
||||
static int rk31xx_lvds_en(void)
|
||||
{
|
||||
struct rk_lvds_device *lvds = rk31xx_lvds;
|
||||
struct rk_screen *screen;
|
||||
|
||||
if (unlikely(!lvds))//|| lvds->sys_state)
|
||||
return 0;
|
||||
|
||||
screen = &lvds->screen;
|
||||
rk_fb_get_prmry_screen(screen);
|
||||
|
||||
/* enable clk */
|
||||
rk31xx_lvds_clk_enable(lvds);
|
||||
|
||||
switch (screen->type) {
|
||||
case SCREEN_LVDS:
|
||||
rk31xx_output_lvds(lvds, screen);
|
||||
break;
|
||||
case SCREEN_RGB:
|
||||
rk31xx_output_lvttl(lvds, screen);
|
||||
break;
|
||||
default:
|
||||
printk("unsupport screen type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
lvds->sys_state = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rk_fb_trsm_ops trsm_lvds_ops = {
|
||||
.enable = rk31xx_lvds_en,
|
||||
.disable = rk31xx_lvds_disable,
|
||||
.dsp_pwr_on = rk31xx_lvds_pwr_on,
|
||||
.dsp_pwr_off = rk31xx_lvds_pwr_off,
|
||||
};
|
||||
#if defined(CONFIG_OF)
|
||||
static struct rk_lvds_drvdata rk31xx_lvds_drvdata = {
|
||||
.soc_type = LVDS_SOC_RK312X,
|
||||
};
|
||||
|
||||
static struct rk_lvds_drvdata rk3368_lvds_drvdata = {
|
||||
.soc_type = LVDS_SOC_RK3368,
|
||||
};
|
||||
|
||||
static struct rk_lvds_drvdata rk3366_lvds_drvdata = {
|
||||
.soc_type = LVDS_SOC_RK3366,
|
||||
};
|
||||
|
||||
static const struct of_device_id rk31xx_lvds_dt_ids[] = {
|
||||
{.compatible = "rockchip,rk31xx-lvds",
|
||||
.data = (void *)&rk31xx_lvds_drvdata,},
|
||||
{.compatible = "rockchip,rk3368-lvds",
|
||||
.data = (void *)&rk3368_lvds_drvdata,},
|
||||
{.compatible = "rockchip,rk3366-lvds",
|
||||
.data = (void *)&rk3366_lvds_drvdata,},
|
||||
{}
|
||||
};
|
||||
|
||||
/*MODULE_DEVICE_TABLE(of, rk31xx_lvds_dt_ids);*/
|
||||
|
||||
#endif
|
||||
|
||||
static int rk31xx_lvds_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk_lvds_device *lvds;
|
||||
struct resource *res;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *match;
|
||||
int ret = 0;
|
||||
|
||||
if (!np) {
|
||||
dev_err(&pdev->dev, "Don't find lvds device tree node.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk_lvds_device), GFP_KERNEL);
|
||||
if (!lvds) {
|
||||
dev_err(&pdev->dev, "kzalloc rk31xx lvds failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
lvds->dev = &pdev->dev;
|
||||
match = of_match_node(rk31xx_lvds_dt_ids, np);
|
||||
lvds->data = (struct rk_lvds_drvdata *)match->data;
|
||||
dev_info(lvds->dev, "%s,type=%d\n",
|
||||
__func__, lvds->data->soc_type);
|
||||
|
||||
rk_fb_get_prmry_screen(&lvds->screen);
|
||||
if ((lvds->screen.type != SCREEN_RGB) &&
|
||||
(lvds->screen.type != SCREEN_LVDS)) {
|
||||
dev_err(&pdev->dev, "screen is not lvds/rgb!\n");
|
||||
ret = -EINVAL;
|
||||
goto err_screen_type;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, lvds);
|
||||
dev_set_name(lvds->dev, "rk31xx-lvds");
|
||||
|
||||
#ifdef CONFIG_PINCTRL
|
||||
if (lvds->dev->pins == NULL && lvds->screen.type == SCREEN_RGB) {
|
||||
lvds->pins = devm_kzalloc(lvds->dev, sizeof(*(lvds->pins)),
|
||||
GFP_KERNEL);
|
||||
if (!lvds->pins) {
|
||||
dev_err(lvds->dev, "kzalloc lvds pins failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lvds->pins->p = devm_pinctrl_get(lvds->dev);
|
||||
if (IS_ERR(lvds->pins->p)) {
|
||||
dev_info(lvds->dev, "no pinctrl handle\n");
|
||||
devm_kfree(lvds->dev, lvds->pins);
|
||||
lvds->pins = NULL;
|
||||
} else {
|
||||
lvds->pins->default_state =
|
||||
pinctrl_lookup_state(lvds->pins->p, "lcdc");
|
||||
lvds->pins->sleep_state =
|
||||
pinctrl_lookup_state(lvds->pins->p, "sleep");
|
||||
if (IS_ERR(lvds->pins->default_state)) {
|
||||
dev_info(lvds->dev, "no default pinctrl state\n");
|
||||
devm_kfree(lvds->dev, lvds->pins);
|
||||
lvds->pins = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* lvds regs on MIPIPHY_REG */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mipi_lvds_phy");
|
||||
lvds->regbase = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(lvds->regbase)) {
|
||||
dev_err(&pdev->dev, "ioremap mipi-lvds phy reg failed\n");
|
||||
return PTR_ERR(lvds->regbase);
|
||||
}
|
||||
|
||||
/* pll lock on status reg that is MIPICTRL Register */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mipi_lvds_ctl");
|
||||
lvds->ctrl_reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(lvds->ctrl_reg)) {
|
||||
dev_err(&pdev->dev, "ioremap mipi-lvds ctl reg failed\n");
|
||||
return PTR_ERR(lvds->ctrl_reg);
|
||||
}
|
||||
#ifdef CONFIG_MFD_SYSCON
|
||||
if ((lvds->data->soc_type == LVDS_SOC_RK3368) ||
|
||||
(lvds->data->soc_type == LVDS_SOC_RK3366)) {
|
||||
lvds->grf_lvds_base =
|
||||
syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
|
||||
if (IS_ERR(lvds->grf_lvds_base)) {
|
||||
dev_err(&pdev->dev, "can't find rockchip,grf property\n");
|
||||
return PTR_ERR(lvds->grf_lvds_base);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ret = rk31xx_lvds_clk_init(lvds);
|
||||
if(ret < 0)
|
||||
goto err_clk_init;
|
||||
|
||||
if (support_uboot_display()) {
|
||||
rk31xx_lvds_clk_enable(lvds);
|
||||
/*lvds->sys_state = true;*/
|
||||
}
|
||||
|
||||
rk31xx_lvds = lvds;
|
||||
rk_fb_trsm_ops_register(&trsm_lvds_ops, SCREEN_LVDS);
|
||||
dev_info(&pdev->dev, "rk31xx lvds driver probe success\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_init:
|
||||
err_screen_type:
|
||||
devm_kfree(&pdev->dev, lvds);
|
||||
lvds = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk31xx_lvds_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk31xx_lvds_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static struct platform_driver rk31xx_lvds_driver = {
|
||||
.driver = {
|
||||
.name = "rk31xx-lvds",
|
||||
.owner = THIS_MODULE,
|
||||
#if defined(CONFIG_OF)
|
||||
.of_match_table = of_match_ptr(rk31xx_lvds_dt_ids),
|
||||
#endif
|
||||
},
|
||||
.probe = rk31xx_lvds_probe,
|
||||
.remove = rk31xx_lvds_remove,
|
||||
.shutdown = rk31xx_lvds_shutdown,
|
||||
};
|
||||
|
||||
static int __init rk31xx_lvds_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk31xx_lvds_driver);
|
||||
}
|
||||
|
||||
static void __exit rk31xx_lvds_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk31xx_lvds_driver);
|
||||
}
|
||||
|
||||
fs_initcall(rk31xx_lvds_init);
|
||||
module_exit(rk31xx_lvds_exit);
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _RK31XX_LVDS_H_
|
||||
#define _RK31XX_LVDS_H_
|
||||
|
||||
#include <linux/rk_screen.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define BITS(x, bit) ((x) << (bit))
|
||||
#define BITS_MASK(x, mask, bit) BITS((x) & (mask), bit)
|
||||
#define BITS_EN(mask, bit) BITS(mask, bit + 16)
|
||||
|
||||
/* RK312X_GRF_LVDS_CON0 */
|
||||
#define v_LVDS_DATA_SEL(x) (BITS_MASK(x, 1, 0) | BITS_EN(1, 0))
|
||||
#define v_LVDS_OUTPUT_FORMAT(x) (BITS_MASK(x, 3, 1) | BITS_EN(3, 1))
|
||||
#define v_LVDS_MSBSEL(x) (BITS_MASK(x, 1, 3) | BITS_EN(1, 3))
|
||||
#define v_LVDSMODE_EN(x) (BITS_MASK(x, 1, 6) | BITS_EN(1, 6))
|
||||
#define v_MIPIPHY_TTL_EN(x) (BITS_MASK(x, 1, 7) | BITS_EN(1, 7))
|
||||
#define v_MIPIPHY_LANE0_EN(x) (BITS_MASK(x, 1, 8) | BITS_EN(1, 8))
|
||||
#define v_MIPIDPI_FORCEX_EN(x) (BITS_MASK(x, 1, 9) | BITS_EN(1, 9))
|
||||
|
||||
/* RK3368_GRF_SOC_CON7 0x41c*/
|
||||
/* RK3366_GRF_SOC_CON5 0x414*/
|
||||
#define v_RK3368_LVDS_OUTPUT_FORMAT(x) (BITS_MASK(x, 3, 13) | BITS_EN(3, 13))
|
||||
#define v_RK3368_LVDS_MSBSEL(x) (BITS_MASK(x, 1, 11) | BITS_EN(1, 11))
|
||||
#define v_RK3368_LVDSMODE_EN(x) (BITS_MASK(x, 1, 12) | BITS_EN(1, 12))
|
||||
#define v_RK3368_MIPIPHY_TTL_EN(x) (BITS_MASK(x, 1, 15) | BITS_EN(1, 15))
|
||||
#define v_RK3368_MIPIPHY_LANE0_EN(x) (BITS_MASK(x, 1, 5) | BITS_EN(1, 5))
|
||||
#define v_RK3368_MIPIDPI_FORCEX_EN(x) (BITS_MASK(x, 1, 6) | BITS_EN(1, 6))
|
||||
enum {
|
||||
LVDS_DATA_FROM_LCDC = 0,
|
||||
LVDS_DATA_FORM_EBC,
|
||||
};
|
||||
|
||||
enum {
|
||||
LVDS_MSB_D0 = 0,
|
||||
LVDS_MSB_D7,
|
||||
};
|
||||
|
||||
/* RK312X_GRF_SOC_CON1 */
|
||||
#define v_MIPITTL_CLK_EN(x) (BITS_MASK(x, 1, 7) | BITS_EN(1, 7))
|
||||
#define v_MIPITTL_LANE0_EN(x) (BITS_MASK(x, 1, 11) | BITS_EN(1, 11))
|
||||
#define v_MIPITTL_LANE1_EN(x) (BITS_MASK(x, 1, 12) | BITS_EN(1, 12))
|
||||
#define v_MIPITTL_LANE2_EN(x) (BITS_MASK(x, 1, 13) | BITS_EN(1, 13))
|
||||
#define v_MIPITTL_LANE3_EN(x) (BITS_MASK(x, 1, 14) | BITS_EN(1, 14))
|
||||
|
||||
|
||||
#define MIPIPHY_REG0 0x0000
|
||||
#define m_LANE_EN_0 BITS(1, 2)
|
||||
#define m_LANE_EN_1 BITS(1, 3)
|
||||
#define m_LANE_EN_2 BITS(1, 4)
|
||||
#define m_LANE_EN_3 BITS(1, 5)
|
||||
#define m_LANE_EN_CLK BITS(1, 5)
|
||||
#define v_LANE_EN_0(x) BITS(1, 2)
|
||||
#define v_LANE_EN_1(x) BITS(1, 3)
|
||||
#define v_LANE_EN_2(x) BITS(1, 4)
|
||||
#define v_LANE_EN_3(x) BITS(1, 5)
|
||||
#define v_LANE_EN_CLK(x) BITS(1, 5)
|
||||
|
||||
#define MIPIPHY_REG1 0x0004
|
||||
#define m_SYNC_RST BITS(1, 0)
|
||||
#define m_LDO_PWR_DOWN BITS(1, 1)
|
||||
#define m_PLL_PWR_DOWN BITS(1, 2)
|
||||
#define v_SYNC_RST(x) BITS_MASK(x, 1, 0)
|
||||
#define v_LDO_PWR_DOWN(x) BITS_MASK(x, 1, 1)
|
||||
#define v_PLL_PWR_DOWN(x) BITS_MASK(x, 1, 2)
|
||||
|
||||
#define MIPIPHY_REG3 0x000c
|
||||
#define m_PREDIV BITS(0x1f, 0)
|
||||
#define m_FBDIV_MSB BITS(1, 5)
|
||||
#define v_PREDIV(x) BITS_MASK(x, 0x1f, 0)
|
||||
#define v_FBDIV_MSB(x) BITS_MASK(x, 1, 5)
|
||||
|
||||
#define MIPIPHY_REG4 0x0010
|
||||
#define v_FBDIV_LSB(x) BITS_MASK(x, 0xff, 0)
|
||||
|
||||
#define MIPIPHY_REGE0 0x0380
|
||||
#define m_MSB_SEL BITS(1, 0)
|
||||
#define m_DIG_INTER_RST BITS(1, 2)
|
||||
#define m_LVDS_MODE_EN BITS(1, 5)
|
||||
#define m_TTL_MODE_EN BITS(1, 6)
|
||||
#define m_MIPI_MODE_EN BITS(1, 7)
|
||||
#define v_MSB_SEL(x) BITS_MASK(x, 1, 0)
|
||||
#define v_DIG_INTER_RST(x) BITS_MASK(x, 1, 2)
|
||||
#define v_LVDS_MODE_EN(x) BITS_MASK(x, 1, 5)
|
||||
#define v_TTL_MODE_EN(x) BITS_MASK(x, 1, 6)
|
||||
#define v_MIPI_MODE_EN(x) BITS_MASK(x, 1, 7)
|
||||
|
||||
#define MIPIPHY_REGE1 0x0384
|
||||
#define m_DIG_INTER_EN BITS(1, 7)
|
||||
#define v_DIG_INTER_EN(x) BITS_MASK(x, 1, 7)
|
||||
|
||||
#define MIPIPHY_REGE3 0x038c
|
||||
#define m_MIPI_EN BITS(1, 0)
|
||||
#define m_LVDS_EN BITS(1, 1)
|
||||
#define m_TTL_EN BITS(1, 2)
|
||||
#define v_MIPI_EN(x) BITS_MASK(x, 1, 0)
|
||||
#define v_LVDS_EN(x) BITS_MASK(x, 1, 1)
|
||||
#define v_TTL_EN(x) BITS_MASK(x, 1, 2)
|
||||
|
||||
#define MIPIPHY_REGE4 0x0390
|
||||
#define m_VOCM BITS(3, 4)
|
||||
#define m_DIFF_V BITS(3, 6)
|
||||
|
||||
#define v_VOCM(x) BITS_MASK(x, 3, 4)
|
||||
#define v_DIFF_V(x) BITS_MASK(x, 3, 6)
|
||||
|
||||
#define MIPIPHY_REGE8 0x03a0
|
||||
|
||||
#define MIPIPHY_REGEB 0x03ac
|
||||
#define v_PLL_PWR_OFF(x) BITS_MASK(x, 1, 2)
|
||||
#define v_LANECLK_EN(x) BITS_MASK(x, 1, 3)
|
||||
#define v_LANE3_EN(x) BITS_MASK(x, 1, 4)
|
||||
#define v_LANE2_EN(x) BITS_MASK(x, 1, 5)
|
||||
#define v_LANE1_EN(x) BITS_MASK(x, 1, 6)
|
||||
#define v_LANE0_EN(x) BITS_MASK(x, 1, 7)
|
||||
|
||||
#define RK3368_GRF_SOC_CON7_LVDS 0x041c
|
||||
#define RK3368_GRF_SOC_CON15_LVDS 0x043c
|
||||
#define RK3366_GRF_SOC_CON5_LVDS 0x0414
|
||||
#define RK3366_GRF_SOC_CON6_LVDS 0x0418
|
||||
#define v_RK3368_FORCE_JETAG(x) (BITS_MASK(x, 1, 13) | BITS_EN(1, 13))
|
||||
|
||||
enum {
|
||||
LVDS_SOC_RK312X,
|
||||
LVDS_SOC_RK3368,
|
||||
LVDS_SOC_RK3366
|
||||
};
|
||||
|
||||
struct rk_lvds_drvdata {
|
||||
u8 soc_type;
|
||||
u32 reversed;
|
||||
};
|
||||
|
||||
struct rk_lvds_device {
|
||||
struct rk_lvds_drvdata *data;
|
||||
struct device *dev;
|
||||
void __iomem *regbase;
|
||||
void __iomem *ctrl_reg;
|
||||
struct regmap *grf_lvds_base;
|
||||
struct clk *pd; /*power domain*/
|
||||
struct clk *pclk; /*phb clk*/
|
||||
struct clk *ctrl_pclk; /* mipi ctrl pclk*/
|
||||
struct clk *ctrl_hclk; /* mipi ctrl hclk*/
|
||||
struct rk_screen screen;
|
||||
bool clk_on;
|
||||
bool sys_state;
|
||||
#ifdef CONFIG_PINCTRL
|
||||
struct dev_pin_info *pins;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline int lvds_writel(struct rk_lvds_device *lvds, u32 offset, u32 val)
|
||||
{
|
||||
writel_relaxed(val, lvds->regbase + offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int lvds_msk_reg(struct rk_lvds_device *lvds, u32 offset,
|
||||
u32 msk, u32 val)
|
||||
{
|
||||
u32 temp;
|
||||
|
||||
temp = readl_relaxed(lvds->regbase + offset) & (0xFF - (msk));
|
||||
writel_relaxed(temp | ((val) & (msk)), lvds->regbase + offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 lvds_readl(struct rk_lvds_device *lvds, u32 offset)
|
||||
{
|
||||
return readl_relaxed(lvds->regbase + offset);
|
||||
}
|
||||
|
||||
static inline int lvds_grf_writel(struct rk_lvds_device *lvds,
|
||||
u32 offset, u32 val)
|
||||
{
|
||||
regmap_write(lvds->grf_lvds_base, offset, val);
|
||||
dsb(sy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int lvds_dsi_writel(struct rk_lvds_device *lvds,
|
||||
u32 offset, u32 val)
|
||||
{
|
||||
writel_relaxed(val, lvds->ctrl_reg + offset);
|
||||
dsb(sy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 lvds_phy_lockon(struct rk_lvds_device *lvds)
|
||||
{
|
||||
u32 val = 0;
|
||||
if (lvds->data->soc_type == LVDS_SOC_RK312X)
|
||||
val = readl_relaxed(lvds->ctrl_reg);
|
||||
else
|
||||
val = readl_relaxed(lvds->ctrl_reg + 0x10);
|
||||
return (val & 0x01);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,672 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __RK32_DP_H
|
||||
#define __RK32_DP_H
|
||||
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/rk_fb.h>
|
||||
|
||||
#include "dpcd_edid.h"
|
||||
|
||||
#define DP_VERSION 0x10
|
||||
|
||||
#define TX_SW_RST 0x14
|
||||
|
||||
#define FUNC_EN_1 0x18
|
||||
#define VID_CAP_FUNC_EN_N (0x1 << 6)
|
||||
#define VID_FIFO_FUNC_EN_N (0x1 << 5)
|
||||
#define AUD_FIFO_FUNC_EN_N (0x1 << 4)
|
||||
#define AUD_FUNC_EN_N (0x1 << 3)
|
||||
#define HDCP_FUNC_EN_N (0x1 << 2)
|
||||
#define SW_FUNC_EN_N (0x1 << 0)
|
||||
|
||||
#define FUNC_EN_2 0x1C
|
||||
#define SSC_FUNC_EN_N (0x1 << 7)
|
||||
#define AUX_FUNC_EN_N (0x1 << 2)
|
||||
#define SERDES_FIFO_FUNC_EN_N (0x1 << 1)
|
||||
#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0)
|
||||
|
||||
#define VIDEO_CTL_1 0x20
|
||||
#define VIDEO_EN (0x1 << 7)
|
||||
#define VIDEO_MUTE (0x1 << 6)
|
||||
|
||||
#define VIDEO_CTL_2 0x24
|
||||
#define IN_D_RANGE_MASK (0x1 << 7)
|
||||
#define IN_D_RANGE_SHIFT (7)
|
||||
#define IN_D_RANGE_CEA (0x1 << 7)
|
||||
#define IN_D_RANGE_VESA (0x0 << 7)
|
||||
#define IN_BPC_MASK (0x7 << 4)
|
||||
#define IN_BPC_SHIFT (4)
|
||||
#define IN_BPC_12_BITS (0x3 << 4)
|
||||
#define IN_BPC_10_BITS (0x2 << 4)
|
||||
#define IN_BPC_8_BITS (0x1 << 4)
|
||||
#define IN_BPC_6_BITS (0x0 << 4)
|
||||
#define IN_COLOR_F_MASK (0x3 << 0)
|
||||
#define IN_COLOR_F_SHIFT (0)
|
||||
#define IN_COLOR_F_YCBCR444 (0x2 << 0)
|
||||
#define IN_COLOR_F_YCBCR422 (0x1 << 0)
|
||||
#define IN_COLOR_F_RGB (0x0 << 0)
|
||||
|
||||
#define VIDEO_CTL_3 0x28
|
||||
#define IN_YC_COEFFI_MASK (0x1 << 7)
|
||||
#define IN_YC_COEFFI_SHIFT (7)
|
||||
#define IN_YC_COEFFI_ITU709 (0x1 << 7)
|
||||
#define IN_YC_COEFFI_ITU601 (0x0 << 7)
|
||||
#define VID_CHK_UPDATE_TYPE_MASK (0x1 << 4)
|
||||
#define VID_CHK_UPDATE_TYPE_SHIFT (4)
|
||||
#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4)
|
||||
#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4)
|
||||
|
||||
#define VIDEO_CTL_4 0x2c
|
||||
#define BIST_EN (0x1 << 3)
|
||||
#define BIST_WH_64 (0x1 << 2)
|
||||
#define BIST_WH_32 (0x0 << 2)
|
||||
#define BIST_TYPE_COLR_BAR (0x0 << 0)
|
||||
#define BIST_TYPE_GRAY_BAR (0x1 << 0)
|
||||
#define BIST_TYPE_MOBILE_BAR (0x2 << 0)
|
||||
|
||||
#define VIDEO_CTL_8 0x3C
|
||||
#define VID_HRES_TH(x) (((x) & 0xf) << 4)
|
||||
#define VID_VRES_TH(x) (((x) & 0xf) << 0)
|
||||
|
||||
#define VIDEO_CTL_10 0x44
|
||||
#define F_SEL (0x1 << 4)
|
||||
#define INTERACE_SCAN_CFG (0x1 << 2)
|
||||
#define VSYNC_POLARITY_CFG (0x1 << 1)
|
||||
#define HSYNC_POLARITY_CFG (0x1 << 0)
|
||||
|
||||
#define TOTAL_LINE_CFG_L 0x48
|
||||
#define TOTAL_LINE_CFG_H 0x4c
|
||||
#define ATV_LINE_CFG_L 0x50
|
||||
#define ATV_LINE_CFG_H 0x54
|
||||
#define VF_PORCH_REG 0x58
|
||||
#define VSYNC_CFG_REG 0x5c
|
||||
#define VB_PORCH_REG 0x60
|
||||
#define TOTAL_PIXELL_REG 0x64
|
||||
#define TOTAL_PIXELH_REG 0x68
|
||||
#define ATV_PIXELL_REG 0x6c
|
||||
#define ATV_PIXELH_REG 0x70
|
||||
#define HF_PORCHL_REG 0x74
|
||||
#define HF_PORCHH_REG 0x78
|
||||
#define HSYNC_CFGL_REG 0x7c
|
||||
#define HSYNC_CFGH_REG 0x80
|
||||
#define HB_PORCHL_REG 0x84
|
||||
#define HB_PORCHH_REG 0x88
|
||||
|
||||
|
||||
#define SSC_REG 0x104
|
||||
#define TX_REG_COMMON 0x114
|
||||
#define DP_AUX 0x120
|
||||
#define DP_BIAS 0x124
|
||||
|
||||
#define PLL_REG_1 0xfc
|
||||
#define REF_CLK_24M (0x1 << 1)
|
||||
#define REF_CLK_27M (0x0 << 1)
|
||||
|
||||
#define PLL_REG_2 0x9e4
|
||||
#define PLL_REG_3 0x9e8
|
||||
#define PLL_REG_4 0x9ec
|
||||
#define PLL_REG_5 0xa00
|
||||
#define DP_PWRDN 0x12c
|
||||
#define PD_INC_BG (0x1 << 7)
|
||||
#define PD_EXP_BG (0x1 << 6)
|
||||
#define PD_AUX (0x1 << 5)
|
||||
#define PD_PLL (0x1 << 4)
|
||||
#define PD_CH3 (0x1 << 3)
|
||||
#define PD_CH2 (0x1 << 2)
|
||||
#define PD_CH1 (0x1 << 1)
|
||||
#define PD_CH0 (0x1 << 0)
|
||||
|
||||
#define DP_RESERVE2 0x134
|
||||
|
||||
#define LANE_MAP 0x35C
|
||||
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
|
||||
#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
|
||||
#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6)
|
||||
#define LANE3_MAP_LOGIC_LANE_3 (0x3 << 6)
|
||||
#define LANE2_MAP_LOGIC_LANE_0 (0x0 << 4)
|
||||
#define LANE2_MAP_LOGIC_LANE_1 (0x1 << 4)
|
||||
#define LANE2_MAP_LOGIC_LANE_2 (0x2 << 4)
|
||||
#define LANE2_MAP_LOGIC_LANE_3 (0x3 << 4)
|
||||
#define LANE1_MAP_LOGIC_LANE_0 (0x0 << 2)
|
||||
#define LANE1_MAP_LOGIC_LANE_1 (0x1 << 2)
|
||||
#define LANE1_MAP_LOGIC_LANE_2 (0x2 << 2)
|
||||
#define LANE1_MAP_LOGIC_LANE_3 (0x3 << 2)
|
||||
#define LANE0_MAP_LOGIC_LANE_0 (0x0 << 0)
|
||||
#define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0)
|
||||
#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0)
|
||||
#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0)
|
||||
|
||||
#define ANALOG_CTL_2 0x374
|
||||
#define SEL_24M (0x1 << 3)
|
||||
|
||||
/*#define ANALOG_CTL_3 0x378
|
||||
#define PLL_FILTER_CTL_1 0x37C
|
||||
#define TX_AMP_TUNING_CTL 0x380*/
|
||||
|
||||
#define AUX_HW_RETRY_CTL 0x390
|
||||
|
||||
#define INT_STA 0x3c0
|
||||
|
||||
#define COMMON_INT_STA_1 0x3C4
|
||||
#define VSYNC_DET (0x1 << 7)
|
||||
#define PLL_LOCK_CHG (0x1 << 6)
|
||||
#define SPDIF_ERR (0x1 << 5)
|
||||
#define SPDIF_UNSTBL (0x1 << 4)
|
||||
#define VID_FORMAT_CHG (0x1 << 3)
|
||||
#define AUD_CLK_CHG (0x1 << 2)
|
||||
#define VID_CLK_CHG (0x1 << 1)
|
||||
#define SW_INT (0x1 << 0)
|
||||
|
||||
#define COMMON_INT_STA_2 0x3C8
|
||||
#define ENC_EN_CHG (0x1 << 6)
|
||||
#define HW_BKSV_RDY (0x1 << 3)
|
||||
#define HW_SHA_DONE (0x1 << 2)
|
||||
#define HW_AUTH_STATE_CHG (0x1 << 1)
|
||||
#define HW_AUTH_DONE (0x1 << 0)
|
||||
|
||||
#define COMMON_INT_STA_3 0x3CC
|
||||
#define AFIFO_UNDER (0x1 << 7)
|
||||
#define AFIFO_OVER (0x1 << 6)
|
||||
#define R0_CHK_FLAG (0x1 << 5)
|
||||
|
||||
#define COMMON_INT_STA_4 0x3D0
|
||||
#define PSR_ACTIVE (0x1 << 7)
|
||||
#define PSR_INACTIVE (0x1 << 6)
|
||||
#define SPDIF_BI_PHASE_ERR (0x1 << 5)
|
||||
#define HOTPLUG_CHG (0x1 << 2)
|
||||
#define HPD_LOST (0x1 << 1)
|
||||
#define PLUG (0x1 << 0)
|
||||
|
||||
#define DP_INT_STA 0x3DC
|
||||
#define INT_HPD (0x1 << 6)
|
||||
#define HW_LT_DONE (0x1 << 5)
|
||||
#define SINK_LOST (0x1 << 3)
|
||||
#define LINK_LOST (0x1 << 2)
|
||||
#define RPLY_RECEIV (0x1 << 1)
|
||||
#define AUX_ERR (0x1 << 0)
|
||||
|
||||
#define COMMON_INT_MASK_1 0x3E0
|
||||
#define COMMON_INT_MASK_2 0x3E4
|
||||
#define COMMON_INT_MASK_3 0x3E8
|
||||
#define COMMON_INT_MASK_4 0x3EC
|
||||
#define DP_INT_STA_MASK 0x3F8
|
||||
|
||||
#define INT_CTL 0x3FC
|
||||
#define SOFT_INT_CTRL (0x1 << 2)
|
||||
#define INT_POL (0x1 << 0)
|
||||
|
||||
#define SYS_CTL_1 0x600
|
||||
#define DET_STA (0x1 << 2)
|
||||
#define FORCE_DET (0x1 << 1)
|
||||
#define DET_CTRL (0x1 << 0)
|
||||
|
||||
#define SYS_CTL_2 0x604
|
||||
#define CHA_CRI(x) (((x) & 0xf) << 4)
|
||||
#define CHA_STA (0x1 << 2)
|
||||
#define FORCE_CHA (0x1 << 1)
|
||||
#define CHA_CTRL (0x1 << 0)
|
||||
|
||||
#define SYS_CTL_3 0x608
|
||||
#define HPD_STATUS (0x1 << 6)
|
||||
#define F_HPD (0x1 << 5)
|
||||
#define HPD_CTRL (0x1 << 4)
|
||||
#define HDCP_RDY (0x1 << 3)
|
||||
#define STRM_VALID (0x1 << 2)
|
||||
#define F_VALID (0x1 << 1)
|
||||
#define VALID_CTRL (0x1 << 0)
|
||||
|
||||
#define SYS_CTL_4 0x60C
|
||||
#define FIX_M_AUD (0x1 << 4)
|
||||
#define ENHANCED (0x1 << 3)
|
||||
#define FIX_M_VID (0x1 << 2)
|
||||
#define M_VID_UPDATE_CTRL (0x3 << 0)
|
||||
|
||||
|
||||
#define PKT_SEND_CTL 0x640
|
||||
#define HDCP_CTL 0x648
|
||||
|
||||
#define LINK_BW_SET 0x680
|
||||
#define LANE_CNT_SET 0x684
|
||||
|
||||
#define TRAINING_PTN_SET 0x688
|
||||
#define SCRAMBLING_DISABLE (0x1 << 5)
|
||||
#define SCRAMBLING_ENABLE (0x0 << 5)
|
||||
#define LINK_QUAL_PATTERN_SET_MASK (0x7 << 2)
|
||||
#define LINK_QUAL_PATTERN_SET_HBR2 (0x5 << 2)
|
||||
#define LINK_QUAL_PATTERN_SET_80BIT (0x4 << 2)
|
||||
#define LINK_QUAL_PATTERN_SET_PRBS7 (0x3 << 2)
|
||||
#define LINK_QUAL_PATTERN_SET_D10_2 (0x1 << 2)
|
||||
#define LINK_QUAL_PATTERN_SET_DISABLE (0x0 << 2)
|
||||
#define SW_TRAINING_PATTERN_SET_MASK (0x3 << 0)
|
||||
#define SW_TRAINING_PATTERN_SET_PTN2 (0x2 << 0)
|
||||
#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0)
|
||||
#define SW_TRAINING_PATTERN_SET_DISABLE (0x0 << 0)
|
||||
|
||||
#define LN0_LINK_TRAINING_CTL 0x68C
|
||||
#define LN1_LINK_TRAINING_CTL 0x690
|
||||
#define LN2_LINK_TRAINING_CTL 0x694
|
||||
#define LN3_LINK_TRAINING_CTL 0x698
|
||||
|
||||
#define HW_LT_CTL 0x6a0
|
||||
#define HW_LT_ERR_CODE_MASK 0x70
|
||||
#define HW_LT_EN (0x1 << 0)
|
||||
|
||||
#define DEBUG_CTL 0x6C0
|
||||
#define PLL_LOCK (0x1 << 4)
|
||||
#define F_PLL_LOCK (0x1 << 3)
|
||||
#define PLL_LOCK_CTRL (0x1 << 2)
|
||||
#define POLL_EN (0x1 << 1)
|
||||
#define PN_INV (0x1 << 0)
|
||||
|
||||
#define HPD_DEGLITCH_L 0x6C4
|
||||
#define HPD_DEGLITCH_H 0x6C8
|
||||
#define LINK_DEBUG_CTL 0x6E0
|
||||
|
||||
#define M_VID_0 0x700
|
||||
#define M_VID_1 0x704
|
||||
#define M_VID_2 0x708
|
||||
#define N_VID_0 0x70C
|
||||
#define N_VID_1 0x710
|
||||
#define N_VID_2 0x714
|
||||
|
||||
#define VIDEO_FIFO_THRD 0x730
|
||||
#define AUDIO_MARGIN 0x73C
|
||||
|
||||
#define M_VID_GEN_FILTER_TH 0x764
|
||||
#define M_AUD_GEN_FILTER_TH 0x778
|
||||
|
||||
#define AUX_CH_STA 0x780
|
||||
#define AUX_BUSY (0x1 << 4)
|
||||
#define AUX_STATUS_MASK (0xf << 0)
|
||||
|
||||
#define AUX_CH_DEFER_CTL 0x788
|
||||
#define DEFER_CTRL_EN (0x1 << 7)
|
||||
#define DEFER_COUNT(x) (((x) & 0x7f) << 0)
|
||||
|
||||
#define AUX_RX_COMM 0x78C
|
||||
#define BUFFER_DATA_CTL 0x790
|
||||
#define BUF_CLR (0x1 << 7)
|
||||
#define BUF_HAVE_DATA (0x1 << 4)
|
||||
#define BUF_DATA_COUNT(x) (((x) & 0xf) << 0)
|
||||
|
||||
#define AUX_CH_CTL_1 0x794
|
||||
#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4)
|
||||
#define AUX_TX_COMM_MASK (0xf << 0)
|
||||
#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3)
|
||||
#define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3)
|
||||
#define AUX_TX_COMM_MOT (0x1 << 2)
|
||||
#define AUX_TX_COMM_WRITE (0x0 << 0)
|
||||
#define AUX_TX_COMM_READ (0x1 << 0)
|
||||
|
||||
#define DP_AUX_ADDR_7_0 0x798
|
||||
#define DP_AUX_ADDR_15_8 0x79C
|
||||
#define DP_AUX_ADDR_19_16 0x7A0
|
||||
|
||||
#define AUX_CH_CTL_2 0x7A4
|
||||
#define PD_AUX_IDLE (0x1 << 3)
|
||||
#define ADDR_ONLY (0x1 << 1)
|
||||
#define AUX_EN (0x1 << 0)
|
||||
|
||||
#define BUF_DATA_0 0x7C0
|
||||
|
||||
#define SOC_GENERAL_CTL 0x800
|
||||
|
||||
/* TX_SW_RESET */
|
||||
#define RST_DP_TX (0x1 << 0)
|
||||
|
||||
/* ANALOG_CTL_1 */
|
||||
#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4)
|
||||
|
||||
|
||||
|
||||
/* ANALOG_CTL_3 */
|
||||
#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5)
|
||||
#define VCO_BIT_600_MICRO (0x5 << 0)
|
||||
|
||||
/* PLL_FILTER_CTL_1 */
|
||||
#define PD_RING_OSC (0x1 << 6)
|
||||
#define AUX_TERMINAL_CTRL_37_5_OHM (0x0 << 4)
|
||||
#define AUX_TERMINAL_CTRL_45_OHM (0x1 << 4)
|
||||
#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
|
||||
#define AUX_TERMINAL_CTRL_65_OHM (0x3 << 4)
|
||||
#define TX_CUR1_2X (0x1 << 2)
|
||||
#define TX_CUR_16_MA (0x3 << 0)
|
||||
|
||||
/* TX_AMP_TUNING_CTL */
|
||||
#define CH3_AMP_SHIFT (24)
|
||||
#define CH3_AMP_400_MV (0x0 << 24)
|
||||
#define CH2_AMP_SHIFT (16)
|
||||
#define CH2_AMP_400_MV (0x0 << 16)
|
||||
#define CH1_AMP_SHIFT (8)
|
||||
#define CH1_AMP_400_MV (0x0 << 8)
|
||||
#define CH0_AMP_SHIFT (0)
|
||||
#define CH0_AMP_400_MV (0x0 << 0)
|
||||
|
||||
/* AUX_HW_RETRY_CTL */
|
||||
#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8)
|
||||
#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3)
|
||||
#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3)
|
||||
#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS (0x1 << 3)
|
||||
#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS (0x2 << 3)
|
||||
#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3)
|
||||
#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0)
|
||||
|
||||
|
||||
|
||||
/* LN0_LINK_TRAINING_CTL */
|
||||
#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
|
||||
#define PRE_EMPHASIS_SET_SHIFT (3)
|
||||
|
||||
|
||||
/* PLL_CTL */
|
||||
#define DP_PLL_PD (0x1 << 7)
|
||||
#define DP_PLL_RESET (0x1 << 6)
|
||||
#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4)
|
||||
#define DP_PLL_REF_BIT_1_1250V (0x5 << 0)
|
||||
#define DP_PLL_REF_BIT_1_2500V (0x7 << 0)
|
||||
|
||||
/* PHY_TEST */
|
||||
#define MACRO_RST (0x1 << 5)
|
||||
#define CH1_TEST (0x1 << 1)
|
||||
#define CH0_TEST (0x1 << 0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define DP_TIMEOUT_LOOP_CNT 100
|
||||
#define MAX_CR_LOOP 5
|
||||
#define MAX_EQ_LOOP 5
|
||||
|
||||
|
||||
|
||||
#define GRF_EDP_REF_CLK_SEL_INTER (1 << 4)
|
||||
#define GRF_EDP_HDCP_EN (1 << 15)
|
||||
#define GRF_EDP_BIST_EN (1 << 14)
|
||||
#define GRF_EDP_MEM_CTL_BY_EDP (1 << 13)
|
||||
#define GRF_EDP_SECURE_EN (1 << 3)
|
||||
#define EDP_SEL_VOP_LIT (1 << 5)
|
||||
|
||||
/* PSR */
|
||||
#define PANEL_SELF_REFRESH_CAPABILITY_SUPPORTED_AND_VERSION 0x70
|
||||
#define PANEL_SELF_REFRESH_CAPABILITIES 0x71
|
||||
#define PSR_SUPPORT 0x1
|
||||
#define PSR_ENABLE 0x170
|
||||
#define SUORPSR_EVENT_STATUS_INDICATOR 0x2007
|
||||
#define SINK_DEVICE_PANEL_SELF_REFRESH_STATUS 0x2008
|
||||
#define LAST_RECEIVED_PSR_SDP 0x200a
|
||||
#define DEFINITION_WITHIN_LINKORSINK_DEVICE_POWER_CONTROL_FIELD 0x600
|
||||
|
||||
#define HB0 0x02F8
|
||||
#define HB1 0x02FC
|
||||
#define HB2 0x0300
|
||||
#define HB3 0x0304
|
||||
#define PB0 0x0308
|
||||
#define PB1 0x030C
|
||||
#define PB2 0x0310
|
||||
#define PB3 0x0314
|
||||
#define DB0 0x0254
|
||||
#define DB1 0x0258
|
||||
#define DB2 0x025C
|
||||
#define DB3 0x0260
|
||||
#define DB4 0x0264
|
||||
#define DB5 0x0268
|
||||
#define DB6 0x026c
|
||||
#define DB7 0x0270
|
||||
#define DP_PD 0x012C
|
||||
#define IF_TYPE 0x0244
|
||||
#define VSC_SHADOW_DB1 0x0320
|
||||
#define PSR_FRAME_UPDATA_CTRL 0x0318
|
||||
#define SPDIF_AUDIO_CTL_0 0x00D8
|
||||
/* PSR END */
|
||||
|
||||
enum dp_irq_type {
|
||||
DP_IRQ_TYPE_HP_CABLE_IN,
|
||||
DP_IRQ_TYPE_HP_CABLE_OUT,
|
||||
DP_IRQ_TYPE_HP_CHANGE,
|
||||
DP_IRQ_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
enum color_coefficient {
|
||||
COLOR_YCBCR601,
|
||||
COLOR_YCBCR709
|
||||
};
|
||||
|
||||
enum dynamic_range {
|
||||
VESA,
|
||||
CEA
|
||||
};
|
||||
|
||||
enum pll_status {
|
||||
DP_PLL_UNLOCKED,
|
||||
DP_PLL_LOCKED
|
||||
};
|
||||
|
||||
enum clock_recovery_m_value_type {
|
||||
CALCULATED_M,
|
||||
REGISTER_M
|
||||
};
|
||||
|
||||
enum video_timing_recognition_type {
|
||||
VIDEO_TIMING_FROM_CAPTURE,
|
||||
VIDEO_TIMING_FROM_REGISTER
|
||||
};
|
||||
|
||||
enum pattern_set {
|
||||
PRBS7,
|
||||
D10_2,
|
||||
TRAINING_PTN1,
|
||||
TRAINING_PTN2,
|
||||
DP_NONE
|
||||
};
|
||||
|
||||
enum color_space {
|
||||
CS_RGB,
|
||||
CS_YCBCR422,
|
||||
CS_YCBCR444
|
||||
};
|
||||
|
||||
enum color_depth {
|
||||
COLOR_6,
|
||||
COLOR_8,
|
||||
COLOR_10,
|
||||
COLOR_12
|
||||
};
|
||||
|
||||
enum link_rate_type {
|
||||
LINK_RATE_1_62GBPS = 0x06,
|
||||
LINK_RATE_2_70GBPS = 0x0a
|
||||
};
|
||||
|
||||
enum link_lane_count_type {
|
||||
LANE_CNT1 = 1,
|
||||
LANE_CNT2 = 2,
|
||||
LANE_CNT4 = 4
|
||||
};
|
||||
|
||||
enum link_training_state {
|
||||
LT_START,
|
||||
LT_CLK_RECOVERY,
|
||||
LT_EQ_TRAINING,
|
||||
FINISHED,
|
||||
FAILED
|
||||
};
|
||||
|
||||
enum voltage_swing_level {
|
||||
VOLTAGE_LEVEL_0,
|
||||
VOLTAGE_LEVEL_1,
|
||||
VOLTAGE_LEVEL_2,
|
||||
VOLTAGE_LEVEL_3,
|
||||
};
|
||||
|
||||
enum pre_emphasis_level {
|
||||
PRE_EMPHASIS_LEVEL_0,
|
||||
PRE_EMPHASIS_LEVEL_1,
|
||||
PRE_EMPHASIS_LEVEL_2,
|
||||
PRE_EMPHASIS_LEVEL_3,
|
||||
};
|
||||
|
||||
enum analog_power_block {
|
||||
AUX_BLOCK,
|
||||
CH0_BLOCK,
|
||||
CH1_BLOCK,
|
||||
CH2_BLOCK,
|
||||
CH3_BLOCK,
|
||||
ANALOG_TOTAL,
|
||||
POWER_ALL
|
||||
};
|
||||
|
||||
struct video_info {
|
||||
char *name;
|
||||
|
||||
bool h_sync_polarity;
|
||||
bool v_sync_polarity;
|
||||
bool interlaced;
|
||||
|
||||
enum color_space color_space;
|
||||
enum dynamic_range dynamic_range;
|
||||
enum color_coefficient ycbcr_coeff;
|
||||
enum color_depth color_depth;
|
||||
|
||||
enum link_rate_type link_rate;
|
||||
enum link_lane_count_type lane_count;
|
||||
};
|
||||
|
||||
struct link_train {
|
||||
int eq_loop;
|
||||
int cr_loop[4];
|
||||
|
||||
u8 link_rate;
|
||||
u8 lane_count;
|
||||
u8 training_lane[4];
|
||||
|
||||
enum link_training_state lt_state;
|
||||
};
|
||||
|
||||
enum {
|
||||
SOC_COMMON = 0,
|
||||
SOC_RK3399
|
||||
};
|
||||
|
||||
struct rk32_edp {
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct regmap *grf;
|
||||
unsigned int irq;
|
||||
struct clk *grf_clk;
|
||||
struct clk *pd;
|
||||
struct clk *clk_edp; /*clk for edp controller*/
|
||||
struct clk *clk_24m; /*clk for edp phy*/
|
||||
struct clk *pclk; /*clk for phb bus*/
|
||||
struct reset_control *rst_24m;
|
||||
struct reset_control *rst_apb;
|
||||
struct link_train link_train;
|
||||
struct video_info video_info;
|
||||
struct rk_screen screen;
|
||||
struct fb_monspecs specs;
|
||||
bool clk_on;
|
||||
bool edp_en;
|
||||
int soctype;
|
||||
struct dentry *debugfs_dir;
|
||||
};
|
||||
|
||||
|
||||
void rk32_edp_enable_video_mute(struct rk32_edp *edp, bool enable);
|
||||
void rk32_edp_stop_video(struct rk32_edp *edp);
|
||||
void rk32_edp_lane_swap(struct rk32_edp *edp, bool enable);
|
||||
void rk32_edp_init_refclk(struct rk32_edp *edp);
|
||||
void rk32_edp_init_interrupt(struct rk32_edp *edp);
|
||||
void rk32_edp_reset(struct rk32_edp *edp);
|
||||
void rk32_edp_config_interrupt(struct rk32_edp *edp);
|
||||
u32 rk32_edp_get_pll_lock_status(struct rk32_edp *edp);
|
||||
void rk32_edp_analog_power_ctr(struct rk32_edp *edp, bool enable);
|
||||
void rk32_edp_init_analog_func(struct rk32_edp *edp);
|
||||
void rk32_edp_init_hpd(struct rk32_edp *edp);
|
||||
void rk32_edp_reset_aux(struct rk32_edp *edp);
|
||||
void rk32_edp_init_aux(struct rk32_edp *edp);
|
||||
int rk32_edp_get_plug_in_status(struct rk32_edp *edp);
|
||||
void rk32_edp_enable_sw_function(struct rk32_edp *edp);
|
||||
int rk32_edp_start_aux_transaction(struct rk32_edp *edp);
|
||||
int rk32_edp_write_byte_to_dpcd(struct rk32_edp *edp,
|
||||
unsigned int reg_addr,
|
||||
unsigned char data);
|
||||
int rk32_edp_read_byte_from_dpcd(struct rk32_edp *edp,
|
||||
unsigned int reg_addr,
|
||||
unsigned char *data);
|
||||
int rk32_edp_write_bytes_to_dpcd(struct rk32_edp *edp,
|
||||
unsigned int reg_addr,
|
||||
unsigned int count,
|
||||
unsigned char data[]);
|
||||
int rk32_edp_read_bytes_from_dpcd(struct rk32_edp *edp,
|
||||
unsigned int reg_addr,
|
||||
unsigned int count,
|
||||
unsigned char data[]);
|
||||
int rk32_edp_select_i2c_device(struct rk32_edp *edp,
|
||||
unsigned int device_addr,
|
||||
unsigned int reg_addr);
|
||||
int rk32_edp_read_byte_from_i2c(struct rk32_edp *edp,
|
||||
unsigned int device_addr,
|
||||
unsigned int reg_addr,
|
||||
unsigned int *data);
|
||||
int rk32_edp_read_bytes_from_i2c(struct rk32_edp *edp,
|
||||
unsigned int device_addr,
|
||||
unsigned int reg_addr,
|
||||
unsigned int count,
|
||||
unsigned char edid[]);
|
||||
void rk32_edp_set_link_bandwidth(struct rk32_edp *edp, u32 bwtype);
|
||||
void rk32_edp_get_link_bandwidth(struct rk32_edp *edp, u32 *bwtype);
|
||||
void rk32_edp_set_lane_count(struct rk32_edp *edp, u32 count);
|
||||
void rk32_edp_get_lane_count(struct rk32_edp *edp, u32 *count);
|
||||
void rk32_edp_enable_enhanced_mode(struct rk32_edp *edp, bool enable);
|
||||
void rk32_edp_set_training_pattern(struct rk32_edp *edp,
|
||||
enum pattern_set pattern);
|
||||
void rk32_edp_set_lane0_pre_emphasis(struct rk32_edp *edp, u32 level);
|
||||
void rk32_edp_set_lane1_pre_emphasis(struct rk32_edp *edp, u32 level);
|
||||
void rk32_edp_set_lane2_pre_emphasis(struct rk32_edp *edp, u32 level);
|
||||
void rk32_edp_set_lane3_pre_emphasis(struct rk32_edp *edp, u32 level);
|
||||
void rk32_edp_set_lane0_link_training(struct rk32_edp *edp,
|
||||
u32 training_lane);
|
||||
void rk32_edp_set_lane1_link_training(struct rk32_edp *edp,
|
||||
u32 training_lane);
|
||||
void rk32_edp_set_lane2_link_training(struct rk32_edp *edp,
|
||||
u32 training_lane);
|
||||
void rk32_edp_set_lane3_link_training(struct rk32_edp *edp,
|
||||
u32 training_lane);
|
||||
u32 rk32_edp_get_lane0_link_training(struct rk32_edp *edp);
|
||||
u32 rk32_edp_get_lane1_link_training(struct rk32_edp *edp);
|
||||
u32 rk32_edp_get_lane2_link_training(struct rk32_edp *edp);
|
||||
u32 rk32_edp_get_lane3_link_training(struct rk32_edp *edp);
|
||||
void rk32_edp_reset_macro(struct rk32_edp *edp);
|
||||
int rk32_edp_init_video(struct rk32_edp *edp);
|
||||
|
||||
void rk32_edp_set_video_color_format(struct rk32_edp *edp,
|
||||
u32 color_depth,
|
||||
u32 color_space,
|
||||
u32 dynamic_range,
|
||||
u32 coeff);
|
||||
int rk32_edp_is_slave_video_stream_clock_on(struct rk32_edp *edp);
|
||||
void rk32_edp_set_video_cr_mn(struct rk32_edp *edp,
|
||||
enum clock_recovery_m_value_type type,
|
||||
u32 m_value,
|
||||
u32 n_value);
|
||||
void rk32_edp_set_video_timing_mode(struct rk32_edp *edp, u32 type);
|
||||
void rk32_edp_enable_video_master(struct rk32_edp *edp, bool enable);
|
||||
void rk32_edp_start_video(struct rk32_edp *edp);
|
||||
int rk32_edp_is_video_stream_on(struct rk32_edp *edp);
|
||||
void rk32_edp_config_video_slave_mode(struct rk32_edp *edp,
|
||||
struct video_info *video_info);
|
||||
void rk32_edp_enable_scrambling(struct rk32_edp *edp);
|
||||
void rk32_edp_disable_scrambling(struct rk32_edp *edp);
|
||||
void rk32_edp_rx_control(struct rk32_edp *edp, bool enable);
|
||||
int rk32_edp_bist_cfg(struct rk32_edp *edp);
|
||||
void rk32_edp_hw_link_training_en(struct rk32_edp *edp);
|
||||
int rk32_edp_get_hw_lt_status(struct rk32_edp *edp);
|
||||
int rk32_edp_wait_hw_lt_done(struct rk32_edp *edp);
|
||||
enum dp_irq_type rk32_edp_get_irq_type(struct rk32_edp *edp);
|
||||
void rk32_edp_clear_hotplug_interrupts(struct rk32_edp *edp);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,233 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include <linux/rockchip/iomap.h>
|
||||
#include <linux/rockchip/grf.h>
|
||||
#include "rk32_lvds.h"
|
||||
|
||||
|
||||
#define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset)
|
||||
#define grf_writel(v,offset) do{ writel_relaxed(v, RK_GRF_VIRT + offset);dsb();} while (0)
|
||||
|
||||
static struct rk32_lvds *rk32_lvds;
|
||||
|
||||
static int rk32_lvds_clk_enable(struct rk32_lvds *lvds)
|
||||
{
|
||||
if (!lvds->clk_on) {
|
||||
clk_prepare_enable(lvds->pd);
|
||||
clk_prepare_enable(lvds->pclk);
|
||||
lvds->clk_on = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk32_lvds_clk_disable(struct rk32_lvds *lvds)
|
||||
{
|
||||
if (lvds->clk_on) {
|
||||
clk_disable_unprepare(lvds->pclk);
|
||||
clk_disable_unprepare(lvds->pd);
|
||||
lvds->clk_on = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk32_lvds_disable(void)
|
||||
{
|
||||
struct rk32_lvds *lvds = rk32_lvds;
|
||||
grf_writel(0xffff8000, RK3288_GRF_SOC_CON7);
|
||||
writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_21); /*disable tx*/
|
||||
writel_relaxed(0xff, lvds->regs + LVDS_CFG_REG_c); /*disable pll*/
|
||||
rk32_lvds_clk_disable(lvds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk32_lvds_en(void)
|
||||
{
|
||||
struct rk32_lvds *lvds = rk32_lvds;
|
||||
struct rk_screen *screen = &lvds->screen;
|
||||
u32 h_bp = 0;
|
||||
u32 val = 0;
|
||||
|
||||
rk_fb_get_prmry_screen(screen);
|
||||
|
||||
/* enable clk */
|
||||
rk32_lvds_clk_enable(lvds);
|
||||
|
||||
/* select lcdc source */
|
||||
if (screen->lcdc_id == 1) /*lcdc1 = vop little,lcdc0 = vop big*/
|
||||
val = LVDS_SEL_VOP_LIT | (LVDS_SEL_VOP_LIT << 16);
|
||||
else
|
||||
val = LVDS_SEL_VOP_LIT << 16;
|
||||
grf_writel(val, RK3288_GRF_SOC_CON6);
|
||||
|
||||
/* set lvds format */
|
||||
val = screen->lvds_format;
|
||||
if ((screen->type == SCREEN_DUAL_LVDS) ||
|
||||
(screen->type == SCREEN_DUAL_LVDS_10BIT))
|
||||
val |= LVDS_DUAL | LVDS_CH0_EN | LVDS_CH1_EN;
|
||||
else if((screen->type == SCREEN_LVDS) ||
|
||||
(screen->type == SCREEN_LVDS_10BIT))
|
||||
val |= LVDS_CH0_EN;
|
||||
else if (screen->type == SCREEN_RGB)
|
||||
val = LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN;
|
||||
|
||||
h_bp = screen->mode.hsync_len + screen->mode.left_margin;
|
||||
if (h_bp & 0x01)
|
||||
val |= LVDS_START_PHASE_RST_1;
|
||||
|
||||
val |= (screen->pin_dclk << 8) | (screen->pin_hsync << 9) |
|
||||
(screen->pin_den << 10);
|
||||
val |= (0xffff << 16);
|
||||
grf_writel(val, RK3288_GRF_SOC_CON7);
|
||||
|
||||
if (screen->type == SCREEN_RGB) {
|
||||
val = 0x007f007f;//0x1<<6 |0x1 <<4;
|
||||
grf_writel(val, RK3288_GRF_GPIO1D_IOMUX);
|
||||
|
||||
lvds_writel(lvds, LVDS_CH0_REG_0, 0x7f);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_1, 0x40);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_2, 0x00);
|
||||
|
||||
lvds_writel(lvds, LVDS_CH0_REG_4, 0x3f);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_5, 0x3f);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_3, 0x46);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_d, 0x0a);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_20,0x44);/* 44:LSB 45:MSB*/
|
||||
writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_c); /*eanble pll*/
|
||||
writel_relaxed(0x92, lvds->regs + LVDS_CFG_REG_21); /*enable tx*/
|
||||
|
||||
lvds_writel(lvds, 0x100, 0x7f);
|
||||
lvds_writel(lvds, 0x104, 0x40);
|
||||
lvds_writel(lvds, 0x108, 0x00);
|
||||
lvds_writel(lvds, 0x10c, 0x46);
|
||||
lvds_writel(lvds, 0x110, 0x3f);
|
||||
lvds_writel(lvds, 0x114, 0x3f);
|
||||
lvds_writel(lvds, 0x134, 0x0a);
|
||||
} else {
|
||||
lvds_writel(lvds, LVDS_CH0_REG_0, 0xbf);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_1, 0x3f);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_2, 0xfe);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_3, 0x46);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_4, 0x00);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_d, 0x0a);
|
||||
lvds_writel(lvds, LVDS_CH0_REG_20,0x44);/* 44:LSB 45:MSB*/
|
||||
writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_c); /*eanble pll*/
|
||||
writel_relaxed(0x92, lvds->regs + LVDS_CFG_REG_21); /*enable tx*/
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct rk_fb_trsm_ops trsm_lvds_ops = {
|
||||
.enable = rk32_lvds_en,
|
||||
.disable = rk32_lvds_disable,
|
||||
};
|
||||
|
||||
static int rk32_lvds_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk32_lvds *lvds;
|
||||
struct resource *res;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
if (!np) {
|
||||
dev_err(&pdev->dev, "Missing device tree node.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk32_lvds), GFP_KERNEL);
|
||||
if (!lvds) {
|
||||
dev_err(&pdev->dev, "no memory for state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
lvds->dev = &pdev->dev;
|
||||
rk_fb_get_prmry_screen(&lvds->screen);
|
||||
if ((lvds->screen.type != SCREEN_RGB) &&
|
||||
(lvds->screen.type != SCREEN_LVDS) &&
|
||||
(lvds->screen.type != SCREEN_DUAL_LVDS) &&
|
||||
(lvds->screen.type != SCREEN_LVDS_10BIT) &&
|
||||
(lvds->screen.type != SCREEN_DUAL_LVDS_10BIT)) {
|
||||
dev_err(&pdev->dev, "screen is not lvds/rgb!\n");
|
||||
writel_relaxed(0xffff8000, RK_GRF_VIRT + RK3288_GRF_SOC_CON7);
|
||||
return -EINVAL;
|
||||
}
|
||||
platform_set_drvdata(pdev, lvds);
|
||||
dev_set_name(lvds->dev, "rk32-lvds");
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
lvds->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(lvds->regs)) {
|
||||
dev_err(&pdev->dev, "ioremap reg failed\n");
|
||||
return PTR_ERR(lvds->regs);
|
||||
}
|
||||
lvds->pclk = devm_clk_get(&pdev->dev,"pclk_lvds");
|
||||
if (IS_ERR(lvds->pclk)) {
|
||||
dev_err(&pdev->dev, "get clk failed\n");
|
||||
return PTR_ERR(lvds->pclk);
|
||||
}
|
||||
lvds->pd = devm_clk_get(&pdev->dev,"pd_lvds");
|
||||
if (IS_ERR(lvds->pd)) {
|
||||
dev_err(&pdev->dev, "get clk failed\n");
|
||||
return PTR_ERR(lvds->pd);
|
||||
}
|
||||
if (support_uboot_display()) {
|
||||
rk32_lvds_clk_enable(lvds);
|
||||
}
|
||||
|
||||
rk32_lvds = lvds;
|
||||
rk_fb_trsm_ops_register(&trsm_lvds_ops,SCREEN_LVDS);
|
||||
dev_info(&pdev->dev, "rk32 lvds driver probe success\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk32_lvds_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id rk32_lvds_dt_ids[] = {
|
||||
{.compatible = "rockchip,rk32-lvds",},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, rk32_lvds_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver rk32_lvds_driver = {
|
||||
.probe = rk32_lvds_probe,
|
||||
.driver = {
|
||||
.name = "rk32-lvds",
|
||||
.owner = THIS_MODULE,
|
||||
#if defined(CONFIG_OF)
|
||||
.of_match_table = of_match_ptr(rk32_lvds_dt_ids),
|
||||
#endif
|
||||
},
|
||||
.shutdown = rk32_lvds_shutdown,
|
||||
};
|
||||
|
||||
static int __init rk32_lvds_module_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk32_lvds_driver);
|
||||
}
|
||||
|
||||
static void __exit rk32_lvds_module_exit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
fs_initcall(rk32_lvds_module_init);
|
||||
module_exit(rk32_lvds_module_exit);
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __RK32_LVDS__
|
||||
#define __RK32_LVDS__
|
||||
|
||||
#define LVDS_CH0_REG_0 0x00
|
||||
#define LVDS_CH0_REG_1 0x04
|
||||
#define LVDS_CH0_REG_2 0x08
|
||||
#define LVDS_CH0_REG_3 0x0c
|
||||
#define LVDS_CH0_REG_4 0x10
|
||||
#define LVDS_CH0_REG_5 0x14
|
||||
#define LVDS_CH0_REG_9 0x24
|
||||
#define LVDS_CFG_REG_c 0x30
|
||||
#define LVDS_CH0_REG_d 0x34
|
||||
#define LVDS_CH0_REG_f 0x3c
|
||||
#define LVDS_CH0_REG_20 0x80
|
||||
#define LVDS_CFG_REG_21 0x84
|
||||
|
||||
#define LVDS_SEL_VOP_LIT (1 << 3)
|
||||
|
||||
#define LVDS_FMT_MASK (0x07 << 16)
|
||||
#define LVDS_MSB (0x01 << 3)
|
||||
#define LVDS_DUAL (0x01 << 4)
|
||||
#define LVDS_FMT_1 (0x01 << 5)
|
||||
#define LVDS_TTL_EN (0x01 << 6)
|
||||
#define LVDS_START_PHASE_RST_1 (0x01 << 7)
|
||||
#define LVDS_DCLK_INV (0x01 << 8)
|
||||
#define LVDS_CH0_EN (0x01 << 11)
|
||||
#define LVDS_CH1_EN (0x01 << 12)
|
||||
#define LVDS_PWRDN (0x01 << 15)
|
||||
|
||||
struct rk32_lvds {
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct clk *pclk; /*phb clk*/
|
||||
struct clk *pd;
|
||||
struct rk_screen screen;
|
||||
bool clk_on;
|
||||
};
|
||||
|
||||
static int inline lvds_writel(struct rk32_lvds *lvds, u32 offset, u32 val)
|
||||
{
|
||||
writel_relaxed(val, lvds->regs + offset);
|
||||
//if (lvds->screen.type == SCREEN_DUAL_LVDS)
|
||||
writel_relaxed(val, lvds->regs + offset + 0x100);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,335 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
drivers/video/rockchip/transmitter/rk32_mipi_dsi.h
|
||||
*/
|
||||
|
||||
#ifndef RK32_MIPI_DSI_H
|
||||
#define RK32_MIPI_DSI_H
|
||||
|
||||
#ifdef CONFIG_RK_3288_DSI_UBOOT
|
||||
#include <asm/arch/rkplat.h>
|
||||
#define RK_GRF_VIRT RKIO_GRF_PHYS
|
||||
#define RK3288_CRU_PHYS RKIO_CRU_PHYS
|
||||
|
||||
#define RK3288_GRF_SOC_CON6 GRF_SOC_CON6
|
||||
#define RK3288_GRF_SOC_CON14 GRF_SOC_CON14
|
||||
#else
|
||||
#include <linux/rockchip/grf.h>
|
||||
#endif
|
||||
|
||||
#define RK3399_GRF_CON7 0xe21c
|
||||
#define RK3399_GRF_CON20 0x6250
|
||||
#define RK3399_GRF_CON22 0x6258
|
||||
#define RK3399_GRF_CON23 0x625c
|
||||
#define RK3399_GRF_CON24 0x6260
|
||||
|
||||
#define MIPI_DSI_PHY_OFFSET 0x0C00
|
||||
#define MIPI_DSI_PHY_SIZE 0x34c
|
||||
|
||||
#define MIPI_DSI_HOST_OFFSET 0x1000
|
||||
|
||||
/* function bits definition register addr | bits | offest */
|
||||
#define REG_ADDR(a) ((a) << 16)
|
||||
#define REG_BITS(a) ((a) << 8)
|
||||
#define BITS_OFFSET(a) (a)
|
||||
#define DSI_HOST_BITS(addr, bits, bit_offset) (REG_ADDR((addr)+MIPI_DSI_HOST_OFFSET) \
|
||||
| REG_BITS(bits) | BITS_OFFSET(bit_offset))
|
||||
#define DSI_DPHY_BITS(addr, bits, bit_offset) (REG_ADDR((addr)+MIPI_DSI_PHY_OFFSET) \
|
||||
| REG_BITS(bits) | BITS_OFFSET(bit_offset))
|
||||
|
||||
/* DWC_DSI_VERSION_0x3133302A */
|
||||
#define VERSION DSI_HOST_BITS(0x000, 32, 0)
|
||||
#define shutdownz DSI_HOST_BITS(0x004, 1, 0)
|
||||
#define TO_CLK_DIVISION DSI_HOST_BITS(0x008, 8, 8)
|
||||
#define TX_ESC_CLK_DIVISION DSI_HOST_BITS(0x008, 8, 0)
|
||||
#define dpi_vcid DSI_HOST_BITS(0x00c, 2, 0)
|
||||
#define en18_loosely DSI_HOST_BITS(0x010, 1, 8)
|
||||
#define dpi_color_coding DSI_HOST_BITS(0x010, 4, 0) /* need modify in code */
|
||||
#define colorm_active_low DSI_HOST_BITS(0x014, 1, 4)
|
||||
#define shutd_active_low DSI_HOST_BITS(0x014, 1, 3)
|
||||
#define hsync_active_low DSI_HOST_BITS(0x014, 1, 2)
|
||||
#define vsync_active_low DSI_HOST_BITS(0x014, 1, 1)
|
||||
#define dataen_active_low DSI_HOST_BITS(0x014, 1, 0)
|
||||
#define outvact_lpcmd_time DSI_HOST_BITS(0x018, 8, 16) /* attence */
|
||||
#define invact_lpcmd_time DSI_HOST_BITS(0x018, 8, 0)
|
||||
/* #define dbi_vcid DSI_HOST_BITS(0x01c, 2, 0) */
|
||||
#define crc_rx_en DSI_HOST_BITS(0x02c, 1, 4)
|
||||
#define ecc_rx_en DSI_HOST_BITS(0x02c, 1, 3)
|
||||
#define bta_en DSI_HOST_BITS(0x02c, 1, 2)
|
||||
#define eotp_rx_en DSI_HOST_BITS(0x02c, 1, 1)
|
||||
#define eotp_tx_en DSI_HOST_BITS(0x02c, 1, 0)
|
||||
#define gen_vid_rx DSI_HOST_BITS(0x030, 2, 0)
|
||||
#define cmd_video_mode DSI_HOST_BITS(0x034, 1, 0)
|
||||
#define vpg_orientation DSI_HOST_BITS(0x038, 1, 24)
|
||||
#define vpg_mode DSI_HOST_BITS(0x038, 1, 20)
|
||||
#define vpg_en DSI_HOST_BITS(0x038, 1, 16)
|
||||
#define lp_cmd_en DSI_HOST_BITS(0x038, 1, 15)
|
||||
#define frame_bta_ack_en DSI_HOST_BITS(0x038, 1, 14)
|
||||
#define lp_hfp_en DSI_HOST_BITS(0x038, 1, 13)
|
||||
#define lp_hbp_en DSI_HOST_BITS(0x038, 1, 12)
|
||||
#define lp_vact_en DSI_HOST_BITS(0x038, 1, 11)
|
||||
#define lp_vfp_en DSI_HOST_BITS(0x038, 1, 10)
|
||||
#define lp_vbp_en DSI_HOST_BITS(0x038, 1, 9)
|
||||
#define lp_vsa_en DSI_HOST_BITS(0x038, 1, 8)
|
||||
#define vid_mode_type DSI_HOST_BITS(0x038, 2, 0)
|
||||
#define vid_pkt_size DSI_HOST_BITS(0x03c, 14, 0)
|
||||
#define num_chunks DSI_HOST_BITS(0x040, 13, 0)
|
||||
#define null_pkt_size DSI_HOST_BITS(0x044, 13, 0)
|
||||
#define vid_hsa_time DSI_HOST_BITS(0x048, 12, 0)
|
||||
#define vid_hbp_time DSI_HOST_BITS(0x04c, 12, 0)
|
||||
#define vid_hline_time DSI_HOST_BITS(0x050, 15, 0)
|
||||
#define vid_vsa_lines DSI_HOST_BITS(0x054, 10, 0)
|
||||
#define vid_vbp_lines DSI_HOST_BITS(0x058, 10, 0)
|
||||
#define vid_vfp_lines DSI_HOST_BITS(0x05c, 10, 0)
|
||||
#define vid_active_lines DSI_HOST_BITS(0x060, 14, 0)
|
||||
#define edpi_cmd_size DSI_HOST_BITS(0x064, 16, 0)
|
||||
#define max_rd_pkt_size DSI_HOST_BITS(0x068, 1, 24)
|
||||
#define dcs_lw_tx DSI_HOST_BITS(0x068, 1, 19)
|
||||
#define dcs_sr_0p_tx DSI_HOST_BITS(0x068, 1, 18)
|
||||
#define dcs_sw_1p_tx DSI_HOST_BITS(0x068, 1, 17)
|
||||
#define dcs_sw_0p_tx DSI_HOST_BITS(0x068, 1, 16)
|
||||
#define gen_lw_tx DSI_HOST_BITS(0x068, 1, 14)
|
||||
#define gen_sr_2p_tx DSI_HOST_BITS(0x068, 1, 13)
|
||||
#define gen_sr_1p_tx DSI_HOST_BITS(0x068, 1, 12)
|
||||
#define gen_sr_0p_tx DSI_HOST_BITS(0x068, 1, 11)
|
||||
#define gen_sw_2p_tx DSI_HOST_BITS(0x068, 1, 10)
|
||||
#define gen_sw_1p_tx DSI_HOST_BITS(0x068, 1, 9)
|
||||
#define gen_sw_0p_tx DSI_HOST_BITS(0x068, 1, 8)
|
||||
#define ack_rqst_en DSI_HOST_BITS(0x068, 1, 1)
|
||||
#define tear_fx_en DSI_HOST_BITS(0x068, 1, 0)
|
||||
#define GEN_HDR DSI_HOST_BITS(0x06c, 32, 0)
|
||||
#define GEN_PLD_DATA DSI_HOST_BITS(0x070, 32, 0)
|
||||
#define gen_rd_cmd_busy DSI_HOST_BITS(0x074, 1, 6)
|
||||
#define gen_pld_r_full DSI_HOST_BITS(0x074, 1, 5)
|
||||
#define gen_pld_r_empty DSI_HOST_BITS(0x074, 1, 4)
|
||||
#define gen_pld_w_full DSI_HOST_BITS(0x074, 1, 3) /* 800byte write GEN_PLD_DATA */
|
||||
#define gen_pld_w_empty DSI_HOST_BITS(0x074, 1, 2)
|
||||
#define gen_cmd_full DSI_HOST_BITS(0x074, 1, 1) /* 20 write GEN_HDR */
|
||||
#define gen_cmd_empty DSI_HOST_BITS(0x074, 1, 0)
|
||||
#define hstx_to_cnt DSI_HOST_BITS(0x078, 16, 16)
|
||||
#define lprx_to_cnt DSI_HOST_BITS(0x078, 16, 0)
|
||||
#define hs_rd_to_cnt DSI_HOST_BITS(0x07c, 16, 0)
|
||||
#define lp_rd_to_cnt DSI_HOST_BITS(0x080, 16, 0)
|
||||
#define presp_to_mode DSI_HOST_BITS(0x084, 1, 24)
|
||||
#define hs_wr_to_cnt DSI_HOST_BITS(0x084, 16, 0)
|
||||
#define lp_wr_to_cnt DSI_HOST_BITS(0x088, 16, 0)
|
||||
#define bta_to_cnt DSI_HOST_BITS(0x08c, 16, 0)
|
||||
/*
|
||||
#define send_3d_cfg DSI_HOST_BITS(0x090, 1, 16)
|
||||
#define right_first DSI_HOST_BITS(0x090, 1, 5)
|
||||
#define second_vsync DSI_HOST_BITS(0x090, 1, 4)
|
||||
#define format_3d DSI_HOST_BITS(0x090, 2, 2)
|
||||
#define mode_3d DSI_HOST_BITS(0x090, 2, 0)
|
||||
*/
|
||||
#define auto_clklane_ctrl DSI_HOST_BITS(0x094, 1, 1)
|
||||
#define phy_txrequestclkhs DSI_HOST_BITS(0x094, 1, 0)
|
||||
#define phy_hs2lp_time_clk_lane DSI_HOST_BITS(0x098, 10, 16)
|
||||
#define phy_hs2hs_time_clk_lane DSI_HOST_BITS(0x098, 10, 0)
|
||||
#define phy_hs2lp_time DSI_HOST_BITS(0x09c, 8, 24)
|
||||
#define phy_lp2hs_time DSI_HOST_BITS(0x09c, 8, 16)
|
||||
#define max_rd_time DSI_HOST_BITS(0x09c, 15, 0)
|
||||
/* new Dependency: DSI_HOST_FPGA = 0. Otherwise, this bit is reserved. */
|
||||
#define phy_forcepll DSI_HOST_BITS(0x0a0, 1, 3)
|
||||
#define phy_enableclk DSI_HOST_BITS(0x0a0, 1, 2)
|
||||
#define phy_rstz DSI_HOST_BITS(0x0a0, 1, 1)
|
||||
#define phy_shutdownz DSI_HOST_BITS(0x0a0, 1, 0)
|
||||
#define phy_stop_wait_time DSI_HOST_BITS(0x0a4, 8, 8)
|
||||
#define n_lanes DSI_HOST_BITS(0x0a4, 2, 0)
|
||||
#define phy_txexitulpslan DSI_HOST_BITS(0x0a8, 1, 3)
|
||||
#define phy_txrequlpslan DSI_HOST_BITS(0x0a8, 1, 2)
|
||||
#define phy_txexitulpsclk DSI_HOST_BITS(0x0a8, 1, 1)
|
||||
#define phy_txrequlpsclk DSI_HOST_BITS(0x0a8, 1, 0)
|
||||
#define phy_tx_triggers DSI_HOST_BITS(0x0ac, 4, 0)
|
||||
|
||||
#define phystopstateclklane DSI_HOST_BITS(0x0b0, 1, 2)
|
||||
#define phylock DSI_HOST_BITS(0x0b0, 1, 0)
|
||||
#define phy_testclk DSI_HOST_BITS(0x0b4, 1, 1)
|
||||
#define phy_testclr DSI_HOST_BITS(0x0b4, 1, 0)
|
||||
#define phy_testen DSI_HOST_BITS(0x0b8, 1, 16)
|
||||
#define phy_testdout DSI_HOST_BITS(0x0b8, 8, 8)
|
||||
#define phy_testdin DSI_HOST_BITS(0x0b8, 8, 0)
|
||||
|
||||
#define PHY_TEST_CTRL1 DSI_HOST_BITS(0x0b8, 17, 0)
|
||||
#define PHY_TEST_CTRL0 DSI_HOST_BITS(0x0b4, 2, 0)
|
||||
|
||||
#define INT_ST0 DSI_HOST_BITS(0x0bc, 21, 0)
|
||||
#define INT_ST1 DSI_HOST_BITS(0x0c0, 18, 0)
|
||||
#define INT_MKS0 DSI_HOST_BITS(0x0c4, 21, 0)
|
||||
#define INT_MKS1 DSI_HOST_BITS(0x0c8, 18, 0)
|
||||
#define INT_FORCE0 DSI_HOST_BITS(0x0d8, 21, 0)
|
||||
#define INT_FORCE1 DSI_HOST_BITS(0x0dc, 18, 0)
|
||||
|
||||
#define code_hs_rx_clock 0x34
|
||||
#define code_hs_rx_lane0 0x44
|
||||
#define code_hs_rx_lane1 0x54
|
||||
#define code_hs_rx_lane2 0x84
|
||||
#define code_hs_rx_lane3 0x94
|
||||
|
||||
#define code_pll_input_div_rat 0x17
|
||||
#define code_pll_loop_div_rat 0x18
|
||||
#define code_pll_input_loop_div_rat 0x19
|
||||
|
||||
#define code_hstxdatalanerequsetstatetime 0x70
|
||||
#define code_hstxdatalanepreparestatetime 0x71
|
||||
#define code_hstxdatalanehszerostatetime 0x72
|
||||
|
||||
/* rk312x MIPI DSI DPHY REGISTERS */
|
||||
#define DPHY_REGISTER0 DSI_DPHY_BITS(0x00, 32, 0)
|
||||
#define DPHY_REGISTER1 DSI_DPHY_BITS(0x04, 32, 0)
|
||||
#define DPHY_REGISTER3 DSI_DPHY_BITS(0x0c, 32, 0)
|
||||
#define DPHY_REGISTER4 DSI_DPHY_BITS(0x10, 32, 0)
|
||||
#define DPHY_REGISTER20 DSI_DPHY_BITS(0X80, 32, 0)
|
||||
|
||||
#define lane_en_ck DSI_DPHY_BITS(0x00, 1, 6)
|
||||
#define lane_en_3 DSI_DPHY_BITS(0x00, 1, 5)
|
||||
#define lane_en_2 DSI_DPHY_BITS(0x00, 1, 4)
|
||||
#define lane_en_1 DSI_DPHY_BITS(0x00, 1, 3)
|
||||
#define lane_en_0 DSI_DPHY_BITS(0x00, 1, 2)
|
||||
#define reg0_phy DSI_DPHY_BITS(0x00, 8, 0)
|
||||
|
||||
#define reg_da_ppfc DSI_DPHY_BITS(0x04, 1, 4)
|
||||
#define reg_da_syncrst DSI_DPHY_BITS(0x04, 1, 2)
|
||||
#define reg_da_ldopd DSI_DPHY_BITS(0x04, 1, 1)
|
||||
#define reg_da_pllpd DSI_DPHY_BITS(0x04, 1, 0)
|
||||
#define reg1_phy DSI_DPHY_BITS(0x04, 8, 0)
|
||||
#define reg5_phy DSI_DPHY_BITS(0x14, 3, 0)
|
||||
#define reg5_3_phy DSI_DPHY_BITS(0x14, 1, 3)
|
||||
#define reg5_7_phy DSI_DPHY_BITS(0x14, 1, 7)
|
||||
#define reg8_phy DSI_DPHY_BITS(0x20, 8, 0)
|
||||
#define rega_phy DSI_DPHY_BITS(0x28, 8, 0)
|
||||
#define regb_phy DSI_DPHY_BITS(0X2c, 8, 0)
|
||||
|
||||
#define reg_fbdiv_8 DSI_DPHY_BITS(0x0c, 1, 5)
|
||||
#define reg_prediv DSI_DPHY_BITS(0x0c, 5, 0)
|
||||
#define reg_fbdiv DSI_DPHY_BITS(0x10, 8, 0)
|
||||
#define reg9_phy DSI_DPHY_BITS(0x24, 8, 0)
|
||||
#define reg10_phy DSI_DPHY_BITS(0X40, 8, 0)
|
||||
#define reg10_4_6_phy DSI_DPHY_BITS(0X40, 3, 4)
|
||||
#define regb_0_3_phy DSI_DPHY_BITS(0X2c, 4, 0)
|
||||
|
||||
#define reg_dig_rstn DSI_DPHY_BITS(0X80, 1, 0)
|
||||
#define reg20_phy DSI_DPHY_BITS(0X80, 8, 0)
|
||||
|
||||
#define DPHY_CLOCK_OFFSET REG_ADDR(0X0100)
|
||||
#define DPHY_LANE0_OFFSET REG_ADDR(0X0180)
|
||||
#define DPHY_LANE1_OFFSET REG_ADDR(0X0200)
|
||||
#define DPHY_LANE2_OFFSET REG_ADDR(0X0280)
|
||||
#define DPHY_LANE3_OFFSET REG_ADDR(0X0300)
|
||||
|
||||
#define reg_ths_settle DSI_DPHY_BITS(0x0000, 4, 0)
|
||||
#define reg_hs_tlpx DSI_DPHY_BITS(0x0014, 6, 0)
|
||||
#define reg_hs_ths_prepare DSI_DPHY_BITS(0x0018, 7, 0)
|
||||
#define reg_hs_the_zero DSI_DPHY_BITS(0x001c, 6, 0)
|
||||
#define reg_hs_ths_trail DSI_DPHY_BITS(0x0020, 7, 0)
|
||||
#define reg_hs_ths_exit DSI_DPHY_BITS(0x0024, 5, 0)
|
||||
#define reg_hs_tclk_post DSI_DPHY_BITS(0x0028, 4, 0)
|
||||
#define reserved DSI_DPHY_BITS(0x002c, 1, 0)
|
||||
#define reg_hs_twakup_h DSI_DPHY_BITS(0x0030, 2, 0)
|
||||
#define reg_hs_twakup_l DSI_DPHY_BITS(0x0034, 8, 0)
|
||||
#define reg_hs_tclk_pre DSI_DPHY_BITS(0x0038, 4, 0)
|
||||
#define reg_hs_tta_go DSI_DPHY_BITS(0x0040, 6, 0)
|
||||
#define reg_hs_tta_sure DSI_DPHY_BITS(0x0044, 6, 0)
|
||||
#define reg_hs_tta_wait DSI_DPHY_BITS(0x0048, 6, 0)
|
||||
/* end of rk312x MIPI DSI DPHY REGISTERS */
|
||||
|
||||
/* global operation timing parameter */
|
||||
struct gotp_m {
|
||||
/* time uint is ns */
|
||||
u32 min;
|
||||
u32 value;
|
||||
u32 max;
|
||||
};
|
||||
|
||||
/*
|
||||
* default time unit is ns
|
||||
* Unit Interval, equal to the duration of any HS state on the Clock Lane
|
||||
*/
|
||||
struct gotp {
|
||||
u32 CLK_MISS; /* min:no max:60 */
|
||||
u32 CLK_POST; /* min:60 ns + 52*UI max:no */
|
||||
u32 CLK_PRE; /* min:8*UI max:no */
|
||||
u32 CLK_PREPARE; /* min:38 max:95 */
|
||||
u32 CLK_SETTLE; /* min:95 max:300 */
|
||||
u32 CLK_TERM_EN; /* min:Time for Dn to reach VTERM-EN max:38 */
|
||||
u32 CLK_TRAIL; /* min:60 max:no */
|
||||
u32 CLK_ZERO; /* min:300 - CLK_PREPARE max:no */
|
||||
u32 D_TERM_EN; /* min:Time for Dn to reach VTERM-EN max:35 ns + 4*UI */
|
||||
u32 EOT; /* min:no max:105 ns + n*12*UI */
|
||||
u32 HS_EXIT; /* min:100 max:no */
|
||||
u32 HS_PREPARE; /* min:40 ns + 4*UI max:85 ns + 6*UI */
|
||||
u32 HS_ZERO; /* min:145 ns + 10*UI - HS_PREPARE max:no */
|
||||
u32 HS_SETTLE; /* min:85 ns + 6*UI max:145 ns + 10*UI */
|
||||
u32 HS_SKIP; /* min:40 max:55 ns + 4*UI */
|
||||
u32 HS_TRAIL; /* min: max( n*8*UI, 60 ns + n*4*UI ) max:no */
|
||||
u32 NIT; /* min:100us max:no */
|
||||
u32 LPX; /* min:50 max:no */
|
||||
u32 TA_GET; /* min:5*TLPX */
|
||||
u32 TA_GO; /* min:4*TLPX */
|
||||
u32 TA_SURE; /* min:TLPX max:2*TLPX */
|
||||
u32 WAKEUP; /* min:1ms max:no */
|
||||
};
|
||||
|
||||
struct dsi_phy {
|
||||
u32 UI;
|
||||
u32 ref_clk; /* input_clk */
|
||||
u32 ddr_clk; /* data bit clk */
|
||||
u32 txbyte_clk; /* 1/8 of ddr_clk */
|
||||
u32 sys_clk;
|
||||
u32 pclk;
|
||||
u32 txclkesc;
|
||||
|
||||
u32 Tddr_clk; /* ps */
|
||||
u32 Ttxbyte_clk; /* ps */
|
||||
u32 Tsys_clk; /* ps */
|
||||
u32 Tpclk; /* ps */
|
||||
u32 Ttxclkesc; /* ps */
|
||||
|
||||
struct clk *refclk;
|
||||
unsigned long iobase;
|
||||
void __iomem *membase;
|
||||
u16 prediv;
|
||||
u16 fbdiv;
|
||||
u8 flag;
|
||||
struct gotp gotp;
|
||||
|
||||
};
|
||||
|
||||
struct dsi_host {
|
||||
u8 flag;
|
||||
u8 lane;
|
||||
u8 format;
|
||||
u8 video_mode;
|
||||
u32 clk;
|
||||
u32 irq;
|
||||
unsigned long iobase;
|
||||
void __iomem *membase;
|
||||
};
|
||||
|
||||
struct dsi {
|
||||
u8 dsi_id;
|
||||
u8 lcdc_id;
|
||||
u8 vid;
|
||||
u8 clk_on;
|
||||
struct regmap *grf_base;
|
||||
struct dsi_phy phy;
|
||||
struct dsi_host host;
|
||||
struct mipi_dsi_ops ops;
|
||||
struct mipi_dsi_screen screen;
|
||||
#ifdef CONFIG_MIPI_DSI_LINUX
|
||||
struct clk *dsi_pclk; /* for mipi phy */
|
||||
struct clk *dsi_host_pclk; /* for mipi host */
|
||||
struct clk *h2p_hclk;
|
||||
#endif
|
||||
struct dentry *debugfs_dir;
|
||||
struct platform_device *pdev;
|
||||
};
|
||||
|
||||
int rk_mipi_get_dsi_clk(void);
|
||||
int rk_mipi_get_dsi_num(void);
|
||||
int rk_mipi_get_dsi_lane(void);
|
||||
static int rk32_mipi_power_down_DDR(void);
|
||||
static int rk32_mipi_power_up_DDR(void);
|
||||
static void rk32_init_phy_mode(int lcdc_id);
|
||||
|
||||
|
||||
#endif /* end of RK32_MIPI_DSI_H */
|
||||
@@ -1,490 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/fb.h>
|
||||
#include <linux/delay.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/board.h>
|
||||
#include "rk610_lcd.h"
|
||||
#include <linux/mfd/rk610_core.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include "../hdmi/rk_hdmi.h"
|
||||
|
||||
static struct rk610_lcd_info *g_lcd_inf = NULL;
|
||||
//static int rk610_scaler_read_p0_reg(struct i2c_client *client, char reg, char *val)
|
||||
//{
|
||||
//return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
|
||||
//}
|
||||
|
||||
static int rk610_scaler_write_p0_reg(struct i2c_client *client, char reg, char *val)
|
||||
{
|
||||
return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
|
||||
}
|
||||
static void rk610_scaler_pll_enable(struct i2c_client *client)
|
||||
{
|
||||
char c;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
|
||||
g_lcd_inf->scl_inf.pll_pwr = ENABLE;
|
||||
|
||||
c = S_PLL_PWR(0)|S_PLL_RESET(0)|S_PLL_BYPASS(0);
|
||||
rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
|
||||
}
|
||||
static void rk610_scaler_pll_disable(struct i2c_client *client)
|
||||
{
|
||||
char c;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
|
||||
g_lcd_inf->scl_inf.pll_pwr = DISABLE;
|
||||
|
||||
c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);
|
||||
rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
|
||||
}
|
||||
static void rk610_scaler_enable(struct i2c_client *client)
|
||||
{
|
||||
char c;
|
||||
bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
g_lcd_inf->scl_inf.scl_pwr = ENABLE;
|
||||
#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
|
||||
if(g_lcd_inf->screen !=NULL){
|
||||
den_inv = g_lcd_inf->screen->s_den_inv;
|
||||
hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;
|
||||
clk_inv = g_lcd_inf->screen->s_clk_inv;
|
||||
}
|
||||
#endif
|
||||
c= SCL_BYPASS(0) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(ENABLE);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
|
||||
}
|
||||
static void rk610_scaler_disable(struct i2c_client *client)
|
||||
{
|
||||
char c;
|
||||
bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
|
||||
g_lcd_inf->scl_inf.scl_pwr = DISABLE;
|
||||
#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
|
||||
if(g_lcd_inf->screen !=NULL){
|
||||
den_inv = g_lcd_inf->screen->s_den_inv;
|
||||
hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;
|
||||
clk_inv = g_lcd_inf->screen->s_clk_inv;
|
||||
}
|
||||
#endif
|
||||
c= SCL_BYPASS(1) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(DISABLE);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
|
||||
}
|
||||
|
||||
static int rk610_output_config(struct i2c_client *client,struct rk_screen *screen,int mode)
|
||||
{
|
||||
char c=0;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
if(SCREEN_LVDS == screen->type){
|
||||
if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){
|
||||
c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(1) |LVDS_PLL_PWR_PIN(0) \
|
||||
|LVDS_LANE_IN_FORMAT(DATA_D0_MSB) \
|
||||
|LVDS_OUTPUT_FORMAT(screen->lvds_format) | LVDS_BIASE_PWR(1);
|
||||
#if defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL) && defined(CONFIG_HDMI_RK610)
|
||||
c |= LVDS_INPUT_SOURCE(FROM_LCD1);
|
||||
#else
|
||||
c |= LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL);
|
||||
#endif
|
||||
rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);
|
||||
c = LCD1_OUT_ENABLE(LCD1_AS_IN);
|
||||
rk610_scaler_write_p0_reg(client, LCD1_CON, &c);
|
||||
c = LVDS_OUT_ENABLE(0x0) |LVDS_TX_PWR_ENABLE(0x0);
|
||||
rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);
|
||||
}
|
||||
else{
|
||||
c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(0) |LVDS_PLL_PWR_PIN(1) \
|
||||
|LVDS_LANE_IN_FORMAT(DATA_D0_MSB) \
|
||||
|LVDS_OUTPUT_FORMAT(screen->lvds_format) | LVDS_BIASE_PWR(0);
|
||||
#if defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL) && defined(CONFIG_HDMI_RK610)
|
||||
c |= LVDS_INPUT_SOURCE(FROM_LCD1);
|
||||
#else
|
||||
c |= LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL);
|
||||
#endif
|
||||
rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);
|
||||
c = LCD1_OUT_ENABLE(LCD1_AS_IN);
|
||||
rk610_scaler_write_p0_reg(client, LCD1_CON, &c);
|
||||
c = LVDS_OUT_ENABLE(0xf) |LVDS_TX_PWR_ENABLE(0xf);
|
||||
rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);
|
||||
|
||||
}
|
||||
}else if(SCREEN_RGB == screen->type){
|
||||
if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){
|
||||
c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC((mode == LCD_OUT_SCL)?LCD1_FROM_SCL : LCD1_FROM_LCD0);
|
||||
rk610_scaler_write_p0_reg(client, LCD1_CON, &c);
|
||||
}
|
||||
else {
|
||||
c = LCD1_OUT_ENABLE(LCD1_AS_IN);
|
||||
rk610_scaler_write_p0_reg(client, LCD1_CON, &c);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
|
||||
static int rk610_scaler_pll_set(struct i2c_client *client,struct rk_screen *screen,u32 clkin )
|
||||
{
|
||||
char c=0;
|
||||
char M=0,N=0,OD=0;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
/***************SET SCALER PLL FROM CLKIN ,DIV 0*/
|
||||
if(screen->s_pixclock != 0){
|
||||
OD = (screen->s_pixclock)&0x3;
|
||||
N = (screen->s_pixclock >>4)&0xf;
|
||||
M = (screen->s_pixclock >>8)&0xff;
|
||||
}else {
|
||||
RK610_ERR(&client->dev,"RK610 Scaler pll not support rate \n");
|
||||
}
|
||||
c = S_PLL_FROM_DIV<<3 | S_PLL_DIV(0);
|
||||
rk610_scaler_write_p0_reg(client, CLOCK_CON0, &c);
|
||||
|
||||
c = S_DIV_N(N)| S_DIV_OD(OD);
|
||||
rk610_scaler_write_p0_reg(client, S_PLL_CON0, &c);
|
||||
c = S_DIV_M(M);
|
||||
rk610_scaler_write_p0_reg(client, S_PLL_CON1, &c);
|
||||
rk610_scaler_pll_enable(client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int scale_hv_factor(struct i2c_client *client ,u32 Hin_act, u32 Hout_act, u32 Vin_act, u32 Vout_act)
|
||||
{
|
||||
char c;
|
||||
u32 hfactor_f,vfactor_f,scl_factor_f;
|
||||
int hfactor;
|
||||
int vfactor;
|
||||
struct scl_hv_info HV2;
|
||||
hfactor_f = ((Hin_act-1)*4096)/(Hout_act-1);
|
||||
if(hfactor_f==4096)
|
||||
{hfactor = 0x1000;}
|
||||
else if(hfactor_f>(int)hfactor_f)
|
||||
{hfactor = (int)hfactor_f+1;}
|
||||
else
|
||||
{hfactor = (int)hfactor_f;}
|
||||
|
||||
scl_factor_f = Vin_act/Vout_act;
|
||||
if(scl_factor_f<2)
|
||||
{vfactor_f = ((Vin_act-1)*4096)/(Vout_act-1);}
|
||||
else
|
||||
{vfactor_f = ((Vin_act-2)*4096)/(Vout_act-1);}
|
||||
if(vfactor_f==4096)
|
||||
{vfactor = 0x1000;}
|
||||
else if(vfactor_f>(int)vfactor_f)
|
||||
{vfactor = (int)vfactor_f+1;}
|
||||
else
|
||||
{vfactor = (int)vfactor_f;}
|
||||
|
||||
HV2.scl_h= hfactor;
|
||||
HV2.scl_v= vfactor;
|
||||
/* SCL FACTOR */
|
||||
c = SCL_H_FACTOR_LSB(HV2.scl_h);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON1, &c);
|
||||
c = SCL_H_FACTOR_MSB(HV2.scl_h);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON2, &c);
|
||||
|
||||
c = SCL_V_FACTOR_LSB(HV2.scl_v);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON3, &c);
|
||||
c = SCL_V_FACTOR_MSB(HV2.scl_v);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON4, &c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk610_scaler_fator_config(struct i2c_client *client ,struct rk_screen *screen)
|
||||
{
|
||||
switch(screen->hdmi_resolution){
|
||||
case HDMI_1920x1080p_60Hz:
|
||||
case HDMI_1920x1080p_50Hz:
|
||||
rk610_scaler_pll_set(client,screen,148500000);
|
||||
/***************set scaler factor********************/
|
||||
scale_hv_factor(client,1920,screen->x_res,1080,screen->y_res);
|
||||
break;
|
||||
case HDMI_1280x720p_60Hz:
|
||||
case HDMI_1280x720p_50Hz:
|
||||
rk610_scaler_pll_set(client,screen,74250000);
|
||||
/***************set scaler factor********************/
|
||||
scale_hv_factor(client,1280,screen->x_res,720,screen->y_res);
|
||||
break;
|
||||
case HDMI_720x576p_50Hz_16_9:
|
||||
case HDMI_720x576p_50Hz_4_3:
|
||||
rk610_scaler_pll_set(client,screen,27000000);
|
||||
/***************set scaler factor********************/
|
||||
scale_hv_factor(client,720,screen->x_res,576,screen->y_res);
|
||||
break;
|
||||
case HDMI_720x480p_60Hz_16_9:
|
||||
case HDMI_720x480p_60Hz_4_3:
|
||||
rk610_scaler_pll_set(client,screen,27000000);
|
||||
/***************set scaler factor********************/
|
||||
scale_hv_factor(client,720,screen->x_res,480,screen->y_res);
|
||||
break;
|
||||
default :
|
||||
RK610_ERR(&client->dev,"RK610 not support dual display at hdmi resolution=%d \n",screen->hdmi_resolution);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int rk610_scaler_output_timing_config(struct i2c_client *client,struct rk_screen *screen)
|
||||
{
|
||||
char c;
|
||||
int h_st = screen->s_hsync_st;
|
||||
int hs_end = screen->s_hsync_len;
|
||||
int h_act_st = hs_end + screen->s_left_margin;
|
||||
int xres = screen->x_res;
|
||||
int h_act_end = h_act_st + xres;
|
||||
int h_total = h_act_end + screen->s_right_margin;
|
||||
int v_st = screen->s_vsync_st;
|
||||
int vs_end = screen->s_vsync_len;
|
||||
int v_act_st = vs_end + screen->s_upper_margin;
|
||||
int yres = screen->y_res;
|
||||
int v_act_end = v_act_st + yres;
|
||||
int v_total = v_act_end + screen->s_lower_margin;
|
||||
|
||||
/* SCL display Frame start point */
|
||||
c = SCL_DSP_HST_LSB(h_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON5, &c);
|
||||
c = SCL_DSP_HST_MSB(h_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON6, &c);
|
||||
|
||||
c = SCL_DSP_VST_LSB(v_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON7, &c);
|
||||
c = SCL_DSP_VST_MSB(v_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON8, &c);
|
||||
/* SCL output timing */
|
||||
|
||||
c = SCL_DSP_HTOTAL_LSB(h_total);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON9, &c);
|
||||
c = SCL_DSP_HTOTAL_MSB(h_total);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON10, &c);
|
||||
|
||||
c = SCL_DSP_HS_END(hs_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON11, &c);
|
||||
|
||||
c = SCL_DSP_HACT_ST_LSB(h_act_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON12, &c);
|
||||
c = SCL_DSP_HACT_ST_MSB(h_act_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON13, &c);
|
||||
|
||||
c = SCL_DSP_HACT_END_LSB(h_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON14, &c);
|
||||
c = SCL_DSP_HACT_END_MSB(h_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON15, &c);
|
||||
|
||||
c = SCL_DSP_VTOTAL_LSB(v_total);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON16, &c);
|
||||
c = SCL_DSP_VTOTAL_MSB(v_total);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON17, &c);
|
||||
|
||||
c = SCL_DSP_VS_END(vs_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON18, &c);
|
||||
|
||||
c = SCL_DSP_VACT_ST(v_act_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON19, &c);
|
||||
|
||||
c = SCL_DSP_VACT_END_LSB(v_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON20, &c);
|
||||
c = SCL_DSP_VACT_END_MSB(v_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON21, &c);
|
||||
|
||||
c = SCL_H_BORD_ST_LSB(h_act_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON22, &c);
|
||||
c = SCL_H_BORD_ST_MSB(h_act_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON23, &c);
|
||||
|
||||
c = SCL_H_BORD_END_LSB(h_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON24, &c);
|
||||
c = SCL_H_BORD_END_MSB(h_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON25, &c);
|
||||
|
||||
c = SCL_V_BORD_ST(v_act_st);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON26, &c);
|
||||
|
||||
c = SCL_V_BORD_END_LSB(v_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON27, &c);
|
||||
c = SCL_V_BORD_END_MSB(v_act_end);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON28, &c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int rk610_scaler_chg(struct i2c_client *client ,struct rk_screen *screen)
|
||||
{
|
||||
|
||||
RK610_DBG(&client->dev,"%s screen->hdmi_resolution=%d\n",__FUNCTION__,screen->hdmi_resolution);
|
||||
rk610_scaler_fator_config(client,screen);
|
||||
rk610_scaler_enable(client);
|
||||
rk610_scaler_output_timing_config(client,screen);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
static int rk610_lcd_scaler_bypass(struct i2c_client *client,bool enable)//enable:0 bypass 1: scale
|
||||
{
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
|
||||
rk610_scaler_disable(client);
|
||||
rk610_scaler_pll_disable(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void rk610_lcd_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct i2c_client *client = g_lcd_inf->client;
|
||||
char c;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
if(g_lcd_inf->screen != NULL){
|
||||
rk610_output_config(client,g_lcd_inf->screen,LCD_OUT_DISABLE);
|
||||
}
|
||||
|
||||
if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){
|
||||
c= SCL_BYPASS(1) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(DISABLE);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
|
||||
}
|
||||
if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){
|
||||
c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);
|
||||
rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
|
||||
}
|
||||
}
|
||||
|
||||
static void rk610_lcd_early_resume(struct early_suspend *h)
|
||||
{
|
||||
struct i2c_client *client = g_lcd_inf->client;
|
||||
char c;
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
|
||||
if(g_lcd_inf->screen != NULL){
|
||||
rk610_output_config(client,g_lcd_inf->screen,g_lcd_inf->disp_mode);
|
||||
}
|
||||
if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){
|
||||
c= SCL_BYPASS(0) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(ENABLE);
|
||||
rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
|
||||
}
|
||||
if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){
|
||||
c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);
|
||||
rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
int rk610_lcd_scaler_set_param(struct rk_screen *screen,bool enable )//enable:0 bypass 1: scale
|
||||
{
|
||||
int ret=0;
|
||||
struct i2c_client *client = g_lcd_inf->client;
|
||||
if(client == NULL){
|
||||
printk("%s client == NULL FAIL\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
if(screen == NULL){
|
||||
printk("%s screen == NULL FAIL\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
|
||||
|
||||
g_lcd_inf->screen = screen;
|
||||
|
||||
#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
|
||||
if(enable == 1){
|
||||
g_lcd_inf->disp_mode = LCD_OUT_SCL;
|
||||
rk610_output_config(client,screen,LCD_OUT_SCL);
|
||||
ret = rk610_scaler_chg(client,screen);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
g_lcd_inf->disp_mode = LCD_OUT_BYPASS;
|
||||
rk610_output_config(client,screen,LCD_OUT_BYPASS);
|
||||
ret = rk610_lcd_scaler_bypass(client,enable);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int rk610_lcd_init(struct rk610_core_info *rk610_core_info)
|
||||
{
|
||||
if(rk610_core_info->client == NULL){
|
||||
printk("%s client == NULL FAIL\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
RK610_DBG(&rk610_core_info->client->dev,"%s \n",__FUNCTION__);
|
||||
|
||||
g_lcd_inf = kmalloc(sizeof(struct rk610_lcd_info), GFP_KERNEL);
|
||||
if(!g_lcd_inf)
|
||||
{
|
||||
dev_err(&rk610_core_info->client->dev, ">> rk610 inf kmalloc fail!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(g_lcd_inf, 0, sizeof(struct rk610_lcd_info));
|
||||
|
||||
g_lcd_inf->client= rk610_core_info->client;
|
||||
|
||||
rk610_core_info->lcd_pdata = (void *)g_lcd_inf;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
g_lcd_inf->early_suspend.suspend = rk610_lcd_early_suspend;
|
||||
g_lcd_inf->early_suspend.resume = rk610_lcd_early_resume;
|
||||
g_lcd_inf->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB- 1;
|
||||
register_early_suspend(&g_lcd_inf->early_suspend);
|
||||
#endif
|
||||
g_lcd_inf->scl_inf.pll_pwr = DISABLE;
|
||||
g_lcd_inf->scl_inf.scl_pwr = DISABLE;
|
||||
g_lcd_inf->disp_mode = LCD_OUT_BYPASS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk610_lcd_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk610_core_info *core_info = NULL;
|
||||
rk_screen *screen = NULL;
|
||||
|
||||
core_info = dev_get_drvdata(pdev->dev.parent);
|
||||
if(!core_info)
|
||||
{
|
||||
dev_err(&pdev->dev,"rk610 core info is null\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
screen = rk_fb_get_prmry_screen();
|
||||
if(!screen)
|
||||
{
|
||||
dev_err(&pdev->dev,"the fb prmry screen is null!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
|
||||
screen->sscreen_set = rk610_lcd_scaler_set_param;
|
||||
#endif
|
||||
rk610_lcd_init(core_info);
|
||||
rk610_lcd_scaler_set_param(screen,0);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
static int rk610_lcd_remove(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk610_lcd_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_driver rk610_lcd_driver = {
|
||||
.driver = {
|
||||
.name = "rk610-lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = rk610_lcd_probe,
|
||||
.remove = rk610_lcd_remove,
|
||||
.shutdown = rk610_lcd_shutdown,
|
||||
};
|
||||
|
||||
static int __init rk610_lcd_module_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk610_lcd_driver);
|
||||
}
|
||||
fs_initcall(rk610_lcd_module_init);
|
||||
static void __exit rk610_lcd_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk610_lcd_driver);
|
||||
}
|
||||
module_exit(rk610_lcd_exit);
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _RK610_LCD_H
|
||||
#define _RK610_LCD_H
|
||||
#include <linux/mfd/rk610_core.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
#define ENABLE 1
|
||||
#define DISABLE 0
|
||||
|
||||
//LVDS lane input format
|
||||
#define DATA_D0_MSB 0
|
||||
#define DATA_D7_MSB 1
|
||||
//LVDS input source
|
||||
#define FROM_LCD1 0
|
||||
#define FROM_LCD0_OR_SCL 1
|
||||
|
||||
/* LCD1 config */
|
||||
#define LCD1_AS_IN 0
|
||||
#define LCD1_AS_OUT 1
|
||||
|
||||
//LCD1 output source
|
||||
#define LCD1_FROM_LCD0 0
|
||||
#define LCD1_FROM_SCL 1
|
||||
|
||||
//SCALER config
|
||||
#define NOBYPASS 0
|
||||
#define BYPASS 1
|
||||
|
||||
//SCALER PLL config
|
||||
#define S_PLL_PWR_ON 0
|
||||
#define S_PLL_PWR_DOWN 1
|
||||
|
||||
/* clock config */
|
||||
#define S_PLL_FROM_DIV 0
|
||||
#define S_PLL_FROM_CLKIN 1
|
||||
#define S_PLL_DIV(x) ((x)&0x7)
|
||||
/*********S_PLL_CON************/
|
||||
//S_PLL_CON0
|
||||
#define S_DIV_N(x) (((x)&0xf)<<4)
|
||||
#define S_DIV_OD(x) (((x)&3)<<0)
|
||||
//S_PLL_CON1
|
||||
#define S_DIV_M(x) ((x)&0xff)
|
||||
//S_PLL_CON2
|
||||
#define S_PLL_UNLOCK (0<<7) //0:unlock 1:pll_lock
|
||||
#define S_PLL_LOCK (1<<7) //0:unlock 1:pll_lock
|
||||
#define S_PLL_PWR(x) (((x)&1)<<2) //0:POWER UP 1:POWER DOWN
|
||||
#define S_PLL_RESET(x) (((x)&1)<<1) //0:normal 1:reset M/N dividers
|
||||
#define S_PLL_BYPASS(x) (((x)&1)<<0) //0:normal 1:bypass
|
||||
//LVDS_CON0
|
||||
#define LVDS_OUT_CLK_PIN(x) (((x)&1)<<7) //clk enable pin, 0: enable
|
||||
#define LVDS_OUT_CLK_PWR_PIN(x) (((x)&1)<<6) //clk pwr enable pin, 1: enable
|
||||
#define LVDS_PLL_PWR_PIN(x) (((x)&1)<<5) //pll pwr enable pin, 0:enable
|
||||
#define LVDS_BIASE_PWR(x) (((x)&1)<<4) //0: power down 1: normal work
|
||||
#define LVDS_LANE_IN_FORMAT(x) (((x)&1)<<3) //0: msb on D0 1:msb on D7
|
||||
#define LVDS_INPUT_SOURCE(x) (((x)&1)<<2) //0: from lcd1 1:from lcd0 or scaler
|
||||
#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<0) //00:8bit format-1 01:8bit format-2 10:8bit format-3 11:6bit format
|
||||
//LVDS_CON1
|
||||
#define LVDS_OUT_ENABLE(x) (((x)&0xf)<<4) //0:output enable 1:output disable
|
||||
#define LVDS_TX_PWR_ENABLE(x) (((x)&0xf)<<0) //0:working mode 1:power down
|
||||
//LCD1_CON
|
||||
#define LCD1_OUT_ENABLE(x) (((x)&1)<<1) //0:lcd1 as input 1:lcd1 as output
|
||||
#define LCD1_OUT_SRC(x) (((x)&1)<<0) //0:from lcd0 1:from scaler
|
||||
//SCL_CON0
|
||||
#define SCL_BYPASS(x) (((x)&1)<<4) //0:not bypass 1:bypass
|
||||
#define SCL_DEN_INV(x) (((x)&1)<<3) //scl_den_inv
|
||||
#define SCL_H_V_SYNC_INV(x) (((x)&1)<<2) //scl_sync_inv
|
||||
#define SCL_OUT_CLK_INV(x) (((x)&1)<<1) //scl_dclk_inv
|
||||
#define SCL_ENABLE(x) (((x)&1)<<0) //scaler enable
|
||||
//SCL_CON1
|
||||
#define SCL_H_FACTOR_LSB(x) ((x)&0xff) //scl_h_factor[7:0]
|
||||
//SCL_CON2
|
||||
#define SCL_H_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_h_factor[13:8]
|
||||
//SCL_CON3
|
||||
#define SCL_V_FACTOR_LSB(x) ((x)&0xff) //scl_v_factor[7:0]
|
||||
//SCL_CON4
|
||||
#define SCL_V_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_v_factor[13:8]
|
||||
//SCL_CON5
|
||||
#define SCL_DSP_HST_LSB(x) ((x)&0xff) //dsp_frame_hst[7:0]
|
||||
//SCL_CON6
|
||||
#define SCL_DSP_HST_MSB(x) (((x)>>8)&0xf) //dsp_frame_hst[11:8]
|
||||
//SCL_CON7
|
||||
#define SCL_DSP_VST_LSB(x) ((x)&0xff) //dsp_frame_vst[7:0]
|
||||
//SCL_CON8
|
||||
#define SCL_DSP_VST_MSB(x) (((x)>>8)&0xf) //dsp_frame_vst[11:8]
|
||||
//SCL_CON9
|
||||
#define SCL_DSP_HTOTAL_LSB(x) ((x)&0xff) //dsp_frame_htotal[7:0]
|
||||
//SCL_CON10
|
||||
#define SCL_DSP_HTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]
|
||||
//SCL_CON11
|
||||
#define SCL_DSP_HS_END(x) ((x)&0xff) //dsp_hs_end
|
||||
//SCL_CON12
|
||||
#define SCL_DSP_HACT_ST_LSB(x) ((x)&0xff) //dsp_hact_st[7:0]
|
||||
//SCL_CON13
|
||||
#define SCL_DSP_HACT_ST_MSB(x) (((x)>>8)&0x3) //dsp_hact_st[9:8]
|
||||
//SCL_CON14
|
||||
#define SCL_DSP_HACT_END_LSB(x) ((x)&0xff) //dsp_hact_end[7:0]
|
||||
//SCL_CON15
|
||||
#define SCL_DSP_HACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]
|
||||
//SCL_CON16
|
||||
#define SCL_DSP_VTOTAL_LSB(x) ((x)&0xff) //dsp_frame_vtotal[7:0]
|
||||
//SCL_CON17
|
||||
#define SCL_DSP_VTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]
|
||||
//SCL_CON18
|
||||
#define SCL_DSP_VS_END(x) ((x)&0xff) //dsp_vs_end
|
||||
//SCL_CON19
|
||||
#define SCL_DSP_VACT_ST(x) ((x)&0xff) //dsp_vact_st[7:0]
|
||||
//SCL_CON20
|
||||
#define SCL_DSP_VACT_END_LSB(x) ((x)&0xff) //dsp_vact_end[7:0]
|
||||
//SCL_CON21
|
||||
#define SCL_DSP_VACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]
|
||||
//SCL_CON22
|
||||
#define SCL_H_BORD_ST_LSB(x) ((x)&0xff) //dsp_hbord_st[7:0]
|
||||
//SCL_CON23
|
||||
#define SCL_H_BORD_ST_MSB(x) (((x)>>8)&0x3) //dsp_hbord_st[9:8]
|
||||
//SCL_CON24
|
||||
#define SCL_H_BORD_END_LSB(x) ((x)&0xff) //dsp_hbord_end[7:0]
|
||||
//SCL_CON25
|
||||
#define SCL_H_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_hbord_end[11:8]
|
||||
//SCL_CON26
|
||||
#define SCL_V_BORD_ST(x) ((x)&0xff) //dsp_vbord_st[7:0]
|
||||
//SCL_CON27
|
||||
#define SCL_V_BORD_END_LSB(x) ((x)&0xff) //dsp_vbord_end[7:0]
|
||||
//SCL_CON25
|
||||
#define SCL_V_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_vbord_end[11:8]
|
||||
|
||||
/* Scaler PLL CONFIG */
|
||||
#define S_PLL_NO_1 0
|
||||
#define S_PLL_NO_2 1
|
||||
#define S_PLL_NO_4 2
|
||||
#define S_PLL_NO_8 3
|
||||
#define S_PLL_M(x) (((x)&0xff)<<8)
|
||||
#define S_PLL_N(x) (((x)&0xf)<<4)
|
||||
#define S_PLL_NO(x) ((S_PLL_NO_##x)&0x3)
|
||||
|
||||
enum{
|
||||
HDMI_RATE_148500000,
|
||||
HDMI_RATE_74250000,
|
||||
HDMI_RATE_27000000,
|
||||
};
|
||||
/* Scaler clk setting */
|
||||
#define SCALE_PLL(_parent_rate,_rate,_m,_n,_no) \
|
||||
HDMI_RATE_ ## _parent_rate ##_S_RATE_ ## _rate \
|
||||
= S_PLL_M(_m) | S_PLL_N(_n) | S_PLL_NO(_no)
|
||||
#define SCALE_RATE(_parent_rate , _rate) \
|
||||
(HDMI_RATE_ ## _parent_rate ## _S_RATE_ ## _rate)
|
||||
|
||||
enum{
|
||||
SCALE_PLL(148500000, 66000000, 16, 9, 4),
|
||||
SCALE_PLL(148500000, 57375000, 17, 11, 4),
|
||||
SCALE_PLL(148500000, 54000000, 16, 11, 4),
|
||||
SCALE_PLL(148500000, 33000000, 16, 9, 8),
|
||||
SCALE_PLL(148500000, 30375000, 18, 11, 8),
|
||||
SCALE_PLL(148500000, 29700000, 16, 10, 8),
|
||||
SCALE_PLL(148500000, 25312500, 15, 11, 8),
|
||||
SCALE_PLL(148500000, 74250000, 12, 6, 4),
|
||||
SCALE_PLL(148500000, 50625000, 15, 11, 4),
|
||||
SCALE_PLL(148500000, 79199997, 32, 15, 4),
|
||||
SCALE_PLL(148500000, 45375000, 22, 9, 8),
|
||||
|
||||
SCALE_PLL(74250000, 66000000, 32, 9, 4),
|
||||
SCALE_PLL(74250000, 57375000, 34, 11, 4),
|
||||
SCALE_PLL(74250000, 54000000, 32, 11, 4),
|
||||
SCALE_PLL(74250000, 33000000, 32, 9, 8),
|
||||
SCALE_PLL(74250000, 30375000, 36, 11, 8),
|
||||
SCALE_PLL(74250000, 25312500, 30, 11, 8),
|
||||
SCALE_PLL(74250000, 74250000, 12, 3, 4),
|
||||
SCALE_PLL(74250000, 67500000, 40, 11, 4),
|
||||
SCALE_PLL(74250000, 50625000, 30, 11, 4),
|
||||
SCALE_PLL(74250000, 79199997, 64,15,4),
|
||||
SCALE_PLL(74250000, 44343750, 43, 9, 8),
|
||||
|
||||
SCALE_PLL(27000000, 75000000, 100, 9, 4),
|
||||
SCALE_PLL(27000000, 72000000, 32, 3, 4),
|
||||
SCALE_PLL(27000000, 63281250, 75, 4, 8),
|
||||
SCALE_PLL(27000000, 60000000, 80, 9, 4),
|
||||
SCALE_PLL(27000000, 54375000, 145, 9, 8),
|
||||
SCALE_PLL(27000000, 31500000, 28, 3, 8),
|
||||
SCALE_PLL(27000000, 30000000, 80, 9, 8),
|
||||
SCALE_PLL(27000000, 70312500, 125, 6, 8),
|
||||
SCALE_PLL(27000000, 46875000, 125, 9, 8),
|
||||
SCALE_PLL(27000000, 56250000, 25, 3, 4)
|
||||
};
|
||||
|
||||
enum {
|
||||
LCD_OUT_SCL,
|
||||
LCD_OUT_BYPASS,
|
||||
LCD_OUT_DISABLE,
|
||||
};
|
||||
struct rk610_pll_info{
|
||||
u32 parent_rate;
|
||||
u32 rate;
|
||||
int m;
|
||||
int n;
|
||||
int od;
|
||||
};
|
||||
struct lcd_mode_inf{
|
||||
int h_pw;
|
||||
int h_bp;
|
||||
int h_vd;
|
||||
int h_fp;
|
||||
int v_pw;
|
||||
int v_bp;
|
||||
int v_vd;
|
||||
int v_fp;
|
||||
int f_hst;
|
||||
int f_vst;
|
||||
struct rk610_pll_info pllclk;
|
||||
};
|
||||
struct scl_hv_info{
|
||||
int scl_h ;
|
||||
int scl_v;
|
||||
};
|
||||
|
||||
struct scl_info{
|
||||
bool pll_pwr;
|
||||
bool scl_pwr;
|
||||
struct scl_hv_info scl_hv;
|
||||
};
|
||||
struct rk610_lcd_info{
|
||||
int disp_mode;
|
||||
|
||||
struct rk_screen *screen;
|
||||
struct scl_info scl_inf;
|
||||
struct i2c_client *client;
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
};
|
||||
extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info);
|
||||
extern int rk610_lcd_scaler_set_param(struct rk_screen *screen,bool enable );
|
||||
#endif
|
||||
@@ -1,221 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include "rk616_lvds.h"
|
||||
|
||||
|
||||
struct rk616_lvds *g_lvds;
|
||||
|
||||
|
||||
static int rk616_lvds_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
|
||||
{
|
||||
struct rk616_route *route = &rk616->route;
|
||||
u32 val = 0;
|
||||
int ret;
|
||||
int odd = (screen->left_margin&0x01)?0:1;
|
||||
|
||||
if(!route->lvds_en) //lvds port is not used ,power down lvds
|
||||
{
|
||||
val &= ~(LVDS_CH1TTL_EN | LVDS_CH0TTL_EN | LVDS_CH1_PWR_EN |
|
||||
LVDS_CH0_PWR_EN | LVDS_CBG_PWR_EN);
|
||||
val |= LVDS_PLL_PWR_DN | (LVDS_CH1TTL_EN << 16) | (LVDS_CH0TTL_EN << 16) |
|
||||
(LVDS_CH1_PWR_EN << 16) | (LVDS_CH0_PWR_EN << 16) |
|
||||
(LVDS_CBG_PWR_EN << 16) | (LVDS_PLL_PWR_DN << 16);
|
||||
ret = rk616->write_dev(rk616,CRU_LVDS_CON0,&val);
|
||||
|
||||
if(!route->lcd1_input) //set lcd1 port for output as RGB interface
|
||||
{
|
||||
val = (LCD1_INPUT_EN << 16);
|
||||
ret = rk616->write_dev(rk616,CRU_IO_CON0,&val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(route->lvds_mode) //lvds mode
|
||||
{
|
||||
|
||||
if(route->lvds_ch_nr == 2) //dual lvds channel
|
||||
{
|
||||
val = 0;
|
||||
val &= ~(LVDS_CH0TTL_EN | LVDS_CH1TTL_EN | LVDS_PLL_PWR_DN);
|
||||
val = (LVDS_DCLK_INV)|(LVDS_CH1_PWR_EN) |(LVDS_CH0_PWR_EN) | LVDS_HBP_ODD(odd) |
|
||||
(LVDS_CBG_PWR_EN) | (LVDS_CH_SEL) | (LVDS_OUT_FORMAT(screen->lvds_format)) |
|
||||
(LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH1_PWR_EN << 16) |
|
||||
(LVDS_CH0_PWR_EN << 16) | (LVDS_CBG_PWR_EN << 16) | (LVDS_CH_SEL << 16) |
|
||||
(LVDS_OUT_FORMAT_MASK) | (LVDS_DCLK_INV << 16) | (LVDS_PLL_PWR_DN << 16) |
|
||||
(LVDS_HBP_ODD_MASK);
|
||||
ret = rk616->write_dev(rk616,CRU_LVDS_CON0,&val);
|
||||
|
||||
rk616_dbg(rk616->dev,"rk616 use dual lvds channel.......\n");
|
||||
}
|
||||
else //single lvds channel
|
||||
{
|
||||
val = 0;
|
||||
val &= ~(LVDS_CH0TTL_EN | LVDS_CH1TTL_EN | LVDS_CH1_PWR_EN | LVDS_PLL_PWR_DN | LVDS_CH_SEL); //use channel 0
|
||||
val |= (LVDS_CH0_PWR_EN) |(LVDS_CBG_PWR_EN) | (LVDS_OUT_FORMAT(screen->lvds_format)) |
|
||||
(LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH0_PWR_EN << 16) |
|
||||
(LVDS_DCLK_INV ) | (LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH0_PWR_EN << 16) |
|
||||
(LVDS_CBG_PWR_EN << 16)|(LVDS_CH_SEL << 16) | (LVDS_PLL_PWR_DN << 16)|
|
||||
(LVDS_OUT_FORMAT_MASK) | (LVDS_DCLK_INV << 16);
|
||||
ret = rk616->write_dev(rk616,CRU_LVDS_CON0,&val);
|
||||
|
||||
rk616_dbg(rk616->dev,"rk616 use single lvds channel.......\n");
|
||||
}
|
||||
|
||||
}
|
||||
else //mux lvds port to RGB mode
|
||||
{
|
||||
val &= ~(LVDS_CBG_PWR_EN| LVDS_CH1_PWR_EN | LVDS_CH0_PWR_EN);
|
||||
val |= (LVDS_CH0TTL_EN)|(LVDS_CH1TTL_EN )|(LVDS_PLL_PWR_DN)|
|
||||
(LVDS_CH0TTL_EN<< 16)|(LVDS_CH1TTL_EN<< 16)|(LVDS_CH1_PWR_EN << 16) |
|
||||
(LVDS_CH0_PWR_EN << 16)|(LVDS_CBG_PWR_EN << 16)|(LVDS_PLL_PWR_DN << 16);
|
||||
ret = rk616->write_dev(rk616,CRU_LVDS_CON0,&val);
|
||||
|
||||
val &= ~(LVDS_OUT_EN);
|
||||
val |= (LVDS_OUT_EN << 16);
|
||||
ret = rk616->write_dev(rk616,CRU_IO_CON0,&val);
|
||||
rk616_dbg(rk616->dev,"rk616 use RGB output.....\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int rk616_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass 1: scale
|
||||
{
|
||||
int ret;
|
||||
struct mfd_rk616 *rk616 = g_lvds->rk616;
|
||||
if(!rk616)
|
||||
{
|
||||
printk(KERN_ERR "%s:mfd rk616 is null!\n",__func__);
|
||||
return -1;
|
||||
}
|
||||
ret = rk616_display_router_cfg(rk616,screen,enable);
|
||||
ret = rk616_lvds_cfg(rk616,screen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int rk616_lvds_init_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
|
||||
{
|
||||
int ret ;
|
||||
ret = rk616_display_router_cfg(rk616,screen,0);
|
||||
ret = rk616_lvds_cfg(rk616,screen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_HAS_EARLYSUSPEND)
|
||||
static void rk616_lvds_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct rk616_lvds *lvds = container_of(h, struct rk616_lvds,early_suspend);
|
||||
struct mfd_rk616 *rk616 = lvds->rk616;
|
||||
u32 val = 0;
|
||||
int ret = 0;
|
||||
|
||||
val &= ~(LVDS_CH1_PWR_EN | LVDS_CH0_PWR_EN | LVDS_CBG_PWR_EN);
|
||||
val |= LVDS_PLL_PWR_DN |(LVDS_CH1_PWR_EN << 16) | (LVDS_CH0_PWR_EN << 16) |
|
||||
(LVDS_CBG_PWR_EN << 16) | (LVDS_PLL_PWR_DN << 16);
|
||||
ret = rk616->write_dev(rk616,CRU_LVDS_CON0,&val);
|
||||
|
||||
val = LCD1_INPUT_EN | (LCD1_INPUT_EN << 16);
|
||||
ret = rk616->write_dev(rk616,CRU_IO_CON0,&val);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void rk616_lvds_late_resume(struct early_suspend *h)
|
||||
{
|
||||
struct rk616_lvds *lvds = container_of(h, struct rk616_lvds,early_suspend);
|
||||
struct mfd_rk616 *rk616 = lvds->rk616;
|
||||
rk616->resume = 1;
|
||||
rk616_lvds_init_cfg(rk616,lvds->screen);
|
||||
rk616->resume = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int rk616_lvds_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk616_lvds *lvds = NULL;
|
||||
struct mfd_rk616 *rk616 = NULL;
|
||||
rk_screen *screen = NULL;
|
||||
lvds = kzalloc(sizeof(struct rk616_lvds),GFP_KERNEL);
|
||||
if(!lvds)
|
||||
{
|
||||
printk(KERN_ALERT "alloc for struct rk616_lvds fail\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rk616 = dev_get_drvdata(pdev->dev.parent);
|
||||
if(!rk616)
|
||||
{
|
||||
dev_err(&pdev->dev,"null mfd device rk616!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
else
|
||||
g_lvds = lvds;
|
||||
lvds->rk616 = rk616;
|
||||
|
||||
screen = rk_fb_get_prmry_screen();
|
||||
if(!screen)
|
||||
{
|
||||
dev_err(&pdev->dev,"the fb prmry screen is null!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
lvds->screen = screen;
|
||||
#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
|
||||
screen->sscreen_set = rk616_scaler_set_param;
|
||||
#endif
|
||||
rk616_lvds_init_cfg(rk616,screen);
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
lvds->early_suspend.suspend = rk616_lvds_early_suspend;
|
||||
lvds->early_suspend.resume = rk616_lvds_late_resume;
|
||||
lvds->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
|
||||
register_early_suspend(&lvds->early_suspend);
|
||||
#endif
|
||||
|
||||
|
||||
dev_info(&pdev->dev,"rk616 lvds probe success!\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int rk616_lvds_remove(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk616_lvds_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_driver rk616_lvds_driver = {
|
||||
.driver = {
|
||||
.name = "rk616-lvds",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = rk616_lvds_probe,
|
||||
.remove = rk616_lvds_remove,
|
||||
.shutdown = rk616_lvds_shutdown,
|
||||
};
|
||||
|
||||
static int __init rk616_lvds_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk616_lvds_driver);
|
||||
}
|
||||
fs_initcall(rk616_lvds_init);
|
||||
static void __exit rk616_lvds_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk616_lvds_driver);
|
||||
}
|
||||
module_exit(rk616_lvds_exit);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __RK616_VIF_H__
|
||||
#define __RK616_VIF_H__
|
||||
#include<linux/mfd/rk616.h>
|
||||
#include<linux/earlysuspend.h>
|
||||
#include<linux/rk_screen.h>
|
||||
|
||||
|
||||
struct rk616_lvds {
|
||||
struct mfd_rk616 *rk616;
|
||||
rk_screen *screen;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,453 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
drivers/video/rockchip/transmitter/rk616_mipi_dsi.h
|
||||
*/
|
||||
#include <linux/rockchip/grf.h>
|
||||
#ifndef RK616_MIPI_DSI_H
|
||||
#define RK616_MIPI_DSI_H
|
||||
|
||||
#define MIPI_DSI_PHY_OFFSET 0x0C00
|
||||
#define MIPI_DSI_PHY_SIZE 0x34c
|
||||
#define MIPI_DSI_HOST_OFFSET 0x1000
|
||||
|
||||
#ifdef DWC_DSI_VERSION_0x3131302A
|
||||
#define MIPI_DSI_HOST_SIZE 0x74
|
||||
#else
|
||||
#define MIPI_DSI_HOST_SIZE 0xcc
|
||||
#endif
|
||||
|
||||
//function bits definition register addr | bits | offest
|
||||
#define REG_ADDR(a) ((a) << 16)
|
||||
#define REG_BITS(a) ((a) << 8)
|
||||
#define BITS_OFFSET(a) (a)
|
||||
#define DSI_HOST_BITS(addr, bits, bit_offset) (REG_ADDR((addr)+MIPI_DSI_HOST_OFFSET) \
|
||||
| REG_BITS(bits) | BITS_OFFSET(bit_offset))
|
||||
#define DSI_DPHY_BITS(addr, bits, bit_offset) (REG_ADDR((addr)+MIPI_DSI_PHY_OFFSET) \
|
||||
| REG_BITS(bits) | BITS_OFFSET(bit_offset))
|
||||
|
||||
#ifdef DWC_DSI_VERSION_0x3131302A
|
||||
|
||||
#define VERSION DSI_HOST_BITS(0x00, 32, 0)
|
||||
#define GEN_HDR DSI_HOST_BITS(0x34, 32, 0)
|
||||
#define GEN_PLD_DATA DSI_HOST_BITS(0x38, 32, 0)
|
||||
#define ERROR_ST0 DSI_HOST_BITS(0x44, 21, 0)
|
||||
#define ERROR_ST1 DSI_HOST_BITS(0x48, 18, 0)
|
||||
#define ERROR_MSK0 DSI_HOST_BITS(0x4C, 21, 0)
|
||||
#define ERROR_MSK1 DSI_HOST_BITS(0x50, 18, 0)
|
||||
|
||||
#define shutdownz DSI_HOST_BITS(0x04, 1, 0)
|
||||
#define en18_loosely DSI_HOST_BITS(0x0c, 1, 10)
|
||||
#define colorm_active_low DSI_HOST_BITS(0x0c, 1, 9)
|
||||
#define shutd_active_low DSI_HOST_BITS(0x0c, 1, 8)
|
||||
#define hsync_active_low DSI_HOST_BITS(0x0c, 1, 7)
|
||||
#define vsync_active_low DSI_HOST_BITS(0x0c, 1, 6)
|
||||
#define dataen_active_low DSI_HOST_BITS(0x0c, 1, 5)
|
||||
#define dpi_color_coding DSI_HOST_BITS(0x0c, 3, 2)
|
||||
#define dpi_vcid DSI_HOST_BITS(0x0c, 1, 0)
|
||||
#define vid_hline_time DSI_HOST_BITS(0x28, 14, 18)
|
||||
#define vid_hbp_time DSI_HOST_BITS(0x28, 9, 9)
|
||||
#define vid_hsa_time DSI_HOST_BITS(0x28, 9, 0)
|
||||
#define vid_active_lines DSI_HOST_BITS(0x2c, 11, 16)
|
||||
#define vid_vfp_lines DSI_HOST_BITS(0x2c, 6, 10)
|
||||
#define vid_vbp_lines DSI_HOST_BITS(0x2c, 6, 4)
|
||||
#define vid_vsa_lines DSI_HOST_BITS(0x2c, 4, 0)
|
||||
#define TO_CLK_DIVISION DSI_HOST_BITS(0x08, 8, 8)
|
||||
#define TX_ESC_CLK_DIVISION DSI_HOST_BITS(0x08, 8, 0)
|
||||
#define gen_vid_rx DSI_HOST_BITS(0x18, 2, 5)
|
||||
#define crc_rx_en DSI_HOST_BITS(0x18, 1, 4)
|
||||
#define ecc_rx_en DSI_HOST_BITS(0x18, 1, 3)
|
||||
#define bta_en DSI_HOST_BITS(0x18, 1, 2)
|
||||
#define eotp_rx_en DSI_HOST_BITS(0x18, 1, 1)
|
||||
#define eotp_tx_en DSI_HOST_BITS(0x18, 1, 0)
|
||||
#define lp_cmd_en DSI_HOST_BITS(0x1c, 1, 12)
|
||||
#define frame_bta_ack_en DSI_HOST_BITS(0x1c, 1, 11)
|
||||
#define en_null_pkt DSI_HOST_BITS(0x1c, 1, 10)
|
||||
#define en_multi_pkt DSI_HOST_BITS(0x1c, 1, 9)
|
||||
#define lp_hfp_en DSI_HOST_BITS(0x1c, 1, 8)
|
||||
#define lp_hbp_en DSI_HOST_BITS(0x1c, 1, 7)
|
||||
#define lp_vact_en DSI_HOST_BITS(0x1c, 1, 6)
|
||||
#define lp_vfp_en DSI_HOST_BITS(0x1c, 1, 5)
|
||||
#define lp_vbp_en DSI_HOST_BITS(0x1c, 1, 4)
|
||||
#define lp_vsa_en DSI_HOST_BITS(0x1c, 1, 3)
|
||||
#define vid_mode_type DSI_HOST_BITS(0x1c, 2, 1)
|
||||
#define en_video_mode DSI_HOST_BITS(0x1c, 1, 0)
|
||||
#define null_pkt_size DSI_HOST_BITS(0x20, 10, 21)
|
||||
#define num_chunks DSI_HOST_BITS(0x20, 10, 11)
|
||||
#define vid_pkt_size DSI_HOST_BITS(0x20, 11, 0)
|
||||
#define tear_fx_en DSI_HOST_BITS(0x24, 1, 14)
|
||||
#define ack_rqst_en DSI_HOST_BITS(0x24, 1, 13)
|
||||
#define dcs_lw_tx DSI_HOST_BITS(0x24, 1, 12)
|
||||
#define gen_lw_tx DSI_HOST_BITS(0x24, 1, 11)
|
||||
#define max_rd_pkt_size DSI_HOST_BITS(0x24, 1, 10)
|
||||
#define dcs_sr_0p_tx DSI_HOST_BITS(0x24, 1, 9)
|
||||
#define dcs_sw_1p_tx DSI_HOST_BITS(0x24, 1, 8)
|
||||
#define dcs_sw_0p_tx DSI_HOST_BITS(0x24, 1, 7)
|
||||
#define gen_sr_2p_tx DSI_HOST_BITS(0x24, 1, 6)
|
||||
#define gen_sr_1p_tx DSI_HOST_BITS(0x24, 1, 5)
|
||||
#define gen_sr_0p_tx DSI_HOST_BITS(0x24, 1, 4)
|
||||
#define gen_sw_2p_tx DSI_HOST_BITS(0x24, 1, 3)
|
||||
#define gen_sw_1p_tx DSI_HOST_BITS(0x24, 1, 2)
|
||||
#define gen_sw_0p_tx DSI_HOST_BITS(0x24, 1, 1)
|
||||
#define en_cmd_mode DSI_HOST_BITS(0x24, 1, 0)
|
||||
#define phy_hs2lp_time DSI_HOST_BITS(0x30, 8, 24)
|
||||
#define phy_lp2hs_time DSI_HOST_BITS(0x30, 8, 16)
|
||||
#define max_rd_time DSI_HOST_BITS(0x30, 15, 0)
|
||||
#define lprx_to_cnt DSI_HOST_BITS(0x40, 16, 16)
|
||||
#define hstx_to_cnt DSI_HOST_BITS(0x40, 16, 0)
|
||||
#define phy_enableclk DSI_HOST_BITS(0x54, 1, 2)
|
||||
//#define phy_rstz DSI_HOST_BITS(0x54, 1, 1)
|
||||
//#define phy_shutdownz DSI_HOST_BITS(0x54, 1, 0)
|
||||
|
||||
#define phy_stop_wait_time DSI_HOST_BITS(0x58, 8, 2)
|
||||
#define n_lanes DSI_HOST_BITS(0x58, 2, 0)
|
||||
#define phy_tx_triggers DSI_HOST_BITS(0x5c, 4, 5)
|
||||
#define phy_txexitulpslan DSI_HOST_BITS(0x5c, 1, 4)
|
||||
#define phy_txrequlpslan DSI_HOST_BITS(0x5c, 1, 3)
|
||||
#define phy_txexitulpsclk DSI_HOST_BITS(0x5c, 1, 2)
|
||||
#define phy_txrequlpsclk DSI_HOST_BITS(0x5c, 1, 1)
|
||||
#define phy_txrequestclkhs DSI_HOST_BITS(0x5c, 1, 0)
|
||||
#define phy_testclk DSI_HOST_BITS(0x64, 1, 1)
|
||||
#define phy_testclr DSI_HOST_BITS(0x64, 1, 0)
|
||||
#define phy_testen DSI_HOST_BITS(0x68, 1, 16)
|
||||
#define phy_testdout DSI_HOST_BITS(0x68, 8, 8)
|
||||
#define phy_testdin DSI_HOST_BITS(0x68, 8, 0)
|
||||
#define outvact_lpcmd_time DSI_HOST_BITS(0x70, 8, 8)
|
||||
#define invact_lpcmd_time DSI_HOST_BITS(0x70, 8, 0)
|
||||
#define gen_rd_cmd_busy DSI_HOST_BITS(0x3c, 1, 6)
|
||||
#define gen_pld_r_full DSI_HOST_BITS(0x3c, 1, 5)
|
||||
#define gen_pld_r_empty DSI_HOST_BITS(0x3c, 1, 4)
|
||||
#define gen_pld_w_full DSI_HOST_BITS(0x3c, 1, 3) //800byte write GEN_PLD_DATA
|
||||
#define gen_pld_w_empty DSI_HOST_BITS(0x3c, 1, 2)
|
||||
#define gen_cmd_full DSI_HOST_BITS(0x3c, 1, 1) //20 write GEN_HDR
|
||||
#define gen_cmd_empty DSI_HOST_BITS(0x3c, 1, 0)
|
||||
#define phystopstateclklane DSI_HOST_BITS(0x60, 1, 2)
|
||||
#define phylock DSI_HOST_BITS(0x60, 1, 0)
|
||||
|
||||
#else //***************************************************************//
|
||||
//DWC_DSI_VERSION_0x3133302A
|
||||
#define VERSION DSI_HOST_BITS(0x000, 32, 0)
|
||||
#define shutdownz DSI_HOST_BITS(0x004, 1, 0)
|
||||
#define TO_CLK_DIVISION DSI_HOST_BITS(0x008, 8, 8)
|
||||
#define TX_ESC_CLK_DIVISION DSI_HOST_BITS(0x008, 8, 0)
|
||||
#define dpi_vcid DSI_HOST_BITS(0x00c, 2, 0)
|
||||
#define en18_loosely DSI_HOST_BITS(0x010, 1, 8)
|
||||
#define dpi_color_coding DSI_HOST_BITS(0x010, 4, 0) //need modify in code
|
||||
#define colorm_active_low DSI_HOST_BITS(0x014, 1, 4)
|
||||
#define shutd_active_low DSI_HOST_BITS(0x014, 1, 3)
|
||||
#define hsync_active_low DSI_HOST_BITS(0x014, 1, 2)
|
||||
#define vsync_active_low DSI_HOST_BITS(0x014, 1, 1)
|
||||
#define dataen_active_low DSI_HOST_BITS(0x014, 1, 0)
|
||||
#define outvact_lpcmd_time DSI_HOST_BITS(0x018, 8, 16) //attence
|
||||
#define invact_lpcmd_time DSI_HOST_BITS(0x018, 8, 0)
|
||||
//#define dbi_vcid DSI_HOST_BITS(0x01c, 2, 0)
|
||||
#define crc_rx_en DSI_HOST_BITS(0x02c, 1, 4)
|
||||
#define ecc_rx_en DSI_HOST_BITS(0x02c, 1, 3)
|
||||
#define bta_en DSI_HOST_BITS(0x02c, 1, 2)
|
||||
#define eotp_rx_en DSI_HOST_BITS(0x02c, 1, 1)
|
||||
#define eotp_tx_en DSI_HOST_BITS(0x02c, 1, 0)
|
||||
#define gen_vid_rx DSI_HOST_BITS(0x030, 2, 0) //libing (0x030, 2, 5)-> (0x030, 2, 0)
|
||||
#define cmd_video_mode DSI_HOST_BITS(0x034, 1, 0)
|
||||
#define vpg_orientation DSI_HOST_BITS(0x038, 1, 24) //libing
|
||||
#define vpg_mode DSI_HOST_BITS(0x038, 1, 20) //libing
|
||||
#define vpg_en DSI_HOST_BITS(0x038, 1, 16) //libing
|
||||
#define lp_cmd_en DSI_HOST_BITS(0x038, 1, 15)
|
||||
#define frame_bta_ack_en DSI_HOST_BITS(0x038, 1, 14)
|
||||
#define lp_hfp_en DSI_HOST_BITS(0x038, 1, 13)
|
||||
#define lp_hbp_en DSI_HOST_BITS(0x038, 1, 12)
|
||||
#define lp_vact_en DSI_HOST_BITS(0x038, 1, 11)
|
||||
#define lp_vfp_en DSI_HOST_BITS(0x038, 1, 10)
|
||||
#define lp_vbp_en DSI_HOST_BITS(0x038, 1, 9)
|
||||
#define lp_vsa_en DSI_HOST_BITS(0x038, 1, 8)
|
||||
#define vid_mode_type DSI_HOST_BITS(0x038, 2, 0)
|
||||
#define vid_pkt_size DSI_HOST_BITS(0x03c, 14, 0)
|
||||
#define num_chunks DSI_HOST_BITS(0x040, 13, 0)
|
||||
#define null_pkt_size DSI_HOST_BITS(0x044, 13, 0)
|
||||
#define vid_hsa_time DSI_HOST_BITS(0x048, 12, 0)
|
||||
#define vid_hbp_time DSI_HOST_BITS(0x04c, 12, 0)
|
||||
#define vid_hline_time DSI_HOST_BITS(0x050, 15, 0)
|
||||
#define vid_vsa_lines DSI_HOST_BITS(0x054, 10, 0)
|
||||
#define vid_vbp_lines DSI_HOST_BITS(0x058, 10, 0)
|
||||
#define vid_vfp_lines DSI_HOST_BITS(0x05c, 10, 0)
|
||||
#define vid_active_lines DSI_HOST_BITS(0x060, 14, 0)
|
||||
#define max_rd_pkt_size DSI_HOST_BITS(0x068, 1, 24)
|
||||
#define dcs_lw_tx DSI_HOST_BITS(0x068, 1, 19)
|
||||
#define dcs_sr_0p_tx DSI_HOST_BITS(0x068, 1, 18)
|
||||
#define dcs_sw_1p_tx DSI_HOST_BITS(0x068, 1, 17)
|
||||
#define dcs_sw_0p_tx DSI_HOST_BITS(0x068, 1, 16)
|
||||
#define gen_lw_tx DSI_HOST_BITS(0x068, 1, 14)
|
||||
#define gen_sr_2p_tx DSI_HOST_BITS(0x068, 1, 13)
|
||||
#define gen_sr_1p_tx DSI_HOST_BITS(0x068, 1, 12)
|
||||
#define gen_sr_0p_tx DSI_HOST_BITS(0x068, 1, 11)
|
||||
#define gen_sw_2p_tx DSI_HOST_BITS(0x068, 1, 10)
|
||||
#define gen_sw_1p_tx DSI_HOST_BITS(0x068, 1, 9)
|
||||
#define gen_sw_0p_tx DSI_HOST_BITS(0x068, 1, 8)
|
||||
#define ack_rqst_en DSI_HOST_BITS(0x068, 1, 1)
|
||||
#define tear_fx_en DSI_HOST_BITS(0x068, 1, 0)
|
||||
#define GEN_HDR DSI_HOST_BITS(0x06c, 32, 0)
|
||||
#define GEN_PLD_DATA DSI_HOST_BITS(0x070, 32, 0) //need modify
|
||||
#define gen_rd_cmd_busy DSI_HOST_BITS(0x074, 1, 6)
|
||||
#define gen_pld_r_full DSI_HOST_BITS(0x074, 1, 5)
|
||||
#define gen_pld_r_empty DSI_HOST_BITS(0x074, 1, 4)
|
||||
#define gen_pld_w_full DSI_HOST_BITS(0x074, 1, 3) //800byte write GEN_PLD_DATA
|
||||
#define gen_pld_w_empty DSI_HOST_BITS(0x074, 1, 2)
|
||||
#define gen_cmd_full DSI_HOST_BITS(0x074, 1, 1) //20 write GEN_HDR
|
||||
#define gen_cmd_empty DSI_HOST_BITS(0x074, 1, 0)
|
||||
#define hstx_to_cnt DSI_HOST_BITS(0x078, 16, 16) //need modify
|
||||
#define lprx_to_cnt DSI_HOST_BITS(0x078, 16, 0)
|
||||
#define hs_rd_to_cnt DSI_HOST_BITS(0x07c, 16, 0) //new(read)
|
||||
#define lp_rd_to_cnt DSI_HOST_BITS(0x080, 16, 0) //new(read)
|
||||
#define presp_to_mode DSI_HOST_BITS(0x084, 1, 24) //new
|
||||
#define hs_wr_to_cnt DSI_HOST_BITS(0x084, 16, 0) //new
|
||||
#define lp_wr_to_cnt DSI_HOST_BITS(0x088, 16, 0) //new
|
||||
#define bta_to_cnt DSI_HOST_BITS(0x08c, 16, 0) //new
|
||||
//#define send_3d_cfg DSI_HOST_BITS(0x090, 1, 16) //new
|
||||
//#define right_first DSI_HOST_BITS(0x090, 1, 5) //new
|
||||
//#define second_vsync DSI_HOST_BITS(0x090, 1, 4) //new
|
||||
//#define format_3d DSI_HOST_BITS(0x090, 2, 2) //new
|
||||
//#define mode_3d DSI_HOST_BITS(0x090, 2, 0) //new
|
||||
#define auto_clklane_ctrl DSI_HOST_BITS(0x094, 1, 1) //new
|
||||
#define phy_txrequestclkhs DSI_HOST_BITS(0x094, 1, 0)
|
||||
#define phy_hs2lp_time_clk_lane DSI_HOST_BITS(0x098, 10, 16) //libing
|
||||
#define phy_hs2hs_time_clk_lane DSI_HOST_BITS(0x098, 10, 0) //libing
|
||||
#define phy_hs2lp_time DSI_HOST_BITS(0x09c, 8, 24)
|
||||
#define phy_lp2hs_time DSI_HOST_BITS(0x09c, 8, 16)
|
||||
#define max_rd_time DSI_HOST_BITS(0x09c, 15, 0)
|
||||
#define phy_forcepll DSI_HOST_BITS(0x0a0, 1, 3) //new Dependency: DSI_HOST_FPGA = 0. Otherwise, this bit is reserved.
|
||||
#define phy_enableclk DSI_HOST_BITS(0x0a0, 1, 2)
|
||||
#define phy_rstz DSI_HOST_BITS(0x0a0, 1, 1) //libing
|
||||
#define phy_shutdownz DSI_HOST_BITS(0x0a0, 1, 0) //libing
|
||||
#define phy_stop_wait_time DSI_HOST_BITS(0x0a4, 8, 8)
|
||||
#define n_lanes DSI_HOST_BITS(0x0a4, 2, 0)
|
||||
#define phy_txexitulpslan DSI_HOST_BITS(0x0a8, 1, 3)
|
||||
#define phy_txrequlpslan DSI_HOST_BITS(0x0a8, 1, 2)
|
||||
#define phy_txexitulpsclk DSI_HOST_BITS(0x0a8, 1, 1)
|
||||
#define phy_txrequlpsclk DSI_HOST_BITS(0x0a8, 1, 0)
|
||||
#define phy_tx_triggers DSI_HOST_BITS(0x0ac, 4, 0)
|
||||
|
||||
#define phystopstateclklane DSI_HOST_BITS(0x0b0, 1, 2)
|
||||
#define phylock DSI_HOST_BITS(0x0b0, 1, 0)
|
||||
#define phy_testclk DSI_HOST_BITS(0x0b4, 1, 1)
|
||||
#define phy_testclr DSI_HOST_BITS(0x0b4, 1, 0)
|
||||
#define phy_testen DSI_HOST_BITS(0x0b8, 1, 16)
|
||||
#define phy_testdout DSI_HOST_BITS(0x0b8, 8, 8)
|
||||
#define phy_testdin DSI_HOST_BITS(0x0b8, 8, 0)
|
||||
|
||||
#define PHY_TEST_CTRL1 DSI_HOST_BITS(0x0b8, 17, 0)
|
||||
#define PHY_TEST_CTRL0 DSI_HOST_BITS(0x0b4, 2, 0)
|
||||
|
||||
#define INT_ST0 DSI_HOST_BITS(0x0bc, 21, 0)
|
||||
#define INT_ST1 DSI_HOST_BITS(0x0c0, 18, 0)
|
||||
#define INT_MKS0 DSI_HOST_BITS(0x0c4, 21, 0)
|
||||
#define INT_MKS1 DSI_HOST_BITS(0x0c8, 18, 0) //libing
|
||||
#define INT_FORCE0 DSI_HOST_BITS(0x0d8, 21, 0) //libing
|
||||
#define INT_FORCE1 DSI_HOST_BITS(0x0dc, 18, 0) //libing
|
||||
|
||||
#define code_hs_rx_clock 0x34
|
||||
#define code_hs_rx_lane0 0x44
|
||||
#define code_hs_rx_lane1 0x54
|
||||
#define code_hs_rx_lane2 0x84
|
||||
#define code_hs_rx_lane3 0x94
|
||||
|
||||
#define code_pll_input_div_rat 0x17
|
||||
#define code_pll_loop_div_rat 0x18
|
||||
#define code_pll_input_loop_div_rat 0x19
|
||||
|
||||
#define code_hstxdatalanerequsetstatetime 0x70
|
||||
#define code_hstxdatalanepreparestatetime 0x71
|
||||
#define code_hstxdatalanehszerostatetime 0x72
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//#define en_null_pkt DSI_HOST_BITS(0x1c, 1, 13) //delete
|
||||
//#define en_multi_pkt DSI_HOST_BITS(0x1c, 1, 13) //delete
|
||||
#endif /* end of DWC_DSI_VERSION_0x3131302A */
|
||||
|
||||
|
||||
|
||||
//MIPI DSI DPHY REGISTERS
|
||||
#define DPHY_REGISTER0 DSI_DPHY_BITS(0x00, 32, 0)
|
||||
#define DPHY_REGISTER1 DSI_DPHY_BITS(0x04, 32, 0)
|
||||
#define DPHY_REGISTER3 DSI_DPHY_BITS(0x0c, 32, 0)
|
||||
#define DPHY_REGISTER4 DSI_DPHY_BITS(0x10, 32, 0)
|
||||
#define DPHY_REGISTER20 DSI_DPHY_BITS(0X80, 32, 0)
|
||||
|
||||
#define lane_en_ck DSI_DPHY_BITS(0x00, 1, 6)
|
||||
#define lane_en_3 DSI_DPHY_BITS(0x00, 1, 5)
|
||||
#define lane_en_2 DSI_DPHY_BITS(0x00, 1, 4)
|
||||
#define lane_en_1 DSI_DPHY_BITS(0x00, 1, 3)
|
||||
#define lane_en_0 DSI_DPHY_BITS(0x00, 1, 2)
|
||||
|
||||
#define reg_da_ppfc DSI_DPHY_BITS(0x04, 1, 4)
|
||||
#define reg_da_syncrst DSI_DPHY_BITS(0x04, 1, 2)
|
||||
#define reg_da_ldopd DSI_DPHY_BITS(0x04, 1, 1)
|
||||
#define reg_da_pllpd DSI_DPHY_BITS(0x04, 1, 0)
|
||||
|
||||
#define reg_fbdiv_8 DSI_DPHY_BITS(0x0c, 1, 5)
|
||||
#define reg_prediv DSI_DPHY_BITS(0x0c, 5, 0)
|
||||
#define reg_fbdiv DSI_DPHY_BITS(0x10, 8, 0)
|
||||
|
||||
#define reg_dig_rstn DSI_DPHY_BITS(0X80, 1, 0)
|
||||
|
||||
#define DPHY_CLOCK_OFFSET REG_ADDR(0X0100)
|
||||
#define DPHY_LANE0_OFFSET REG_ADDR(0X0180)
|
||||
#define DPHY_LANE1_OFFSET REG_ADDR(0X0200)
|
||||
#define DPHY_LANE2_OFFSET REG_ADDR(0X0280)
|
||||
#define DPHY_LANE3_OFFSET REG_ADDR(0X0300)
|
||||
|
||||
#define reg_ths_settle DSI_DPHY_BITS(0x0000, 4, 0)
|
||||
#define reg_hs_tlpx DSI_DPHY_BITS(0x0014, 6, 0)
|
||||
#define reg_hs_ths_prepare DSI_DPHY_BITS(0x0018, 7, 0)
|
||||
#define reg_hs_the_zero DSI_DPHY_BITS(0x001c, 6, 0)
|
||||
#define reg_hs_ths_trail DSI_DPHY_BITS(0x0020, 7, 0)
|
||||
#define reg_hs_ths_exit DSI_DPHY_BITS(0x0024, 5, 0)
|
||||
#define reg_hs_tclk_post DSI_DPHY_BITS(0x0028, 4, 0)
|
||||
#define reserved DSI_DPHY_BITS(0x002c, 1, 0)
|
||||
#define reg_hs_twakup_h DSI_DPHY_BITS(0x0030, 2, 0)
|
||||
#define reg_hs_twakup_l DSI_DPHY_BITS(0x0034, 8, 0)
|
||||
#define reg_hs_tclk_pre DSI_DPHY_BITS(0x0038, 4, 0)
|
||||
#define reg_hs_tta_go DSI_DPHY_BITS(0x0040, 6, 0)
|
||||
#define reg_hs_tta_sure DSI_DPHY_BITS(0x0044, 6, 0)
|
||||
#define reg_hs_tta_wait DSI_DPHY_BITS(0x0048, 6, 0)
|
||||
|
||||
|
||||
#ifdef DWC_DSI_VERSION_0x3131302A
|
||||
//MISC REGISTERS
|
||||
#define DSI_MISC_BITS(addr, bits, bit_offset) (REG_ADDR(addr) \
|
||||
| REG_BITS(bits) | BITS_OFFSET(bit_offset))
|
||||
|
||||
#define CRU_CRU_CLKSEL1_CON (0x005c)
|
||||
#define CRU_CFG_MISC_CON (0x009c)
|
||||
|
||||
#define cfg_mipiclk_gaten DSI_MISC_BITS(CRU_CRU_CLKSEL1_CON, 1, 10)
|
||||
|
||||
#define mipi_int DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 19)
|
||||
#define mipi_edpihalt DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 16)
|
||||
#define pin_forcetxstopmode_3 DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 11)
|
||||
#define pin_forcetxstopmode_2 DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 10)
|
||||
#define pin_forcetxstopmode_1 DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 9)
|
||||
#define pin_forcetxstopmode_0 DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 8)
|
||||
#define pin_forcerxmode_0 DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 7)
|
||||
#define pin_turndisable_0 DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 6)
|
||||
#define dpicolom DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 2)
|
||||
#define dpishutdn DSI_MISC_BITS(CRU_CFG_MISC_CON, 1, 1)
|
||||
|
||||
#else
|
||||
|
||||
//#define mipi_int
|
||||
//#define mipi_edpihalt
|
||||
#define pin_forcetxstopmode_3
|
||||
#define pin_forcetxstopmode_2
|
||||
#define pin_forcetxstopmode_1
|
||||
#define pin_forcetxstopmode_0
|
||||
#define pin_forcerxmode_0
|
||||
#define pin_turndisable_0
|
||||
#define dpicolom
|
||||
#define dpishutdn
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//global operation timing parameter
|
||||
struct gotp_m {
|
||||
//time uint is ns
|
||||
u32 min;
|
||||
u32 value;
|
||||
u32 max;
|
||||
};
|
||||
|
||||
//default time unit is ns
|
||||
//Unit Interval, equal to the duration of any HS state on the Clock Lane
|
||||
struct gotp {
|
||||
u32 CLK_MISS; //min:no max:60
|
||||
u32 CLK_POST; //min:60 ns + 52*UI max:no
|
||||
u32 CLK_PRE; //min:8*UI max:no
|
||||
u32 CLK_PREPARE; //min:38 max:95
|
||||
u32 CLK_SETTLE; //min:95 max:300
|
||||
u32 CLK_TERM_EN; //min:Time for Dn to reach VTERM-EN max:38
|
||||
u32 CLK_TRAIL; //min:60 max:no
|
||||
u32 CLK_ZERO; //min:300 - CLK_PREPARE max:no
|
||||
u32 D_TERM_EN; //min:Time for Dn to reach VTERM-EN max:35 ns + 4*UI
|
||||
u32 EOT; //min:no max:105 ns + n*12*UI
|
||||
u32 HS_EXIT; //min:100 max:no
|
||||
u32 HS_PREPARE; //min:40 ns + 4*UI max:85 ns + 6*UI
|
||||
u32 HS_ZERO; //min:145 ns + 10*UI - HS_PREPARE max:no
|
||||
u32 HS_SETTLE; //min:85 ns + 6*UI max:145 ns + 10*UI
|
||||
u32 HS_SKIP; //min:40 max:55 ns + 4*UI
|
||||
u32 HS_TRAIL; //min: max( n*8*UI, 60 ns + n*4*UI ) max:no
|
||||
u32 NIT; //min:100us max:no
|
||||
u32 LPX; //min:50 max:no
|
||||
u32 TA_GET; //min:5*TLPX
|
||||
u32 TA_GO; //min:4*TLPX
|
||||
u32 TA_SURE; //min:TLPX max:2*TLPX
|
||||
u32 WAKEUP; //min:1ms max:no
|
||||
};
|
||||
|
||||
|
||||
struct dsi_phy {
|
||||
u32 UI;
|
||||
u32 ref_clk; //input_clk
|
||||
u32 ddr_clk; //data bit clk
|
||||
u32 txbyte_clk; //1/8 of ddr_clk
|
||||
u32 sys_clk; //
|
||||
u32 pclk; //
|
||||
u32 txclkesc;
|
||||
|
||||
u32 Tddr_clk; //ps
|
||||
u32 Ttxbyte_clk; //ps
|
||||
u32 Tsys_clk; //ps
|
||||
u32 Tpclk; //ps
|
||||
u32 Ttxclkesc; //ps
|
||||
|
||||
#ifdef CONFIG_MIPI_DSI_LINUX
|
||||
struct clk *refclk;
|
||||
unsigned long iobase;
|
||||
void __iomem *membase;
|
||||
#endif
|
||||
u16 prediv;
|
||||
u16 fbdiv;
|
||||
u8 flag;
|
||||
struct gotp gotp;
|
||||
|
||||
};
|
||||
|
||||
struct dsi_host {
|
||||
u8 flag;
|
||||
u8 lane;
|
||||
u8 format;
|
||||
u8 video_mode;
|
||||
u32 clk;
|
||||
u32 irq;
|
||||
#ifdef CONFIG_MIPI_DSI_LINUX
|
||||
unsigned long iobase;
|
||||
void __iomem *membase;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dsi {
|
||||
u8 dsi_id;
|
||||
u8 lcdc_id;
|
||||
u8 vid;
|
||||
struct dsi_phy phy;
|
||||
struct dsi_host host;
|
||||
struct mipi_dsi_ops ops;
|
||||
struct mipi_dsi_screen screen;
|
||||
#ifdef CONFIG_MIPI_DSI_LINUX
|
||||
struct clk *dsi_pclk;
|
||||
struct clk *dsi_pd;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
#endif
|
||||
struct dentry *debugfs_dir;
|
||||
struct platform_device *pdev;
|
||||
};
|
||||
|
||||
int rk_mipi_get_dsi_clk(void);
|
||||
int rk_mipi_get_dsi_num(void);
|
||||
int rk_mipi_get_dsi_lane(void);
|
||||
|
||||
extern int rk616_mipi_dsi_ft_init(void);
|
||||
int rk_mipi_dsi_init_lite(struct dsi *dsi);
|
||||
#endif /* end of RK616_MIPI_DSI_H */
|
||||
@@ -1,689 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 ROCKCHIP, Inc.
|
||||
* drivers/video/display/transmitter/ssd2828.c
|
||||
* author: hhb@rock-chips.com
|
||||
* create date: 2013-01-17
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/fb.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/board.h>
|
||||
#include <linux/rk_screen.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include "mipi_dsi.h"
|
||||
#include <linux/proc_fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
||||
/* define spi gpio*/
|
||||
#define TXD_PORT ssd2828->spi.mosi
|
||||
#define CLK_PORT ssd2828->spi.sck
|
||||
#define CS_PORT ssd2828->spi.cs
|
||||
#define RXD_PORT ssd2828->spi.miso
|
||||
|
||||
#define CS_OUT() gpio_direction_output(CS_PORT, 0)
|
||||
#define CS_SET() gpio_set_value(CS_PORT, GPIO_HIGH)
|
||||
#define CS_CLR() gpio_set_value(CS_PORT, GPIO_LOW)
|
||||
#define CLK_OUT() gpio_direction_output(CLK_PORT, 0)
|
||||
#define CLK_SET() gpio_set_value(CLK_PORT, GPIO_HIGH)
|
||||
#define CLK_CLR() gpio_set_value(CLK_PORT, GPIO_LOW)
|
||||
#define TXD_OUT() gpio_direction_output(TXD_PORT, 0)
|
||||
#define TXD_SET() gpio_set_value(TXD_PORT, GPIO_HIGH)
|
||||
#define TXD_CLR() gpio_set_value(TXD_PORT, GPIO_LOW)
|
||||
#define RXD_INPUT() gpio_direction_input(RXD_PORT)
|
||||
#define RXD_GET() gpio_get_value(RXD_PORT)
|
||||
|
||||
|
||||
struct ssd2828_t *ssd2828 = NULL;
|
||||
void ssd_set_register(unsigned int reg_and_value);
|
||||
|
||||
int ssd2828_gpio_init(void *data) {
|
||||
int ret = 0;
|
||||
struct reset_t *reset = &ssd2828->reset;
|
||||
struct power_t *vdd = &ssd2828->vddio;
|
||||
struct spi_t *spi = &ssd2828->spi;
|
||||
|
||||
if(reset->reset_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(reset->reset_pin, "ssd2828_reset");
|
||||
if (ret != 0) {
|
||||
//gpio_free(reset->reset_pin);
|
||||
printk("%s: request ssd2828_RST_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(reset->mux_name)
|
||||
rk30_mux_api_set(reset->mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_output(reset->reset_pin, !reset->effect_value);
|
||||
}
|
||||
}
|
||||
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(vdd->enable_pin, "ssd2828_vddio");
|
||||
if (ret != 0) {
|
||||
//gpio_free(vdd->enable_pin);
|
||||
printk("%s: request ssd2828_vddio_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(vdd->mux_name)
|
||||
rk30_mux_api_set(vdd->mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
|
||||
}
|
||||
}
|
||||
|
||||
vdd = &ssd2828->vdd_mipi;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(vdd->enable_pin, "ssd2828_vdd_mipi");
|
||||
if (ret != 0) {
|
||||
//gpio_free(vdd->enable_pin);
|
||||
printk("%s: request ssd2828_vdd_mipi_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(vdd->mux_name)
|
||||
rk30_mux_api_set(vdd->mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
|
||||
}
|
||||
}
|
||||
|
||||
vdd = &ssd2828->shut;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(vdd->enable_pin, "ssd2828_shut");
|
||||
if (ret != 0) {
|
||||
//gpio_free(vdd->enable_pin);
|
||||
printk("%s: request ssd2828_shut_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(vdd->mux_name)
|
||||
rk30_mux_api_set(vdd->mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
|
||||
}
|
||||
}
|
||||
|
||||
if(spi->cs > INVALID_GPIO) {
|
||||
ret = gpio_request(spi->cs, "ssd2828_spi_cs");
|
||||
if (ret != 0) {
|
||||
//gpio_free(spi->cs);
|
||||
printk("%s: request ssd2828_spi->cs_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(spi->cs_mux_name)
|
||||
rk30_mux_api_set(spi->cs_mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_output(spi->cs, GPIO_HIGH);
|
||||
}
|
||||
}
|
||||
if(spi->sck > INVALID_GPIO) {
|
||||
ret = gpio_request(spi->sck, "ssd2828_spi_sck");
|
||||
if (ret != 0) {
|
||||
//gpio_free(spi->sck);
|
||||
printk("%s: request ssd2828_spi->sck_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(spi->sck_mux_name)
|
||||
rk30_mux_api_set(spi->sck_mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_output(spi->sck, GPIO_HIGH);
|
||||
}
|
||||
}
|
||||
if(spi->mosi > INVALID_GPIO) {
|
||||
ret = gpio_request(spi->mosi, "ssd2828_spi_mosi");
|
||||
if (ret != 0) {
|
||||
//gpio_free(spi->mosi);
|
||||
printk("%s: request ssd2828_spi->mosi_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(spi->mosi_mux_name)
|
||||
rk30_mux_api_set(spi->mosi_mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_output(spi->mosi, GPIO_HIGH);
|
||||
}
|
||||
}
|
||||
if(spi->miso > INVALID_GPIO) {
|
||||
ret = gpio_request(spi->miso, "ssd2828_spi_miso");
|
||||
if (ret != 0) {
|
||||
//gpio_free(spi->miso);
|
||||
printk("%s: request ssd2828_spi->miso_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(spi->miso_mux_name)
|
||||
rk30_mux_api_set(spi->miso_mux_name, 0);
|
||||
#endif
|
||||
gpio_direction_input(spi->miso);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int ssd2828_gpio_deinit(void *data) {
|
||||
struct reset_t *reset = &ssd2828->reset;
|
||||
struct power_t *vdd = &ssd2828->vddio;
|
||||
struct spi_t *spi = &ssd2828->spi;
|
||||
|
||||
if(reset->reset_pin > INVALID_GPIO) {
|
||||
gpio_direction_input(reset->reset_pin);
|
||||
gpio_free(reset->reset_pin);
|
||||
}
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
gpio_direction_input(vdd->enable_pin);
|
||||
gpio_free(vdd->enable_pin);
|
||||
}
|
||||
vdd = &ssd2828->vdd_mipi;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
gpio_direction_input(vdd->enable_pin);
|
||||
gpio_free(vdd->enable_pin);
|
||||
}
|
||||
vdd = &ssd2828->shut;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
gpio_direction_input(vdd->enable_pin);
|
||||
gpio_free(vdd->enable_pin);
|
||||
}
|
||||
if(spi->cs > INVALID_GPIO) {
|
||||
gpio_direction_input(spi->cs);
|
||||
gpio_free(spi->cs);
|
||||
}
|
||||
if(spi->sck > INVALID_GPIO) {
|
||||
gpio_direction_input(spi->sck);
|
||||
gpio_free(spi->sck);
|
||||
}
|
||||
if(spi->mosi > INVALID_GPIO) {
|
||||
gpio_direction_input(spi->mosi);
|
||||
gpio_free(spi->mosi);
|
||||
}
|
||||
if(spi->miso > INVALID_GPIO) {
|
||||
gpio_free(spi->miso);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssd2828_reset(void *data) {
|
||||
int ret = 0;
|
||||
struct reset_t *reset = &ssd2828->reset;
|
||||
if(reset->reset_pin <= INVALID_GPIO)
|
||||
return -1;
|
||||
gpio_set_value(reset->reset_pin, reset->effect_value);
|
||||
if(reset->time_before_reset <= 0)
|
||||
msleep(10);
|
||||
else
|
||||
msleep(reset->time_before_reset);
|
||||
|
||||
gpio_set_value(reset->reset_pin, !reset->effect_value);
|
||||
if(reset->time_after_reset <= 0)
|
||||
msleep(5);
|
||||
else
|
||||
msleep(reset->time_after_reset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssd2828_vdd_enable(void *data) {
|
||||
int ret = 0;
|
||||
struct power_t *vdd = (struct power_t *)data;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
gpio_set_value(vdd->enable_pin, vdd->effect_value);
|
||||
} else if(vdd->name) {
|
||||
struct regulator *ldo = regulator_get(NULL, vdd->name);
|
||||
if (ldo == NULL || IS_ERR(ldo) ){
|
||||
printk("%s: get %s ldo failed!\n", __func__, vdd->name);
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
regulator_set_voltage(ldo, vdd->voltage, vdd->voltage);
|
||||
regulator_enable(ldo);
|
||||
printk(" %s set %s=%dmV end\n", __func__, vdd->name, regulator_get_voltage(ldo));
|
||||
regulator_put(ldo);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssd2828_vdd_disable(void *data) {
|
||||
int ret = 0;
|
||||
struct power_t *vdd = (struct power_t *)data;
|
||||
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
gpio_set_value(vdd->enable_pin, !vdd->effect_value);
|
||||
} else if(vdd->name) {
|
||||
struct regulator *ldo = regulator_get(NULL, vdd->name);
|
||||
if (ldo == NULL || IS_ERR(ldo) ){
|
||||
printk("%s: get %s ldo failed!\n", __func__, vdd->name);
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
while(regulator_is_enabled(ldo) > 0){
|
||||
regulator_disable(ldo);
|
||||
}
|
||||
regulator_put(ldo);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ssd2828_power_up(void) {
|
||||
|
||||
int ret = 0;
|
||||
struct ssd2828_t *ssd = (struct ssd2828_t *)ssd2828;
|
||||
struct spi_t *spi = &ssd2828->spi;
|
||||
ssd->vdd_mipi.enable(&ssd->vdd_mipi);
|
||||
ssd->vddio.enable(&ssd->vddio);
|
||||
ssd->reset.do_reset(&ssd->reset);
|
||||
ssd->shut.enable(&ssd->shut);
|
||||
|
||||
gpio_direction_output(spi->cs, GPIO_HIGH);
|
||||
gpio_direction_output(spi->sck, GPIO_LOW);
|
||||
gpio_direction_input(spi->miso);
|
||||
gpio_direction_output(spi->mosi, GPIO_LOW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssd2828_power_down(void) {
|
||||
|
||||
int ret = 0;
|
||||
struct ssd2828_t *ssd = (struct ssd2828_t *)ssd2828;
|
||||
struct spi_t *spi = &ssd2828->spi;
|
||||
|
||||
ssd->shut.disable(&ssd->shut);
|
||||
msleep(10);
|
||||
|
||||
ssd_set_register(0x00b70300);
|
||||
msleep(1);
|
||||
ssd_set_register(0x00b70304);
|
||||
msleep(1);
|
||||
ssd_set_register(0x00b90000);
|
||||
msleep(10);
|
||||
|
||||
//set all gpio to low to avoid current leakage
|
||||
gpio_direction_output(spi->cs, GPIO_LOW);
|
||||
gpio_direction_output(spi->sck, GPIO_LOW);
|
||||
gpio_direction_output(spi->miso, GPIO_LOW);
|
||||
gpio_direction_output(spi->mosi, GPIO_LOW);
|
||||
gpio_direction_output(ssd->reset.reset_pin, GPIO_LOW);
|
||||
|
||||
ssd->vddio.disable(&ssd->vddio);
|
||||
ssd->vdd_mipi.disable(&ssd->vdd_mipi);
|
||||
ssd->shut.enable(&ssd->shut);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* spi write a data frame,type mean command or data
|
||||
3 wire 24 bit SPI interface
|
||||
*/
|
||||
|
||||
static void spi_send_data(unsigned int data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
CS_SET();
|
||||
udelay(1);
|
||||
CLK_SET();
|
||||
TXD_SET();
|
||||
|
||||
CS_CLR();
|
||||
udelay(1);
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
{
|
||||
//udelay(1);
|
||||
CLK_CLR();
|
||||
udelay(1);
|
||||
if (data & 0x00800000) {
|
||||
TXD_SET();
|
||||
} else {
|
||||
TXD_CLR();
|
||||
}
|
||||
udelay(1);
|
||||
CLK_SET();
|
||||
udelay(1);
|
||||
data <<= 1;
|
||||
}
|
||||
|
||||
TXD_SET();
|
||||
CS_SET();
|
||||
}
|
||||
|
||||
static void spi_recv_data(unsigned int* data)
|
||||
{
|
||||
unsigned int i = 0, temp = 0x73; //read data
|
||||
|
||||
CS_SET();
|
||||
udelay(1);
|
||||
CLK_SET();
|
||||
TXD_SET();
|
||||
|
||||
CS_CLR();
|
||||
udelay(1);
|
||||
|
||||
for(i = 0; i < 8; i++) // 8 bits Data
|
||||
{
|
||||
udelay(1);
|
||||
CLK_CLR();
|
||||
if (temp & 0x80)
|
||||
TXD_SET();
|
||||
else
|
||||
TXD_CLR();
|
||||
temp <<= 1;
|
||||
udelay(1);
|
||||
CLK_SET();
|
||||
udelay(1);
|
||||
}
|
||||
udelay(1);
|
||||
temp = 0;
|
||||
for(i = 0; i < 16; i++) // 16 bits Data
|
||||
{
|
||||
udelay(1);
|
||||
CLK_CLR();
|
||||
udelay(1);
|
||||
CLK_SET();
|
||||
udelay(1);
|
||||
temp <<= 1;
|
||||
if(RXD_GET() == GPIO_HIGH)
|
||||
temp |= 0x01;
|
||||
|
||||
}
|
||||
|
||||
TXD_SET();
|
||||
CS_SET();
|
||||
*data = temp;
|
||||
}
|
||||
|
||||
#define DEVIE_ID (0x70 << 16)
|
||||
void send_ctrl_cmd(unsigned int cmd)
|
||||
{
|
||||
unsigned int out = (DEVIE_ID | cmd );
|
||||
spi_send_data(out);
|
||||
}
|
||||
|
||||
static void send_data_cmd(unsigned int data)
|
||||
{
|
||||
unsigned int out = (DEVIE_ID | (0x2 << 16) | data );
|
||||
spi_send_data(out);
|
||||
}
|
||||
|
||||
unsigned int ssd_read_register(unsigned int reg) {
|
||||
unsigned int data = 0;
|
||||
send_ctrl_cmd(reg);
|
||||
spi_recv_data(&data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void ssd_set_register(unsigned int reg_and_value)
|
||||
{
|
||||
send_ctrl_cmd(reg_and_value >> 16);
|
||||
send_data_cmd(reg_and_value & 0x0000ffff);
|
||||
}
|
||||
|
||||
int ssd_set_registers(unsigned int reg_array[], int n) {
|
||||
|
||||
int i = 0;
|
||||
for(i = 0; i < n; i++) {
|
||||
if(reg_array[i] < 0x00b00000) { //the lowest address is 0xb0 of ssd2828
|
||||
if(reg_array[i] < 20000)
|
||||
udelay(reg_array[i]);
|
||||
else {
|
||||
mdelay(reg_array[i]/1000);
|
||||
}
|
||||
} else {
|
||||
ssd_set_register(reg_array[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssd_mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) {
|
||||
//unsigned int data = 0, i = 0;
|
||||
ssd_set_register(0x00B70343); //
|
||||
ssd_set_register(0x00B80000);
|
||||
ssd_set_register(0x00Bc0001);
|
||||
|
||||
ssd_set_register(0x00Bf0000 | regs[0]);
|
||||
msleep(1);
|
||||
ssd_set_register(0x00B7034b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int _ssd2828_send_packet(unsigned char type, unsigned char regs[], u32 n) {
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssd2828_send_packet(unsigned char type, unsigned char regs[], u32 n) {
|
||||
return _ssd2828_send_packet(type, regs, n);
|
||||
}
|
||||
|
||||
int ssd_mipi_dsi_read_dcs_packet(unsigned char *data, u32 n) {
|
||||
//DCS READ
|
||||
unsigned int i = 0;
|
||||
|
||||
i = ssd_read_register(0xc6);
|
||||
printk("read mipi slave error:%04x\n", i);
|
||||
ssd_set_register(0x00B70382);
|
||||
ssd_set_register(0x00BB0008);
|
||||
ssd_set_register(0x00C1000A);
|
||||
ssd_set_register(0x00C00001);
|
||||
ssd_set_register(0x00Bc0001);
|
||||
ssd_set_register(0x00Bf0000 | *data);
|
||||
msleep(10);
|
||||
i = ssd_read_register(0xc6);
|
||||
printk("read mipi slave error:%04x\n", i);
|
||||
|
||||
if(i & 1) {
|
||||
i = ssd_read_register(0xff);
|
||||
printk("read %02x:%04x\n", *data, i);
|
||||
i = ssd_read_register(0xff);
|
||||
printk("read %02x:%04x\n", *data, i);
|
||||
i = ssd_read_register(0xff);
|
||||
printk("read %02x:%04x\n", *data, i);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ssd2828_get_id(void) {
|
||||
|
||||
int id = -1;
|
||||
ssd2828_power_up();
|
||||
id = ssd_read_register(0xb0);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static struct mipi_dsi_ops ssd2828_ops = {
|
||||
.id = 0x2828,
|
||||
.name = "ssd2828",
|
||||
.get_id = ssd2828_get_id,
|
||||
.dsi_set_regs = ssd_set_registers,
|
||||
.dsi_send_dcs_packet = ssd_mipi_dsi_send_dcs_packet,
|
||||
.dsi_read_dcs_packet = ssd_mipi_dsi_read_dcs_packet,
|
||||
.power_up = ssd2828_power_up,
|
||||
.power_down = ssd2828_power_down,
|
||||
|
||||
};
|
||||
|
||||
static struct proc_dir_entry *reg_proc_entry;
|
||||
|
||||
int reg_proc_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
|
||||
{
|
||||
int ret = -1;
|
||||
char *buf = kmalloc(count, GFP_KERNEL);
|
||||
char *data = buf;
|
||||
unsigned int regs_val = 0, read_val = 0;
|
||||
ret = copy_from_user((void*)buf, buff, count);
|
||||
|
||||
while(1) {
|
||||
data = strstr(data, "0x");
|
||||
if(data == NULL)
|
||||
goto reg_proc_write_exit;
|
||||
sscanf(data, "0x%x", ®s_val);
|
||||
ssd_set_register(regs_val);
|
||||
read_val = ssd_read_register(regs_val >> 16);
|
||||
regs_val &= 0xffff;
|
||||
if(read_val != regs_val)
|
||||
printk("%s fail:0x%04x\n", __func__, read_val);
|
||||
data += 3;
|
||||
}
|
||||
|
||||
reg_proc_write_exit:
|
||||
kfree(buf);
|
||||
msleep(10);
|
||||
return count;
|
||||
}
|
||||
|
||||
int reg_proc_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
|
||||
{
|
||||
#if 0
|
||||
int ret = -1;
|
||||
const char buf[32] = {0};
|
||||
unsigned int regs_val = 0;
|
||||
ret = copy_from_user((void*)buf, buff, count);
|
||||
sscanf(buf, "0x%x", ®s_val);
|
||||
regs_val = ssd_read_register(regs_val);
|
||||
sprintf(buf, "0x%04x\n", regs_val);
|
||||
copy_to_user(buff, buf, 4);
|
||||
|
||||
printk("%s:%04x\n", __func__, regs_val);
|
||||
msleep(10);
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
int reg_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
//printk("%s\n", __func__);
|
||||
//msleep(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reg_proc_close(struct inode *inode, struct file *file)
|
||||
{
|
||||
//printk("%s\n", __func__);
|
||||
//msleep(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct file_operations reg_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = reg_proc_open,
|
||||
.release = reg_proc_close,
|
||||
.write = reg_proc_write,
|
||||
.read = reg_proc_read,
|
||||
};
|
||||
|
||||
static int reg_proc_init(char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
reg_proc_entry = create_proc_entry(name, 0666, NULL);
|
||||
if(reg_proc_entry == NULL) {
|
||||
printk("Couldn't create proc entry : %s!\n", name);
|
||||
ret = -ENOMEM;
|
||||
return ret ;
|
||||
}
|
||||
else {
|
||||
printk("Create proc entry:%s success!\n", name);
|
||||
reg_proc_entry->proc_fops = ®_proc_fops;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ssd2828_probe(struct platform_device *pdev) {
|
||||
|
||||
if(pdev->dev.platform_data)
|
||||
ssd2828 = pdev->dev.platform_data;
|
||||
|
||||
if(!ssd2828->gpio_init)
|
||||
ssd2828->gpio_init = ssd2828_gpio_init;
|
||||
|
||||
if(!ssd2828->gpio_deinit)
|
||||
ssd2828->gpio_deinit = ssd2828_gpio_deinit;
|
||||
|
||||
if(!ssd2828->power_up)
|
||||
ssd2828->power_up = ssd2828_power_up;
|
||||
if(!ssd2828->power_down)
|
||||
ssd2828->power_down = ssd2828_power_down;
|
||||
|
||||
if(!ssd2828->reset.do_reset)
|
||||
ssd2828->reset.do_reset = ssd2828_reset;
|
||||
|
||||
if(!ssd2828->vddio.enable)
|
||||
ssd2828->vddio.enable = ssd2828_vdd_enable;
|
||||
if(!ssd2828->vddio.disable)
|
||||
ssd2828->vddio.disable = ssd2828_vdd_disable;
|
||||
|
||||
if(!ssd2828->vdd_mipi.enable)
|
||||
ssd2828->vdd_mipi.enable = ssd2828_vdd_enable;
|
||||
if(!ssd2828->vdd_mipi.disable)
|
||||
ssd2828->vdd_mipi.disable = ssd2828_vdd_disable;
|
||||
|
||||
if(!ssd2828->shut.enable)
|
||||
ssd2828->shut.enable = ssd2828_vdd_enable;
|
||||
if(!ssd2828->shut.disable)
|
||||
ssd2828->shut.disable = ssd2828_vdd_disable;
|
||||
|
||||
|
||||
ssd2828_gpio_init(NULL);
|
||||
reg_proc_init(ssd2828_ops.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ssd2828_remove(struct platform_device *pdev) {
|
||||
|
||||
if(ssd2828) {
|
||||
ssd2828_gpio_deinit(NULL);
|
||||
ssd2828 = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct platform_driver ssd2828_driver = {
|
||||
.probe = ssd2828_probe,
|
||||
.remove = ssd2828_remove,
|
||||
//.suspend = mipi_dsi_suspend,
|
||||
//.resume = mipi_dsi_resume,
|
||||
.driver = {
|
||||
.name = "ssd2828",
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init ssd2828_init(void)
|
||||
{
|
||||
platform_driver_register(&ssd2828_driver);
|
||||
if(!ssd2828)
|
||||
return -1;
|
||||
register_dsi_ops(&ssd2828_ops);
|
||||
if(ssd2828->id > 0)
|
||||
ssd2828_ops.id = ssd2828->id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ssd2828_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ssd2828_driver);
|
||||
del_dsi_ops(&ssd2828_ops);
|
||||
}
|
||||
|
||||
subsys_initcall_sync(ssd2828_init);
|
||||
module_exit(ssd2828_exit);
|
||||
@@ -1,744 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 ROCKCHIP, Inc.
|
||||
* drivers/video/display/transmitter/tc358768.c
|
||||
* author: hhb@rock-chips.com
|
||||
* create date: 2012-10-26
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/fb.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/board.h>
|
||||
#include <linux/rk_screen.h>
|
||||
#include <linux/ktime.h>
|
||||
#include "mipi_dsi.h"
|
||||
|
||||
#define CONFIG_TC358768_I2C 1
|
||||
#define CONFIG_TC358768_I2C_CLK 400*1000
|
||||
|
||||
|
||||
#if 0
|
||||
#define dsi_debug printk
|
||||
#else
|
||||
#define dsi_debug(fmt...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TC358768_I2C
|
||||
static struct tc358768_t *tc358768 = NULL;
|
||||
static struct i2c_client *tc358768_client = NULL;
|
||||
static struct mipi_dsi_ops tc358768_ops;
|
||||
|
||||
|
||||
u32 i2c_write_32bits(u32 value)
|
||||
{
|
||||
struct i2c_msg msgs;
|
||||
int ret = -1;
|
||||
char buf[4];
|
||||
buf[0] = value>>24;
|
||||
buf[1] = value>>16;
|
||||
buf[2] = value>>8;
|
||||
buf[3] = value;
|
||||
|
||||
msgs.addr = tc358768_client->addr;
|
||||
msgs.flags = tc358768_client->flags;
|
||||
msgs.len = 4;
|
||||
msgs.buf = buf;
|
||||
msgs.scl_rate = CONFIG_TC358768_I2C_CLK;
|
||||
msgs.udelay = tc358768_client->udelay;
|
||||
|
||||
ret = i2c_transfer(tc358768_client->adapter, &msgs, 1);
|
||||
if(ret < 0)
|
||||
printk("%s:i2c_transfer fail =%d\n",__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 i2c_read_32bits(u32 value)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
int ret = -1;
|
||||
char buf[4];
|
||||
buf[0] = value>>8;
|
||||
buf[1] = value;
|
||||
|
||||
msgs[0].addr = tc358768_client->addr;
|
||||
msgs[0].flags = tc358768_client->flags;
|
||||
msgs[0].len = 2;
|
||||
msgs[0].buf = buf;
|
||||
msgs[0].scl_rate = CONFIG_TC358768_I2C_CLK;
|
||||
msgs[0].udelay = tc358768_client->udelay;
|
||||
|
||||
msgs[1].addr = tc358768_client->addr;
|
||||
msgs[1].flags = tc358768_client->flags | I2C_M_RD;
|
||||
msgs[1].len = 2;
|
||||
msgs[1].buf = buf;
|
||||
msgs[1].scl_rate = CONFIG_TC358768_I2C_CLK;
|
||||
msgs[1].udelay = tc358768_client->udelay;
|
||||
|
||||
ret = i2c_transfer(tc358768_client->adapter, msgs, 2);
|
||||
if(ret < 0)
|
||||
printk("%s:i2c_transfer fail =%d\n",__func__, ret);
|
||||
else
|
||||
ret = (buf[0]<<8) | buf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int tc358768_gpio_init(void *data) {
|
||||
int ret = 0;
|
||||
struct reset_t *reset = &tc358768->reset;
|
||||
struct power_t *vdd = &tc358768->vddc;
|
||||
if(reset->reset_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(reset->reset_pin, "tc358768_reset");
|
||||
if (ret != 0) {
|
||||
//gpio_free(reset->reset_pin);
|
||||
printk("%s: request TC358768_RST_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(reset->mux_name)
|
||||
rk30_mux_api_set(reset->mux_name, reset->mux_mode);
|
||||
#endif
|
||||
gpio_direction_output(reset->reset_pin, !reset->effect_value);
|
||||
}
|
||||
}
|
||||
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(vdd->enable_pin, "tc358768_vddc");
|
||||
if (ret != 0) {
|
||||
//gpio_free(vdd->enable_pin);
|
||||
printk("%s: request TC358768_vddc_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(vdd->mux_name)
|
||||
rk30_mux_api_set(vdd->mux_name, vdd->mux_mode);
|
||||
#endif
|
||||
gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
|
||||
}
|
||||
}
|
||||
|
||||
vdd = &tc358768->vddio;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(vdd->enable_pin, "tc358768_vddio");
|
||||
if (ret != 0) {
|
||||
//gpio_free(vdd->enable_pin);
|
||||
printk("%s: request TC358768_vddio_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(vdd->mux_name)
|
||||
rk30_mux_api_set(vdd->mux_name, vdd->mux_mode);
|
||||
#endif
|
||||
gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
|
||||
}
|
||||
}
|
||||
|
||||
vdd = &tc358768->vdd_mipi;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
ret = gpio_request(vdd->enable_pin, "tc358768_vdd_mipi");
|
||||
if (ret != 0) {
|
||||
//gpio_free(vdd->enable_pin);
|
||||
printk("%s: request TC358768_vdd_mipi_PIN error\n", __func__);
|
||||
} else {
|
||||
#if OLD_RK_IOMUX
|
||||
if(vdd->mux_name)
|
||||
rk30_mux_api_set(vdd->mux_name, vdd->mux_mode);
|
||||
#endif
|
||||
gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int tc358768_gpio_deinit(void *data) {
|
||||
struct reset_t *reset = &tc358768->reset;
|
||||
struct power_t *vdd = &tc358768->vddc;
|
||||
gpio_direction_input(reset->reset_pin);
|
||||
gpio_free(reset->reset_pin);
|
||||
|
||||
gpio_direction_input(vdd->enable_pin);
|
||||
gpio_free(vdd->enable_pin);
|
||||
|
||||
vdd = &tc358768->vddio;
|
||||
gpio_direction_input(vdd->enable_pin);
|
||||
gpio_free(vdd->enable_pin);
|
||||
|
||||
vdd = &tc358768->vdd_mipi;
|
||||
gpio_direction_input(vdd->enable_pin);
|
||||
gpio_free(vdd->enable_pin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tc358768_reset(void *data) {
|
||||
int ret = 0;
|
||||
struct reset_t *reset = &tc358768->reset;
|
||||
if(reset->reset_pin <= INVALID_GPIO)
|
||||
return -1;
|
||||
gpio_set_value(reset->reset_pin, reset->effect_value);
|
||||
if(reset->time_before_reset <= 0)
|
||||
msleep(1);
|
||||
else
|
||||
msleep(reset->time_before_reset);
|
||||
|
||||
gpio_set_value(reset->reset_pin, !reset->effect_value);
|
||||
if(reset->time_after_reset <= 0)
|
||||
msleep(5);
|
||||
else
|
||||
msleep(reset->time_after_reset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc358768_vdd_enable(void *data) {
|
||||
int ret = 0;
|
||||
struct power_t *vdd = (struct power_t *)data;
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
gpio_set_value(vdd->enable_pin, vdd->effect_value);
|
||||
} else {
|
||||
//for other control
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc358768_vdd_disable(void *data) {
|
||||
int ret = 0;
|
||||
struct power_t *vdd = (struct power_t *)data;
|
||||
|
||||
if(vdd->enable_pin > INVALID_GPIO) {
|
||||
gpio_set_value(vdd->enable_pin, !vdd->effect_value);
|
||||
} else {
|
||||
//for other control
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int tc358768_power_up(void) {
|
||||
|
||||
int ret = 0;
|
||||
struct tc358768_t *tc = (struct tc358768_t *)tc358768;
|
||||
|
||||
tc->vddc.enable(&tc->vddc);
|
||||
tc->vdd_mipi.enable(&tc->vdd_mipi);
|
||||
tc->vddio.enable(&tc->vddio);
|
||||
tc->reset.do_reset(&tc->reset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc358768_power_down(void) {
|
||||
|
||||
int ret = 0;
|
||||
struct tc358768_t *tc = (struct tc358768_t *)tc358768;
|
||||
|
||||
tc->vddio.disable(&tc->vddio);
|
||||
tc->vdd_mipi.disable(&tc->vdd_mipi);
|
||||
tc->vddc.disable(&tc->vddc);
|
||||
gpio_set_value(tc358768->reset.reset_pin, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tc358768_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
int ret = 0;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
|
||||
dev_warn(&adapter->dev,
|
||||
"I2C-Adapter doesn't support I2C_FUNC_I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
tc358768 = (struct tc358768_t *)client->dev.platform_data;
|
||||
if(!tc358768) {
|
||||
ret = -1;
|
||||
printk("%s:%d tc358768 is null\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tc358768_client = client;
|
||||
if(!tc358768_client) {
|
||||
ret = -1;
|
||||
printk("%s:%d tc358768_client is null\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(!tc358768->gpio_init)
|
||||
tc358768->gpio_init = tc358768_gpio_init;
|
||||
|
||||
if(!tc358768->gpio_deinit)
|
||||
tc358768->gpio_deinit = tc358768_gpio_deinit;
|
||||
|
||||
if(!tc358768->power_up)
|
||||
tc358768->power_up = tc358768_power_up;
|
||||
if(!tc358768->power_down)
|
||||
tc358768->power_down = tc358768_power_down;
|
||||
|
||||
if(!tc358768->reset.do_reset)
|
||||
tc358768->reset.do_reset = tc358768_reset;
|
||||
|
||||
if(!tc358768->vddc.enable)
|
||||
tc358768->vddc.enable = tc358768_vdd_enable;
|
||||
if(!tc358768->vddc.disable)
|
||||
tc358768->vddc.disable = tc358768_vdd_disable;
|
||||
|
||||
if(!tc358768->vddio.enable)
|
||||
tc358768->vddio.enable = tc358768_vdd_enable;
|
||||
if(!tc358768->vddio.disable)
|
||||
tc358768->vddio.disable = tc358768_vdd_disable;
|
||||
|
||||
if(!tc358768->vdd_mipi.enable)
|
||||
tc358768->vdd_mipi.enable = tc358768_vdd_enable;
|
||||
if(!tc358768->vdd_mipi.disable)
|
||||
tc358768->vdd_mipi.disable = tc358768_vdd_disable;
|
||||
|
||||
tc358768_gpio_init(NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static int tc358768_remove(struct i2c_client *client)
|
||||
{
|
||||
tc358768_gpio_deinit(NULL);
|
||||
tc358768_client = NULL;
|
||||
tc358768 = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tc358768_id[] = {
|
||||
{"tc358768", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tc358768_id);
|
||||
|
||||
static struct i2c_driver tc358768_driver = {
|
||||
.probe = tc358768_probe,
|
||||
.remove = tc358768_remove,
|
||||
.id_table = tc358768_id,
|
||||
.driver = {
|
||||
.name = "tc358768",
|
||||
},
|
||||
};
|
||||
#else
|
||||
|
||||
u32 spi_read_32bits(u32 addr)
|
||||
{
|
||||
unsigned int i = 32;
|
||||
//a frame starts
|
||||
CS_CLR();
|
||||
CLK_SET();
|
||||
|
||||
addr <<= 16;
|
||||
addr &= 0xfffe0000;
|
||||
addr |= 0x00010000;
|
||||
|
||||
udelay(2);
|
||||
while(i--) {
|
||||
CLK_CLR();
|
||||
if(addr & 0x80000000)
|
||||
TXD_SET();
|
||||
else
|
||||
TXD_CLR();
|
||||
addr <<= 1;
|
||||
udelay(2);
|
||||
CLK_SET();
|
||||
udelay(2);
|
||||
}
|
||||
//a frame ends
|
||||
CS_SET();
|
||||
|
||||
|
||||
udelay(2);
|
||||
CS_CLR();
|
||||
addr = 0xfffe0000;
|
||||
i = 16;
|
||||
while(i--) {
|
||||
CLK_CLR();
|
||||
if(addr & 0x80000000)
|
||||
TXD_SET();
|
||||
else
|
||||
TXD_CLR();
|
||||
addr <<= 1;
|
||||
udelay(2);
|
||||
CLK_SET();
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
TXD_SET();
|
||||
|
||||
addr = 0;
|
||||
i = 16;
|
||||
while(i--) {
|
||||
CLK_CLR();
|
||||
udelay(1);
|
||||
CLK_SET();
|
||||
udelay(1);
|
||||
if (gpio_get_value(gLcd_info->rxd_pin) == 1)
|
||||
addr |= 1 << i;
|
||||
udelay(1);
|
||||
}
|
||||
CS_SET();
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
//32 bits per frame
|
||||
u32 spi_write_32bits(u32 value)
|
||||
{
|
||||
int i = 32;
|
||||
|
||||
//a frame starts
|
||||
CS_CLR();
|
||||
CLK_SET();
|
||||
|
||||
while(i--) {
|
||||
CLK_CLR();
|
||||
if(value & 0x80000000)
|
||||
TXD_SET();
|
||||
else
|
||||
TXD_CLR();
|
||||
value <<= 1;
|
||||
CLK_SET();
|
||||
}
|
||||
//a frame ends
|
||||
CS_SET();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
u32 tc358768_wr_reg_32bits(u32 data) {
|
||||
#ifdef CONFIG_TC358768_I2C
|
||||
i2c_write_32bits(data);
|
||||
#else
|
||||
spi_write_32bits(data);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 tc358768_wr_reg_32bits_delay(u32 delay, u32 data) {
|
||||
//wait a minute according to the source format
|
||||
if(delay < 20000)
|
||||
udelay(delay);
|
||||
else {
|
||||
mdelay(delay/1000);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TC358768_I2C
|
||||
i2c_write_32bits(data);
|
||||
#else
|
||||
spi_write_32bits(data);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u32 tc358768_rd_reg_32bits(u32 addr) {
|
||||
#ifdef CONFIG_TC358768_I2C
|
||||
return i2c_read_32bits(addr);
|
||||
#else
|
||||
return spi_read_32bits(addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void tc_print(u32 addr) {
|
||||
dsi_debug("+++++++++++addr->%04x: %04x\n", addr, tc358768_rd_reg_32bits(addr));
|
||||
}
|
||||
|
||||
#define tc358768_wr_regs_32bits(reg_array) _tc358768_wr_regs_32bits(reg_array, ARRAY_SIZE(reg_array))
|
||||
int _tc358768_wr_regs_32bits(unsigned int reg_array[], u32 n) {
|
||||
|
||||
int i = 0;
|
||||
dsi_debug("%s:%d\n", __func__, n);
|
||||
for(i = 0; i < n; i++) {
|
||||
if(reg_array[i] < 0x00020000) {
|
||||
if(reg_array[i] < 20000)
|
||||
udelay(reg_array[i]);
|
||||
else {
|
||||
mdelay(reg_array[i]/1000);
|
||||
}
|
||||
} else {
|
||||
tc358768_wr_reg_32bits(reg_array[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tc358768_command_tx_less8bytes(unsigned char type, unsigned char *regs, u32 n) {
|
||||
int i = 0;
|
||||
unsigned int command[] = {
|
||||
0x06020000,
|
||||
0x06040000,
|
||||
0x06100000,
|
||||
0x06120000,
|
||||
0x06140000,
|
||||
0x06160000,
|
||||
};
|
||||
|
||||
if(n <= 2)
|
||||
command[0] |= 0x1000; //short packet
|
||||
else {
|
||||
command[0] |= 0x4000; //long packet
|
||||
command[1] |= n; //word count byte
|
||||
}
|
||||
command[0] |= type; //data type
|
||||
|
||||
//dsi_debug("*cmd:\n");
|
||||
//dsi_debug("0x%08x\n", command[0]);
|
||||
//dsi_debug("0x%08x\n", command[1]);
|
||||
|
||||
for(i = 0; i < (n + 1)/2; i++) {
|
||||
command[i+2] |= regs[i*2];
|
||||
if((i*2 + 1) < n)
|
||||
command[i+2] |= regs[i*2 + 1] << 8;
|
||||
dsi_debug("0x%08x\n", command[i+2]);
|
||||
}
|
||||
|
||||
_tc358768_wr_regs_32bits(command, (n + 1)/2 + 2);
|
||||
tc358768_wr_reg_32bits(0x06000001); //Packet Transfer
|
||||
//wait until packet is out
|
||||
i = 100;
|
||||
while(tc358768_rd_reg_32bits(0x0600) & 0x01) {
|
||||
if(i-- == 0)
|
||||
break;
|
||||
tc_print(0x0600);
|
||||
}
|
||||
//udelay(50);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tc358768_command_tx_more8bytes_hs(unsigned char type, unsigned char regs[], u32 n) {
|
||||
|
||||
int i = 0;
|
||||
unsigned int dbg_data = 0x00E80000, temp = 0;
|
||||
unsigned int command[] = {
|
||||
0x05000080, //HS data 4 lane, EOT is added
|
||||
0x0502A300,
|
||||
0x00080001,
|
||||
0x00500000, //Data ID setting
|
||||
0x00220000, //Transmission byte count= byte
|
||||
0x00E08000, //Enable I2C/SPI write to VB
|
||||
0x00E20048, //Total word count = 0x48 (max 0xFFF). This value should be adjusted considering trade off between transmission time and transmission start/stop time delay
|
||||
0x00E4007F, //Vertical blank line = 0x7F
|
||||
};
|
||||
|
||||
|
||||
command[3] |= type; //data type
|
||||
command[4] |= n & 0xffff; //Transmission byte count
|
||||
|
||||
tc358768_wr_regs_32bits(command);
|
||||
|
||||
for(i = 0; i < (n + 1)/2; i++) {
|
||||
temp = dbg_data | regs[i*2];
|
||||
if((i*2 + 1) < n)
|
||||
temp |= (regs[i*2 + 1] << 8);
|
||||
//dsi_debug("0x%08x\n", temp);
|
||||
tc358768_wr_reg_32bits(temp);
|
||||
}
|
||||
if((n % 4 == 1) || (n % 4 == 2)) //4 bytes align
|
||||
tc358768_wr_reg_32bits(dbg_data);
|
||||
|
||||
tc358768_wr_reg_32bits(0x00E0C000); //Start command transmisison
|
||||
tc358768_wr_reg_32bits(0x00E00000); //Stop command transmission. This setting should be done just after above setting to prevent multiple output
|
||||
udelay(200);
|
||||
//Re-Initialize
|
||||
//tc358768_wr_regs_32bits(re_initialize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//low power mode only for tc358768a
|
||||
int tc358768_command_tx_more8bytes_lp(unsigned char type, unsigned char regs[], u32 n) {
|
||||
|
||||
int i = 0;
|
||||
unsigned int dbg_data = 0x00E80000, temp = 0;
|
||||
unsigned int command[] = {
|
||||
0x00080001,
|
||||
0x00500000, //Data ID setting
|
||||
0x00220000, //Transmission byte count= byte
|
||||
0x00E08000, //Enable I2C/SPI write to VB
|
||||
};
|
||||
|
||||
command[1] |= type; //data type
|
||||
command[2] |= n & 0xffff; //Transmission byte count
|
||||
|
||||
tc358768_wr_regs_32bits(command);
|
||||
|
||||
for(i = 0; i < (n + 1)/2; i++) {
|
||||
temp = dbg_data | regs[i*2];
|
||||
if((i*2 + 1) < n)
|
||||
temp |= (regs[i*2 + 1] << 8);
|
||||
//dsi_debug("0x%08x\n", temp);
|
||||
tc358768_wr_reg_32bits(temp);
|
||||
|
||||
}
|
||||
if((n % 4 == 1) || (n % 4 == 2)) //4 bytes align
|
||||
tc358768_wr_reg_32bits(dbg_data);
|
||||
|
||||
tc358768_wr_reg_32bits(0x00E0E000); //Start command transmisison
|
||||
udelay(1000);
|
||||
tc358768_wr_reg_32bits(0x00E02000); //Keep Mask High to prevent short packets send out
|
||||
tc358768_wr_reg_32bits(0x00E00000); //Stop command transmission. This setting should be done just after above setting to prevent multiple output
|
||||
udelay(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _tc358768_send_packet(unsigned char type, unsigned char regs[], u32 n) {
|
||||
|
||||
if(n <= 8) {
|
||||
tc358768_command_tx_less8bytes(type, regs, n);
|
||||
} else {
|
||||
//tc358768_command_tx_more8bytes_hs(type, regs, n);
|
||||
tc358768_command_tx_more8bytes_lp(type, regs, n);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tc358768_send_packet(unsigned char type, unsigned char regs[], u32 n) {
|
||||
return _tc358768_send_packet(type, regs, n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The DCS is separated into two functional areas: the User Command Set and the Manufacturer Command
|
||||
Set. Each command is an eight-bit code with 00h to AFh assigned to the User Command Set and all other
|
||||
codes assigned to the Manufacturer Command Set.
|
||||
*/
|
||||
int _mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) {
|
||||
|
||||
unsigned char type = 0;
|
||||
if(n == 1) {
|
||||
type = DTYPE_DCS_SWRITE_0P;
|
||||
} else if (n == 2) {
|
||||
type = DTYPE_DCS_SWRITE_1P;
|
||||
} else if (n > 2) {
|
||||
type = DTYPE_DCS_LWRITE;
|
||||
}
|
||||
_tc358768_send_packet(type, regs, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) {
|
||||
return _mipi_dsi_send_dcs_packet(regs, n);
|
||||
}
|
||||
|
||||
|
||||
int _tc358768_rd_lcd_regs(unsigned char type, char comd, int size, unsigned char* buf) {
|
||||
|
||||
unsigned char regs[8];
|
||||
u32 count = 0, data30, data32;
|
||||
regs[0] = size;
|
||||
regs[1] = 0;
|
||||
tc358768_command_tx_less8bytes(0x37, regs, 2);
|
||||
tc358768_wr_reg_32bits(0x05040010);
|
||||
tc358768_wr_reg_32bits(0x05060000);
|
||||
regs[0] = comd;
|
||||
tc358768_command_tx_less8bytes(type, regs, 1);
|
||||
|
||||
while (!(tc358768_rd_reg_32bits(0x0410) & 0x20)){
|
||||
printk("error 0x0410:%04x\n", tc358768_rd_reg_32bits(0x0410));
|
||||
msleep(1);
|
||||
if(count++ > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data30 = tc358768_rd_reg_32bits(0x0430); //data id , word count[0:7]
|
||||
//printk("0x0430:%04x\n", data30);
|
||||
data32 = tc358768_rd_reg_32bits(0x0432); //word count[8:15] ECC
|
||||
//printk("0x0432:%04x\n", data32);
|
||||
|
||||
while(size > 0) {
|
||||
data30 = tc358768_rd_reg_32bits(0x0430);
|
||||
//printk("0x0430:%04x\n", data30);
|
||||
data32 = tc358768_rd_reg_32bits(0x0432);
|
||||
//printk("0x0432:%04x\n", data32);
|
||||
|
||||
if(size-- > 0)
|
||||
*buf++ = (u8)data30;
|
||||
else
|
||||
break;
|
||||
if(size-- > 0)
|
||||
*buf++ = (u8)(data30 >> 8);
|
||||
else
|
||||
break;
|
||||
if(size-- > 0) {
|
||||
*buf++ = (u8)data32;
|
||||
if(size-- > 0)
|
||||
*buf++ = (u8)(data32 >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
data30 = tc358768_rd_reg_32bits(0x0430);
|
||||
//printk("0x0430:%04x\n", data30);
|
||||
data32 = tc358768_rd_reg_32bits(0x0432);
|
||||
//printk("0x0432:%04x\n", data32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mipi_dsi_read_dcs_packet(unsigned char *data, u32 n) {
|
||||
//DCS READ
|
||||
_tc358768_rd_lcd_regs(0x06, *data, n, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tc358768_get_id(void) {
|
||||
|
||||
int id = -1;
|
||||
|
||||
tc358768_power_up();
|
||||
id = tc358768_rd_reg_32bits(0);
|
||||
return id;
|
||||
}
|
||||
|
||||
static struct mipi_dsi_ops tc358768_ops = {
|
||||
.id = 0x4401,
|
||||
.name = "tc358768a",
|
||||
.get_id = tc358768_get_id,
|
||||
.dsi_set_regs = _tc358768_wr_regs_32bits,
|
||||
.dsi_send_dcs_packet = mipi_dsi_send_dcs_packet,
|
||||
.dsi_read_dcs_packet = mipi_dsi_read_dcs_packet,
|
||||
.power_up = tc358768_power_up,
|
||||
.power_down = tc358768_power_down,
|
||||
|
||||
};
|
||||
|
||||
static int __init tc358768_module_init(void)
|
||||
{
|
||||
#ifdef CONFIG_TC358768_I2C
|
||||
i2c_add_driver(&tc358768_driver);
|
||||
|
||||
if(!tc358768 || !tc358768_client)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
register_dsi_ops(&tc358768_ops);
|
||||
if(tc358768->id > 0)
|
||||
tc358768_ops.id = tc358768->id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit tc358768_module_exit(void)
|
||||
{
|
||||
del_dsi_ops(&tc358768_ops);
|
||||
#ifdef CONFIG_TC358768_I2C
|
||||
i2c_del_driver(&tc358768_driver);
|
||||
#endif
|
||||
}
|
||||
|
||||
subsys_initcall_sync(tc358768_module_init);
|
||||
//module_exit(tc358768_module_init);
|
||||
module_exit(tc358768_module_exit);
|
||||
@@ -1,343 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/display-sys.h>
|
||||
#include <linux/rk_screen.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#endif
|
||||
|
||||
#include "../../edid.h"
|
||||
|
||||
#ifdef CONFIG_SWITCH
|
||||
#include <linux/switch.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define DDC_ADDR 0x50
|
||||
#define DDC_I2C_RATE 100*1000
|
||||
#define INVALID_GPIO -1
|
||||
#define GPIO_HIGH 1
|
||||
#define GPIO_LOW 0
|
||||
#define DISPLAY_SOURCE_LCDC0 0
|
||||
#define DISPLAY_SOURCE_LCDC1 1
|
||||
|
||||
//static char *vgaenvent[] = {"INTERFACE=VGA", NULL};
|
||||
|
||||
static const struct fb_videomode rk29_mode[] = {
|
||||
//name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag(used for vic)
|
||||
{ "1024x768p@60Hz", 60, 1024, 768, KHZ2PICOS(65000), 160, 24, 29, 3, 136, 6, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
|
||||
{ "1280x720p@60Hz", 60, 1280, 720, KHZ2PICOS(74250), 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
|
||||
{ "1280x1024p@60Hz", 60, 1280, 1024, KHZ2PICOS(108000), 248, 48, 38, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
|
||||
{ "1366x768p@60Hz", 60, 1366, 768, KHZ2PICOS(85500), 213, 70, 24, 3, 143, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
|
||||
{ "1440x900p@60Hz", 60, 1440, 900, KHZ2PICOS(116500), 232, 80, 25, 3, 152, 6, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
|
||||
{ "1680x1050p@60Hz", 60, 1680, 1050, KHZ2PICOS(146250), 280, 104, 30, 3, 176, 6, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
|
||||
{ "1920x1080p@60Hz", 60, 1920, 1080, KHZ2PICOS(148500), 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
|
||||
};
|
||||
|
||||
struct rockchip_vga {
|
||||
struct device *dev; /*i2c device*/
|
||||
struct rk_display_device *ddev; /*display device*/
|
||||
struct i2c_client *client;
|
||||
struct list_head modelist;
|
||||
struct fb_monspecs specs;
|
||||
struct rk_screen screen;
|
||||
int indx;
|
||||
int en_pin;
|
||||
int en_val;
|
||||
int lcdc_id;
|
||||
#ifdef CONFIG_SWITCH
|
||||
struct switch_dev switch_vga;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int i2c_master_reg8_recv(const struct i2c_client *client,
|
||||
const char reg, char *buf, int count, int scl_rate)
|
||||
{
|
||||
struct i2c_adapter *adap=client->adapter;
|
||||
struct i2c_msg msgs[2];
|
||||
int ret;
|
||||
char reg_buf = reg;
|
||||
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].flags = client->flags;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].buf = ®_buf;
|
||||
msgs[0].scl_rate = scl_rate;
|
||||
|
||||
msgs[1].addr = client->addr;
|
||||
msgs[1].flags = client->flags | I2C_M_RD;
|
||||
msgs[1].len = count;
|
||||
msgs[1].buf = (char *)buf;
|
||||
msgs[1].scl_rate = scl_rate;
|
||||
|
||||
ret = i2c_transfer(adap, msgs, 2);
|
||||
|
||||
return (ret == 2)? count : ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned char *rk29fb_ddc_read(struct i2c_client *client)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
dev_err(&client->dev, "unable to allocate memory for EDID\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*Check ddc i2c communication is available or not*/
|
||||
rc = i2c_master_reg8_recv(client, 0, buf, 6, DDC_I2C_RATE);
|
||||
if (rc == 6) {
|
||||
memset(buf, 0, EDID_LENGTH);
|
||||
rc = i2c_master_reg8_recv(client, 0, buf, EDID_LENGTH, DDC_I2C_RATE);
|
||||
if(rc == EDID_LENGTH)
|
||||
return buf;
|
||||
}
|
||||
|
||||
dev_err(&client->dev, "unable to read EDID block.\n");
|
||||
kfree(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int vga_mode2screen(struct fb_videomode *modedb, struct rk_screen *screen)
|
||||
{
|
||||
if(modedb == NULL || screen == NULL)
|
||||
return -1;
|
||||
|
||||
memset(screen, 0, sizeof(struct rk_screen));
|
||||
memcpy(&screen->mode, modedb, sizeof(*modedb));
|
||||
screen->mode.pixclock = PICOS2KHZ(screen->mode.pixclock);
|
||||
screen->mode.pixclock /= 250;
|
||||
screen->mode.pixclock *= 250;
|
||||
screen->mode.pixclock *= 1000;
|
||||
screen->xsize = screen->mode.xres;
|
||||
screen->ysize = screen->mode.yres;
|
||||
screen->overscan.left = 100;
|
||||
screen->overscan.top = 100;
|
||||
screen->overscan.right = 100;
|
||||
screen->overscan.bottom = 100;
|
||||
/* screen type & face */
|
||||
screen->type = SCREEN_RGB;
|
||||
screen->face = OUT_P888;
|
||||
|
||||
screen->pin_vsync = (screen->mode.sync & FB_SYNC_VERT_HIGH_ACT) ? 1:0;
|
||||
screen->pin_hsync = (screen->mode.sync & FB_SYNC_HOR_HIGH_ACT) ? 1:0;
|
||||
screen->pin_den = 0;
|
||||
screen->pin_dclk = 0;
|
||||
|
||||
/* Swap rule */
|
||||
screen->swap_rb = 0;
|
||||
screen->swap_rg = 0;
|
||||
screen->swap_gb = 0;
|
||||
screen->swap_delta = 0;
|
||||
screen->swap_dumy = 0;
|
||||
/* Operation function*/
|
||||
screen->init = NULL;
|
||||
screen->standby = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int vga_switch_screen(struct rockchip_vga *vga, int indx)
|
||||
{
|
||||
struct fb_videomode *mode = &vga->specs.modedb[indx];
|
||||
struct rk_screen *screen = &vga->screen;
|
||||
vga_mode2screen(mode, screen);
|
||||
rk_fb_switch_screen(screen, 1 ,vga->lcdc_id);
|
||||
vga->indx = indx;
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
static int vga_get_screen_info(struct rockchip_vga *vga)
|
||||
{
|
||||
u8 *edid;
|
||||
int i;
|
||||
struct fb_monspecs *specs = &vga->specs;
|
||||
struct list_head *modelist = &vga->modelist;
|
||||
edid = rk29fb_ddc_read(vga->client);
|
||||
if (!edid) {
|
||||
dev_info(vga->dev, "get edid failed!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
fb_edid_to_monspecs(edid,specs);
|
||||
INIT_LIST_HEAD(modelist);
|
||||
for (i = 0; i < specs->modedb_len; i++) {
|
||||
fb_add_videomode(&specs->modedb[i], modelist);
|
||||
dev_dbg(vga->dev, "%4dx%4d@%d---dclk:%ld\n",
|
||||
specs->modedb[i].xres, specs->modedb[i].yres,
|
||||
specs->modedb[i].refresh,
|
||||
(PICOS2KHZ(specs->modedb[i].pixclock)/250)*250*1000);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int vga_get_modelist(struct rk_display_device *device,
|
||||
struct list_head **modelist)
|
||||
{
|
||||
struct rockchip_vga *vga = device->priv_data;
|
||||
*modelist = &vga->modelist;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vga_set_mode(struct rk_display_device *device,
|
||||
struct fb_videomode *mode)
|
||||
{
|
||||
struct rockchip_vga *vga = device->priv_data;
|
||||
struct rk_screen *screen = &vga->screen;
|
||||
vga_mode2screen(mode, screen);
|
||||
rk_fb_switch_screen(screen, 1 ,vga->lcdc_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vga_get_mode(struct rk_display_device *device,
|
||||
struct fb_videomode *mode)
|
||||
{
|
||||
//struct vga *vga = device->priv_data;
|
||||
//struct fb_videomode *vmode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rk_display_ops vga_display_ops = {
|
||||
.getmodelist = vga_get_modelist,
|
||||
.setmode = vga_set_mode,
|
||||
.getmode = vga_get_mode,
|
||||
};
|
||||
|
||||
static int vga_display_probe(struct rk_display_device *device, void *devdata)
|
||||
{
|
||||
device->owner = THIS_MODULE;
|
||||
strcpy(device->type, "VGA");
|
||||
device->priority = DISPLAY_PRIORITY_VGA;
|
||||
device->priv_data = devdata;
|
||||
device->ops = &vga_display_ops;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct rk_display_driver display_vga = {
|
||||
.probe = vga_display_probe,
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct rk_display_device * vga_register_display_sysfs(struct rockchip_vga *vga)
|
||||
{
|
||||
return rk_display_device_register(&display_vga, vga->dev, vga);
|
||||
}
|
||||
|
||||
void vga_unregister_display_sysfs(struct rockchip_vga *vga)
|
||||
{
|
||||
if (vga->ddev)
|
||||
rk_display_device_unregister(vga->ddev);
|
||||
}
|
||||
|
||||
|
||||
static int vga_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
struct rockchip_vga *vga;
|
||||
struct device_node *np = client->dev.of_node;
|
||||
enum of_gpio_flags pwr_flags;
|
||||
|
||||
if (!np) {
|
||||
dev_err(&client->dev, "no device node found!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vga = devm_kzalloc(&client->dev, sizeof(*vga), GFP_KERNEL);
|
||||
if (!vga) {
|
||||
dev_err(&client->dev, "allocate for vga failed!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vga->client = client;
|
||||
vga->dev = &client->dev;
|
||||
i2c_set_clientdata(client, vga);
|
||||
vga->ddev = vga_register_display_sysfs(vga);
|
||||
if (IS_ERR(vga->ddev))
|
||||
dev_warn(vga->dev, "Unable to create device for vga :%ld",
|
||||
PTR_ERR(vga->ddev));
|
||||
|
||||
vga->en_pin = of_get_named_gpio_flags(np, "pwr_gpio", 0, &pwr_flags);
|
||||
if (!gpio_is_valid(vga->en_pin)) {
|
||||
dev_err(vga->dev, "failed to get pwr_gpio!\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
vga->en_val = (pwr_flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1;
|
||||
vga->lcdc_id = DISPLAY_SOURCE_LCDC1;
|
||||
|
||||
ret = devm_gpio_request(vga->dev, vga->en_pin, "pwr_pin");
|
||||
if(ret < 0) {
|
||||
dev_err(vga->dev, "request for pwr_pin failed!\n ");
|
||||
goto err;
|
||||
}
|
||||
gpio_direction_output(vga->en_pin, vga->en_val);
|
||||
ret = vga_get_screen_info(vga);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
vga_switch_screen(vga, 7);
|
||||
|
||||
printk("VGA probe successful\n");
|
||||
return 0;
|
||||
err:
|
||||
vga_unregister_display_sysfs(vga);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int vga_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static struct of_device_id vga_dt_ids[] = {
|
||||
{.compatible = "rockchip,vga" },
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id vga_id[] = {
|
||||
{ "vga_i2c", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver vga_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "vga_i2c",
|
||||
.owner = THIS_MODULE,
|
||||
#if defined(CONFIG_OF)
|
||||
.of_match_table = of_match_ptr(vga_dt_ids),
|
||||
#endif
|
||||
},
|
||||
.probe = &vga_i2c_probe,
|
||||
.remove = &vga_i2c_remove,
|
||||
.id_table = vga_id,
|
||||
};
|
||||
|
||||
static int __init rockchip_vga_init(void)
|
||||
{
|
||||
return i2c_add_driver(&vga_i2c_driver);
|
||||
}
|
||||
|
||||
static void __exit rockchip_vga_exit(void)
|
||||
{
|
||||
i2c_del_driver(&vga_i2c_driver);
|
||||
}
|
||||
|
||||
module_init(rockchip_vga_init);
|
||||
module_exit(rockchip_vga_exit);
|
||||
Reference in New Issue
Block a user