diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/include/kgd_pp_interface.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/analogix/Kconfig | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/analogix/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/analogix/anx7580.c | 623 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/analogix/anx7580_regs.h | 1033 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_panel_orientation_quirks.c | 7 |
16 files changed, 1734 insertions, 14 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index afe39421d10c..df59a6919d87 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1104,6 +1104,8 @@ struct amdgpu_device { bool dc_enabled; /* Mask of active clusters */ uint32_t aid_mask; + + bool csib_initialized; }; static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1ecc6b095a87..b2def958aad2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4410,6 +4410,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) if (amdgpu_sriov_vf(adev)) amdgpu_virt_release_full_gpu(adev, false); + r = amdgpu_dpm_set_rlc_state(adev, false); + if (r) + dev_err(adev->dev, "Failed to notify RLC to be OFF.\n"); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 7429b20257a6..72085a3ef53c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -147,7 +147,7 @@ void amdgpu_ring_commit(struct amdgpu_ring *ring) count %= ring->funcs->align_mask + 1; ring->funcs->insert_nop(ring, count); - mb(); + smp_wmb(); amdgpu_ring_set_wptr(ring); if (ring->funcs->end_use) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index f7ad883a70fa..8256f80d468d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -3492,6 +3492,7 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev); static void gfx_v10_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 instance, int xcc_id); static u32 gfx_v10_0_get_wgp_active_bitmap_per_sh(struct amdgpu_device *adev); +static int gfx_v10_0_wait_for_idle(void *handle); static int gfx_v10_0_rlc_backdoor_autoload_buffer_init(struct amdgpu_device *adev); static void gfx_v10_0_rlc_backdoor_autoload_buffer_fini(struct amdgpu_device *adev); @@ -5931,7 +5932,7 @@ static int gfx_v10_0_cp_gfx_load_microcode(struct amdgpu_device *adev) return 0; } -static int gfx_v10_0_cp_gfx_start(struct amdgpu_device *adev) +static int gfx_v10_csib_submit(struct amdgpu_device *adev) { struct amdgpu_ring *ring; const struct cs_section_def *sect = NULL; @@ -5939,13 +5940,6 @@ static int gfx_v10_0_cp_gfx_start(struct amdgpu_device *adev) int r, i; int ctx_reg_offset; - /* init the CP */ - WREG32_SOC15(GC, 0, mmCP_MAX_CONTEXT, - adev->gfx.config.max_hw_contexts - 1); - WREG32_SOC15(GC, 0, mmCP_DEVICE_ID, 1); - - gfx_v10_0_cp_gfx_enable(adev, true); - ring = &adev->gfx.gfx_ring[0]; r = amdgpu_ring_alloc(ring, gfx_v10_0_get_csb_size(adev) + 4); if (r) { @@ -6008,6 +6002,25 @@ static int gfx_v10_0_cp_gfx_start(struct amdgpu_device *adev) amdgpu_ring_commit(ring); } + + gfx_v10_0_wait_for_idle(adev); + adev->csib_initialized = true; + + return 0; +}; + +static int gfx_v10_0_cp_gfx_start(struct amdgpu_device *adev) +{ + /* init the CP */ + WREG32_SOC15(GC, 0, mmCP_MAX_CONTEXT, + adev->gfx.config.max_hw_contexts - 1); + WREG32_SOC15(GC, 0, mmCP_DEVICE_ID, 1); + + gfx_v10_0_cp_gfx_enable(adev, true); + + if (!adev->csib_initialized) + gfx_v10_csib_submit(adev); + return 0; } @@ -7167,8 +7180,11 @@ static int gfx_v10_0_hw_fini(void *handle) return 0; } +static int gfx_v10_0_set_powergating_state(void *handle, + enum amd_powergating_state state); static int gfx_v10_0_suspend(void *handle) { + gfx_v10_0_set_powergating_state(handle, AMD_CG_STATE_UNGATE); return gfx_v10_0_hw_fini(handle); } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 28e6fa8d7860..c1aeeb927a0b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -147,7 +147,7 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU); #define PSP_FOOTER_BYTES 0x100 /* Maximum backlight level. */ -#define AMDGPU_MAX_BL_LEVEL 0xFFFF +#define AMDGPU_MAX_BL_LEVEL 0xFFF /** * DOC: overview @@ -7349,7 +7349,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) drm_add_modes_noedid(connector, 1920, 1080); } else { amdgpu_dm_connector_ddc_get_modes(connector, edid); - amdgpu_dm_connector_add_common_modes(encoder, connector); + if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) + amdgpu_dm_connector_add_common_modes(encoder, connector); amdgpu_dm_connector_add_freesync_modes(connector, edid); } amdgpu_dm_fbc_init(connector); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index e5f4587aa40c..55bb9fa9eb62 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -963,7 +963,9 @@ void dce110_edp_backlight_control( return; } - if (link->panel_cntl) { + if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled || + link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || + link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c index 81fd50ee97c3..fdbe3d42cd7b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c @@ -75,6 +75,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = { .get_hw_state = dcn10_get_hw_state, .clear_status_bits = dcn10_clear_status_bits, .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, + .edp_backlight_control = dce110_edp_backlight_control, .edp_power_control = dce110_edp_power_control, .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, .set_cursor_position = dcn10_set_cursor_position, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 2039a345f23a..e4626f2072f0 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -266,8 +266,8 @@ bool set_default_brightness_aux(struct dc_link *link) if (link && link->dpcd_sink_ext_caps.bits.oled == 1) { if (!read_default_bl_aux(link, &default_backlight)) default_backlight = 150000; - // if < 5 nits or > 5000, it might be wrong readback - if (default_backlight < 5000 || default_backlight > 5000000) + // if < 1 nits or > 5000, it might be wrong readback + if (default_backlight < 1000 || default_backlight > 5000000) default_backlight = 150000; // return edp_set_backlight_level_nits(link, true, diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 9f542f6e19ed..ec9e740aa913 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -420,6 +420,10 @@ struct amd_pm_funcs { struct dpm_clocks *clock_table); int (*get_smu_prv_buf_details)(void *handle, void **addr, size_t *size); void (*pm_compute_clocks)(void *handle); + /** + * @system_features_control: Enable/disable all SMU features. + */ + int (*system_features_control)(void *handle, bool en); }; struct metrics_table_header { diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 078aaaa53162..5c36fc114e91 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -180,6 +180,24 @@ int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, return ret; } +int amdgpu_dpm_set_rlc_state(struct amdgpu_device *adev, bool en) +{ + int ret = 0; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + + if (pp_funcs && pp_funcs->system_features_control) { + mutex_lock(&adev->pm.mutex); + + ret = pp_funcs->system_features_control( + adev->powerplay.pp_handle, + en); + + mutex_unlock(&adev->pm.mutex); + } + + return ret; +} + bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev) { const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index 42172b00be66..a96406c4109f 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -401,6 +401,8 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev); int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, enum pp_mp1_state mp1_state); +int amdgpu_dpm_set_rlc_state(struct amdgpu_device *adev, bool en); + int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev); int amdgpu_dpm_baco_exit(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig index 173dada218ec..2ad49e625c77 100644 --- a/drivers/gpu/drm/bridge/analogix/Kconfig +++ b/drivers/gpu/drm/bridge/analogix/Kconfig @@ -13,6 +13,12 @@ config DRM_ANALOGIX_ANX6345 ANX6345 transforms the LVTTL RGB output of an application processor to eDP or DisplayPort. +config DRM_ANALOGIX_ANX7580 + tristate "Analogix ANX7580 Decoder" + depends on I2C + help + Support for the Analogix ANX7580 to MIPI DSI bridge. + config DRM_ANALOGIX_ANX78XX tristate "Analogix ANX78XX bridge" select DRM_ANALOGIX_DP diff --git a/drivers/gpu/drm/bridge/analogix/Makefile b/drivers/gpu/drm/bridge/analogix/Makefile index 44da392bb9f9..f7f39671845a 100644 --- a/drivers/gpu/drm/bridge/analogix/Makefile +++ b/drivers/gpu/drm/bridge/analogix/Makefile @@ -3,4 +3,5 @@ analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o analogix-i2c-dptx.o obj-$(CONFIG_DRM_ANALOGIX_ANX6345) += analogix-anx6345.o obj-$(CONFIG_DRM_ANALOGIX_ANX7625) += anx7625.o obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o +obj-$(CONFIG_DRM_ANALOGIX_ANX7580) += anx7580.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o diff --git a/drivers/gpu/drm/bridge/analogix/anx7580.c b/drivers/gpu/drm/bridge/analogix/anx7580.c new file mode 100644 index 000000000000..2852f8671f59 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/anx7580.c @@ -0,0 +1,623 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright(c) 2023, Valve Software. All rights reserved. + * + */ +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> +#include <linux/workqueue.h> +#include <linux/delay.h> +#include <linux/interrupt.h> + +#include "anx7580_regs.h" + +#define LOG_TAG "ANX" + +typedef struct { + struct i2c_client *client; + u8 panel_read_data[512]; + int panel_read_reg_addr, panel_read_num_bytes; + unsigned int read_sid, read_offset, read_len; + uint16_t dp_vtotal; + struct delayed_work work; +} anx7580_t; + +/* i2c functions ported from analogix chicago android driver */ + +static int anx7580_i2c_write_byte( anx7580_t * anx, u8 slave_id, u16 offset_addr, u8 data ) +{ + int ret = 0; + + if ((((slave_id & 0x0F)!=0)&&((offset_addr&0xFF00)!=0))||((offset_addr&0xF000)!=0)) { + pr_err( "%s %s: I2C slave_id or offset_addr ERROR!! %02x %04x\n",LOG_TAG,__func__,slave_id,offset_addr ); + return -EINVAL; + } + + anx->client->addr = ( ANX7580_SLAVE_ID_ADDR >> 1 ); + ret = i2c_smbus_write_byte_data( anx->client, 0x00, (slave_id | (u8)((offset_addr&0x0F00)>>8)) ); + if ( ret < 0 ) { + pr_err("%s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr); + }else{ + anx->client->addr = ( ANX7580_OFFSET_ADDR >> 1 ); + ret = i2c_smbus_write_byte_data( anx->client, (u8)(offset_addr&0x00FF), data ); + if ( ret < 0 ) { + pr_err( "%s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr ); + } + } + return ret; +} + +static int anx7580_i2c_write_block( anx7580_t * anx, u8 slave_id, u16 offset_addr, u8 length, u8 *p_data ) +{ + int ret = 0; + + if ((((slave_id & 0x0F)!=0)&&((offset_addr&0xFF00)!=0))||((offset_addr&0xF000)!=0)) { + pr_info( "%s %s: I2C slave_id or offset_addr ERROR!! %02x %04x\n",LOG_TAG,__func__,slave_id,offset_addr ); + return -EINVAL; + } + + anx->client->addr = ( ANX7580_SLAVE_ID_ADDR >> 1 ); + ret = i2c_smbus_write_byte_data( anx->client, 0x00, (slave_id | (u8)((offset_addr&0x0F00)>>8)) ); + if (ret < 0) { + pr_err( "%s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr ); + }else{ + anx->client->addr = ( ANX7580_OFFSET_ADDR >> 1 ); + ret = i2c_smbus_write_i2c_block_data( anx->client, (u8)(offset_addr&0x00FF), length, p_data ); + if (ret < 0) { + pr_err( "%s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr ); + } + } + return ret; +} + +static int anx7580_i2c_write_byte4( anx7580_t * anx, u8 slave_id, u16 offset_addr, u32 data ) +{ + int ret = 0; + u8 buf[4],i; + for ( i=0; i<4; i++ ) { + buf[i] = (u8)(data&0x000000FF); + data = data >> 8; + } + + ret = anx7580_i2c_write_block( anx, slave_id, offset_addr, 4, &buf[0] ); + + return ret; +} + +static int anx7580_i2c_read_byte( anx7580_t * anx, u8 slave_id, u16 offset_addr, u8 *p_data ) +{ + int ret = 0; + + if ((((slave_id & 0x0F)!=0)&&((offset_addr&0xFF00)!=0))||((offset_addr&0xF000)!=0)) { + pr_info( "%s %s: I2C slave_id or offset_addr ERROR!! %02x %04x\n",LOG_TAG,__func__,slave_id,offset_addr ); + return -EINVAL; + } + + anx->client->addr = ( ANX7580_SLAVE_ID_ADDR >> 1 ); + ret = i2c_smbus_write_byte_data( anx->client, 0x00, (slave_id | (u8)((offset_addr&0x0F00)>>8)) ); + if (ret < 0) { + pr_err("%s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr); + }else{ + anx->client->addr = ( ANX7580_OFFSET_ADDR >> 1 ); + ret = i2c_smbus_read_byte_data( anx->client, (u8)(offset_addr&0x00FF) ); + if (ret < 0) { + pr_err(" %s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr ); + return ret; + } + *p_data = (u8)ret; + } + return ret; +} + +static int anx7580_i2c_read_block( anx7580_t * anx, u8 slave_id, u16 offset_addr, u8 length, u8 *p_data ) +{ + int ret = 0; + + if ((((slave_id & 0x0F)!=0)&&((offset_addr&0xFF00)!=0))||((offset_addr&0xF000)!=0)) { + pr_err( "%s %s: I2C slave_id or offset_addr ERROR!! %02x %04x\n",LOG_TAG,__func__,slave_id,offset_addr ); + return -EINVAL; + } + + anx->client->addr = (ANX7580_SLAVE_ID_ADDR >> 1); + ret = i2c_smbus_write_byte_data( anx->client, 0x00, (slave_id | (u8)((offset_addr&0x0F00)>>8)) ); + if (ret < 0) { + pr_err( "%s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr ); + } else { + anx->client->addr = ( ANX7580_OFFSET_ADDR >> 1 ); + ret = i2c_smbus_read_i2c_block_data( anx->client, (u8)(offset_addr&0x00FF), length, p_data ); + if (ret < 0) { + pr_err("%s %s: failed to write i2c addr=%x\n", LOG_TAG,__func__, anx->client->addr); + } + } + return ret; +} + +static int anx7580_i2c_read_byte4( anx7580_t * anx, u8 slave_id, u16 offset_addr, u32 *p_data ) +{ + int ret = 0; + u8 buf[4],i; + + ret = anx7580_i2c_read_block( anx, slave_id, offset_addr, 4, &buf[0] ); + + if ( ret>=0 ) { + *p_data = 0; + for ( i=0; i<3; i++ ){ + *p_data += (u32)(buf[3-i]); + *p_data = *p_data<<8; + } + *p_data += (u32)(buf[3-i]); + } + + return ret; +} + +static void anx7580_panel_dcs_cmd( anx7580_t * anx, uint8_t cmd ) +{ + uint32_t reg_val = DCS_WRITE_NO_PARAM | cmd << 8; + anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, GEN_HDR, reg_val ); +} + +static void anx7580_panel_write_immediate( anx7580_t * anx, uint8_t reg, uint8_t val ) +{ + uint32_t reg_val = DCS_WRITE_ONE_PARAM | reg << 8 | val << 16; + anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, GEN_HDR, reg_val ); +} + +static void anx7580_panel_write_long( anx7580_t * anx, void * _buf, uint8_t len ) +{ + const uint8_t *buf = _buf; + for ( uint32_t v = 0, l = len; l; ) { + int i; + + // swap byte order in string to meet anx mipi port interface requirements + for ( i = 0; i < 4 && l; i++, l-- ) { + v = ( v >> 8 ) | ( *( buf++ ) << 24 ); + } + anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, GEN_PLD_DATA, v >> ( 8 * ( 4 - i ) ) ); + } + anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, GEN_HDR, ( ( len ) << 8 ) | DCS_WRITE_LONG ); +} + +//----------------------------------------------------------------------------- +// Reset mipi output block +// Must do this after panel read to clear buffer offset +static int anx7580_mipi_reset( anx7580_t * anx ) +{ + anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, PWR_UP, 0 ); + return anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, PWR_UP, 1 ); +}; + +//Minimum time between DCS transfers. +//Right now, we are going to indiscriminately wait, since the methodology for +//timing out and verifiying transaction seems to be fraught with peril. +// +//This seems to be pretty reliable in my tests. +#define DCS_INTERWRITE_DELAY_MS 34 + +static uint32_t anx7580_dcs_read( anx7580_t * anx, uint8_t reg, uint8_t len, uint8_t *pay ) +{ + uint32_t data, bytes_copied = 0, returned_bytes = 0; + uint16_t dcs_timeout_msec = 0; + uint32_t fifo_status; + + // request len number of bytes from reg + anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, GEN_HDR, ( len << 8 ) | DCS_SET_RETURN_SIZE ); + anx7580_i2c_write_byte4( anx, SLAVEID_MIPI_PORT0, GEN_HDR, ( uint32_t )DCS_READ | ( reg << 8 ) ); + + do + { + anx7580_i2c_read_byte4( anx, SLAVEID_MIPI_PORT0, CMD_PKT_STATUS, &fifo_status ); + msleep(1); + dcs_timeout_msec++; + } + while (( fifo_status & 0x10 ) && ( dcs_timeout_msec < DCS_INTERWRITE_DELAY_MS ) ); + + if ( dcs_timeout_msec >= DCS_INTERWRITE_DELAY_MS ) { + pr_err( "anx7580: MIPI Read timeout\n" ); + return 0; + } + + // get data from anx7580 fifo + do + { + anx7580_i2c_read_byte4(anx, SLAVEID_MIPI_PORT0, GEN_PLD_DATA, &data ); + for ( uint8_t i = 0; i < 4 && ( i + returned_bytes ) < len; i++ ) + { + pay[bytes_copied++] = ( data >> ( i * 8 ) ) & 0xFF; + } + returned_bytes += 4; + anx7580_i2c_read_byte4( anx, SLAVEID_MIPI_PORT0, CMD_PKT_STATUS, &fifo_status ); + } while ( !( fifo_status & 0x10 ) ); + + // must reset mipi buffers after read to correct offset + anx7580_mipi_reset(anx); + + return bytes_copied; +} + +static void anx7580_read_chip_id(anx7580_t * anx) +{ + u8 reg_temp; + u16 reg_int; + + anx7580_i2c_read_byte( anx,SLAVEID_SPI, CHIP_ID_HIGH, ®_temp ); + reg_int = ((((u16)reg_temp)<<8)&0xFF00); + anx7580_i2c_read_byte( anx,SLAVEID_SPI, CHIP_ID_LOW, ®_temp ); + reg_int |= (((u16)reg_temp)&0x00FF); + pr_info( "anx7580: Chip ID = %04X\n", reg_int ); +} + +static u8 anx7580_check_ocm_status(anx7580_t * anx) +{ + u8 reg_temp; + // Check OCM status + anx7580_i2c_read_byte( anx, SLAVEID_SERDES,SERDES_POWER_CONTROL, ®_temp ); + if ( OCM_LOAD_DONE == ( OCM_LOAD_DONE & reg_temp ) ) { + return 1; + } + return 0; +} + +static void anx7580_get_dp_vtotal(anx7580_t * anx, uint16_t * dp_vtotal) +{ + uint8_t high, low; + anx7580_i2c_read_byte( anx, SLAVEID_MAIN_LINK, ADDR_VTOTAL_DBG, &high ); + anx7580_i2c_read_byte( anx, SLAVEID_MAIN_LINK, ADDR_VTOTAL_DBG+4, &low ); + *dp_vtotal = high << 8 | low; +} + +// sysfs interface +static ssize_t bmode_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int result; + unsigned int mode; + anx7580_t *anx = dev_get_drvdata(device); + if ( !anx ) { + return 0; + } + + result = sscanf( buf, "%d", &mode ); + if( result == 1 ) { + if ( mode == 1 ){ + anx7580_panel_write_immediate( anx, 0x53, 0xE0 ); // high brightness mode + } else if (mode == 2){ + anx7580_panel_write_immediate( anx, 0x53, 0x28 ); // normal mode, update brightness within 32 frame + } else if (mode == 3){ + anx7580_panel_write_immediate( anx, 0x53, 0x20 ); // normal mode, update brightness within 32 frame + } + } + return count; +} + +static ssize_t bmode_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + uint8_t brightness_mode_reg, count, bytes_copied = 0; + anx7580_t *anx = dev_get_drvdata( device ); + // TODO return current brightness mode + bytes_copied = anx7580_dcs_read( anx, 0x53, 1, &brightness_mode_reg ); + if ( brightness_mode_reg == 0xE0 ) { + count = sprintf( buf, "High Brightness\n"); + } else if ( brightness_mode_reg == 0x28 ) { + count = sprintf( buf, "Normal Brightness 32 frames\n" ); + } else if ( brightness_mode_reg == 0x20 ) { + count = sprintf( buf, "Normal Brightness 1 frames\n" ); + } else { + count = sprintf( buf, "Unknown Brightness mode %x\n", brightness_mode_reg ); + } + return count; +} + +static ssize_t brightness_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int result; + unsigned int brightness; + uint8_t cmd[3]; + anx7580_t *anx = dev_get_drvdata( device ); + + result = sscanf( buf, "%d", &brightness ); + + if ( result == 1 ) { + // limit brightness to 16 bits + brightness &= 0xFFFF; + cmd[0] = 0x51; + cmd[1] = ( brightness & 0xFF00 ) >> 8; + cmd[2] = brightness & 0xFF; + + anx7580_panel_write_long( anx, cmd, 3 ); + } + return count; +} + +static ssize_t brightness_show( struct device *device, struct device_attribute *attr, char *buf ) +{ + uint8_t brightness_reg[2]; + uint8_t count, bytes_copied = 0; + anx7580_t *anx = dev_get_drvdata( device ); + // TODO return current brightness mode + bytes_copied = anx7580_dcs_read( anx, 0x51, 2, brightness_reg ); + if (bytes_copied) { + count = sprintf( buf, "Brightness %d\n", (int)(brightness_reg[0] << 8 | brightness_reg[1]) ); + } else { + count = sprintf( buf, "Brightness Unknwn\n" ); + } + return count; +} + +static ssize_t panel_read_show( struct device *device, struct device_attribute *attr, char *buf ) +{ + int ret; + ssize_t len = 0; + unsigned int i; + anx7580_t *anx = dev_get_drvdata( device ); + ret = anx7580_dcs_read( anx, anx->panel_read_reg_addr, anx->panel_read_num_bytes, anx->panel_read_data ); + if ( ret < 0 ) { + pr_err( "anx7580: failed to read panel reg %u\n", anx->panel_read_reg_addr ); + return ret; + } else { + for (i = 0; i < anx->panel_read_num_bytes; i++) { + ret = scnprintf( buf + len, PAGE_SIZE - len, "%x ", + anx->panel_read_data[i] ); + if ( ret < 0 ) + return ret; + len += ret; + } + buf[len - 1] = '\n'; + return len; + } +} + +static ssize_t panel_read_store( struct device *device, struct device_attribute *attr,const char *buf, size_t count ) +{ + int ret; + anx7580_t *anx = dev_get_drvdata( device ); + ret = sscanf( buf, "%2x %d", &anx->panel_read_reg_addr, &anx->panel_read_num_bytes ); + if(ret != 2) { + pr_err( "anx7580: panel read got wrong number of input parameters from sscanf" ); + return -EINVAL; + } + return count; +} + +static ssize_t panel_write_store( struct device *device, struct device_attribute *attr,const char *buf, size_t count ) +{ + int ret; + int addr, len, i, v; + char char_data[256]; + u8 payload[256]; + anx7580_t *anx = dev_get_drvdata(device); + // get the base parameters + ret = sscanf( buf, "%2x %d %s", &addr, &len, char_data ); + if(ret != 3) { + pr_err( "anx7580: panel write got wrong number of input parameters (%d) from sscanf", ret ); + return -EINVAL; + } + // TODO: for now we limit writes to a total of 256 bytes + if(len >256) { + pr_err( "anx7580: panel write exceed max length %d\n", len ); + return -EINVAL; + } + payload[0] = addr; + // get the data payload + for ( i=0; i<len; i++ ) { + if ( sscanf( char_data + i * 2, "%2x", &v ) != 1 ) break; + payload[i+1] = (unsigned char)v; + } + + if ( len == 0 ) + anx7580_panel_dcs_cmd( anx, payload[0] ); + if ( len == 1 ) + anx7580_panel_write_immediate( anx, payload[0], payload[1] ); + else + anx7580_panel_write_long( anx, payload, len ); + + pr_info( "anx7580: wrote %s to reg %x\n", char_data, addr ); + + return count; +} + +static ssize_t panel_write_show( struct device *device, struct device_attribute *attr, char *buf ) +{ + return 0; +} + +static ssize_t anx7580_read_reg_store( struct device *device, struct device_attribute *attr,const char *buf, size_t count ) +{ + int ret; + anx7580_t *anx = dev_get_drvdata(device); + ret = sscanf( buf, "%x %x %u", &anx->read_sid, &anx->read_offset, &anx->read_len); + if ( ret != 3 ) { + pr_err( "anx7580: invalid reg read params\n" ); + return -EINVAL; + } + return count; +} + +static ssize_t anx7580_read_reg_show( struct device *device, struct device_attribute *attr, char *buf ) +{ + ssize_t len = 0; + unsigned int i, ret; + uint8_t data[256]; + anx7580_t *anx = dev_get_drvdata(device); + anx7580_i2c_read_block(anx, anx->read_sid, anx->read_offset, anx->read_len, data); + for (i = 0; i < anx->read_len; i++) { + ret = scnprintf( buf + len, PAGE_SIZE - len, "%x ", data[i] ); + if ( ret < 0 ) + return ret; + len += ret; + } + buf[len - 1] = '\n'; + return len; +} + +static ssize_t anx7580_write_reg_store( struct device *device, struct device_attribute *attr,const char *buf, size_t count ) +{ + int ret; + unsigned int write_byte_sid, write_byte_offset, write_byte_data; + anx7580_t *anx = dev_get_drvdata(device); + ret = sscanf( buf, "%x %x %x", &write_byte_sid, &write_byte_offset, &write_byte_data); + if ( ret != 3 ) { + pr_err( "anx7580: invalid write byte params\n" ); + return -EINVAL; + } + anx7580_i2c_write_byte(anx, write_byte_sid, write_byte_offset, write_byte_data); + return count; +} + +static ssize_t anx7580_write_reg_show( struct device *device, struct device_attribute *attr, char *buf ) +{ + return 0; +} + +static ssize_t anx7580_write_reg4_store( struct device *device, struct device_attribute *attr,const char *buf, size_t count ) +{ + int ret, i, v; + unsigned int sid, offset; + char char_data[4*2]; + unsigned int reg_value = 0; + anx7580_t *anx = dev_get_drvdata(device); + + // get the base parameters + ret = sscanf( buf, "%x %x %s", &sid, &offset, char_data ); + if(ret != 3) { + pr_err( "anx7580: panel write got wrong number of input parameters (%d) from sscanf", ret ); + return -EINVAL; + } + + // get the data payload + for ( i=0; i<4; i++ ) { + if ( sscanf( char_data + i * 2, "%2x", &v ) != 1 ) break; + reg_value = ( reg_value << (8) ) | (unsigned char)v; + } + // pr_info("anx7580: write4 %x %x = %x\n", sid, offset, reg_value); + anx7580_i2c_write_byte4(anx, sid, offset, reg_value); + return count; +} + +static ssize_t anx7580_write_reg4_show( struct device *device, struct device_attribute *attr, char *buf ) +{ + return 0; +} + +static struct device_attribute anx7580_attrs[] = { + __ATTR(bmode, 0664, bmode_show, bmode_store), + __ATTR(brightness, 0664, brightness_show, brightness_store), + __ATTR(panel_read, 0664, panel_read_show, panel_read_store), + __ATTR(panel_write, 0664, panel_write_show, panel_write_store), + __ATTR(anx7580_read_reg, 0664, anx7580_read_reg_show, anx7580_read_reg_store), + __ATTR(anx7580_write_reg, 0664, anx7580_write_reg_show, anx7580_write_reg_store), + __ATTR(anx7580_write_reg4, 0664, anx7580_write_reg4_show, anx7580_write_reg4_store), +}; + +static int anx7580_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + anx7580_t *anx; + unsigned int i; + int ret; + + if ( !i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK) ) { + pr_err("%s: i2c bus does not support the anx7580\n", __func__); + ret = -ENODEV; + goto exit; + } + + anx = kzalloc(sizeof(anx7580_t), GFP_KERNEL); + if ( !anx ) { + pr_err("%s: failed to allocate driver data\n", __func__); + ret = -ENOMEM; + goto exit; + } + + dev_set_drvdata( &client->dev, anx ); + anx->client = client; + + // anx7580 is powered on by bios, so we assume ocm wait period is complete + if ( anx7580_check_ocm_status(anx) ) + { + // OCM load done + // Read Chip ID + anx7580_read_chip_id(anx); + // store current dp vtotal for future mode changes + anx7580_get_dp_vtotal(anx, &anx->dp_vtotal); + pr_info("anx7580: initial dp vtotal %d\n", anx->dp_vtotal); + } + + for ( i=0; i < ARRAY_SIZE(anx7580_attrs); i++ ) + { + if ( device_create_file(&client->dev, &anx7580_attrs[i]) ) + pr_err( "anx7580: could not create sysfs index %d\n", i ); + } + +exit: + return 0; +} + +static void anx7580_remove(struct i2c_client *client) +{ + anx7580_t *data; + unsigned int i; + data = i2c_get_clientdata(client); + for (i=0; i < ARRAY_SIZE(anx7580_attrs); i++) + { + device_remove_file(&client->dev, &anx7580_attrs[i]); + } + kfree(data); +} + +static int anx7580_runtime_suspend(struct device *dev) +{ + return 0; +} + +static int anx7580_runtime_resume(struct device *dev) +{ + return 0; +} + +static DEFINE_RUNTIME_DEV_PM_OPS(anx7580_pm_ops, anx7580_runtime_suspend, + anx7580_runtime_resume, NULL); + +static const struct acpi_device_id anx7580_acpi_match[] = { + { "ANX7580A", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, anx7580_acpi_match); + +static const struct i2c_device_id anx7580_i2c_ids[] = { + { "anx7580", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, anx7580_i2c_ids); + +static const struct of_device_id anx7580_of_ids[] = { + { .compatible = "analogix,anx7580", }, + { } +}; +MODULE_DEVICE_TABLE(of, anx7580_of_ids); + +static struct i2c_driver anx7580_i2c_driver = { + .driver = { + .name = "anx7580", + .pm = pm_ptr(&anx7580_pm_ops), + .of_match_table = anx7580_of_ids, + .acpi_match_table = anx7580_acpi_match, + }, + .probe = anx7580_probe, + .remove = anx7580_remove, + .id_table = anx7580_i2c_ids, +}; +module_i2c_driver(anx7580_i2c_driver); + +MODULE_AUTHOR("Keith Mikoleit <keithm@valvesoftware.com>"); +MODULE_DESCRIPTION("Analogix ANX7580 DP to MIPI Bridge Interface"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/drivers/gpu/drm/bridge/analogix/anx7580_regs.h b/drivers/gpu/drm/bridge/analogix/anx7580_regs.h new file mode 100644 index 000000000000..9b51239f90fe --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/anx7580_regs.h @@ -0,0 +1,1033 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright(c) 2023, Valve Software. All rights reserved. + * + */ + +#ifndef __ANX7580_H__ +#define __ANX7580_H__ + +/* +// From ACPI Tables +l ANX1 (_HID:ANX7580A) for “Select Slave ID”, 7-bit slave address is 0x47 +l ANX2 (_HID:ANX7580D) for “Select Offset”, 7-bit slave address is 0x43 +l GPIO AGPIO90 for interrupt pin ANX_APU_INT# +*/ + +// combine the two endpoints into a single driver by manually modifying the i2c address +#define ANX7580_SLAVE_ID_ADDR 0x8E +#define ANX7580_OFFSET_ADDR 0x86 + +/********* ANX7580 Register **********/ + +#define _BIT0 0x01 +#define _BIT1 0x02 +#define _BIT2 0x04 +#define _BIT3 0x08 +#define _BIT4 0x10 +#define _BIT5 0x20 +#define _BIT6 0x40 +#define _BIT7 0x80 + +// Register Slave ID definition +#define SLAVEID_SPI 0x01 +#define SLAVEID_PPS 0x02 +#define SLAVEID_EDID 0x03 +#define SLAVEID_MIPI_CTRL 0x08 +#define SLAVEID_SERDES 0x0A +#define SLAVEID_DP_TOP 0xA0 +#define SLAVEID_DPCD 0x10 +#define SLAVEID_MAIN_LINK 0x20 +#define SLAVEID_DP_IP 0x30 +#define SLAVEID_AUDIO 0x50 +#define SLAVEID_VIDEO 0x60 +#define SLAVEID_PLL 0x70 +#define SLAVEID_MIPI_PORT0 0xC0 +#define SLAVEID_MIPI_PORT1 0xD0 +#define SLAVEID_MIPI_PORT2 0xE0 +#define SLAVEID_MIPI_PORT3 0xF0 + +//************************************************* +//SLAVEID_SPI 0x0100 register offset_addr definition +//************************************************* +#define R_RAM_CS 0x0000 +#define R_RAM_ADDR_H 0x0001 +#define R_RAM_ADDR_L 0x0002 +#define R_RAM_LEN_H 0x0003 +#define R_RAM_LEN_L 0x0004 +#define R_RAM_CTRL 0x0005 +// bit definition +#define FLASH_DONE _BIT7 +#define BOOT_LOAD_DONE _BIT6 +#define CRC_OK _BIT5 +#define LOAD_DONE _BIT4 +#define DECRYPT_EN _BIT1 +#define LOAD_START _BIT0 + +#define R_FLASH_ADDR_H 0x000F +#define R_FLASH_ADDR_L 0x0010 +#define R_FLASH_ADDR_0 0x0011 +#define R_FLASH_LEN_H 0x0031 +#define R_FLASH_LEN_L 0x0032 +#define R_FLASH_RW_CTRL 0x0033 +// bit definition +#define READ_DELAY_SELECT _BIT7 +#define GENERAL_INSTRUCTION_EN _BIT6 +#define FLASH_ERASE_EN _BIT5 +#define RDID_READ_EN _BIT4 +#define REMS_READ_EN _BIT3 +#define WRITE_STATUS_EN _BIT2 +#define FLASH_READ _BIT1 +#define FLASH_WRITE _BIT0 + +#define R_FLASH_STATUS_0 0x0034 +#define R_FLASH_STATUS_2 0x0036 +// data definition +// Flash operation commands - refer to Table 2 in GD25D10B/05B datasheet +#define WRITE_ENABLE 0x06 +#define WRITE_DISABLE 0x04 +#define DEEP_POWER_DOWN 0xB9 +#define DEEP_PD_REL 0xAB /* Release from Deep Power-Down */ +#define CHIP_ERASE_A 0xC7 +#define CHIP_ERASE_B 0x60 + +#define R_FLASH_STATUS_3 0x0037 +// data definition +#define SECTOR_ERASE 0x20 +#define BLOCK_ERASE_32K 0x52 +#define BLOCK_ERASE_64K 0xD8 + +#define R_FLASH_STATUS_4 0x0038 +// bit definition +/* Status Register Protect bit, operates in conjunction with the Write Protect (WP#) signal */ +/* The SRP bit and WP signal set the device to the Hardware Protected mode. */ +/* When the SRP = 1, and WP# signal is Low, the non-volatile bits of the Status Register (SRP, BP2, BP1, BP0) + become read-only and the Write Status Register (WRSR) instruction is not executed. */ +/* The default value of SRP bit is 0. */ +#define SRP0 _BIT7 + +/* Block Protect bits */ +/* These bits are non-volatile. They define the size of the area to be software protected against Program and Erase commands. */ +/* These bits are written with the Write Status Register (WRSR) command. */ +/* When the (BP4, BP3, BP2, BP1, BP0) bits are set to 1, the relevant memory area becomes protected against Page Program (PP), + Sector Erase (SE), and Block Erase (BE) commands. Refer to Table 1.0 in GD25D10B/05B datasheet for details. */ +/* The (BP4, BP3, BP2, BP1, BP0) bits can be written provided that the Hardware Protected mode has not been set. */ +#define BP4 _BIT6 +#define BP3 _BIT5 +#define BP2 _BIT4 +#define BP1 _BIT3 +#define BP0 _BIT2 + +/* Write Enable Latch bit, indicates the status of the internal Write Enable Latch. */ +/* When WEL bit is 1, the internal Write Enable Latch is set. */ +/* When WEL bit is 0, the internal Write Enable Latch is reset, and Write Status Register, Program or + Erase commands are NOT accepted. */ +/* The default value of WEL bit is 0. */ +#define WEL _BIT1 + +/* Write In Progress bit, indicates whether the memory is busy in program/erase/write status register progress. */ +/* When WIP bit is 1, it means the device is busy in program/erase/write status register progress. */ +/* When WIP bit is 0, it means the device is not in program/erase/write status register progress. */ +/* The default value of WIP bit is 0. */ +#define WIP _BIT0 + +#define R_FLASH_CTRL_0 0x003F +// bit definition +#define AUX_DET _BIT5 + +#define R_DSC_CTRL_0 0x0040 +// bit definition +#define READ_STATUS_EN _BIT7 +#define DSC_EN _BIT0 + + +#define GPIO_CTRL_1 0x0048 +#define GPIO_CTRL_2 0x0049 +// bit definition +#define HDCP14_ST _BIT6 +#define R_AUX_DET_MASK _BIT5 +#define TRAN_ORDER _BIT4 +// data definition +#define PANEL_INFO_MASK 0x1F + +#define GPIO_STATUS_1 0x004B +// bit definition +#define FLASH_WP _BIT0 + +#define FLASH_READ_D0 0x0060 +// data definition +#define FLASH_READ_MAX_LENGTH 0x20 +#define FLASH_WRITE_MAX_LENGTH 0x20 + +#define R_SYS_CTRL_1 0x0081 +#define REG_BAUD_DIV_RATIO 0x0087 +#define REG_OCM_INTR_END_COUNTER 0x0088 +#define OCM_DEBUG_CTRL 0x0089 +// bit definition +#define OCM_INT_GATE _BIT7 +#define OCM_RESET _BIT6 + +#define INT_NOTIFY_MCU0 0x0090 +// bit definition +#define AUX_CABLE_OUT _BIT0 +#define VIDEO_STABLE _BIT1 +#define VIDEO_RE_CALCULATE _BIT2 +#define AUX_CABLE_IN _BIT3 +#define VIDEO_INPUT_EMPTY _BIT4 +#define AUDIO_MN_RST _BIT5 +#define AUDIO_PLL_RST _BIT7 + +#define INT_NOTIFY_MCU1 0x0091 +// bit definition +#define CHIP_STANDBY_MODE _BIT0 +#define CHIP_NORMAL_MODE _BIT1 +#define DP_PHY_CTS_START _BIT2 +#define DP_PHY_CTS_STOP _BIT3 +#define DP_LINK_TRAINING_FAIL _BIT4 + +#define MISC_NOTIFY_OCM1 0x0092 +// bit definition +#define TURN_ON_OCM_MAILBOX _BIT1 + +#define VIDEO_STABLE_DELAY_L 0x0093 +#define VIDEO_STABLE_DELAY_H 0x0094 +#define VIDEO_EMPTY_DELAY 0x0095 + +#define CHIP_ID_HIGH 0x0096 +#define CHIP_ID_LOW 0x0097 +#define OCM_VERSION_MAJOR 0x0098 +#define OCM_BUILD_NUM 0x0099 +#define SECURE_OCM_VERSION 0x009B +#define HDCP_LOAD_STATUS 0x009C +// bit definition +#define OCM_FW_CRC32 _BIT7 +#define HDCP_22_FW_LOAD_DONE _BIT5 +#define HDCP_22_KEY_LOAD_DONE _BIT4 +#define HDCP_14_KEY_LOAD_DONE _BIT3 +#define HDCP_22_FW_CRC32 _BIT2 +#define HDCP_22_KEY_CRC32 _BIT1 +#define HDCP_14_KEY_CRC32 _BIT0 + +#define SW_PANEL_FRAME_RATE 0x009D + +#define MISC_NOTIFY_OCM0 0x009E +// bit definition +#define RESET_DP_PHY_WHEN_VIDEO_MUTE _BIT1 +#define ENABLE_EMPTY_RESET_DP_PHY _BIT2 +#define ENABLE_DP_LS_CHECK _BIT3 +#define ENABLE_STANDBY_MODE _BIT4 +#define AUD_MCLK_ALWAYS_ON _BIT5 +#define PANEL_INFO_SET_DONE _BIT6 +#define MCU_LOAD_DONE _BIT7 + +#define M_VALUE_MULTIPLY 0x009F +#define SW_H_ACTIVE_L 0x00A0 +#define SW_H_ACTIVE_H 0x00A1 +// data definition +#define SW_H_ACTIVE_H_BITS 0x3F + +#define SW_HFP_L 0x00A2 +#define SW_HFP_H 0x00A3 +// data definition +#define SW_HFP_H_BITS 0x0F + +#define SW_HSYNC_L 0x00A4 +#define SW_HSYNC_H 0x00A5 +// data definition +#define SW_HSYNC_H_BITS 0x0F + +#define SW_HBP_L 0x00A6 +#define SW_HBP_H 0x00A7 +// data definition +#define SW_HBP_H_BITS 0x0F + +#define SW_V_ACTIVE_L 0x00A8 +#define SW_V_ACTIVE_H 0x00A9 +// data definition +#define SW_V_ACTIVE_H_BITS 0x3F + +#define SW_VFP_L 0x00AA +#define SW_VFP_H 0x00AB +// data definition +#define SW_VFP_H_BITS 0x0F + +#define SW_VSYNC_L 0x00AC +#define SW_VSYNC_H 0x00AD +// data definition +#define SW_VSYNC_H_BITS 0x0F + +#define SW_VBP_L 0x00AE +#define SW_VBP_H 0x00AF +// data definition +#define SW_VBP_H_BITS 0x0F + +#define SW_PANEL_INFO_0 0x00B0 +// data definition +#define REG_PANEL_COUNT_SHIFT 6 +#define REG_MIPI_TOTAL_PORT_SHIFT 4 +#define REG_MIPI_LANE_COUNT_SHIFT 2 +#define REG_PANEL_VIDEO_MODE_SHIFT 0 +// data definition +#define REG_PANEL_COUNT 0xC0 +#define REG_MIPI_TOTAL_PORT 0x30 +#define REG_MIPI_LANE_COUNT 0x0C +#define REG_PANEL_VIDEO_MODE 0x03 + +#define SW_PANEL_INFO_1 0x00B1 +// data definition +#define REG_PANEL_TRANS_MODE_SHIFT 2 +// data definition +#define REG_PANEL_TRANS_MODE 0x0C +// bit definition +#define REG_PANEL_ORDER _BIT0 +#define REG_PANEL_DSC_MODE _BIT1 +#define VIDEO_BIST_MODE _BIT5 +#define SET_DPHY_TIMING _BIT6 + +#define SW_AUD_MAUD_SVAL_7_0 0xB2 +#define SW_AUD_MAUD_SVAL_15_8 0xB3 +#define SW_AUD_MAUD_SVAL_23_16 0xB4 +#define SW_AUD_NAUD_SVAL_7_0 0xB5 +#define SW_AUD_NAUD_SVAL_15_8 0xB6 +#define SW_AUD_NAUD_SVAL_23_16 0xB7 + +#define TEST_PATTERN_CTRL 0x00ED +// data definition + #define TEST_PATTERN_EN 0x80 + #define DISPLAY_BIST_EN 0x08 + #define TEST_PATTERN_MODE1 0x10 + #define TEST_PATTERN_MODE2 0x20 + #define TEST_PATTERN_MODE3 0x30 + +#define H_BLANK_L 0x00EF +#define H_BLANK_H 0x00F0 + +#define REG_BYTE_CLK_EN 0x00F1 +#define MIPI_CLK_EN 0x00F2 +#define CONFIG_X_ACCESS_FIFO 0x00F6 // config_x(i2c_master) read data out +#define CONFIG_X_CTRL_0 0x00F7 // config_x(i2c_master) device address +#define CONFIG_X_CTRL_1 0x00F8 // config_x(i2c_master) offset +#define CONFIG_X_CTRL_2 0x00F9 +// bit definition +#define CONFIG_X_GLH_SEL _BIT7 +#define CONFIG_X_CMD _BIT6|_BIT5|_BIT4 +#define I2C_BYTE_READ 0x00 +#define I2C_BYTE_WRITE 0x10 +#define I2C_RESET 0x40 +#define CONFIG_X_SPEED _BIT3|_BIT2 +#define CONFIG_X_NO_STOP _BIT1 +#define CONFIG_X_NO_ACK _BIT0 + +#define CONFIG_X_CTRL_3 0x00FA // config_x(i2c_master) access number low byte +#define CONFIG_X_CTRL_4 0x00FB +// bit definition +#define CONFIG_X_DDC_STATE _BIT7|_BIT6|_BIT5|_BIT4|_BIT3 +#define CONFIG_X_MODE _BIT2 +#define CONFIG_X_ACCESS_NUM_HIGH _BIT1|_BIT0 + +#define CONFIG_X_CTRL_5 0x00FC +#define CONFIG_X_CTRL_6 0x00FD +#define OCM_DEBUG 0x00FE +#define R_VERSION 0x00FF + +//************************************************* +//SLAVEID_PPS 0x0200 register offset_addr definition +//************************************************* +#define REG_ADDR_ACTIVE_LINE_CFG_L 0x0014 +#define REG_ADDR_ACTIVE_LINE_CFG_H 0x0015 +// data definition +#define REG_V_ACTIVE_H_BITS 0x3F + +#define REG_ADDR_V_SYNC_CFG 0x0017 +#define REG_ADDR_TOTAL_PIXEL_CFG_L 0x0019 +#define REG_ADDR_TOTAL_PIXEL_CFG_H 0x001A +// data definition +#define REG_H_TOTAL_H_BITS 0x3F + +#define REG_ADDR_ACTIVE_PIXEL_CFG_L 0x001B +#define REG_ADDR_ACTIVE_PIXEL_CFG_H 0x001C +// data definition +#define REG_H_ACTIVE_H_BITS 0x3F + +#define REG_ADDR_H_F_PORCH_CFG_L 0x001D +#define REG_ADDR_H_F_PORCH_CFG_H 0x001E +// data definition +#define REG_HFP_H_BITS 0x0F + +#define REG_ADDR_H_SYNC_CFG_L 0x001F +#define REG_ADDR_H_SYNC_CFG_H 0x0020 +// data definition +#define REG_HSYNC_H_BITS 0x0F + +#define REG_ADDR_H_B_PORCH_CFG_L 0x0021 +#define REG_ADDR_H_B_PORCH_CFG_H 0x0022 +// data definition +#define REG_HBP_H_BITS 0x0F + +#define REG_ADDR_V_F_PORCH_CFG_L 0x0023 +#define REG_ADDR_V_F_PORCH_CFG_H 0x0024 +// data definition +#define REG_VFP_H_BITS 0x0F + +#define REG_ADDR_V_B_PORCH_CFG_L 0x0025 +#define REG_ADDR_V_B_PORCH_CFG_H 0x0026 +// data definition +#define REG_VBP_H_BITS 0x0F + +#define DSC_DEBUG_2 0x007C +// bit definitions +#define FIFO_OF_ERR_BUF00 _BIT7 +#define FIFO_OF_ERR_BUF01 _BIT6 +#define FIFO_OF_ERR_BUF10 _BIT5 +#define FIFO_OF_ERR_BUF11 _BIT4 +#define FIFO_UF_ERR_BUF00 _BIT3 +#define FIFO_UF_ERR_BUF01 _BIT2 +#define FIFO_UF_ERR_BUF10 _BIT1 +#define FIFO_UF_ERR_BUF11 _BIT0 + +#define PPS_REG_0 0x0080 +#define PPS_REG_96 0x00e0 +#define PPS_REG_97 0x00e1 +#define PPS_REG_98 0x00e2 +#define PPS_REG_99 0x00e3 +#define PPS_REG_100 0x00e4 +#define PPS_REG_101 0x00e5 +#define PPS_REG_102 0x00e6 +#define PPS_REG_103 0x00e7 +#define PPS_REG_104 0x00e8 +#define PPS_REG_105 0x00e9 +#define PPS_REG_106 0x00ea +#define PPS_REG_107 0x00eb +#define PPS_REG_108 0x00ec +#define PPS_REG_109 0x00ed +#define PPS_REG_110 0x00ee +#define PPS_REG_111 0x00ef + +#define R_MISC_DEBUG 0x00FB +#define PRE_FILLER_BUF0_15_8 0x00FC +#define PRE_FILLER_BUF0_7_0 0x00FD +#define PRE_FILLER_BUF1_15_8 0x00FE +#define PRE_FILLER_BUF1_7_0 0x00FF + +//************************************************* +//EDID 0x0300 buffer register offset_addr definition +//************************************************* +#define EDID_EXTENSION_BUF 0x0080 + +// Other EDID information +#define EDID_LENGTH 128 +#define EDID_EXTENSION_LENGTH 128 +// EDID position +#define EDID_MANUFACTURER_ID_H 0x08 +#define EDID_MANUFACTURER_ID_L 0x09 +#define EDID_PRODUCT_ID_L 0x0A +#define EDID_PRODUCT_ID_H 0x0B +#define EDID_SERIAL_NUM_L 0x0C +#define EDID_SERIAL_NUM_H 0x0E +#define EDID_WEEK 0x10 +#define EDID_YEAR 0x11 + +#define EDID_DB1_PIXEL_CLOCK_L 0x36 +#define EDID_DB1_PIXEL_CLOCK_H 0x37 + +#define EDID_DB1_BASE 0x36 +#define EDID_DB2_BASE 0x48 +#define EDID_DB3_BASE 0x5A +#define EDID_DB4_BASE 0x6C + +#define EDID_DB_MAX 4 +#define EDID_DB_SIZE 18 +#define EDID_DB_DUMMY 0x10 + +#define EDID_PIXEL_CLK_L 0 +#define EDID_PIXEL_CLK_H 1 +#define EDID_HACTIVE_L 2 +#define EDID_HBP_L 3 +#define EDID_HACT_HBP_H 4 +#define EDID_VACTIVE_L 5 +#define EDID_VBP_L 6 +#define EDID_VACT_VBP_H 7 +#define EDID_HFP_L 8 +#define EDID_HSYNC_L 9 +#define EDID_VFP_VSYNC_L 10 +#define EDID_HFP_HSYNC_VFP_VSYNC_H 11 +#define EDID_H_DISPLAY_SIZE 12 +#define EDID_FEATURES_BITMAP 17 + +#define EDID_EXTERN_PANEL_DATA 0x49 +#define EDID_VFP_MAX_VALUE 63 + +//************************************************* +//SLAVEID_MIPI_CTRL 0x0800 register offset_addr definition +//************************************************* +#define R_MIPI_TX_PORT_PD 0x0000 +// bit definition +#define MIPI_PORT_3_PD _BIT7 +#define MIPI_PORT_2_PD _BIT6 +#define MIPI_PORT_1_PD _BIT5 +#define MIPI_PORT_0_PD _BIT4 + +#define R_MIP_TX_PHY_TIMER_0 0x0001 +#define R_MIP_TX_PHY_TIMER_1 0x0002 +#define R_MIP_TX_PHY_TIMER_2 0x0003 +#define R_MIP_TX_PHY_TIMER_3 0x0004 +#define R_MIP_TX_PHY_TIMER_4 0x0005 +#define R_MIP_TX_PHY_TIMER_5 0x0006 +#define R_MIP_TX_PHY_TIMER_6 0x0007 +#define R_MIP_TX_PHY_TIMER_7 0x0008 +#define R_MIP_TX_PHY_TIMER_8 0x0009 +#define R_MIP_TX_PHY_TIMER_9 0x000A +#define R_MIP_TX_PHY_TIMER_10 0x000B +#define R_MIP_TX_PHY_TIMER_11 0x000C +#define R_MIP_TX_PHY_TIMER_12 0x000D +#define R_MIP_TX_PHY_TIMER_13 0x000E +#define R_MIP_TX_TLPX_COUNTER 0x0018 +#define R_MIP_TX_SELECT 0x0019 +#define R_MIP_TX_STATE 0x0022 +// bit definition +#define MIPI_TX_STABLE_STATE _BIT0 + +#define R_MIP_TX_INT 0x0023 +// bit definition +#define MIPI_PORT_3_INT _BIT5 +#define MIPI_PORT_2_INT _BIT4 +#define MIPI_PORT_1_INT _BIT3 +#define MIPI_PORT_0_INT _BIT2 +#define MIPI_STABLE_INT _BIT1 +#define MIPI_JITTER_INT _BIT0 + +#define R_MIP_TX_INT_MASK 0x0024 +// bit definition +#define MIPI_STABLE_INT_MASK _BIT1 +#define MIPI_JITTER_INT_MASK _BIT0 + +#define R_MIP_TX_INT_CLR 0x0025 +// bit definition +#define MIPI_STABLE_INT_CLR _BIT1 +#define MIPI_JITTER_INT_CLR _BIT0 + +#define R_MIP_TX_PHY_TIMER_14 0x002A +#define R_MIP_TX_PHY_TIMER_15 0x002B +#define R_MIP_TX_PHY_TIMER_16 0x002C +#define R_MIP_TX_PHY_TIMER_17 0x002D +#define R_MIP_TX_PHY_TIMER_18 0x002E +#define R_MIP_TX_PHY_TIMER_19 0x002F +#define R_MIP_TX_PHY_TIMER_20 0x0030 +#define R_MIP_TX_PHY_TIMER_21 0x0031 +#define R_MIPI_PHY 0x003A + +//************************************************* +//SLAVEID_SERDES 0x0A00 register offset_addr definition +//************************************************* +#define SERDES_REG_2 0x0002 +#define SERDES_REG_3 0x0003 +// bit definition +#define REG_BYPASS_SIGNAL_DET _BIT5 +#define REG_BYPASS_STATE _BIT4 + +#define SERDES_REG_7 0x0007 +#define SERDES_REG_9 0x0009 +// bit definition +#define REG_LANE_OK_SW _BIT4 +#define SWAP_AUX_R _BIT5 +#define SWAP_AUX_T _BIT6 + +#define DPPLL_REG2 0x0022 +// bit definition +#define EXT_INTR_OUTPUT _BIT2 + +#define SERDES_REG_38 0x0026 +// data definition +#define ALL_SET_LANE0 0x00 +#define ALL_SET_LANE1 0x55 +#define ALL_SET_LANE2 0xAA +#define ALL_SET_LANE3 0xFF +// data definition +#define PHY_SINK_TEST_LANE_SEL_0 0x00 +#define PHY_SINK_TEST_LANE_SEL_1 0x10 +#define PHY_SINK_TEST_LANE_SEL_2 0x20 +#define PHY_SINK_TEST_LANE_SEL_3 0x30 + +#define SERDES_SET_1_RX_REG1 0x002B +#define SERDES_SET_2_RX_REG2 0x002C +#define SERDES_SET_5_RX_REG5 0x002F + +#define SERDES_SET_7 0x0031 +#define SERDES_SET_8_RX_REG8 0x0032 +#define SERDES_SET_9_RX_REG9 0x0033 +#define SERDES_SET_13_RX_REG13 0x0037 +#define SERDES_SET_14_RX_REG14 0x0038 +#define SERDES_SET_15_RX_REG15 0x0039 +#define SERDES_POWER_CONTROL 0x003C +// bit definition +#define OCM_LOAD_DONE _BIT4 +#define PD_V10_AUX_PHY _BIT3 +#define PD_V10_DPRX _BIT2 +#define PD_V10_APLL _BIT1 +#define PD_V10_MIPI _BIT0 + + +#define REG0_0_RX_REG0 0x003E +#define REG0_1_RX_REG0 0x003F +#define REG0_2_RX_REG0 0x0040 +#define REG0_3_RX_REG0 0x0041 +#define REG7_0_RX_REG7 0x0042 +#define REG7_1_RX_REG7 0x0043 +#define REG7_2_RX_REG7 0x0044 +#define REG7_3_RX_REG7 0x0045 +#define REG16_0_RX_REG16 0x0046 +#define REG16_1_RX_REG16 0x0047 +#define REG16_2_RX_REG16 0x0048 +#define REG16_3_RX_REG16 0x0049 +#define REG_CR 0x004A + +//************************************************* +//SLAVEID_DP_TOP 0xA000 register offset_addr definition +//************************************************* +#define ADDR_PWD_SEL 0x0000 +#define HDCP1_PWD_SW_EN _BIT4 + +#define ADDR_PWD_CTRL_0 0x0004 +// bit definition +#define PWD_AUX_CH _BIT4 + +#define ADDR_PWD_CTRL_1 0x0008 +// bit definition +#define PWD_HDCP2 _BIT5 +#define PWD_HDCP1 _BIT4 +#define PWD_AUDPLL _BIT3 +#define PWD_AUD _BIT2 + +#define ADDR_RST_SEL_0 0x0010 +// bit definition +#define HDCP1DEC_AUTO_RST _BIT5 +#define HDCP1AUTH_AUTO_RST _BIT4 +#define AUD_AUTO_RST _BIT3 + +#define ADDR_RST_SEL_1 0x0014 +// bit definition +#define MAIN_VID_CHANGE_RST_EN _BIT4 +#define ALIGN_STATUS_RST_EN _BIT3 +#define LANE_DEC_RST_EN _BIT2 +#define AUDIOPLL_AUTO_RST _BIT1 +#define VIDEOPLL_AUTO_RST _BIT0 + + +#define ADDR_RST_CTRL_0 0x0018 +// bit definition +#define RST_SW_RESET _BIT1 +#define RST_LOGIC_RESET _BIT0 + +#define ADDR_RST_CTRL_1 0x001C +// bit definition +#define RST_SERDESCTRL_RESET _BIT7 +#define RST_HDCP2_RESET _BIT6 +#define RST_HDCP1DEC_RESET _BIT5 +#define RST_HDCP1AUTH_RESET _BIT4 +#define RST_VID_RESET _BIT3 +#define RST_MAINLINK_RESET _BIT2 +#define RST_RXTOP_RESET _BIT1 +#define RST_AUX_CH_RESET _BIT0 + +#define ADDR_RST_CTRL_2 0x0020 +// bit definition +#define RST_VIDEOPLLPRE_RESET _BIT4 +#define RST_VIDEOPLL_RESET _BIT3 +#define RST_AUDIOPLL_RESET _BIT2 +#define RST_AUDIOMNADJ_RESET _BIT1 +#define RST_AUDIO_RESET _BIT0 + +#define ADDR_MISC_CTRL 0x0030 +#define ADDR_POWER_STATUS 0x0040 +// bit definition +#define AUX_STATUS _BIT2 +#define MAIN_LINK_STATUS _BIT1 +#define VIDEO_STATUS _BIT0 + +#define ADDR_SW_INTR_CTRL 0x0044 +// bit definition +#define PLL_INTR _BIT7 +#define PLL_INTR_MASK _BIT6 +#define SOFT_INTR _BIT0 + +#define ADDR_INTR 0x0048 +#define ADDR_INTR_MASK 0x004c +#define MAIN_LINK_INTR _BIT0 +#define DP_IP_INTR _BIT1 +#define DPCD_INTR _BIT2 +#define AUDIO_INTR _BIT3 +#define VIDEO_INTR _BIT4 +#define SERDES_INTR _BIT5 +#define HDCP1_INTR _BIT6 +#define VIDEO_ON_INT _BIT7 + +//************************************************* +//SLAVEID_DPCD 0x1000 register offset_addr definition +//************************************************* +#define DPCD_REV 0x0000 +#define MAX_LINK_RATE 0x0001 +#define MAX_LANE_COUNT 0x0002 +#define MAX_DOWNSPREAD 0x0003 +#define DP_PWR_VOLTAGE_CAP 0x0004 +#define DOWN_STREAM_PORT_PRESENT 0x0005 +#define MAIN_LINK_CHANNEL_CODING 0x0006 +#define DOWN_STREAM_PORT_COUNT 0x0007 +#define RECEIVE_PORT0_CAP_0 0x0008 +#define RECEIVE_PORT0_CAP_1 0x0009 +#define RECEIVE_PORT1_CAP_0 0x000A +#define eDP_CONFIGURATION_CAP 0x000D +#define TRAINING_AUX_RD_INTERVAL 0x000E + +#define LINK_BW_SET 0x0100 +// data definition +#define DPCD_BW_1P62G 0x06 +#define DPCD_BW_2P7G 0x0A +#define DPCD_BW_5P4G 0x14 +#define DPCD_BW_6P75G 0x1E + +#define LANE_COUNT_SET 0x0101 +#define TRAINING_PATTERN_SET 0x0102 +// data definition +#define TRAINING_PATTERN_SELECT 0x03 +#define LT_NOT_IN_PROGRESS 0x00 +#define LT_PATTERN_SEQUENCE1 0x01 +#define LT_PATTERN_SEQUENCE2 0x02 + +#define SINK_COUNT 0x0200 +#define LANE_ALIGN_STATUS_UPDATED 0x0204 +// bit definition +#define INTERLANE_ALIGN_DONE _BIT0 + +#define TEST_SINK_MISC 0x0246 +// data definition +#define TEST_CRC_COUNT 0x0F +// bit definition +#define TEST_CRC_SUPPORTED _BIT5 + +#define TEST_SINK 0x0270 +// bit definition +#define TEST_SINK_START _BIT0 +#define PHY_SINK_TEST_LANE_SEL 0x30 +#define PHY_SINK_TEST_LANE_EN _BIT7 +#define PHY_SINK_TEST_LANE_SEL_POS 4 + +#define DPCD_SINK_IEEE_OUI_FIRST 0x0400 +#define DPCD_SINK_IEEE_OUI_SECOND 0x0401 +#define DPCD_SINK_IEEE_OUI_THIRD 0x0402 + +#define ADDR_BW_CHANGE 0x04F1 +#define DPCD_BW_CHANDE _BIT6 + +#define AUX_FLOATING_ZONE 0x04F2 +#define FLOATING_DPCD_0_INTR_0 _BIT0 + +#define DPCD_INTR0 0x04F4 +#define DPCD_INTR1 0x04F5 +#define DPCD_INTR2 0x04F6 +#define DPCD_INTR3 0x04F7 + +#define DPCD_BRANCH_IEEE_OUI_FIRST 0x0500 +#define DPCD_BRANCH_IEEE_OUI_SECOND 0x0501 +#define DPCD_BRANCH_IEEE_OUI_THIRD 0x0502 + +#define DPCD_POWEWR_STATE 0x0600 +// data difinition +#define POWER_STATE_MASK 0x07 +#define POWER_STATE_NORMAL 0x01 +#define POWER_STATE_SLEEP 0x02 +#define POWER_STATE_STANDBY 0x05 + +//************************************************* +//SLAVEID_MAIN_LINK 0x2000 register offset_addr definition +//************************************************* +#define ADDR_HSTART_DBG 0x0048 +#define ADDR_HSW_DBG 0x0050 +#define ADDR_HTOTAL_DBG 0x0058 +#define ADDR_HWIDTH15_8_DBG 0x0060 +#define ADDR_HWIDTH7_0_DBG 0x0064 +#define ADDR_VHEIGHT15_8_DBG 0x0068 +#define ADDR_VHEIGHT7_0_DBG 0x006C +#define ADDR_VSW_DBG 0x0078 +#define ADDR_VTOTAL_DBG 0x0080 +#define ADDR_MAIN_LINK_CTRL 0x009C +// bit definition +#define FORCE_MN_READY _BIT7 +#define FORCE_M_N _BIT6 +#define FIELD_INV_EN _BIT5 +#define MAIN_WRITE_EN _BIT4 +#define REFILL_ON_FIFO_ERROR _BIT3 +#define RESET_ON_FIFO_ERROR _BIT2 +#define OVERFLOW_COMPENSATE_EN _BIT1 +#define UNDERFLOW_COMPENSATE_EN _BIT0 + +#define ADDR_M_FORCE_VALUE_3 0x00A0 +#define ADDR_M_FORCE_VALUE_2 0x00A4 +#define ADDR_M_FORCE_VALUE_1 0x00A8 +#define ADDR_N_FORCE_VALUE_3 0x00AC +#define ADDR_N_FORCE_VALUE_2 0x00B0 +#define ADDR_N_FORCE_VALUE_1 0x00B4 +#define ADDR_VIDEO_ACTIVE_MASK 0x00D4 +// bit defintion +#define VIDEO_UNMUTE_JUDGE_MASK _BIT2 +#define MSA_JUDGE_MASK _BIT1 +#define VIDEO_M_READY_MASK _BIT0 + +#define ADDR_VIDEO_FIFO_PRE_FILLER_L 0x00E8 +#define ADDR_VIDEO_FIFO_PRE_FILLER_H 0x00EC +#define ADDR_AVI_INFOR 0x0100 +#define ADDR_LINK_LAYER_STATE_2 0x0284 +// bit definition +#define MAIN_DATA_OUT_EN _BIT4 + +#define ADDR_VID_M_RPT_23_16 0x0290 +#define ADDR_VID_M_RPT_15_8 0x0294 +#define ADDR_VID_M_RPT_7_0 0x0298 +#define ADDR_NVID_23_16 0x029C +#define ADDR_NVID_15_8 0x02A0 +#define ADDR_NVID_7_0 0x02A4 +#define ADDR_AUD_PACK_STATUS 0x02B4 +// data definition +#define AUDIO_CHANNEL_COUNT 0x07 + +#define ADDR_MAIN_LINK_INTR0 0x02C0 +#define ADDR_MAIN_LINK_INTR1 0x02C4 +#define ADDR_MAIN_LINK_INTR2 0x02C8 +// bit definition +#define BE_CNT_ERR_IN_FRAME_INTR _BIT1 +#define BS_CNT_ERR_IN_FRAME_INTR _BIT0 + +#define ADDR_MAIN_LINK_INTR0_MASK 0x02D0 +// bit definition +#define M_N_AUD_IND _BIT6 +#define VSC_PACKAGE_CHANGE _BIT5 +#define SPD_INFO_CHANGE _BIT4 +#define AVI_INFO_CHANGE _BIT3 +#define MPEG_INFO_CHANGE _BIT2 +#define OTHER_INFO_RECEIVED_INT _BIT1 +#define AUDIO_INFO_CHANGE _BIT0 + +#define ADDR_MAIN_LINK_INTR1_MASK 0x02D4 +// bit definition +#define MSA_UPDATE_INTR _BIT6 +#define AUDIO_CH_COUNT_CHANGE_INT _BIT5 +#define AUDIO_M_N_CHANGE_INT _BIT4 +#define MAIN_LOST_FLAG _BIT3 +#define VOTING_ERROR _BIT2 +#define MAIN_FIFO_OVFL _BIT1 +#define MAIN_FIFO_UNFL _BIT0 + +#define ADDR_MAIN_LINK_INTR2_MASK 0x02D8 +// bit defintion +#define BE_CNT_ERR_IN_LINE_INTR _BIT3 +#define BS_CNT_ERR_IN_LINE_INTR _BIT2 +#define BE_CNT_ERR_IN_FRAME_INTR _BIT1 +#define BS_CNT_ERR_IN_FRAME_INTR _BIT0 + +#define ADDR_MAIN_LINK_INTR0_AEC 0x02E0 +#define ADDR_MAIN_LINK_INTR1_AEC 0x02E4 +#define ADDR_MAIN_LINK_INTR2_AEC 0x02E8 +#define ADDR_MAIN_LINK_STATUS_0 0x02F0 +// bit definition +#define VIDEO_MN_READY_INT _BIT1 +#define VIDEO_UNMUTE_INT _BIT0 + + +//************************************************* +//SLAVEID_DP_IP 0x3000 register offset_addr definition +//************************************************* +#define ADDR_SYSTEM_CTRL_0 0x0028 +// bit definition +#define SYNC_STATUS_SEL _BIT5 +#define ALIGN_LATCH_LOW _BIT4 +#define FORCE_HPD_VALUE _BIT3 +#define FORCE_HPD_EN _BIT2 +#define POL_MAKE_SEL _BIT1 +#define CHK_DU_EN _BIT0 + +#define ADDR_SYSTEM_CTRL_1 0x002C +#define ADDR_SYSTEM_STATUS_1 0x0038 +// bit definition +#define AUX_CMD_RCV _BIT1 +#define AUX_CMD_REPLY _BIT0 + +#define ADDR_RCD_PN_CONVERTE 0x0064 +// bit definition +#define BYPASS_RC_PAT_CHK _BIT5 + +#define ADDR_HDCP2_CTRL 0x0140 +// bit definition +#define HDCP2_FW_EN _BIT5 +#define HDCP_VERSION _BIT6 + +#define ADDR_HDCP2_DEBUG_2 0x014C +#define ADDR_HDCP2_STATUS 0x0154 +// bit definition +#define ENCRYPT_STATUS _BIT1 + +#define ADDR_FLOATING_DPCD_ZONE_0_L 0x0180 +#define ADDR_FLOATING_DPCD_ZONE_0_H 0x0184 +#define ADDR_FLOATING_DPCD_ZONE_1_L 0x0188 +#define ADDR_FLOATING_DPCD_ZONE_1_H 0x018C +#define ADDR_FLOATING_DPCD_ZONE_2_L 0x0190 +#define ADDR_FLOATING_DPCD_ZONE_2_H 0x0194 +#define ADDR_FLOATING_DPCD_ZONE_3_L 0x0198 +#define ADDR_FLOATING_DPCD_ZONE_3_H 0x019C + +#define ADDR_HPD_ACTIVE_WAIT_TIMER 0x0270 + +#define ADDR_AUX_CH_STATUS 0x030C +// bit definition +#define AUX_ADO_INTR_LAT _BIT3 +#define AUX_TIMEOUT_LAT _BIT2 +#define AUX_MII_ERR_LAT _BIT1 +#define AUX_LEN_ERR_LAT _BIT0 + +#define ADDR_DPIP_INTR 0x0320 +#define ADDR_DPIP_INTR_MASK 0x0330 +// bit definition +#define ALIGN_STATUS_UNLOCK_INTR _BIT3 +#define LINK_TRAINING_FAIL_INTR _BIT2 +#define AUX_CH_ERR_INTR _BIT1 +#define VID_FORMAT_CHANGE _BIT0 + +#define ADDR_DPIP_INTR_AEC 0x0340 +#define ADDR_AUX_ADDR_L 0x0368 +// bit definition +#define AUX_ADDR_ERROR 0x40 + +//************************************************* +//SLAVEID_AUDIO 0x5000 register offset_addr definition +//************************************************* +#define ADDR_AUD_MCTRL 0x000C +// bit definition +#define AUD_SOFTMUTE_EN _BIT7 +#define HARD_MUTE_EN _BIT3 +#define AUD_MUTEDONE_INT_ON_UNMUTE _BIT2 +#define AUD_UNMUTE_ON_DE _BIT1 +#define AUD_MUTE _BIT0 + +#define ADDR_AUD_INTR 0x0010 +#define ADDR_AUD_INTR_MASK 0x0014 +// bit definition +#define AUD_CH_STATUS_CHANGE_INT _BIT7 +#define VBID_AUD_MUTE_INTR _BIT6 +#define AUD_FIFO_UND_INT _BIT5 +#define AUD_FIFO_OVER_INT _BIT4 +#define AUD_LINKERR_INT _BIT3 +#define AUD_DECERR_INT _BIT2 +#define AUD_SPDIFERR_INT _BIT1 +#define AUD_MUTEDONE_INT _BIT0 + +#define ADDR_AUD_AAC 0x0044 +// bit definition +#define AAC_EN _BIT0 + +#define ADDR_AUD_INTR_AEC 0x0048 +#define ADDR_AUD_ACR_CTRL_1 0x0050 +// bit definition +#define MAUD_SEL _BIT1 +#define NAUD_SEL _BIT0 + +#define ADDR_NAUD_SVAL_7_0 0x0054 +#define ADDR_NAUD_SVAL_15_8 0x0058 +#define ADDR_NAUD_SVAL_23_16 0x005C +#define ADDR_MAUD_SVAL_7_0 0x0084 +#define ADDR_MAUD_SVAL_15_8 0x0088 +#define ADDR_MAUD_SVAL_23_16 0x008C + +#define ADDR_DBG_AUD_SAMPLE_CNT_7_0 0x00C8 +#define ADDR_DBG_AUD_SAMPLE_CNT_15_8 0x00CC +#define ADDR_AUD_CTRL1 0x00DC +#define ADDR_AUD_CTRL2 0x00E0 +#define ADDR_AUD_AFC_CTRL 0x0100 +// bit definition +#define RE_COUNT_EN _BIT2 +#define STEP_SCALE _BIT1 +#define AFC_FUNC_EN _BIT0 + +#define ADDR_AUD_CTRL4 0x0248 +#define ADDR_DBG_AUD_CS_3 0x0270 +// bit definition +#define AUD_SAMPLE_RATE 0x0F + +//************************************************* +//SLAVEID_VIDEO 0x6000 register offset_addr definition +//************************************************* +#define ADDR_ACT_PIX_LOW 0x0010 +#define ADDR_ACT_PIX_HIGH 0x0014 +#define ADDR_ACT_LINE_LOW 0x0018 +#define ADDR_ACT_LINE_HIGH 0x001C +#define ADDR_VID_STABLE_DET 0x0040 +// bit definition +#define VID_STRM_STABLE_STATUS _BIT2 + +#define ADDR_VID_INT 0x00C0 +#define ADDR_VID_INT_MASK 0x00C4 +// bit definition +#define VSYNC_DET_INT _BIT5 +#define V_RES_CHANGED _BIT4 +#define H_RES_CHANGED _BIT3 +#define SYNC_POL_CHANGED _BIT2 +#define VID_TYPE_CHANGED _BIT1 +#define VID_STRM_STABLE_INT _BIT0 + +//************************************************* +//SLAVEID_PLL 0x7000 register offset_addr definition +//************************************************* +#define ADDR_VPLL_ANALOG_4 0x0010 +#define ADDR_VPLL_CTRL_0 0x0014 +#define ADDR_VPLL_CTRL_2 0x001C +#define ADDR_VPLL_CTRL_3 0x0020 +#define ADDR_PLL_INTR 0x0090 +#define ADDR_PLL_INTR_MASK 0x0094 +// bit definition +#define VPLL_UNLOCK_INT _BIT3 +#define APLL_UNLOCK_INT _BIT2 +#define APLL_INTP_N_CHG _BIT1 +#define APLL_INTP_FS_CHG _BIT0 + +#define ADDR_PLL_INTR_AEC 0x0098 + +//************************************************* +//MIPI TX 0xC000 register offset_addr definition +//************************************************* +#define PWR_UP 0x0004 +#define CLKMGR_CFG 0x0008 +#define DPI_COLOR_CODING 0x0010 +#define DPI_CFG_POL 0x0014 +#define PCKHDL_CFG 0x002C +#define GEN_VCID 0x0030 +#define MODE_CFG 0x0034 +#define VID_MODE_CFG 0x0038 +#define VID_PKT_SIZE 0x003C +#define VID_HSA_TIME 0x0048 +#define VID_HBP_TIME 0x004C +#define VID_HLINE_TIME 0x0050 +#define VID_VSA_LINES 0x0054 +#define VID_VBP_LINES 0x0058 +#define VID_VFP_LINES 0x005C +#define VID_VACTIVE_LINES 0x0060 +#define CMD_MODE_CFG 0x0068 +#define LPCLK_CTRL 0x0094 +#define PHY_TMR_LPCLK_CFG 0x0098 +#define PHY_TMR_CFG 0x009C +#define PHY_RSTZ 0x00A0 +#define PHY_IF_CFG 0x00A4 +#define INT_MSK0 0x00C4 +#define INT_MSK1 0x00C8 +#define GEN_HDR 0x006C +#define GEN_PLD_DATA 0x0070 +#define CMD_PKT_STATUS 0x0074 +// bit definition +#define gen_pld_w_empty _BIT2 + +#define DSC_PARAMETER 0x00F0 + +// MIPI DCS packet types +#define DCS_WRITE_NO_PARAM 0x05 +#define DCS_WRITE_ONE_PARAM 0x15 +#define DCS_WRITE_LONG 0x39 +#define DCS_SET_RETURN_SIZE 0x37 +#define DCS_READ 0x06 + +#endif /* __ANX7580_H__ */ \ No newline at end of file diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 0cb646cb04ee..014101e92b5a 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -395,6 +395,13 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Valve Steam Deck */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* VIOS LTH17 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), |