diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 10:01:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 10:01:40 -0700 |
commit | 68a32ba14177d4a21c4a9a941cf1d7aea86d436f (patch) | |
tree | 945c20860766c22b19d1806d5b5db5b37bc65b65 /drivers/gpu/drm/drm_edid.c | |
parent | 3aa139aa9fdc138a84243dc49dc18d9b40e1c6e4 (diff) | |
parent | a1a1ca70deb3ec600eeabb21de7f3f48aaae5695 (diff) |
Merge tag 'drm-next-2021-04-28' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"The usual lots of work all over the place.
i915 has gotten some Alderlake work and prelim DG1 code, along with a
major locking rework over the GEM code, and brings back the property
of timing out long running jobs using a watchdog. amdgpu has some
Alderbran support (new GPU), freesync HDMI support along with a lot
other fixes.
Outside of the drm, there is a new printf specifier added which should
have all the correct acks/sobs:
- printk fourcc modifier support added %p4cc
Summary:
core:
- drm_crtc_commit_wait
- atomic plane state helpers reworked for full state
- dma-buf heaps API rework
- edid: rework and improvements for displayid
dp-mst:
- better topology logging
bridge:
- Chipone ICN6211
- Lontium LT8912B
- anx7625 regulator support
panel:
- fix lt9611 4k panels handling
simple-kms:
- add plane state helpers
ttm:
- debugfs support
- removal of unused sysfs
- ignore signaled moved fences
- ioremap buffer according to mem caching
i915:
- Alderlake S enablement
- Conversion to dma_resv_locking
- Bring back watchdog timeout support
- legacy ioctl cleanups
- add GEM TDDO and RFC process
- DG1 LMEM preparation work
- intel_display.c refactoring
- Gen9/TGL PCH combination support
- eDP MSO Support
- multiple PSR instance support
- Link training debug updates
- Disable PSR2 support on JSL/EHL
- DDR5/LPDDR5 support for bw calcs
- LSPCON limited to gen9/10 platforms
- HSW/BDW async flip/VTd corruption workaround
- SAGV watermark fixes
- SNB hard hang on ring resume fix
- Limit imported dma-buf size
- move to use new tasklet API
- refactor KBL/TGL/ADL-S display/gt steppings
- refactoring legacy DP/HDMI, FB plane code out
amdgpu:
- uapi: add ioctl to query video capabilities
- Iniital AMD Freesync HDMI support
- Initial Adebaran support
- 10bpc dithering improvements
- DCN secure display support
- Drop legacy IO BAR requirements
- PCIE/S0ix/RAS/Prime/Reset fixes
- Display ASSR support
- SMU gfx busy queues for RV/PCO
- Initial LTTPR display work
amdkfd:
- MMU notifier fixes
- APU fixes
radeon:
- debugfs cleanps
- fw error handling ifix
- Flexible array cleanups
msm:
- big DSI phy/pll cleanup
- sc7280 initial support
- commong bandwidth scaling path
- shrinker locking contention fixes
- unpin/swap support for GEM objcets
ast:
- cursor plane handling reworked
tegra:
- don't register DP AUX channels before connectors
zynqmp:
- fix OOB struct padding memset
gma500:
- drop ttm and medfield support
exynos:
- request_irq cleanup function
mediatek:
- fine tune line time for EOTp
- MT8192 dpi support
- atomic crtc config updates
- don't support HDMI connector creation
mxsdb:
- imx8mm support
panfrost:
- MMU IRQ handling rework
qxl:
- locking fixes
- resource deallocation changes
sun4i:
- add alpha properties to UI/VI layers
vc4:
- RPi4 CEC support
vmwgfx:
- doc cleanups
arc:
- moved to drm/tiny"
* tag 'drm-next-2021-04-28' of git://anongit.freedesktop.org/drm/drm: (1390 commits)
drm/ttm: Don't count pages in SG BOs against pages_limit
drm/ttm: fix return value check
drm/bridge: lt8912b: fix incorrect handling of of_* return values
drm: bridge: fix LONTIUM use of mipi_dsi_() functions
drm: bridge: fix ANX7625 use of mipi_dsi_() functions
drm/amdgpu: page retire over debugfs mechanism
drm/radeon: Fix a missing check bug in radeon_dp_mst_detect()
drm/amd/display: Fix the Wunused-function warning
drm/radeon/r600: Fix variables that are not used after assignment
drm/amdgpu/smu7: fix CAC setting on TOPAZ
drm/amd/display: Update DCN302 SR Exit Latency
drm/amdgpu: enable ras eeprom on aldebaran
drm/amdgpu: RAS harvest on driver load
drm/amdgpu: add ras aldebaran ras eeprom driver
drm/amd/pm: increase time out value when sending msg to SMU
drm/amdgpu: add DMUB outbox event IRQ source define/complete/debug flag
drm/amd/pm: add the callback to get vbios bootup values for vangogh
drm/radeon: Fix size overflow
drm/amdgpu: Fix size overflow
drm/amdgpu: move mmhub ras_func init to ip specific file
...
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 171 |
1 files changed, 38 insertions, 133 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c2bbe7bee7b6..81d5f2524246 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1585,8 +1585,6 @@ module_param_named(edid_fixup, edid_fixup, int, 0400); MODULE_PARM_DESC(edid_fixup, "Minimum number of valid EDID header bytes (0-8, default 6)"); -static int validate_displayid(u8 *displayid, int length, int idx); - static int drm_edid_block_checksum(const u8 *raw_edid) { int i; @@ -3241,10 +3239,10 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, /* * Search EDID for CEA extension block. */ -static u8 *drm_find_edid_extension(const struct edid *edid, - int ext_id, int *ext_index) +const u8 *drm_find_edid_extension(const struct edid *edid, + int ext_id, int *ext_index) { - u8 *edid_ext = NULL; + const u8 *edid_ext = NULL; int i; /* No EDID or EDID extensions */ @@ -3253,7 +3251,7 @@ static u8 *drm_find_edid_extension(const struct edid *edid, /* Find CEA extension */ for (i = *ext_index; i < edid->extensions; i++) { - edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); + edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1); if (edid_ext[0] == ext_id) break; } @@ -3266,63 +3264,30 @@ static u8 *drm_find_edid_extension(const struct edid *edid, return edid_ext; } - -static u8 *drm_find_displayid_extension(const struct edid *edid, - int *length, int *idx, - int *ext_index) +static const u8 *drm_find_cea_extension(const struct edid *edid) { - u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, ext_index); - struct displayid_hdr *base; - int ret; - - if (!displayid) - return NULL; - - /* EDID extensions block checksum isn't for us */ - *length = EDID_LENGTH - 1; - *idx = 1; - - ret = validate_displayid(displayid, *length, *idx); - if (ret) - return NULL; - - base = (struct displayid_hdr *)&displayid[*idx]; - *length = *idx + sizeof(*base) + base->bytes; - - return displayid; -} - -static u8 *drm_find_cea_extension(const struct edid *edid) -{ - int length, idx; - struct displayid_block *block; - u8 *cea; - u8 *displayid; - int ext_index; + const struct displayid_block *block; + struct displayid_iter iter; + const u8 *cea; + int ext_index = 0; /* Look for a top level CEA extension block */ /* FIXME: make callers iterate through multiple CEA ext blocks? */ - ext_index = 0; cea = drm_find_edid_extension(edid, CEA_EXT, &ext_index); if (cea) return cea; /* CEA blocks can also be found embedded in a DisplayID block */ - ext_index = 0; - for (;;) { - displayid = drm_find_displayid_extension(edid, &length, &idx, - &ext_index); - if (!displayid) - return NULL; - - idx += sizeof(struct displayid_hdr); - for_each_displayid_db(displayid, block, idx, length) { - if (block->tag == DATA_BLOCK_CTA) - return (u8 *)block; + displayid_iter_edid_begin(edid, &iter); + displayid_iter_for_each(block, &iter) { + if (block->tag == DATA_BLOCK_CTA) { + cea = (const u8 *)block; + break; } } + displayid_iter_end(&iter); - return NULL; + return cea; } static __always_inline const struct drm_display_mode *cea_mode_for_vic(u8 vic) @@ -4503,8 +4468,8 @@ static void clear_eld(struct drm_connector *connector) static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) { uint8_t *eld = connector->eld; - u8 *cea; - u8 *db; + const u8 *cea; + const u8 *db; int total_sad_count = 0; int mnl; int dbl; @@ -4600,7 +4565,7 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) { int count = 0; int i, start, end, dbl; - u8 *cea; + const u8 *cea; cea = drm_find_cea_extension(edid); if (!cea) { @@ -4619,7 +4584,7 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) } for_each_cea_db(cea, i, start, end) { - u8 *db = &cea[i]; + const u8 *db = &cea[i]; if (cea_db_tag(db) == AUDIO_BLOCK) { int j; @@ -4631,7 +4596,7 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) if (!*sads) return -ENOMEM; for (j = 0; j < count; j++) { - u8 *sad = &db[1 + j * 3]; + const u8 *sad = &db[1 + j * 3]; (*sads)[j].format = (sad[0] & 0x78) >> 3; (*sads)[j].channels = sad[0] & 0x7; @@ -4755,7 +4720,7 @@ EXPORT_SYMBOL(drm_av_sync_delay); */ bool drm_detect_hdmi_monitor(struct edid *edid) { - u8 *edid_ext; + const u8 *edid_ext; int i; int start_offset, end_offset; @@ -4793,7 +4758,7 @@ EXPORT_SYMBOL(drm_detect_hdmi_monitor); */ bool drm_detect_monitor_audio(struct edid *edid) { - u8 *edid_ext; + const u8 *edid_ext; int i, j; bool has_audio = false; int start_offset, end_offset; @@ -5287,32 +5252,6 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi return quirks; } -static int validate_displayid(u8 *displayid, int length, int idx) -{ - int i, dispid_length; - u8 csum = 0; - struct displayid_hdr *base; - - base = (struct displayid_hdr *)&displayid[idx]; - - DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", - base->rev, base->bytes, base->prod_id, base->ext_count); - - /* +1 for DispID checksum */ - dispid_length = sizeof(*base) + base->bytes + 1; - if (dispid_length > length - idx) - return -EINVAL; - - for (i = 0; i < dispid_length; i++) - csum += displayid[idx + i]; - if (csum) { - DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum); - return -EINVAL; - } - - return 0; -} - static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev, struct displayid_detailed_timings_1 *timings) { @@ -5359,7 +5298,7 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d } static int add_displayid_detailed_1_modes(struct drm_connector *connector, - struct displayid_block *block) + const struct displayid_block *block) { struct displayid_detailed_timing_block *det = (struct displayid_detailed_timing_block *)block; int i; @@ -5387,27 +5326,16 @@ static int add_displayid_detailed_1_modes(struct drm_connector *connector, static int add_displayid_detailed_modes(struct drm_connector *connector, struct edid *edid) { - u8 *displayid; - int length, idx; - struct displayid_block *block; + const struct displayid_block *block; + struct displayid_iter iter; int num_modes = 0; - int ext_index = 0; - for (;;) { - displayid = drm_find_displayid_extension(edid, &length, &idx, - &ext_index); - if (!displayid) - break; - - idx += sizeof(struct displayid_hdr); - for_each_displayid_db(displayid, block, idx, length) { - switch (block->tag) { - case DATA_BLOCK_TYPE_1_DETAILED_TIMING: - num_modes += add_displayid_detailed_1_modes(connector, block); - break; - } - } + displayid_iter_edid_begin(edid, &iter); + displayid_iter_for_each(block, &iter) { + if (block->tag == DATA_BLOCK_TYPE_1_DETAILED_TIMING) + num_modes += add_displayid_detailed_1_modes(connector, block); } + displayid_iter_end(&iter); return num_modes; } @@ -6041,43 +5969,20 @@ static void drm_parse_tiled_block(struct drm_connector *connector, } } -static void drm_displayid_parse_tiled(struct drm_connector *connector, - const u8 *displayid, int length, int idx) -{ - const struct displayid_block *block; - - idx += sizeof(struct displayid_hdr); - for_each_displayid_db(displayid, block, idx, length) { - DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n", - block->tag, block->rev, block->num_bytes); - - switch (block->tag) { - case DATA_BLOCK_TILED_DISPLAY: - drm_parse_tiled_block(connector, block); - break; - default: - DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag); - break; - } - } -} - void drm_update_tile_info(struct drm_connector *connector, const struct edid *edid) { - const void *displayid = NULL; - int ext_index = 0; - int length, idx; + const struct displayid_block *block; + struct displayid_iter iter; connector->has_tile = false; - for (;;) { - displayid = drm_find_displayid_extension(edid, &length, &idx, - &ext_index); - if (!displayid) - break; - drm_displayid_parse_tiled(connector, displayid, length, idx); + displayid_iter_edid_begin(edid, &iter); + displayid_iter_for_each(block, &iter) { + if (block->tag == DATA_BLOCK_TILED_DISPLAY) + drm_parse_tiled_block(connector, block); } + displayid_iter_end(&iter); if (!connector->has_tile && connector->tile_group) { drm_mode_put_tile_group(connector->dev, connector->tile_group); |