video: rockchip: remove unused transmitter driver

Change-Id: I01c7291b55c9183902ecb55c6b0b2e79d2aa3097
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
Tao Huang
2019-09-09 17:55:24 +08:00
parent d96d147740
commit c620d25edd
31 changed files with 0 additions and 16857 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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,
};

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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", &regs_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", &regs_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 = &reg_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);

View File

@@ -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);

View File

@@ -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 = &reg_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);