mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
Merge tag 'MMI-U1UGS34.23-110-23-2' of https://github.com/MotorolaMobilityLLC/kernel-msm-5.4-techpack-display into lineage-22.2
Fogos push for Android 14 * tag 'MMI-U1UGS34.23-110-23-2' of https://github.com/MotorolaMobilityLLC/kernel-msm-5.4-techpack-display: (116 commits) dsi_panel: panel_feature: corret the code mistake dsi_panel: fix the bug of local HBM gpu/msm: check fps value before enable lhbm msm/display-drivers: release lhbm resource dsi/dfps: update the dfps code to support "OLED+vid mode" dsi/dfps: set the right fps when panel resume Support 120Hz command sending dts/display: [bangkok] update the dsc configure for tianma panel display-drivers: local hbm: add suport for dc_hybird_threshold optimze lcd log kernel:pnangn:update 2nd panel brightness settings to 11bits kernel/panel:power on/off reset sequence display/backlight: support hbm dcs only with 51 cmd display/dsi:add new lcd backlight align type for bit11_4 display: The lcd backlight shift mode update drm_ioctl: add return value for set_param drm/dsi_panel: resend hbm off commands msm/drm:compatible with different hbm table in panel drm/msm:add delay between mipi0 to reset0 when power off drm/panel: check panel status before send custom commands ... Conflicts: techpack/display/msm/sde/sde_connector.c techpack/display/msm/sde/sde_kms.c Change-Id: I13ede04c21415717cd009ae73871894f1be74927
This commit is contained in:
commit
654ea8a9cd
30 changed files with 3949 additions and 113 deletions
|
|
@ -12,3 +12,4 @@ export CONFIG_MSM_SDE_ROTATOR=y
|
|||
export CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
|
||||
export CONFIG_DRM_SDE_RSC=y
|
||||
export CONFIG_DISPLAY_BUILD=y
|
||||
export CONFIG_DRM_DYNAMIC_REFRESH_RATE=y
|
||||
|
|
|
|||
|
|
@ -17,4 +17,5 @@
|
|||
#define CONFIG_MSM_SDE_ROTATOR 1
|
||||
#define CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG 1
|
||||
#define CONFIG_DRM_SDE_RSC 1
|
||||
#define CONFIG_DRM_DYNAMIC_REFRESH_RATE 1
|
||||
|
||||
|
|
|
|||
|
|
@ -11,3 +11,4 @@ export CONFIG_QCOM_MDSS_PLL=y
|
|||
export CONFIG_MSM_SDE_ROTATOR=y
|
||||
export CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
|
||||
export CONFIG_DRM_SDE_RSC=y
|
||||
export CONFIG_DRM_DYNAMIC_REFRESH_RATE=y
|
||||
|
|
|
|||
|
|
@ -17,3 +17,4 @@
|
|||
#define CONFIG_MSM_SDE_ROTATOR 1
|
||||
#define CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG 1
|
||||
#define CONFIG_DRM_SDE_RSC 1
|
||||
#define CONFIG_DRM_DYNAMIC_REFRESH_RATE 1
|
||||
|
|
|
|||
|
|
@ -690,6 +690,27 @@ struct drm_msm_display_hint {
|
|||
#define DRM_IOCTL_MSM_DISPLAY_HINT DRM_IOW((DRM_COMMAND_BASE + \
|
||||
DRM_MSM_DISPLAY_HINT), struct drm_msm_display_hint)
|
||||
|
||||
/* panel feature */
|
||||
typedef enum {
|
||||
PARAM_HBM = 0,
|
||||
PARAM_CABC,
|
||||
PARAM_ACL,
|
||||
PARAM_DC,
|
||||
POWER_MODE_MAX_NUM,
|
||||
PARAM_COLOR = POWER_MODE_MAX_NUM,
|
||||
PARAM_MAX_NUM
|
||||
} paramId_t;
|
||||
|
||||
struct panel_param_info {
|
||||
paramId_t param_idx;
|
||||
__u32 value;
|
||||
};
|
||||
|
||||
#define DRM_SET_PANEL_FEATURE (DRM_COMMAND_END -1)
|
||||
#define DRM_IOCTL_SET_PANEL_FEATURE DRM_IOWR(DRM_SET_PANEL_FEATURE, struct panel_param_info)
|
||||
#define DRM_GET_PANEL_FEATURE (DRM_COMMAND_END-2)
|
||||
#define DRM_IOCTL_GET_PANEL_FEATURE DRM_IOWR(DRM_GET_PANEL_FEATURE, struct panel_param_info)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ msm_drm-$(CONFIG_DRM_MSM_SDE) += sde/sde_crtc.o \
|
|||
sde/sde_core_perf.o \
|
||||
sde/sde_rm.o \
|
||||
sde/sde_kms_utils.o \
|
||||
sde/sde_motUtil.o \
|
||||
sde/sde_kms.o \
|
||||
sde/sde_plane.o \
|
||||
sde/sde_connector.o \
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ void dsi_ctrl_hw_cmn_set_video_timing(struct dsi_ctrl_hw *ctrl,
|
|||
u32 reg = 0;
|
||||
u32 hs_start = 0;
|
||||
u32 hs_end, active_h_start, active_h_end, h_total, width = 0;
|
||||
u32 bytes_per_pkt, pkt_per_line, eol_byte_num;
|
||||
u32 bytes_per_pkt, pkt_per_line, eol_byte_num, datatype;
|
||||
u32 vs_start = 0, vs_end = 0;
|
||||
u32 vpos_start = 0, vpos_end, active_v_start, active_v_end, v_total;
|
||||
|
||||
|
|
@ -342,7 +342,9 @@ void dsi_ctrl_hw_cmn_set_video_timing(struct dsi_ctrl_hw *ctrl,
|
|||
&pkt_per_line, &eol_byte_num);
|
||||
reg = bytes_per_pkt << 16;
|
||||
/* data type of compressed image */
|
||||
reg |= (0x0b << 8);
|
||||
datatype = mode->dsc->datatype;
|
||||
if(!datatype) datatype = 0x0b;
|
||||
reg |= (datatype << 8);
|
||||
/*
|
||||
* pkt_per_line:
|
||||
* 0 == 1 pkt
|
||||
|
|
|
|||
|
|
@ -263,6 +263,27 @@ enum dsi_dyn_clk_feature_type {
|
|||
* @DSI_CMD_SET_POST_TIMING_SWITCH: Post timing switch
|
||||
* @DSI_CMD_SET_QSYNC_ON Enable qsync mode
|
||||
* @DSI_CMD_SET_QSYNC_OFF Disable qsync mode
|
||||
* @DSI_CMD_SET_HBM_FOD_ON: Turning HBM_FOD on
|
||||
* @DSI_CMD_SET_HBM_ON: Turning HBM on
|
||||
* @DSI_CMD_SET_HBM_OFF: Turning HBM off
|
||||
* @DSI_CMD_SET_ACL_ON: Turning ACL on
|
||||
* @DSI_CMD_SET_ACL_OFF: Turning ACL off
|
||||
* @DSI_CMD_SET_HBM_DIM_OFF: Turning HBM DIM off
|
||||
* @DSI_CMD_SET_CABC_UI: CABC UI mode
|
||||
* @DSI_CMD_SET_CABC_MV: CABC MV mode
|
||||
* @DSI_CMD_SET_CABC_DIS: CABC DIS mode
|
||||
* @DSI_CMD_SET_DFPS_CMD_120: DFPS switch to 120
|
||||
* @DSI_CMD_SET_DFPS_CMD_90: DFPS switch to 90
|
||||
* @DSI_CMD_SET_DFPS_CMD_60: DFPS switch to 60
|
||||
* @DSI_CMD_SET_DC_ON: DC mode on
|
||||
* @DSI_CMD_SET_DC_OFF: DC mode off
|
||||
* @DSI_CMD_SET_BRIGHTNESS_1E: Send demura codes when brightness changes to 0-1E
|
||||
* @DSI_CMD_SET_BRIGHTNESS_1FD: Send demura codes when brightness changes to 1F-1FD
|
||||
* @DSI_CMD_SET_BRIGHTNESS_2FF: Send demura codes when brightness changes to 1FE-2FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_3FF: Send demura codes when brightness changes to 300-3FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_4FF: Send demura codes when brightness changes to 400-4FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_5FF: Send demura codes when brightness changes to 500-5FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_FFF: Send demura codes when brightness changes to 600-FFF
|
||||
* @DSI_CMD_SET_MAX
|
||||
*/
|
||||
enum dsi_cmd_set_type {
|
||||
|
|
@ -289,6 +310,27 @@ enum dsi_cmd_set_type {
|
|||
DSI_CMD_SET_POST_TIMING_SWITCH,
|
||||
DSI_CMD_SET_QSYNC_ON,
|
||||
DSI_CMD_SET_QSYNC_OFF,
|
||||
DSI_CMD_SET_HBM_FOD_ON,
|
||||
DSI_CMD_SET_HBM_ON,
|
||||
DSI_CMD_SET_HBM_OFF,
|
||||
DSI_CMD_SET_ACL_ON,
|
||||
DSI_CMD_SET_ACL_OFF,
|
||||
DSI_CMD_SET_HBM_DIM_OFF,
|
||||
DSI_CMD_SET_CABC_UI,
|
||||
DSI_CMD_SET_CABC_MV,
|
||||
DSI_CMD_SET_CABC_DIS,
|
||||
DSI_CMD_SET_DFPS_CMD_120,
|
||||
DSI_CMD_SET_DFPS_CMD_90,
|
||||
DSI_CMD_SET_DFPS_CMD_60,
|
||||
DSI_CMD_SET_DC_ON,
|
||||
DSI_CMD_SET_DC_OFF,
|
||||
DSI_CMD_SET_BRIGHTNESS_1E,
|
||||
DSI_CMD_SET_BRIGHTNESS_1FD,
|
||||
DSI_CMD_SET_BRIGHTNESS_2FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_3FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_4FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_5FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_FFF,
|
||||
DSI_CMD_SET_MAX
|
||||
};
|
||||
|
||||
|
|
@ -622,11 +664,13 @@ struct dsi_display_mode_priv_info {
|
|||
u32 dsi_transfer_time_us;
|
||||
u64 clk_rate_hz;
|
||||
u64 min_dsi_clk_hz;
|
||||
u32 phy_drive_strength;
|
||||
|
||||
struct msm_display_topology topology;
|
||||
struct msm_display_dsc_info dsc;
|
||||
struct msm_display_vdc_info vdc;
|
||||
bool dsc_enabled;
|
||||
bool panel_dsc_update_pps_disable;
|
||||
bool vdc_enabled;
|
||||
struct msm_ratio pclk_scale;
|
||||
struct msm_roi_caps roi_caps;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -20,6 +20,8 @@
|
|||
#include "dsi_ctrl.h"
|
||||
#include "dsi_phy.h"
|
||||
#include "dsi_panel.h"
|
||||
#include "sde_connector.h"
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define MAX_DSI_CTRLS_PER_DISPLAY 2
|
||||
#define DSI_CLIENT_NAME_SIZE 20
|
||||
|
|
@ -270,6 +272,7 @@ struct dsi_display {
|
|||
bool misr_enable;
|
||||
u32 misr_frame_count;
|
||||
u32 esd_trigger;
|
||||
bool disp_esd_chk_underway;
|
||||
/* multiple dsi error handlers */
|
||||
struct workqueue_struct *err_workq;
|
||||
struct work_struct fifo_underflow_work;
|
||||
|
|
@ -299,12 +302,13 @@ struct dsi_display {
|
|||
|
||||
int tx_cmd_buf_ndx;
|
||||
struct dsi_panel_cmd_set cmd_set;
|
||||
|
||||
bool enabled;
|
||||
u32 panel_idx;
|
||||
};
|
||||
|
||||
int dsi_display_dev_probe(struct platform_device *pdev);
|
||||
int dsi_display_dev_remove(struct platform_device *pdev);
|
||||
void dsi_display_dev_shutdown(struct platform_device *pdev);
|
||||
|
||||
/**
|
||||
* dsi_display_get_num_of_displays() - returns number of display devices
|
||||
|
|
@ -596,6 +600,8 @@ int dsi_post_clkoff_cb(void *priv, enum dsi_clk_type clk_type,
|
|||
enum dsi_lclk_type l_type,
|
||||
enum dsi_clk_state curr_state);
|
||||
|
||||
int dsi_display_set_param(void *display, struct msm_param_info *param_info);
|
||||
|
||||
/**
|
||||
* dsi_post_clkon_cb() - Callback after clock is turned on
|
||||
* @priv: private data pointer.
|
||||
|
|
@ -701,6 +707,29 @@ int dsi_display_cmd_transfer(struct drm_connector *connector,
|
|||
*/
|
||||
int dsi_display_cmd_receive(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, u8 *recv_buf, u32 recv_buf_len);
|
||||
/**
|
||||
* dsi_display_motUtil_transfer() - Convert motUtil data and transfer command
|
||||
* to the panel
|
||||
* @display: Handle to display.
|
||||
* @cmd_buf: Command buffer
|
||||
* @cmd_buf_len: Command buffer length in bytes
|
||||
* @motUtil_data: motUtil data information
|
||||
*/
|
||||
int dsi_display_motUtil_transfer(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data);
|
||||
|
||||
/**
|
||||
* dsi_display_trigger_panel_dead_event() - Trigger ESD recovery
|
||||
*
|
||||
* @display: Handle to display.
|
||||
*/
|
||||
int dsi_display_trigger_panel_dead_event(struct dsi_display *display);
|
||||
/**
|
||||
* dsi_display_force_esd_disable() - check if ESD UTAG is forced to disable ESD
|
||||
* @display: Handle to display.
|
||||
*/
|
||||
bool dsi_display_force_esd_disable(void *display);
|
||||
|
||||
|
||||
/**
|
||||
* dsi_display_soft_reset() - perform a soft reset on DSI controller
|
||||
|
|
@ -764,6 +793,20 @@ enum dsi_pixel_format dsi_display_get_dst_format(
|
|||
struct drm_connector *connector,
|
||||
void *display);
|
||||
|
||||
/*
|
||||
* dsi_display_cmd_mipi_transfer() - Sending the MIPI DSI command
|
||||
* @display: Handle to display
|
||||
* @msg: MIPI DSI command information
|
||||
* @flags: Modifier flags
|
||||
* Return: if this is a MIPI DSI read then it will return number read byte
|
||||
* in success case. Otherwise will be "<=0"
|
||||
* if this is a MIPI DSI write then it will return "0" for success
|
||||
*
|
||||
*/
|
||||
int dsi_display_cmd_mipi_transfer(struct dsi_display *display,
|
||||
struct mipi_dsi_msg *msg,
|
||||
u32 flags);
|
||||
|
||||
/**
|
||||
* dsi_display_cont_splash_config() - initialize splash resources
|
||||
* @display: Handle to display
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -37,6 +37,38 @@
|
|||
#define MIPI_DSI_MSG_ASYNC_OVERRIDE BIT(4)
|
||||
#define MIPI_DSI_MSG_CMD_DMA_SCHED BIT(5)
|
||||
|
||||
#define DSI_PANEL_MAX_PANEL_LEN 128
|
||||
#define MAX_PARAM_NAME 10
|
||||
|
||||
#define BRIGHTNESS_HBM_ON 0xFFFFFFFE
|
||||
#define BRIGHTNESS_HBM_OFF (BRIGHTNESS_HBM_ON - 1)
|
||||
#define HBM_BRIGHTNESS(value) ((value) == HBM_OFF_STATE ?\
|
||||
BRIGHTNESS_HBM_OFF : BRIGHTNESS_HBM_ON)
|
||||
|
||||
/* HBM implementation is different, depending on display and backlight hardware
|
||||
* design, which is classified into the following types:
|
||||
* HBM_TYPE_OLED: OLED panel, HBM is controlled by DSI register only, which
|
||||
* is independent on brightness.
|
||||
* HBM_TYPE_LCD_DCS_WLED: LCD panel, HBM is controlled by DSI register, and
|
||||
* brightness is decided by WLED IC on I2C/SPI bus.
|
||||
* HBM_TYPE_LCD_DCS_ONLY: LCD panel, brightness/HBM is controlled by DSI
|
||||
* register only.
|
||||
* HBM_TYPE_LCD_WLED_ONLY: LCD panel, brightness/HBM is controlled by WLED
|
||||
* IC only.
|
||||
* HBM_TYPE_LCD_DCS_GPIO: LCD panel, HBM is controlled by GPIO, and brightness
|
||||
* is controlled by DSI register.
|
||||
*
|
||||
* Note: brightness must be at maximum while enabling HBM for all LCD panels
|
||||
*/
|
||||
|
||||
enum panel_hbm_type {
|
||||
HBM_TYPE_OLED = 0,
|
||||
HBM_TYPE_LCD_DCS_WLED,
|
||||
HBM_TYPE_LCD_DCS_ONLY,
|
||||
HBM_TYPE_LCD_WLED_ONLY,
|
||||
HBM_TYPE_LCD_DCS_GPIO
|
||||
};
|
||||
|
||||
enum dsi_panel_rotation {
|
||||
DSI_PANEL_ROTATE_NONE = 0,
|
||||
DSI_PANEL_ROTATE_HV_FLIP,
|
||||
|
|
@ -48,7 +80,9 @@ enum dsi_backlight_type {
|
|||
DSI_BACKLIGHT_PWM = 0,
|
||||
DSI_BACKLIGHT_WLED,
|
||||
DSI_BACKLIGHT_DCS,
|
||||
DSI_BACKLIGHT_DUMMY,
|
||||
DSI_BACKLIGHT_EXTERNAL,
|
||||
DSI_BACKLIGHT_I2C,
|
||||
DSI_BACKLIGHT_UNKNOWN,
|
||||
DSI_BACKLIGHT_MAX,
|
||||
};
|
||||
|
|
@ -58,6 +92,12 @@ enum bl_update_flag {
|
|||
BL_UPDATE_NONE,
|
||||
};
|
||||
|
||||
enum dsi_backlight_level_align_type {
|
||||
DSI_BACKLIGHT_LEVEL_ALIGN_NORMAL = 0,
|
||||
DSI_BACKLIGHT_LEVEL_ALIGN_BIT15_8_BIT3_0 = 1,
|
||||
DSI_BACKLIGHT_LEVEL_ALIGN_BIT11_4_BYTE0 = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
MODE_GPIO_NOT_VALID = 0,
|
||||
MODE_SEL_DUAL_PORT,
|
||||
|
|
@ -84,6 +124,10 @@ struct dsi_dfps_capabilities {
|
|||
u32 *dfps_list;
|
||||
u32 dfps_list_len;
|
||||
bool dfps_support;
|
||||
bool dfps_send_cmd_support;
|
||||
bool dfps_send_cmd_with_te_async;
|
||||
u32 panel_on_fps;
|
||||
u32 current_fps;
|
||||
};
|
||||
|
||||
struct dsi_qsync_capabilities {
|
||||
|
|
@ -118,13 +162,19 @@ struct dsi_backlight_config {
|
|||
enum dsi_backlight_type type;
|
||||
enum bl_update_flag bl_update;
|
||||
|
||||
bool bl_2bytes_enable;
|
||||
bool bl_shift_left_1bit;
|
||||
u32 bl_min_level;
|
||||
u32 bl_max_level;
|
||||
u32 brightness_max_level;
|
||||
u32 brightness_default_level;
|
||||
u32 bl_level;
|
||||
u32 bl_scale;
|
||||
u32 bl_scale_sv;
|
||||
u32 bl_level_align;
|
||||
bool bl_inverted_dbv;
|
||||
bool bl_demura_cmd;
|
||||
u32 demura_type;
|
||||
|
||||
int en_gpio;
|
||||
/* PWM params */
|
||||
|
|
@ -135,7 +185,8 @@ struct dsi_backlight_config {
|
|||
/* WLED params */
|
||||
struct led_trigger *wled;
|
||||
struct backlight_device *raw_bd;
|
||||
|
||||
struct backlight_device *i2c_bd;
|
||||
|
||||
/* DCS params */
|
||||
bool lp_mode;
|
||||
};
|
||||
|
|
@ -153,10 +204,12 @@ struct dsi_panel_reset_config {
|
|||
int disp_en_gpio;
|
||||
int lcd_mode_sel_gpio;
|
||||
u32 mode_sel_state;
|
||||
bool panel_on_rst_pull_down;
|
||||
};
|
||||
|
||||
enum esd_check_status_mode {
|
||||
ESD_MODE_REG_READ,
|
||||
ESD_MODE_TE_CHK_REG_RD,
|
||||
ESD_MODE_SW_BTA,
|
||||
ESD_MODE_PANEL_TE,
|
||||
ESD_MODE_SW_SIM_SUCCESS,
|
||||
|
|
@ -182,6 +235,68 @@ struct dsi_panel_spr_info {
|
|||
enum msm_display_spr_pack_type pack_type;
|
||||
};
|
||||
|
||||
struct dsi_panel_lhbm_config {
|
||||
bool enable;
|
||||
u32 dc_hybird_threshold;
|
||||
bool resend_lbhm_off;
|
||||
u32 dbv_level;
|
||||
u32 alpha_reg;
|
||||
u32 alpha_size;
|
||||
u32 *alpha;
|
||||
bool lhbm_wait_for_fps_valid;
|
||||
u32 lhbm_wait_for_fps_count;
|
||||
u32 lhbm_wait_for_fps_interval;
|
||||
u32 *lhbm_not_allowed_fps_list;
|
||||
u32 lhbm_not_allowed_fps_list_len;
|
||||
};
|
||||
|
||||
enum panel_idx {
|
||||
MAIN_IDX = 0,
|
||||
SEC_INX,
|
||||
PANEL_IDX_MAX,
|
||||
};
|
||||
|
||||
enum acl_state {
|
||||
ACL_OFF_STATE = 0,
|
||||
ACL_ON_STATE,
|
||||
ACL_STATE_NUM,
|
||||
};
|
||||
|
||||
enum hbm_state {
|
||||
HBM_OFF_STATE = 0,
|
||||
HBM_ON_STATE,
|
||||
HBM_FOD_ON_STATE,
|
||||
HBM_STATE_NUM
|
||||
};
|
||||
|
||||
enum cabc_state {
|
||||
CABC_UI_STATE,
|
||||
CABC_MV_STATE,
|
||||
CABC_DIS_STATE,
|
||||
CABC_STATE_NUM,
|
||||
};
|
||||
|
||||
enum dc_state {
|
||||
DC_OFF_STATE = 0,
|
||||
DC_ON_STATE,
|
||||
DC_STATE_NUM,
|
||||
};
|
||||
|
||||
struct panel_param_val_map {
|
||||
int state;
|
||||
enum dsi_cmd_set_type type;
|
||||
struct dsi_panel_cmd_set *cmds;
|
||||
};
|
||||
|
||||
struct panel_param {
|
||||
const char *param_name;
|
||||
struct panel_param_val_map *val_map;
|
||||
u16 val_max;
|
||||
const u16 default_value;
|
||||
u16 value;
|
||||
bool is_supported;
|
||||
};
|
||||
|
||||
struct dsi_tlmm_gpio {
|
||||
u32 num;
|
||||
u32 addr;
|
||||
|
|
@ -201,6 +316,10 @@ struct dsi_panel_ops {
|
|||
int (*parse_gpios)(struct dsi_panel *panel);
|
||||
int (*parse_power_cfg)(struct dsi_panel *panel);
|
||||
};
|
||||
enum touch_state {
|
||||
TOUCH_DEEP_SLEEP_STATE = 0,
|
||||
TOUCH_LOW_POWER_STATE,
|
||||
};
|
||||
|
||||
struct dsi_panel {
|
||||
const char *name;
|
||||
|
|
@ -235,6 +354,8 @@ struct dsi_panel {
|
|||
struct drm_panel_hdr_properties hdr_props;
|
||||
struct drm_panel_esd_config esd_config;
|
||||
|
||||
struct dsi_panel_lhbm_config lhbm_config;
|
||||
|
||||
struct dsi_parser_utils utils;
|
||||
|
||||
bool lp11_init;
|
||||
|
|
@ -242,8 +363,11 @@ struct dsi_panel {
|
|||
bool ulps_suspend_enabled;
|
||||
bool allow_phy_power_off;
|
||||
bool reset_gpio_always_on;
|
||||
bool need_execute_shutdown;
|
||||
atomic_t esd_recovery_pending;
|
||||
|
||||
u32 delayms_before_resetlow;
|
||||
|
||||
bool is_twm_en;
|
||||
bool skip_panel_off;
|
||||
bool panel_initialized;
|
||||
|
|
@ -261,14 +385,43 @@ struct dsi_panel {
|
|||
|
||||
int panel_test_gpio;
|
||||
int power_mode;
|
||||
bool keep_regulators_on;
|
||||
enum dsi_panel_physical_type panel_type;
|
||||
|
||||
struct dsi_tlmm_gpio *tlmm_gpio;
|
||||
u32 tlmm_gpio_count;
|
||||
|
||||
struct dsi_panel_ops panel_ops;
|
||||
bool esd_utag_enable;
|
||||
u64 panel_id;
|
||||
u64 panel_ver;
|
||||
u32 panel_regDA;
|
||||
char panel_name[DSI_PANEL_MAX_PANEL_LEN];
|
||||
char panel_supplier[DSI_PANEL_MAX_PANEL_LEN];
|
||||
|
||||
u32 disp_on_chk_val;
|
||||
bool no_panel_on_read_support;
|
||||
|
||||
bool panel_hbm_fod;
|
||||
bool panel_hbm_dim_off;
|
||||
|
||||
enum panel_hbm_type hbm_type;
|
||||
u32 bl_lvl_during_hbm;
|
||||
|
||||
struct panel_param *param_cmds;
|
||||
|
||||
enum touch_state tp_state;
|
||||
bool tp_state_check_enable;
|
||||
|
||||
int panel_recovery_retry;
|
||||
bool is_panel_dead;
|
||||
|
||||
bool is_hbm_using_51_cmd;
|
||||
int hbm_en_gpio;
|
||||
};
|
||||
|
||||
bool dsi_display_all_displays_dead(void);
|
||||
|
||||
static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel)
|
||||
{
|
||||
return panel->ulps_feature_enabled;
|
||||
|
|
@ -299,7 +452,8 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
|
|||
struct device_node *parser_node,
|
||||
const char *type,
|
||||
int topology_override,
|
||||
bool trusted_vm_env);
|
||||
bool trusted_vm_env,
|
||||
u32 panel_idx);
|
||||
|
||||
int dsi_panel_trigger_esd_attack(struct dsi_panel *panel, bool trusted_vm_env);
|
||||
|
||||
|
|
@ -340,6 +494,8 @@ int dsi_panel_set_nolp(struct dsi_panel *panel);
|
|||
|
||||
int dsi_panel_prepare(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_reset(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_enable(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_post_enable(struct dsi_panel *panel);
|
||||
|
|
@ -383,6 +539,8 @@ struct dsi_panel *dsi_panel_ext_bridge_get(struct device *parent,
|
|||
|
||||
int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_parse_panel_cfg(struct dsi_panel *panel, bool is_primary);
|
||||
|
||||
void dsi_panel_ext_bridge_put(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_get_io_resources(struct dsi_panel *panel,
|
||||
|
|
@ -402,4 +560,16 @@ int dsi_panel_create_cmd_packets(const char *data, u32 length, u32 count,
|
|||
void dsi_panel_destroy_cmd_packets(struct dsi_panel_cmd_set *set);
|
||||
|
||||
void dsi_panel_dealloc_cmd_packets(struct dsi_panel_cmd_set *set);
|
||||
|
||||
int dsi_panel_set_param(struct dsi_panel *panel,
|
||||
struct msm_param_info *param_info);
|
||||
|
||||
void dsi_panel_reset_param(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_get_elvss_data(struct dsi_panel *panel);
|
||||
int dsi_panel_get_elvss_data_1(struct dsi_panel *panel);
|
||||
int dsi_panel_set_elvss_dim_off(struct dsi_panel *panel, u8 val);
|
||||
int dsi_panel_parse_elvss_config(struct dsi_panel *panel, u8 elv_vl);
|
||||
int dsi_panel_dfps_send_cmd(struct dsi_panel *panel);
|
||||
|
||||
#endif /* _DSI_PANEL_H_ */
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ static const struct dsi_ver_spec_info dsi_phy_v2_0 = {
|
|||
static const struct dsi_ver_spec_info dsi_phy_v3_0 = {
|
||||
.version = DSI_PHY_VERSION_3_0,
|
||||
.lane_cfg_count = 4,
|
||||
.strength_cfg_count = 2,
|
||||
.strength_cfg_count = 4,
|
||||
.regulator_cfg_count = 0,
|
||||
.timing_cfg_count = 12,
|
||||
};
|
||||
|
|
@ -1114,6 +1114,32 @@ int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dsi_phy_set_drive_strength_params - drive strength parameters for the panel
|
||||
* @phy: DSI PHY handle
|
||||
* @drive strength: array holding timing params.
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_phy_set_drive_strength_params(struct msm_dsi_phy *phy,
|
||||
u32 drive_strength)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!phy || !drive_strength) {
|
||||
DSI_PHY_ERR(phy, "Invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&phy->phy_lock);
|
||||
|
||||
|
||||
phy->cfg.phy_drive_strength = drive_strength;
|
||||
|
||||
mutex_unlock(&phy->phy_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* dsi_phy_set_timing_params() - timing parameters for the panel
|
||||
* @phy: DSI PHY handle
|
||||
|
|
@ -1147,7 +1173,6 @@ int dsi_phy_set_timing_params(struct msm_dsi_phy *phy,
|
|||
|
||||
if (phy->hw.ops.commit_phy_timing && commit)
|
||||
phy->hw.ops.commit_phy_timing(&phy->hw, &phy->cfg.timing);
|
||||
|
||||
mutex_unlock(&phy->phy_lock);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,6 +256,16 @@ int dsi_phy_set_clamp_state(struct msm_dsi_phy *phy, bool enable);
|
|||
int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy,
|
||||
struct link_clk_freq *clk_freq);
|
||||
|
||||
/**
|
||||
* dsi_phy_set_drive_strength_params() - drive strength parameters for the panel
|
||||
* @phy: DSI PHY handle
|
||||
* @drive_strength: DSI PHY Drive Strength
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_phy_set_drive_strength_params(struct msm_dsi_phy *phy,
|
||||
u32 drive_strength);
|
||||
|
||||
/**
|
||||
* dsi_phy_set_timing_params() - timing parameters for the panel
|
||||
* @phy: DSI PHY handle
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ struct dsi_phy_per_lane_cfgs {
|
|||
* @force_clk_lane_hs:Boolean whether to force clock lane in HS mode.
|
||||
* @phy_type: Phy-type (Dphy/Cphy).
|
||||
* @bit_clk_rate_hz: DSI bit clk rate in HZ.
|
||||
* @drive_strength: DSI PHY drive strength.
|
||||
*/
|
||||
struct dsi_phy_cfg {
|
||||
struct dsi_phy_per_lane_cfgs lanecfg;
|
||||
|
|
@ -115,6 +116,7 @@ struct dsi_phy_cfg {
|
|||
bool force_clk_lane_hs;
|
||||
enum dsi_phy_type phy_type;
|
||||
unsigned long bit_clk_rate_hz;
|
||||
u32 phy_drive_strength;
|
||||
};
|
||||
|
||||
struct dsi_phy_hw;
|
||||
|
|
|
|||
|
|
@ -185,6 +185,12 @@ static void dsi_phy_hw_v3_0_lane_settings(struct dsi_phy_hw *phy,
|
|||
DSI_W32(phy, DSIPHY_LNX_LPRX_CTRL(i), 0);
|
||||
DSI_W32(phy, DSIPHY_LNX_PIN_SWAP(i), 0x0);
|
||||
DSI_W32(phy, DSIPHY_LNX_HSTX_STR_CTRL(i), 0x88);
|
||||
if(cfg->phy_drive_strength) {
|
||||
DSI_W32(phy, DSIPHY_LNX_HSTX_STR_CTRL(i), cfg->phy_drive_strength);
|
||||
DSI_PHY_WARN(phy, "DSIPHY_LNX_HSTX_STR_CTRL of lane%d is rewrite to 0x%x from 0x88\n",
|
||||
i, cfg->phy_drive_strength);
|
||||
}
|
||||
|
||||
}
|
||||
dsi_phy_hw_v3_0_config_lpcdrx(phy, cfg, true);
|
||||
|
||||
|
|
@ -194,8 +200,8 @@ static void dsi_phy_hw_v3_0_lane_settings(struct dsi_phy_hw *phy,
|
|||
DSI_W32(phy, DSIPHY_LNX_CFG1(i), cfg->lanecfg.lane[i][1]);
|
||||
DSI_W32(phy, DSIPHY_LNX_CFG2(i), cfg->lanecfg.lane[i][2]);
|
||||
DSI_W32(phy, DSIPHY_LNX_CFG3(i), cfg->lanecfg.lane[i][3]);
|
||||
DSI_W32(phy, DSIPHY_LNX_OFFSET_TOP_CTRL(i), 0x0);
|
||||
DSI_W32(phy, DSIPHY_LNX_OFFSET_BOT_CTRL(i), 0x0);
|
||||
DSI_W32(phy, DSIPHY_LNX_OFFSET_TOP_CTRL(i), cfg->strength.lane[i][2]);
|
||||
DSI_W32(phy, DSIPHY_LNX_OFFSET_BOT_CTRL(i), cfg->strength.lane[i][3]);
|
||||
DSI_W32(phy, DSIPHY_LNX_TX_DCTRL(i), tx_dctrl[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,6 +349,11 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
|
|||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c;
|
||||
glbl_str_swi_cal_sel_ctrl = 0x00;
|
||||
glbl_hstx_str_ctrl_0 = 0x88;
|
||||
|
||||
if (cfg->phy_drive_strength != glbl_hstx_str_ctrl_0) {
|
||||
glbl_str_swi_cal_sel_ctrl = 0x03;
|
||||
glbl_hstx_str_ctrl_0 = cfg->phy_drive_strength;
|
||||
}
|
||||
} else {
|
||||
vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
|
||||
glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ static int dsi_pwr_parse_supply_node(struct dsi_parser_utils *utils,
|
|||
int i = 0;
|
||||
u32 tmp = 0;
|
||||
struct device_node *node = NULL;
|
||||
bool is_always_on = FALSE;
|
||||
|
||||
dsi_for_each_child_node(root, node) {
|
||||
const char *st = NULL;
|
||||
|
|
@ -112,6 +113,14 @@ static int dsi_pwr_parse_supply_node(struct dsi_parser_utils *utils,
|
|||
regs->vregs[i].post_off_sleep = tmp;
|
||||
}
|
||||
|
||||
is_always_on = utils->read_bool(node, "qcom,supply-always-on");
|
||||
if (!is_always_on) {
|
||||
DSI_DEBUG("qcom,supply-always-on not specified\n");
|
||||
} else {
|
||||
regs->vregs[i].is_always_on = is_always_on;
|
||||
DSI_INFO("%s: always-on is specified\n", regs->vregs[i].vreg_name);
|
||||
}
|
||||
|
||||
DSI_DEBUG("[%s] minv=%d maxv=%d, en_load=%d, dis_load=%d\n",
|
||||
regs->vregs[i].vreg_name,
|
||||
regs->vregs[i].min_voltage,
|
||||
|
|
@ -206,6 +215,12 @@ static int dsi_pwr_enable_vregs(struct dsi_regulator_info *regs, bool enable)
|
|||
pre_off_ms = vreg->pre_off_sleep;
|
||||
post_off_ms = vreg->post_off_sleep;
|
||||
|
||||
if (vreg->is_always_on)
|
||||
{
|
||||
DSI_INFO("%s is always on\n", vreg->vreg_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pre_off_ms)
|
||||
usleep_range((pre_off_ms * 1000),
|
||||
(pre_off_ms * 1000) + 10);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct dsi_vreg {
|
|||
u32 post_on_sleep;
|
||||
u32 pre_off_sleep;
|
||||
u32 post_off_sleep;
|
||||
bool is_always_on;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include <drm/drm_of.h>
|
||||
#include <drm/drm_auth.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
#include "msm_gem.h"
|
||||
|
|
@ -428,6 +429,11 @@ static int msm_drm_uninit(struct device *dev)
|
|||
priv->registered = false;
|
||||
}
|
||||
|
||||
if (priv->msm_drv_notifier.notifier_call) {
|
||||
unregister_reboot_notifier(&priv->msm_drv_notifier);
|
||||
priv->msm_drv_notifier.notifier_call = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
if (fbdev && priv->fbdev)
|
||||
msm_fbdev_free(ddev);
|
||||
|
|
@ -755,6 +761,23 @@ static struct msm_kms *_msm_drm_component_init_helper(
|
|||
return kms;
|
||||
}
|
||||
|
||||
static void msm_pdev_shutdown(struct platform_device *pdev);
|
||||
static int msm_drv_shutdown_notifier_cb(struct notifier_block *nb,
|
||||
unsigned long event, void *unused)
|
||||
{
|
||||
struct device *dev;
|
||||
struct platform_device *pdev;
|
||||
struct msm_drm_private *priv = container_of(nb, struct msm_drm_private,
|
||||
msm_drv_notifier);
|
||||
|
||||
dev = priv->dev->dev;
|
||||
pdev = to_platform_device(dev);
|
||||
dev_warn(dev, "prepare to shutdown\n");
|
||||
msm_pdev_shutdown(pdev);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int msm_drm_device_init(struct platform_device *pdev,
|
||||
struct drm_driver *drv)
|
||||
{
|
||||
|
|
@ -938,6 +961,16 @@ static int msm_drm_component_init(struct device *dev)
|
|||
|
||||
drm_kms_helper_poll_init(ddev);
|
||||
|
||||
priv->msm_drv_notifier.notifier_call = msm_drv_shutdown_notifier_cb;
|
||||
priv->msm_drv_notifier.next = NULL;
|
||||
priv->msm_drv_notifier.priority = 1;
|
||||
ret = register_reboot_notifier(&priv->msm_drv_notifier);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register for reboot_notifier. ret = %d\n",
|
||||
ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
|
@ -1750,6 +1783,38 @@ int msm_ioctl_display_hint_ops(struct drm_device *dev, void *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int msm_ioctl_set_panel_feature(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct msm_drm_private *priv;
|
||||
struct msm_kms *kms;
|
||||
struct panel_param_info *param_info = data;
|
||||
int ret;
|
||||
|
||||
priv = dev->dev_private;
|
||||
kms = priv->kms;
|
||||
|
||||
if (unlikely(!param_info)) {
|
||||
DRM_ERROR("ioctl_set_panel_feature invalid data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_INFO("ioctl_set_panel_feature idx=%d, value=%d\n",
|
||||
param_info->param_idx, param_info->value);
|
||||
|
||||
if (kms && kms->funcs && kms->funcs->set_panel_feature) {
|
||||
ret = kms->funcs->set_panel_feature(kms, *param_info);
|
||||
if (ret) {
|
||||
DRM_ERROR("kms set_panel_feature failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_ioctl_desc msm_ioctls[] = {
|
||||
DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
|
|
@ -1765,6 +1830,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
|
|||
DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(MSM_DISPLAY_HINT, msm_ioctl_display_hint_ops,
|
||||
DRM_UNLOCKED),
|
||||
DRM_IOCTL_DEF_DRV(SET_PANEL_FEATURE, msm_ioctl_set_panel_feature,
|
||||
DRM_UNLOCKED),
|
||||
};
|
||||
|
||||
static const struct vm_operations_struct vm_ops = {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <linux/sde_vm_event.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
|
|
@ -215,12 +216,18 @@ enum msm_mdp_conn_property {
|
|||
CONNECTOR_PROP_QSYNC_MODE,
|
||||
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
|
||||
|
||||
/* MOT feature panel*/
|
||||
CONNECTOR_PROP_HBM,
|
||||
CONNECTOR_PROP_CABC,
|
||||
CONNECTOR_PROP_ACL,
|
||||
CONNECTOR_PROP_DC,
|
||||
/* total # of properties */
|
||||
CONNECTOR_PROP_COUNT
|
||||
};
|
||||
|
||||
#define MSM_GPU_MAX_RINGS 4
|
||||
#define MAX_H_TILES_PER_DISPLAY 2
|
||||
#define MSM_DISP_NAME_LEN_MAX 128
|
||||
|
||||
/**
|
||||
* enum msm_display_compression_type - compression method used for pixel stream
|
||||
|
|
@ -351,6 +358,27 @@ struct msm_roi_caps {
|
|||
struct msm_roi_alignment align;
|
||||
};
|
||||
|
||||
enum msm_param_state {
|
||||
PARAM_STATE_OFF = 0,
|
||||
PARAM_STATE_ON,
|
||||
PARAM_STATE_NUM,
|
||||
PARAM_STATE_DISABLE = 0xFFFF,
|
||||
};
|
||||
|
||||
enum msm_param_id {
|
||||
PARAM_HBM_ID = 0,
|
||||
PARAM_CABC_ID,
|
||||
PARAM_ACL_ID,
|
||||
PARAM_DC_ID,
|
||||
PARAM_ID_NUM
|
||||
};
|
||||
|
||||
struct msm_param_info {
|
||||
enum msm_param_id param_idx;
|
||||
enum msm_mdp_conn_property param_conn_idx;
|
||||
int value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct msm_display_dsc_info - defines dsc configuration
|
||||
* @config DSC encoder configuration
|
||||
|
|
@ -374,6 +402,7 @@ struct msm_roi_caps {
|
|||
* @half_panel_pu True for single and dual dsc encoders if partial
|
||||
* update sets the roi width to half of mode width
|
||||
* False in all other cases
|
||||
* @datatype: data type of compressed image
|
||||
*/
|
||||
struct msm_display_dsc_info {
|
||||
struct drm_dsc_config config;
|
||||
|
|
@ -396,6 +425,8 @@ struct msm_display_dsc_info {
|
|||
u32 dsc_4hsmerge_padding;
|
||||
u32 dsc_4hsmerge_alignment;
|
||||
bool half_panel_pu;
|
||||
int datatype;
|
||||
bool dsc_novatek_ic;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -727,6 +758,10 @@ struct msm_resource_caps_info {
|
|||
* @h_tile_instance: Controller instance used per tile. Number of elements is
|
||||
* based on num_of_h_tiles
|
||||
* @is_connected: Set to true if display is connected
|
||||
* @panel_id
|
||||
* @panel_ver
|
||||
* @panel_regDA
|
||||
* @panel_name[MSM_DISP_NAME_LEN_MAX];
|
||||
* @width_mm: Physical width
|
||||
* @height_mm: Physical height
|
||||
* @max_width: Max width of display. In case of hot pluggable display
|
||||
|
|
@ -756,6 +791,12 @@ struct msm_display_info {
|
|||
|
||||
bool is_connected;
|
||||
|
||||
uint64_t panel_id;
|
||||
uint64_t panel_ver;
|
||||
uint32_t panel_regDA;
|
||||
char panel_name[MSM_DISP_NAME_LEN_MAX];
|
||||
char panel_supplier[MSM_DISP_NAME_LEN_MAX];
|
||||
|
||||
unsigned int width_mm;
|
||||
unsigned int height_mm;
|
||||
|
||||
|
|
@ -939,6 +980,7 @@ struct msm_drm_private {
|
|||
|
||||
struct mutex vm_client_lock;
|
||||
struct list_head vm_client_list;
|
||||
struct notifier_block msm_drv_notifier;
|
||||
};
|
||||
|
||||
/* get struct msm_kms * from drm_device * */
|
||||
|
|
|
|||
|
|
@ -135,6 +135,9 @@ struct msm_kms_funcs {
|
|||
/* topology dsc information */
|
||||
int (*get_dsc_count)(const struct msm_kms *kms,
|
||||
u32 hdisplay, u32 *num_dsc);
|
||||
/* set panel feature */
|
||||
int (*set_panel_feature)(const struct msm_kms *kms,
|
||||
struct panel_param_info param_info);
|
||||
};
|
||||
|
||||
struct msm_kms {
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
|
|||
if (brightness > c_conn->thermal_max_brightness)
|
||||
brightness = c_conn->thermal_max_brightness;
|
||||
|
||||
if(brightness && brightness < display->panel->bl_config.bl_min_level)
|
||||
brightness = display->panel->bl_config.bl_min_level;
|
||||
|
||||
/* map UI brightness into driver backlight level with rounding */
|
||||
bl_lvl = mult_frac(brightness, bl_max_level, brightness_max_level);
|
||||
|
||||
|
|
@ -244,7 +247,7 @@ static int sde_backlight_setup(struct sde_connector *c_conn,
|
|||
props.type = BACKLIGHT_RAW;
|
||||
props.power = FB_BLANK_UNBLANK;
|
||||
props.max_brightness = brightness_max_level;
|
||||
props.brightness = brightness_max_level;
|
||||
props.brightness = bl_config->brightness_default_level;
|
||||
snprintf(bl_node_name, BL_NODE_NAME_SIZE, "panel%u-backlight",
|
||||
display_count);
|
||||
c_conn->bl_device = backlight_device_register(bl_node_name, dev->dev,
|
||||
|
|
@ -589,8 +592,10 @@ void sde_connector_schedule_status_work(struct drm_connector *connector,
|
|||
return;
|
||||
|
||||
sde_connector_get_info(connector, &info);
|
||||
if (c_conn->ops.check_status &&
|
||||
(info.capabilities & MSM_DISPLAY_ESD_ENABLED)) {
|
||||
if ((c_conn->ops.force_esd_disable &&
|
||||
(c_conn->ops.force_esd_disable(c_conn->display) == false)) &&
|
||||
(c_conn->ops.check_status &&
|
||||
(info.capabilities & MSM_DISPLAY_ESD_ENABLED))) {
|
||||
if (en) {
|
||||
u32 interval;
|
||||
|
||||
|
|
@ -811,6 +816,24 @@ static int _sde_connector_update_hdr_metadata(struct sde_connector *c_conn,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int _sde_connector_update_param(struct sde_connector *c_conn,
|
||||
struct msm_param_info *param_info)
|
||||
{
|
||||
struct dsi_display *dsi_display;
|
||||
int rc = 0;
|
||||
|
||||
if (!c_conn) {
|
||||
SDE_ERROR("Invalid params sde_connector null\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dsi_display = c_conn->display;
|
||||
if (dsi_display && c_conn->ops.set_param)
|
||||
rc = c_conn->ops.set_param(dsi_display, param_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _sde_connector_update_dirty_properties(
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
|
|
@ -1492,6 +1515,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
|
|||
int idx, rc;
|
||||
uint64_t fence_user_fd;
|
||||
uint64_t __user prev_user_fd;
|
||||
struct msm_param_info param_info;
|
||||
|
||||
if (!connector || !state || !property) {
|
||||
SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n",
|
||||
|
|
@ -1598,6 +1622,38 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
|
|||
msm_property_set_dirty(&c_conn->property_info,
|
||||
&c_state->property_state, idx);
|
||||
break;
|
||||
case CONNECTOR_PROP_HBM:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_HBM_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_HBM;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
case CONNECTOR_PROP_ACL:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_ACL_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_ACL;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
case CONNECTOR_PROP_CABC:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_CABC_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_CABC;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
case CONNECTOR_PROP_DC:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_DC_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_DC;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2674,6 +2730,59 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int sde_connector_install_panel_params(struct sde_connector *c_conn)
|
||||
{
|
||||
struct panel_param *param_cmds;
|
||||
uint32_t prop_idx;
|
||||
int i;
|
||||
struct dsi_display *dsi_display;
|
||||
u16 prop_max, prop_min, prop_init;
|
||||
|
||||
if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI)
|
||||
return 0;
|
||||
|
||||
dsi_display = (struct dsi_display *) (c_conn->display);
|
||||
param_cmds = dsi_display->panel->param_cmds;
|
||||
for (i = 0; i < PARAM_ID_NUM; i++) {
|
||||
SDE_DEBUG("%s:i = %d param_name = %s is_support=%d\n",
|
||||
__func__, i,
|
||||
param_cmds->param_name, param_cmds->is_supported);
|
||||
|
||||
if (!strncmp(param_cmds->param_name, "HBM", 3))
|
||||
prop_idx = CONNECTOR_PROP_HBM;
|
||||
else if (!strncmp(param_cmds->param_name, "CABC", 4))
|
||||
prop_idx = CONNECTOR_PROP_CABC;
|
||||
else if (!strncmp(param_cmds->param_name, "ACL", 3))
|
||||
prop_idx = CONNECTOR_PROP_ACL;
|
||||
else if (!strncmp(param_cmds->param_name, "DC", 2))
|
||||
prop_idx = CONNECTOR_PROP_DC;
|
||||
else {
|
||||
SDE_ERROR("Invalid param_name =%s\n",
|
||||
param_cmds->param_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (param_cmds->is_supported) {
|
||||
prop_max = param_cmds->val_max;
|
||||
prop_min = PARAM_STATE_OFF;
|
||||
prop_init = param_cmds->default_value;
|
||||
} else {
|
||||
prop_max = PARAM_STATE_OFF;
|
||||
prop_min = PARAM_STATE_OFF;
|
||||
prop_init = PARAM_STATE_DISABLE;
|
||||
}
|
||||
|
||||
msm_property_install_volatile_range( &c_conn->property_info,
|
||||
param_cmds->param_name, 0x0,
|
||||
prop_min, prop_max,
|
||||
prop_init, prop_idx);
|
||||
|
||||
param_cmds++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sde_connector_set_blob_data(struct drm_connector *conn,
|
||||
struct drm_connector_state *state,
|
||||
enum msm_mdp_conn_property prop_id)
|
||||
|
|
@ -3119,6 +3228,14 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
rc = sde_connector_install_panel_params(c_conn);
|
||||
if (rc) {
|
||||
SDE_ERROR_CONN(c_conn,
|
||||
"failed to install property for panel params. rc =%d\n",
|
||||
rc);
|
||||
goto error_cleanup_fence;
|
||||
}
|
||||
|
||||
rc = sde_connector_get_info(&c_conn->base, &display_info);
|
||||
if (!rc && (connector_type == DRM_MODE_CONNECTOR_DSI) &&
|
||||
(display_info.capabilities & MSM_DISPLAY_CAP_VID_MODE))
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "msm_prop.h"
|
||||
#include "sde_kms.h"
|
||||
#include "sde_fence.h"
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define SDE_CONNECTOR_NAME_SIZE 16
|
||||
#define SDE_CONNECTOR_DHDR_MEMPOOL_MAX_SIZE SZ_32
|
||||
|
|
@ -277,6 +278,32 @@ struct sde_connector_ops {
|
|||
int (*cmd_receive)(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, u8 *recv_buf, u32 recv_buf_len);
|
||||
|
||||
/**
|
||||
* motUtil_transfer - Convert motUtil data and Transfer command
|
||||
* to the connected display panel
|
||||
* @display: Pointer to private display handle
|
||||
* @cmd_buf: Command buffer
|
||||
* @cmd_buf_len: Command buffer length in bytes
|
||||
* @motUtil_data: motUtil data information
|
||||
* Returns: Zero for success, negetive for failure
|
||||
*/
|
||||
int (*motUtil_transfer)(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data);
|
||||
|
||||
/**
|
||||
* force_esd_disable - force to disable check_status
|
||||
* @display: Pointer to private display handle
|
||||
* Returns: true for forcing ESD disable
|
||||
*/
|
||||
bool (*force_esd_disable)(void *display);
|
||||
|
||||
/**
|
||||
* set_param - set display's feature param setting
|
||||
* @display: Pointer to private display handle
|
||||
* Returns: Zero for success, negative for failure
|
||||
*/
|
||||
int (*set_param)(void *display, struct msm_param_info *param_info);
|
||||
|
||||
/**
|
||||
* config_hdr - configure HDR
|
||||
* @connector: Pointer to drm connector structure
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <drm/drm_atomic_uapi.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
#include "msm_mmu.h"
|
||||
|
|
@ -60,6 +63,8 @@
|
|||
#include <linux/qtee_shmbridge.h>
|
||||
#include <linux/haven/hh_irq_lend.h>
|
||||
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "sde_trace.h"
|
||||
|
||||
|
|
@ -152,6 +157,7 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms)
|
|||
|
||||
(void) sde_debugfs_vbif_init(sde_kms, debugfs_root);
|
||||
(void) sde_debugfs_core_irq_init(sde_kms, debugfs_root);
|
||||
(void) sde_debugfs_mot_util_init(sde_kms, debugfs_root);
|
||||
|
||||
rc = sde_core_perf_debugfs_init(&sde_kms->perf, debugfs_root);
|
||||
if (rc) {
|
||||
|
|
@ -1755,7 +1761,10 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
|||
.post_kickoff = dsi_conn_post_kickoff,
|
||||
.check_status = dsi_display_check_status,
|
||||
.enable_event = dsi_conn_enable_event,
|
||||
.motUtil_transfer = dsi_display_motUtil_transfer,
|
||||
.cmd_transfer = dsi_display_cmd_transfer,
|
||||
.force_esd_disable = dsi_display_force_esd_disable,
|
||||
.set_param = dsi_display_set_param,
|
||||
.cont_splash_config = dsi_display_cont_splash_config,
|
||||
.cont_splash_res_disable = dsi_display_cont_splash_res_disable,
|
||||
.get_panel_vfp = dsi_display_get_panel_vfp,
|
||||
|
|
@ -1779,6 +1788,8 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
|||
.get_dst_format = NULL,
|
||||
.check_status = NULL,
|
||||
.cmd_transfer = NULL,
|
||||
.force_esd_disable = NULL,
|
||||
.set_param = NULL,
|
||||
.cont_splash_config = NULL,
|
||||
.cont_splash_res_disable = NULL,
|
||||
.get_panel_vfp = NULL,
|
||||
|
|
@ -1801,6 +1812,8 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
|||
.set_colorspace = dp_connector_set_colorspace,
|
||||
.config_hdr = dp_connector_config_hdr,
|
||||
.cmd_transfer = NULL,
|
||||
.force_esd_disable = NULL,
|
||||
.set_param = NULL,
|
||||
.cont_splash_config = dp_display_cont_splash_config,
|
||||
.cont_splash_res_disable = NULL,
|
||||
.get_panel_vfp = NULL,
|
||||
|
|
@ -3723,6 +3736,31 @@ static int sde_kms_get_dsc_count(const struct msm_kms *kms,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sde_kms_set_panel_feature(const struct msm_kms *kms,
|
||||
struct panel_param_info param_info)
|
||||
{
|
||||
struct sde_kms *sde_kms;
|
||||
struct dsi_display *display;
|
||||
struct msm_param_info param_info_msm;
|
||||
int rc = 0;
|
||||
|
||||
if (!kms) {
|
||||
SDE_ERROR("invalid input args\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_kms = to_sde_kms(kms);
|
||||
param_info_msm.param_idx = (enum msm_param_id)param_info.param_idx;
|
||||
param_info_msm.value = param_info.value;
|
||||
display = (struct dsi_display *)sde_kms->dsi_displays[0];
|
||||
rc = dsi_display_set_param(display, ¶m_info_msm);
|
||||
if (rc)
|
||||
SDE_ERROR("set param %d value %d failed\n",
|
||||
param_info_msm.param_idx, param_info_msm.value);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _sde_kms_null_commit(struct drm_device *dev,
|
||||
struct drm_encoder *enc)
|
||||
{
|
||||
|
|
@ -4191,6 +4229,7 @@ static const struct msm_kms_funcs kms_funcs = {
|
|||
.trigger_null_flush = sde_kms_trigger_null_flush,
|
||||
.get_mixer_count = sde_kms_get_mixer_count,
|
||||
.get_dsc_count = sde_kms_get_dsc_count,
|
||||
.set_panel_feature = sde_kms_set_panel_feature,
|
||||
};
|
||||
|
||||
static int _sde_kms_mmu_destroy(struct sde_kms *sde_kms)
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@
|
|||
#define SDE_KMS_OPS_PREPARE_PLANE_FB BIT(3)
|
||||
|
||||
/* ESD status check interval in miliseconds */
|
||||
#define STATUS_CHECK_INTERVAL_MS 5000
|
||||
#define STATUS_CHECK_INTERVAL_MS 8000
|
||||
|
||||
/**
|
||||
* enum sde_kms_smmu_state: smmu state
|
||||
|
|
|
|||
420
techpack/display/msm/sde/sde_motUtil.c
Normal file
420
techpack/display/msm/sde/sde_motUtil.c
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "motUtil:[%s]" fmt, __func__
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "sde_connector.h"
|
||||
#include "sde_encoder.h"
|
||||
#include "sde_motUtil.h"
|
||||
#include "dsi_display.h"
|
||||
|
||||
|
||||
#define MAIN_DSI_CONN_NAME "DSI-1"
|
||||
#define CLI_DSI_CONN_NAME "DSI-2"
|
||||
|
||||
struct motUtil motUtil_data;
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_string2num(const char __user *buf,
|
||||
size_t count, char buffer[])
|
||||
{
|
||||
char *input, *input_copy, *token, *input_dup = NULL;
|
||||
const char *delim =" ";
|
||||
u32 buf_size = 0;
|
||||
int rc=0, strtoint;
|
||||
|
||||
/*copy the data from user space*/
|
||||
input = kmalloc(count + 1, GFP_KERNEL);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(input, buf, count)) {
|
||||
SDE_ERROR("copy from user failed\n");
|
||||
rc = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
input[count]='\0';
|
||||
SDE_INFO("input_cmd = %s\n", input);
|
||||
|
||||
input_copy = kstrdup(input, GFP_KERNEL);
|
||||
if (!input_copy) {
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
input_dup = input_copy,
|
||||
token = strsep(&input_copy, delim);
|
||||
while (token) {
|
||||
rc = kstrtoint(token, 0, &strtoint);
|
||||
if (rc) {
|
||||
rc = -EIO;
|
||||
SDE_ERROR("input buffer conversion failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (buf_size >= MAX_CMD_PAYLOAD_SIZE) {
|
||||
SDE_ERROR("buffer size exceeding the limit %d\n",
|
||||
MAX_CMD_PAYLOAD_SIZE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
buffer[buf_size++] = (strtoint & 0xff);
|
||||
token = strsep(&input_copy, delim);
|
||||
}
|
||||
|
||||
SDE_DEBUG("command packet size in bytes: %u\n", buf_size);
|
||||
rc = buf_size;
|
||||
end:
|
||||
kfree(input_dup);
|
||||
kfree(input);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct drm_connector *_sde_debugfs_motUtil_get_drm_conn(
|
||||
struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct drm_device *dev = kms->dev;
|
||||
struct drm_connector *conn = NULL;
|
||||
int found_conn = 0;
|
||||
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||
if (panel_type == MOTUTIL_MAIN_DISP) {
|
||||
if (!strncmp(conn->name, MAIN_DSI_CONN_NAME, 5)) {
|
||||
SDE_DEBUG("found MAIN disp conn\n");
|
||||
found_conn = 1;
|
||||
break;
|
||||
}
|
||||
} else if (panel_type == MOTUTIL_CLI_DISP) {
|
||||
if (!strncmp(conn->name, CLI_DSI_CONN_NAME, 5)) {
|
||||
SDE_DEBUG("found CLI disp conn\n");
|
||||
found_conn = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
if (found_conn)
|
||||
return conn;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct sde_connector *_sde_debugfs_motUtil_get_sde_conn(
|
||||
struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct drm_connector *conn = NULL;
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
|
||||
conn = _sde_debugfs_motUtil_get_drm_conn(kms, count, input);
|
||||
if (conn)
|
||||
sde_conn = to_sde_connector(conn);
|
||||
else
|
||||
DRM_ERROR("Can not find SDE Connector for %s\n",
|
||||
(input[DISPUTIL_PANEL_TYPE] == MOTUTIL_MAIN_DISP) ?
|
||||
"Main Display" : "CLI Display");
|
||||
|
||||
return sde_conn;
|
||||
}
|
||||
|
||||
static int _sde_debugfs_motUtil_transfer(struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
int ret = 0;
|
||||
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
|
||||
|
||||
if (panel_type > MOTUTIL_CLI_DISP) {
|
||||
SDE_ERROR("Invalid panel number = %d\n", panel_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_conn = _sde_debugfs_motUtil_get_sde_conn(kms, count, input);
|
||||
if (!sde_conn) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sde_conn && !sde_conn->ops.motUtil_transfer) {
|
||||
SDE_ERROR("no motUtil_transfer support for connector name %s\n",
|
||||
sde_conn->name);
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (motUtil_data.rd_buf) {
|
||||
mutex_lock(&sde_conn->lock);
|
||||
ret = sde_conn->ops.motUtil_transfer(sde_conn->display,
|
||||
input, count, &motUtil_data);
|
||||
motUtil_data.cmd_status = ret;
|
||||
motUtil_data.read_len = ret;
|
||||
mutex_unlock(&sde_conn->lock);
|
||||
|
||||
ret = count;
|
||||
} else
|
||||
ret = -ENOMEM;
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int _sde_debugfs_motUtil_kms_prop_test(struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct drm_connector *conn = NULL;
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
struct drm_property *property;
|
||||
|
||||
int ret = 0;
|
||||
enum msm_mdp_conn_property conn_prop_idx;
|
||||
uint64_t prop_val;
|
||||
|
||||
conn = _sde_debugfs_motUtil_get_drm_conn(kms, count, input);
|
||||
if (!conn) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sde_conn = to_sde_connector(conn);
|
||||
if (!sde_conn) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (count < KMSPROPTEST_NEW_VAL) {
|
||||
DRM_ERROR(" Number of Input data is invalid (%zu).\n", count);
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (input[KMSPROPTEST_PROP_INDEX]) {
|
||||
case KMSPROPTEST_TYPE_HBM:
|
||||
conn_prop_idx = CONNECTOR_PROP_HBM;
|
||||
break;
|
||||
case KMSPROPTEST_TYPE_ACL:
|
||||
conn_prop_idx = CONNECTOR_PROP_ACL;
|
||||
break;
|
||||
case KMSPROPTEST_TYPE_CABC:
|
||||
conn_prop_idx = CONNECTOR_PROP_CABC;
|
||||
break;
|
||||
case KMSPROPTEST_TYPE_DC:
|
||||
conn_prop_idx = CONNECTOR_PROP_DC;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR(" Invalid KMSPROPTEST_PROP_INDEX = %d\n",
|
||||
input[KMSPROPTEST_PROP_INDEX]);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
property = msm_property_index_to_drm_property(&sde_conn->property_info,
|
||||
conn_prop_idx);
|
||||
if (!property) {
|
||||
SDE_ERROR("invalid property index %d for sde_conn_name=%s\n",
|
||||
conn_prop_idx, sde_conn->name);
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
prop_val = sde_connector_get_property(conn->state, conn_prop_idx);
|
||||
if (prop_val == PARAM_STATE_DISABLE) {
|
||||
DRM_ERROR("This KMS Property=%d is disabled\n", conn_prop_idx);
|
||||
ret = -EPERM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch(input[KMSPROPTEST_PROP_TYPE]) {
|
||||
case KMSPROPTEST_GETPROP:
|
||||
motUtil_data.read_cmd = true;
|
||||
motUtil_data.val = (int)prop_val;
|
||||
break;
|
||||
case KMSPROPTEST_SETPROP:
|
||||
motUtil_data.read_cmd = false;
|
||||
if (conn->funcs && conn->funcs->atomic_set_property) {
|
||||
ret = conn->funcs->atomic_set_property(conn,
|
||||
conn->state, property,
|
||||
input[KMSPROPTEST_NEW_VAL]);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
DRM_ERROR("Unsupport KMS set property\n");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid KMSPROPTEST_PROP_TYPE = %d\n",
|
||||
input[KMSPROPTEST_PROP_TYPE]);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
motUtil_data.cmd_status = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_exe_command(struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
int ret = 0;
|
||||
enum sde_motUtil_type motUtil_type = input[0];
|
||||
|
||||
motUtil_data.motUtil_type = motUtil_type;
|
||||
switch (motUtil_type) {
|
||||
case MOTUTIL_DISP_UTIL:
|
||||
ret = _sde_debugfs_motUtil_transfer(kms, count, input);
|
||||
break;
|
||||
case MOTUTIL_KMS_PROP_TEST:
|
||||
ret = _sde_debugfs_motUtil_kms_prop_test(kms, count, input);
|
||||
break;
|
||||
default:
|
||||
SDE_ERROR("Un-support motUtil type = %d\n", motUtil_type);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _sde_debugfs_motUtil_open(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
if (!inode || !file)
|
||||
return -EINVAL;
|
||||
|
||||
/* non-seekable */
|
||||
file->private_data = inode->i_private;
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_write(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
u32 buf_size = 0;
|
||||
char buffer[MAX_CMD_PAYLOAD_SIZE];
|
||||
struct sde_kms *kms = (struct sde_kms *)file->private_data;
|
||||
int ret = 0;
|
||||
|
||||
if (*ppos || !kms) {
|
||||
SDE_ERROR("invalid argument(s)\n");
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
buf_size = _sde_debugfs_motUtil_string2num(buf, count, buffer);
|
||||
if (buf_size <= 0){
|
||||
SDE_ERROR("invalid input\n");
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mutex_lock(&motUtil_data.lock);
|
||||
ret = _sde_debugfs_motUtil_exe_command(kms, count, buffer);
|
||||
mutex_unlock(&motUtil_data.lock);
|
||||
end:
|
||||
motUtil_data.cmd_status = ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_dispUtil_read(char *buffer)
|
||||
{
|
||||
int blen = 0, i;
|
||||
|
||||
if (motUtil_data.read_len) {
|
||||
blen = snprintf(buffer, 16, "motUtil_read: ");
|
||||
for (i = 0; i < motUtil_data.read_len; i ++)
|
||||
blen += snprintf((buffer + blen) , 6, "0x%02x ",
|
||||
*motUtil_data.rd_buf++);
|
||||
|
||||
blen += snprintf((buffer + blen), 2, "\n");
|
||||
} else
|
||||
SDE_ERROR("motUtil failed to read from panel\n");
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_read(struct file *file,
|
||||
char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
int blen = 0;
|
||||
char buffer[MAX_CMD_PAYLOAD_SIZE];
|
||||
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&motUtil_data.lock);
|
||||
if (motUtil_data.cmd_status < 0 || !motUtil_data.read_cmd) {
|
||||
blen = snprintf(buffer, MAX_CMD_PAYLOAD_SIZE,
|
||||
"motUtil_status: %d\n",
|
||||
motUtil_data.cmd_status);
|
||||
} else if (motUtil_data.motUtil_type == MOTUTIL_DISP_UTIL) {
|
||||
blen = _sde_debugfs_motUtil_dispUtil_read(buffer);
|
||||
} else if (motUtil_data.motUtil_type == MOTUTIL_KMS_PROP_TEST) {
|
||||
blen = snprintf(buffer, 16, "motUtil_read: ");
|
||||
blen += snprintf((buffer + blen), 12, "0x%08x ",
|
||||
motUtil_data.val);
|
||||
blen += snprintf((buffer + blen), 2, "\n");
|
||||
}
|
||||
|
||||
|
||||
SDE_INFO("%s\n", buffer);
|
||||
|
||||
if (blen <= 0) {
|
||||
SDE_ERROR("snprintf failed, blen %d\n", blen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (copy_to_user(buf, buffer, min(count, (size_t)blen+1))) {
|
||||
SDE_ERROR("copy to user buffer failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
*ppos += blen;
|
||||
mutex_unlock(&motUtil_data.lock);
|
||||
return blen;
|
||||
}
|
||||
|
||||
static const struct file_operations sde_debugfs_motUtil_fops = {
|
||||
.open = _sde_debugfs_motUtil_open,
|
||||
.read = _sde_debugfs_motUtil_read,
|
||||
.write = _sde_debugfs_motUtil_write,
|
||||
};
|
||||
|
||||
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
|
||||
struct dentry *parent)
|
||||
{
|
||||
debugfs_create_file("motUtil", 0606, parent,
|
||||
sde_kms, &sde_debugfs_motUtil_fops);
|
||||
|
||||
motUtil_data.rd_buf = kzalloc(SZ_4K, GFP_KERNEL);
|
||||
if (!motUtil_data.rd_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
motUtil_data.te_enable = true;
|
||||
mutex_init(&motUtil_data.lock);
|
||||
return 0;
|
||||
}
|
||||
151
techpack/display/msm/sde/sde_motUtil.h
Normal file
151
techpack/display/msm/sde/sde_motUtil.h
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 __MOTUTIL_H__
|
||||
#define __MOTUTIL_H__
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* /d/dri/0/debug/motUtil sysfs *
|
||||
* - This is Mot debug sysfs to provide some tools to test panel and panel *
|
||||
* features. This tool only exist with the userdebug and Engineering build *
|
||||
* - Currently, this motUtil will provide 3 kind of tests and it can enhance *
|
||||
* to test more if needed *
|
||||
* - Test#1: DispUtil: This test is able to send any MIPI DSI command and *
|
||||
* it can read any data back from the panel *
|
||||
* - Test#2: TeTest: This test will be used to test the TE trace between *
|
||||
* the panels and MDSS to make sure it works *
|
||||
* - Test#3: kmsPropTest: This test will test the panel features such as *
|
||||
* HBM, ACL, CABC, etc. It can read these features configurations*
|
||||
* in the KMS property and it can change these setting from KMS *
|
||||
* property. *
|
||||
* - Usage: *
|
||||
* - 1st byte will indicate which motUtil test will be run. *
|
||||
* 0x00 = dispUtil, 0x01 = TeTest, 0x02 = kmsPropTest *
|
||||
* --------------------------------------------------------------------------*
|
||||
* - dispUtil: *
|
||||
* 1st byte: 0x00: dispUtil *
|
||||
* 2nd byte: 0x00: primary panel and 0x01: Secondary panel *
|
||||
* 3rd byte: 0x00: MIPI write cmd to panel and 0x01: MIPI read *
|
||||
* 4th byte: 0x00: MIPI HS mode and 0x01: MIPI LP mode *
|
||||
* 5th byte: 0x00: MIPI DCS cmd and 0x01: MIPI generaic cmd *
|
||||
* 6th byte: Indicate number of bytes to read from panel *
|
||||
* 7th and 8th: Indicate number of bytes for the payload cmd *
|
||||
* 9th and .. :the payload cmd *
|
||||
* - Example: *
|
||||
* echo "0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x28" > motUtil *
|
||||
* - This will send a mipi DSC command "0x28" to panel and *
|
||||
* which will request the panel to turn off the panel *
|
||||
* cat motUtil *
|
||||
* - This will report a sending previous cmd status *
|
||||
* 0: send success or errno if it fails *
|
||||
* echo "0x00 0x01 0x01 0x00 0x00 0x01 0x00 0x01 0x0a" > motUtil *
|
||||
* - This will send MIPI read cmd "0xa" to the panel. *
|
||||
* cat motUtil *
|
||||
* - number of reading bytes from previous command or errno if it fails*
|
||||
*---------------------------------------------------------------------------*
|
||||
* - TeTest: This test has been removed *
|
||||
*---------------------------------------------------------------------------*
|
||||
* - kmsPropTest *
|
||||
* 1st byte: kmsPropTest *
|
||||
* 2nd byte: 0x00: primary panel and 0x01: Secondary panel *
|
||||
* 3rd byte: 0x00: get KMS property and 0x01: set KMS property *
|
||||
* 4th byte: 0x00: HBM 0x01: ACL for the KMS property/panel feature *
|
||||
* 5th byte: new data for a "set KMS property" operation *
|
||||
* - Example *
|
||||
* echo "0x02 0x00 0x010 0x00 0x00" > motUtil *
|
||||
* - This will read the HBM setting of the primary panel in the KMS *
|
||||
* property. *
|
||||
* cat motUtil *
|
||||
* - This will return the status of previous cmd. *
|
||||
* 0 if success or errno if it fails *
|
||||
* echo "0x02 0x00 0x01 0x00 0x01" > motUtil *
|
||||
* - This will turn on the HBM feature of the primary panel in the KMS *
|
||||
* property. The panel's backlight will be brighter when HBM is on *
|
||||
* cat motUtil *
|
||||
* - This will return the status of previous cmd. *
|
||||
* 0 if success or errno if it fails *
|
||||
* echo "0x02 0x00 0x010 0x00 0x00" > motUtil *
|
||||
* - This will read back the HBM setting in KMS property *
|
||||
* echo "0x02 0x00 0x01 0x00 0x00" > motUtil *
|
||||
* - This will turn off the HBM feature of the primary panel in the KMS *
|
||||
* property. The panel's backlight will be dimmer when HBM is off *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
enum sde_motUtil_type {
|
||||
MOTUTIL_DISP_UTIL = 0,
|
||||
MOTUTIL_TE_TEST,
|
||||
MOTUTIL_KMS_PROP_TEST,
|
||||
};
|
||||
|
||||
enum sde_motUtil_disp_cmd {
|
||||
DISPUTIL_TYPE = 0,
|
||||
DISPUTIL_PANEL_TYPE,
|
||||
DISPUTIL_CMD_TYPE,
|
||||
DISPUTIL_CMD_XFER_MODE,
|
||||
DISPUTIL_MIPI_CMD_TYPE,
|
||||
DISPUTIL_NUM_BYTE_RD,
|
||||
DISPUTIL_PAYLOAD_LEN_U,
|
||||
DISPUTIL_PAYLOAD_LEN_L,
|
||||
DISPUTIL_PAYLOAD,
|
||||
};
|
||||
|
||||
enum sde_motUtil_kmsPropTest_cmd {
|
||||
KMSPROPTEST_TYPE,
|
||||
KMSPROPTEST_PANEL_TYPE,
|
||||
KMSPROPTEST_PROP_TYPE,
|
||||
KMSPROPTEST_PROP_INDEX,
|
||||
KMSPROPTEST_NEW_VAL,
|
||||
};
|
||||
|
||||
enum sde_motUtil_kmsPropTest_ConnPropType {
|
||||
KMSPROPTEST_TYPE_HBM,
|
||||
KMSPROPTEST_TYPE_ACL,
|
||||
KMSPROPTEST_TYPE_CABC,
|
||||
KMSPROPTEST_TYPE_DC,
|
||||
};
|
||||
|
||||
struct motUtil {
|
||||
struct mutex lock;
|
||||
enum sde_motUtil_type motUtil_type;
|
||||
bool read_cmd;
|
||||
int cmd_status;
|
||||
u16 read_len;
|
||||
u8 *rd_buf;
|
||||
int val;
|
||||
bool te_enable;
|
||||
};
|
||||
|
||||
#define DISPUTIL_DSI_WRITE 0
|
||||
#define DISPUTIL_DSI_READ 1
|
||||
|
||||
#define DISPUTIL_DSI_DCS 0
|
||||
#define DISPUTIL_DSI_GENERIC 1
|
||||
|
||||
#define DISPUTIL_DSI_HS_MODE 0
|
||||
#define DISPUTIL_DSI_LP_MODE 1
|
||||
|
||||
#define KMSPROPTEST_GETPROP 0
|
||||
#define KMSPROPTEST_SETPROP 1
|
||||
|
||||
#define MOTUTIL_MAIN_DISP 0
|
||||
#define MOTUTIL_CLI_DISP 1
|
||||
|
||||
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
|
||||
struct dentry *parent);
|
||||
|
||||
#endif /* __MOTUTIL_H__ */
|
||||
|
|
@ -63,7 +63,7 @@ static char sde_dsc_rc_range_min_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
|
|||
static char sde_dsc_rc_range_max_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
|
||||
/* DSC v1.1 */
|
||||
{4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15},
|
||||
{4, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19},
|
||||
{8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19},
|
||||
{7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
|
||||
/* DSC v1.1 SCR and DSC v1.2 RGB 444 */
|
||||
{4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13},
|
||||
|
|
@ -103,6 +103,71 @@ static char sde_dsc_rc_range_bpg[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
|
|||
{10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12},
|
||||
};
|
||||
|
||||
static char sde_dsc_rc_range_min_qp_nt[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
|
||||
/* DSC v1.1 */
|
||||
{0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13},
|
||||
{0, 4, 5, 5, 7, 7, 7, 7, 7, 8, 9, 9, 9, 12, 16},
|
||||
{0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
|
||||
/* DSC v1.1 SCR and DSC v1.2 RGB 444 */
|
||||
{0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 12},
|
||||
{0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 16},
|
||||
{0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
|
||||
/* DSC v1.2 YUV422 */
|
||||
{0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10},
|
||||
{0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 16},
|
||||
{0, 4, 9, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 17, 20},
|
||||
{0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12},
|
||||
/* DSC v1.2 YUV420 */
|
||||
{0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10},
|
||||
{0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14},
|
||||
{0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12},
|
||||
};
|
||||
|
||||
/*
|
||||
* Rate control - Max QP values for each ratio type in sde_dsc_ratio_type
|
||||
*/
|
||||
static char sde_dsc_rc_range_max_qp_nt[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
|
||||
/* DSC v1.1 */
|
||||
{4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15},
|
||||
{8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17},
|
||||
{7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
|
||||
/* DSC v1.1 SCR and DSC v1.2 RGB 444 */
|
||||
{4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13},
|
||||
{8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17},
|
||||
{7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
|
||||
/* DSC v1.2 YUV422 */
|
||||
{3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12},
|
||||
{2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11},
|
||||
{7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
|
||||
{2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13},
|
||||
/* DSC v1.2 YUV420 */
|
||||
{2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 12},
|
||||
{2, 5, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15},
|
||||
{2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13},
|
||||
};
|
||||
/*
|
||||
* Rate control - bpg offset values for each ratio type in sde_dsc_ratio_type
|
||||
*/
|
||||
static char sde_dsc_rc_range_bpg_nt[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
|
||||
/* DSC v1.1 */
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12},
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12},
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12},
|
||||
/* DSC v1.1 SCR and DSC V1.2 RGB 444 */
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12},
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12},
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12},
|
||||
/* DSC v1.2 YUV422 */
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12},
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12},
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12},
|
||||
{10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12},
|
||||
/* DSC v1.2 YUV420 */
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12},
|
||||
{2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12},
|
||||
{10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12},
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps to lookup the sde_dsc_ratio_type index used in rate control tables
|
||||
*/
|
||||
|
|
@ -352,6 +417,148 @@ int sde_dsc_populate_dsc_config(struct drm_dsc_config *dsc, int scr_ver) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sde_dsc_populate_dsc_config_nt(struct drm_dsc_config *dsc, int scr_ver) {
|
||||
int bpp, bpc;
|
||||
int groups_per_line, groups_total;
|
||||
int min_rate_buffer_size;
|
||||
int hrd_delay;
|
||||
int pre_num_extra_mux_bits, num_extra_mux_bits;
|
||||
int slice_bits;
|
||||
int data;
|
||||
int final_value, final_scale;
|
||||
int i, ratio_idx;
|
||||
|
||||
dsc->rc_model_size = 8192;
|
||||
|
||||
if ((dsc->dsc_version_major == 0x1) &&
|
||||
(dsc->dsc_version_minor == 0x1)) {
|
||||
if (scr_ver == 0x1)
|
||||
dsc->first_line_bpg_offset = 15;
|
||||
else
|
||||
dsc->first_line_bpg_offset = 13;
|
||||
} else if (dsc->dsc_version_minor == 0x2) {
|
||||
dsc->first_line_bpg_offset = _get_dsc_v1_2_bpg_offset(dsc);
|
||||
}
|
||||
|
||||
dsc->rc_edge_factor = 6;
|
||||
dsc->rc_tgt_offset_high = 3;
|
||||
dsc->rc_tgt_offset_low = 3;
|
||||
dsc->simple_422 = 0;
|
||||
dsc->convert_rgb = 1;
|
||||
dsc->vbr_enable = 0;
|
||||
|
||||
bpp = DSC_BPP(*dsc);
|
||||
bpc = dsc->bits_per_component;
|
||||
|
||||
ratio_idx = _get_rc_table_index(dsc, scr_ver);
|
||||
if (ratio_idx == -EINVAL)
|
||||
return ratio_idx;
|
||||
|
||||
for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++)
|
||||
dsc->rc_buf_thresh[i] = sde_dsc_rc_buf_thresh[i];
|
||||
|
||||
for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
|
||||
dsc->rc_range_params[i].range_min_qp =
|
||||
sde_dsc_rc_range_min_qp_nt[ratio_idx][i];
|
||||
dsc->rc_range_params[i].range_max_qp =
|
||||
sde_dsc_rc_range_max_qp_nt[ratio_idx][i];
|
||||
dsc->rc_range_params[i].range_bpg_offset =
|
||||
sde_dsc_rc_range_bpg_nt[ratio_idx][i];
|
||||
}
|
||||
|
||||
if (bpp == 8) {
|
||||
dsc->initial_offset = 6144;
|
||||
dsc->initial_xmit_delay = 512;
|
||||
} else if (bpp == 10) {
|
||||
dsc->initial_offset = 5632;
|
||||
dsc->initial_xmit_delay = 410;
|
||||
} else {
|
||||
dsc->initial_offset = 2048;
|
||||
dsc->initial_xmit_delay = 341;
|
||||
}
|
||||
|
||||
dsc->line_buf_depth = bpc + 1;
|
||||
|
||||
if (bpc == 8) {
|
||||
dsc->flatness_min_qp = 3;
|
||||
dsc->flatness_max_qp = 12;
|
||||
dsc->rc_quant_incr_limit0 = 11;
|
||||
dsc->rc_quant_incr_limit1 = 11;
|
||||
dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
|
||||
} else if (bpc == 10) { /* 10bpc */
|
||||
dsc->flatness_min_qp = 7;
|
||||
dsc->flatness_max_qp = 16;
|
||||
dsc->rc_quant_incr_limit0 = 15;
|
||||
dsc->rc_quant_incr_limit1 = 15;
|
||||
dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
|
||||
} else { /* 12 bpc */
|
||||
dsc->flatness_min_qp = 11;
|
||||
dsc->flatness_max_qp = 20;
|
||||
dsc->rc_quant_incr_limit0 = 19;
|
||||
dsc->rc_quant_incr_limit1 = 19;
|
||||
dsc->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
|
||||
}
|
||||
if ((dsc->dsc_version_minor == 0x2) && (dsc->native_420)) {
|
||||
dsc->second_line_bpg_offset = 12;
|
||||
dsc->second_line_offset_adj = 512;
|
||||
dsc->nsl_bpg_offset = 2048 *
|
||||
(DIV_ROUND_UP(dsc->second_line_bpg_offset,
|
||||
(dsc->slice_height - 1)));
|
||||
}
|
||||
|
||||
groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3);
|
||||
|
||||
dsc->slice_chunk_size = dsc->slice_width * bpp / 8;
|
||||
if ((dsc->slice_width * bpp) % 8)
|
||||
dsc->slice_chunk_size++;
|
||||
|
||||
/* rbs-min */
|
||||
min_rate_buffer_size = dsc->rc_model_size - dsc->initial_offset +
|
||||
dsc->initial_xmit_delay * bpp +
|
||||
groups_per_line * dsc->first_line_bpg_offset;
|
||||
|
||||
hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, bpp);
|
||||
|
||||
dsc->initial_dec_delay = hrd_delay - dsc->initial_xmit_delay;
|
||||
|
||||
dsc->initial_scale_value = 8 * dsc->rc_model_size /
|
||||
(dsc->rc_model_size - dsc->initial_offset);
|
||||
|
||||
slice_bits = 8 * dsc->slice_chunk_size * dsc->slice_height;
|
||||
|
||||
groups_total = groups_per_line * dsc->slice_height;
|
||||
|
||||
data = dsc->first_line_bpg_offset * 2048;
|
||||
|
||||
dsc->nfl_bpg_offset = DIV_ROUND_UP(data, (dsc->slice_height - 1));
|
||||
|
||||
pre_num_extra_mux_bits = 3 * (dsc->mux_word_size + (4 * bpc + 4) - 2);
|
||||
|
||||
num_extra_mux_bits = pre_num_extra_mux_bits - (dsc->mux_word_size -
|
||||
((slice_bits - pre_num_extra_mux_bits) % dsc->mux_word_size));
|
||||
|
||||
data = 2048 * (dsc->rc_model_size - dsc->initial_offset
|
||||
+ num_extra_mux_bits);
|
||||
dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total);
|
||||
|
||||
data = dsc->initial_xmit_delay * bpp;
|
||||
final_value = dsc->rc_model_size - data + num_extra_mux_bits;
|
||||
|
||||
final_scale = 8 * dsc->rc_model_size /
|
||||
(dsc->rc_model_size - final_value);
|
||||
|
||||
dsc->final_offset = final_value;
|
||||
|
||||
data = (final_scale - 9) * (dsc->nfl_bpg_offset +
|
||||
dsc->slice_bpg_offset);
|
||||
dsc->scale_increment_interval = (2048 * dsc->final_offset) / data;
|
||||
|
||||
dsc->scale_decrement_interval = groups_per_line /
|
||||
(dsc->initial_scale_value - 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info,
|
||||
int intf_width)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,5 +18,7 @@ int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info,
|
|||
int sde_dsc_create_pps_buf_cmd(struct msm_display_dsc_info *dsc_info,
|
||||
char *buf, int pps_id, u32 len);
|
||||
|
||||
int sde_dsc_populate_dsc_config_nt(struct drm_dsc_config *dsc, int scr_ver);
|
||||
|
||||
#endif /* __SDE_DSC_HELPER_H__ */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue