forked from luck/tmp_suning_uos_patched
drm-misc-next for v5.9:
Cross-subsystem Changes: - Improve dma-buf docs. Core Changes: - Add NV15, Q410, Q401 yuv formats. - Add uncompressed AFBC modifier. - Add DP helepr for reading Ignore MSA from DPCD. - Add missing panel type for some panels - Optimize drm/mm hole handling. - Constify connector to infoframe functions. - Add debugfs for VRR monitor range. Driver Changes: - Assorted small bugfixes in panfrost, malidp, panel/otm8009a. - Convert tfp410 dt bindings to yaml, and rework time calculations. - Add support for a few more simple panels. - Cleanups and optimizations for ast. - Allow adv7511 and simple-bridge to be used without connector creation. - Cleanups to dw-hdmi function prototypes. - Remove enabled bool from tiny/repaper and mipi-dbi, atomic handles it. - Remove unused header file from dw-mipi-dsi - Begin removing ttm_bo->offset. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEuXvWqAysSYEJGuVH/lWMcqZwE8MFAl7103UACgkQ/lWMcqZw E8NTPhAAiB/FjDzZq86qg61OSLeB8yEOHFfWvwRyydentg3aeIhuMXUKGEmBCwwZ IAbmfbR2PwrpUF/iyZ0JuI2NWs9ErB2/9unhW9CyIo/Ij34LXL+1PW+qjq6FIq6O quWMbZMm23rQbOnHXr9BHEJh9qs1WrvQkZF+8AxgJJ0JmLMjkbhcyupN6tZC2uWQ 2e1p0A3zRVb+Avk9xHaWz5pShYbZ68S7ysIpIOh0KGpQvmu7TExzqLgg/rJcqVKd Ze6URs8SZ7Lwx6EM8ixJ4pd39OnrkWpEafacIqhpJv794Uftgec8mV7eBc4y8WJa 4/VNz7QbhtYKkFClTSvPhh001vUpDZnqdi/t7GsxHoY30InMpUD+zO29P1BkD+gf geWE5NxV9Tv549GosuwggG4LWa+sZxl2iurdDATyxh2wips9zR1gNUzqK5rsnptZ CN3OqeUaBRljM2oXV9o5/zc9fb3HMdFaLut1XKUX7fHOYrWXN+KBEv530/zaBTNq 7gzadci/VkebOxIJ/6wMFqqBedrNlEYAjD3X/WCJUk2Y1V4R60oMtBNVG27jW8ov JY5wrt8HXMzLfdk2CIZ08mIXJmQqWHyFCBvJEtAyULMvKWUKzg32R4hqtirAJM5c 9w9SzZ4RjrJIBVKR8hl6zE8WGqH/BWRiJXa+NelUP3i64Hk/B44= =72wu -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-2020-06-26' of git://anongit.freedesktop.org/drm/drm-misc into drm-next drm-misc-next for v5.9: Cross-subsystem Changes: - Improve dma-buf docs. Core Changes: - Add NV15, Q410, Q401 yuv formats. - Add uncompressed AFBC modifier. - Add DP helepr for reading Ignore MSA from DPCD. - Add missing panel type for some panels - Optimize drm/mm hole handling. - Constify connector to infoframe functions. - Add debugfs for VRR monitor range. Driver Changes: - Assorted small bugfixes in panfrost, malidp, panel/otm8009a. - Convert tfp410 dt bindings to yaml, and rework time calculations. - Add support for a few more simple panels. - Cleanups and optimizations for ast. - Allow adv7511 and simple-bridge to be used without connector creation. - Cleanups to dw-hdmi function prototypes. - Remove enabled bool from tiny/repaper and mipi-dbi, atomic handles it. - Remove unused header file from dw-mipi-dsi - Begin removing ttm_bo->offset. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/b1e53620-7937-895c-bfcf-ed208be59c7c@linux.intel.com
This commit is contained in:
commit
f75020fcb9
|
@ -1,66 +0,0 @@
|
|||
TFP410 DPI to DVI encoder
|
||||
=========================
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,tfp410"
|
||||
|
||||
Optional properties:
|
||||
- powerdown-gpios: power-down gpio
|
||||
- reg: I2C address. If and only if present the device node should be placed
|
||||
into the I2C controller node where the TFP410 I2C is connected to.
|
||||
- ti,deskew: data de-skew in 350ps increments, from -4 to +3, as configured
|
||||
through th DK[3:1] pins. This property shall be present only if the TFP410
|
||||
is not connected through I2C.
|
||||
|
||||
Required nodes:
|
||||
|
||||
This device has two video ports. Their connections are modeled using the OF
|
||||
graph bindings specified in [1]. Each port node shall have a single endpoint.
|
||||
|
||||
- Port 0 is the DPI input port. Its endpoint subnode shall contain a
|
||||
pclk-sample and bus-width property and a remote-endpoint property as specified
|
||||
in [1].
|
||||
- If pclk-sample is not defined, pclk-sample = 0 should be assumed for
|
||||
backward compatibility.
|
||||
- If bus-width is not defined then bus-width = 24 should be assumed for
|
||||
backward compatibility.
|
||||
bus-width = 24: 24 data lines are connected and single-edge mode
|
||||
bus-width = 12: 12 data lines are connected and dual-edge mode
|
||||
|
||||
- Port 1 is the DVI output port. Its endpoint subnode shall contain a
|
||||
remote-endpoint property is specified in [1].
|
||||
|
||||
[1] Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
tfp410: encoder@0 {
|
||||
compatible = "ti,tfp410";
|
||||
powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
|
||||
ti,deskew = <4>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
tfp410_in: endpoint@0 {
|
||||
pclk-sample = <1>;
|
||||
bus-width = <24>;
|
||||
remote-endpoint = <&dpi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
tfp410_out: endpoint@0 {
|
||||
remote-endpoint = <&dvi_connector_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
131
Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
Normal file
131
Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
Normal file
|
@ -0,0 +1,131 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/bridge/ti,tfp410.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TFP410 DPI to DVI encoder
|
||||
|
||||
maintainers:
|
||||
- Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
- Jyri Sarha <jsarha@ti.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,tfp410
|
||||
|
||||
reg:
|
||||
description: I2C address of the device.
|
||||
maxItems: 1
|
||||
|
||||
powerdown-gpios:
|
||||
maxItems: 1
|
||||
|
||||
ti,deskew:
|
||||
description:
|
||||
Data de-skew value in 350ps increments, from 0 to 7, as configured
|
||||
through the DK[3:1] pins. The de-skew multiplier is computed as
|
||||
(DK[3:1] - 4), so it ranges from -4 to 3.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
|
||||
ports:
|
||||
description:
|
||||
A node containing input and output port nodes with endpoint
|
||||
definitions as documented in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
type: object
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
description: DPI input port.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
reg:
|
||||
const: 0
|
||||
|
||||
endpoint:
|
||||
type: object
|
||||
|
||||
properties:
|
||||
pclk-sample:
|
||||
description:
|
||||
Endpoint sampling edge.
|
||||
enum:
|
||||
- 0 # Falling edge
|
||||
- 1 # Rising edge
|
||||
default: 0
|
||||
|
||||
bus-width:
|
||||
description:
|
||||
Endpoint bus width.
|
||||
enum:
|
||||
- 12 # 12 data lines connected and dual-edge mode
|
||||
- 24 # 24 data lines connected and single-edge mode
|
||||
default: 24
|
||||
|
||||
port@1:
|
||||
description: DVI output port.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
reg:
|
||||
const: 1
|
||||
|
||||
endpoint:
|
||||
type: object
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- ports
|
||||
|
||||
if:
|
||||
required:
|
||||
- reg
|
||||
then:
|
||||
properties:
|
||||
ti,deskew: false
|
||||
else:
|
||||
required:
|
||||
- ti,deskew
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
tfp410: encoder {
|
||||
compatible = "ti,tfp410";
|
||||
powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
|
||||
ti,deskew = <3>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
tfp410_in: endpoint {
|
||||
pclk-sample = <1>;
|
||||
bus-width = <24>;
|
||||
remote-endpoint = <&dpi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
tfp410_out: endpoint {
|
||||
remote-endpoint = <&dvi_connector_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -81,6 +81,10 @@ properties:
|
|||
- boe,nv140fhmn49
|
||||
# CDTech(H.K.) Electronics Limited 4.3" 480x272 color TFT-LCD panel
|
||||
- cdtech,s043wq26h-ct7
|
||||
# CDTech(H.K.) Electronics Limited 7" WSVGA (1024x600) TFT LCD Panel
|
||||
- cdtech,s070pws19hp-fc21
|
||||
# CDTech(H.K.) Electronics Limited 7" WVGA (800x480) TFT LCD Panel
|
||||
- cdtech,s070swv29hg-dc44
|
||||
# CDTech(H.K.) Electronics Limited 7" 800x480 color TFT-LCD panel
|
||||
- cdtech,s070wv95-ct16
|
||||
# Chunghwa Picture Tubes Ltd. 7" WXGA TFT LCD panel
|
||||
|
@ -247,6 +251,8 @@ properties:
|
|||
- starry,kr122ea0sra
|
||||
# Tianma Micro-electronics TM070JDHG30 7.0" WXGA TFT LCD panel
|
||||
- tianma,tm070jdhg30
|
||||
# Tianma Micro-electronics TM070JVHG33 7.0" WXGA TFT LCD panel
|
||||
- tianma,tm070jvhg33
|
||||
# Tianma Micro-electronics TM070RVHG71 7.0" WXGA TFT LCD panel
|
||||
- tianma,tm070rvhg71
|
||||
# Toshiba 8.9" WXGA (1280x768) TFT LCD panel
|
||||
|
|
|
@ -100,11 +100,11 @@ CPU Access to DMA Buffer Objects
|
|||
.. kernel-doc:: drivers/dma-buf/dma-buf.c
|
||||
:doc: cpu access
|
||||
|
||||
Fence Poll Support
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Implicit Fence Poll Support
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/dma-buf.c
|
||||
:doc: fence polling
|
||||
:doc: implicit fence polling
|
||||
|
||||
Kernel Functions and Structures Reference
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -161,11 +161,11 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)
|
|||
}
|
||||
|
||||
/**
|
||||
* DOC: fence polling
|
||||
* DOC: implicit fence polling
|
||||
*
|
||||
* To support cross-device and cross-driver synchronization of buffer access
|
||||
* implicit fences (represented internally in the kernel with &struct fence) can
|
||||
* be attached to a &dma_buf. The glue for that and a few related things are
|
||||
* implicit fences (represented internally in the kernel with &struct dma_fence)
|
||||
* can be attached to a &dma_buf. The glue for that and a few related things are
|
||||
* provided in the &dma_resv structure.
|
||||
*
|
||||
* Userspace can query the state of these implicitly tracked fences using poll()
|
||||
|
|
|
@ -918,7 +918,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
|||
bo->pin_count++;
|
||||
|
||||
if (max_offset != 0) {
|
||||
u64 domain_start = bo->tbo.bdev->man[mem_type].gpu_offset;
|
||||
u64 domain_start = amdgpu_ttm_domain_start(adev,
|
||||
mem_type);
|
||||
WARN_ON_ONCE(max_offset <
|
||||
(amdgpu_bo_gpu_offset(bo) - domain_start));
|
||||
}
|
||||
|
@ -1484,7 +1485,25 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
|
|||
WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
|
||||
!(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS));
|
||||
|
||||
return amdgpu_gmc_sign_extend(bo->tbo.offset);
|
||||
return amdgpu_bo_gpu_offset_no_check(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_bo_gpu_offset_no_check - return GPU offset of bo
|
||||
* @bo: amdgpu object for which we query the offset
|
||||
*
|
||||
* Returns:
|
||||
* current GPU offset of the object without raising warnings.
|
||||
*/
|
||||
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
uint64_t offset;
|
||||
|
||||
offset = (bo->tbo.mem.start << PAGE_SHIFT) +
|
||||
amdgpu_ttm_domain_start(adev, bo->tbo.mem.mem_type);
|
||||
|
||||
return amdgpu_gmc_sign_extend(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -293,6 +293,7 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv,
|
|||
bool intr);
|
||||
int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr);
|
||||
u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo);
|
||||
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo);
|
||||
int amdgpu_bo_validate(struct amdgpu_bo *bo);
|
||||
int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow,
|
||||
struct dma_fence **fence);
|
||||
|
|
|
@ -91,7 +91,6 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
|||
case TTM_PL_TT:
|
||||
/* GTT memory */
|
||||
man->func = &amdgpu_gtt_mgr_func;
|
||||
man->gpu_offset = adev->gmc.gart_start;
|
||||
man->available_caching = TTM_PL_MASK_CACHING;
|
||||
man->default_caching = TTM_PL_FLAG_CACHED;
|
||||
man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
|
||||
|
@ -99,7 +98,6 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
|||
case TTM_PL_VRAM:
|
||||
/* "On-card" video ram */
|
||||
man->func = &amdgpu_vram_mgr_func;
|
||||
man->gpu_offset = adev->gmc.vram_start;
|
||||
man->flags = TTM_MEMTYPE_FLAG_FIXED |
|
||||
TTM_MEMTYPE_FLAG_MAPPABLE;
|
||||
man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
|
||||
|
@ -110,7 +108,6 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
|||
case AMDGPU_PL_OA:
|
||||
/* On-chip GDS memory*/
|
||||
man->func = &ttm_bo_manager_func;
|
||||
man->gpu_offset = 0;
|
||||
man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_CMA;
|
||||
man->available_caching = TTM_PL_FLAG_UNCACHED;
|
||||
man->default_caching = TTM_PL_FLAG_UNCACHED;
|
||||
|
@ -258,7 +255,8 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
|
|||
|
||||
if (mm_node->start != AMDGPU_BO_INVALID_OFFSET) {
|
||||
addr = mm_node->start << PAGE_SHIFT;
|
||||
addr += bo->bdev->man[mem->mem_type].gpu_offset;
|
||||
addr += amdgpu_ttm_domain_start(amdgpu_ttm_adev(bo->bdev),
|
||||
mem->mem_type);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
@ -843,6 +841,27 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
|
|||
(offset >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_ttm_domain_start - Returns GPU start address
|
||||
* @adev: amdgpu device object
|
||||
* @type: type of the memory
|
||||
*
|
||||
* Returns:
|
||||
* GPU start address of a memory domain
|
||||
*/
|
||||
|
||||
uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case TTM_PL_TT:
|
||||
return adev->gmc.gart_start;
|
||||
case TTM_PL_VRAM:
|
||||
return adev->gmc.vram_start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TTM backend functions.
|
||||
*/
|
||||
|
@ -1239,9 +1258,6 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
|
|||
bo->mem = tmp;
|
||||
}
|
||||
|
||||
bo->offset = (bo->mem.start << PAGE_SHIFT) +
|
||||
bo->bdev->man[bo->mem.mem_type].gpu_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
|
|||
int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
|
||||
int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
|
||||
uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
|
||||
int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages);
|
||||
|
|
|
@ -144,7 +144,7 @@ static void amdgpu_vm_sdma_copy_ptes(struct amdgpu_vm_update_params *p,
|
|||
|
||||
src += p->num_dw_left * 4;
|
||||
|
||||
pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
|
||||
pe += amdgpu_bo_gpu_offset_no_check(bo);
|
||||
trace_amdgpu_vm_copy_ptes(pe, src, count, p->immediate);
|
||||
|
||||
amdgpu_vm_copy_pte(p->adev, ib, pe, src, count);
|
||||
|
@ -171,7 +171,7 @@ static void amdgpu_vm_sdma_set_ptes(struct amdgpu_vm_update_params *p,
|
|||
{
|
||||
struct amdgpu_ib *ib = p->job->ibs;
|
||||
|
||||
pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
|
||||
pe += amdgpu_bo_gpu_offset_no_check(bo);
|
||||
trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->immediate);
|
||||
if (count < 3) {
|
||||
amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags,
|
||||
|
|
|
@ -928,7 +928,7 @@ int malidp_de_planes_init(struct drm_device *drm)
|
|||
const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
|
||||
struct malidp_plane *plane = NULL;
|
||||
enum drm_plane_type plane_type;
|
||||
unsigned long crtcs = 1 << drm->mode_config.num_crtc;
|
||||
unsigned long crtcs = BIT(drm->mode_config.num_crtc);
|
||||
unsigned long flags = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 |
|
||||
DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
|
||||
unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
|
||||
|
|
|
@ -10,7 +10,7 @@ MODULE_FIRMWARE("ast_dp501_fw.bin");
|
|||
|
||||
static int ast_load_dp501_microcode(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
|
||||
return request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ static bool wait_fw_ready(struct ast_private *ast)
|
|||
|
||||
static bool ast_write_cmd(struct drm_device *dev, u8 data)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
int retry = 0;
|
||||
if (wait_nack(ast)) {
|
||||
send_nack(ast);
|
||||
|
@ -115,7 +115,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data)
|
|||
|
||||
static bool ast_write_data(struct drm_device *dev, u8 data)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
|
||||
if (wait_nack(ast)) {
|
||||
send_nack(ast);
|
||||
|
@ -133,7 +133,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data)
|
|||
#if 0
|
||||
static bool ast_read_data(struct drm_device *dev, u8 *data)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u8 tmp;
|
||||
|
||||
*data = 0;
|
||||
|
@ -172,7 +172,7 @@ static u32 get_fw_base(struct ast_private *ast)
|
|||
|
||||
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u32 i, data;
|
||||
u32 boot_address;
|
||||
|
||||
|
@ -188,7 +188,7 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
|
|||
|
||||
static bool ast_launch_m68k(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u32 i, data, len = 0;
|
||||
u32 boot_address;
|
||||
u8 *fw_addr = NULL;
|
||||
|
@ -255,7 +255,7 @@ static bool ast_launch_m68k(struct drm_device *dev)
|
|||
|
||||
u8 ast_get_dp501_max_clk(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u32 boot_address, offset, data;
|
||||
u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
|
||||
|
||||
|
@ -283,7 +283,7 @@ u8 ast_get_dp501_max_clk(struct drm_device *dev)
|
|||
|
||||
bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u32 i, boot_address, offset, data;
|
||||
|
||||
boot_address = get_fw_base(ast);
|
||||
|
@ -312,7 +312,7 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
|
|||
|
||||
static bool ast_init_dvo(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u8 jreg;
|
||||
u32 data;
|
||||
ast_write32(ast, 0xf004, 0x1e6e0000);
|
||||
|
@ -385,7 +385,7 @@ static bool ast_init_dvo(struct drm_device *dev)
|
|||
|
||||
static void ast_init_analog(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u32 data;
|
||||
|
||||
/*
|
||||
|
@ -412,7 +412,7 @@ static void ast_init_analog(struct drm_device *dev)
|
|||
|
||||
void ast_init_3rdtx(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u8 jreg;
|
||||
|
||||
if (ast->chip == AST2300 || ast->chip == AST2400) {
|
||||
|
@ -438,7 +438,7 @@ void ast_init_3rdtx(struct drm_device *dev)
|
|||
|
||||
void ast_release_firmware(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
|
||||
release_firmware(ast->dp501_fw);
|
||||
ast->dp501_fw = NULL;
|
||||
|
|
|
@ -59,7 +59,6 @@ static struct drm_driver driver;
|
|||
static const struct pci_device_id pciidlist[] = {
|
||||
AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL),
|
||||
AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL),
|
||||
/* AST_VGA_DEVICE(PCI_CHIP_AST1180, NULL), - don't bind to 1180 for now */
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
|
@ -189,9 +188,6 @@ static int ast_pm_freeze(struct device *dev)
|
|||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct drm_device *ddev = pci_get_drvdata(pdev);
|
||||
|
||||
if (!ddev || !ddev->dev_private)
|
||||
return -ENODEV;
|
||||
return ast_drm_freeze(ddev);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
|
||||
#define PCI_CHIP_AST2000 0x2000
|
||||
#define PCI_CHIP_AST2100 0x2010
|
||||
#define PCI_CHIP_AST1180 0x1180
|
||||
|
||||
|
||||
enum ast_chip {
|
||||
|
@ -64,7 +63,6 @@ enum ast_chip {
|
|||
AST2300,
|
||||
AST2400,
|
||||
AST2500,
|
||||
AST1180,
|
||||
};
|
||||
|
||||
enum ast_tx_chip {
|
||||
|
@ -138,6 +136,11 @@ struct ast_private {
|
|||
const struct firmware *dp501_fw; /* dp501 fw */
|
||||
};
|
||||
|
||||
static inline struct ast_private *to_ast_private(struct drm_device *dev)
|
||||
{
|
||||
return dev->dev_private;
|
||||
}
|
||||
|
||||
int ast_driver_load(struct drm_device *dev, unsigned long flags);
|
||||
void ast_driver_unload(struct drm_device *dev);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,
|
|||
static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
|
||||
{
|
||||
struct device_node *np = dev->pdev->dev.of_node;
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
uint32_t data, jregd0, jregd1;
|
||||
|
||||
/* Defaults */
|
||||
|
@ -79,7 +79,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
|
|||
scu_rev)) {
|
||||
/* We do, disable P2A access */
|
||||
ast->config_mode = ast_use_dt;
|
||||
DRM_INFO("Using device-tree for configuration\n");
|
||||
drm_info(dev, "Using device-tree for configuration\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
|
|||
/* P2A works, grab silicon revision */
|
||||
ast->config_mode = ast_use_p2a;
|
||||
|
||||
DRM_INFO("Using P2A bridge for configuration\n");
|
||||
drm_info(dev, "Using P2A bridge for configuration\n");
|
||||
|
||||
/* Read SCU7c (silicon revision register) */
|
||||
ast_write32(ast, 0xf004, 0x1e6e0000);
|
||||
|
@ -112,12 +112,12 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
|
|||
}
|
||||
|
||||
/* We have a P2A bridge but it's disabled */
|
||||
DRM_INFO("P2A bridge disabled, using default configuration\n");
|
||||
drm_info(dev, "P2A bridge disabled, using default configuration\n");
|
||||
}
|
||||
|
||||
static int ast_detect_chip(struct drm_device *dev, bool *need_post)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
uint32_t jreg, scu_rev;
|
||||
|
||||
/*
|
||||
|
@ -128,7 +128,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
|
|||
*/
|
||||
if (!ast_is_vga_enabled(dev)) {
|
||||
ast_enable_vga(dev);
|
||||
DRM_INFO("VGA not enabled on entry, requesting chip POST\n");
|
||||
drm_info(dev, "VGA not enabled on entry, requesting chip POST\n");
|
||||
*need_post = true;
|
||||
} else
|
||||
*need_post = false;
|
||||
|
@ -142,50 +142,42 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
|
|||
ast_detect_config_mode(dev, &scu_rev);
|
||||
|
||||
/* Identify chipset */
|
||||
if (dev->pdev->device == PCI_CHIP_AST1180) {
|
||||
ast->chip = AST1100;
|
||||
DRM_INFO("AST 1180 detected\n");
|
||||
} else {
|
||||
if (dev->pdev->revision >= 0x40) {
|
||||
ast->chip = AST2500;
|
||||
DRM_INFO("AST 2500 detected\n");
|
||||
} else if (dev->pdev->revision >= 0x30) {
|
||||
ast->chip = AST2400;
|
||||
DRM_INFO("AST 2400 detected\n");
|
||||
} else if (dev->pdev->revision >= 0x20) {
|
||||
ast->chip = AST2300;
|
||||
DRM_INFO("AST 2300 detected\n");
|
||||
} else if (dev->pdev->revision >= 0x10) {
|
||||
switch (scu_rev & 0x0300) {
|
||||
case 0x0200:
|
||||
ast->chip = AST1100;
|
||||
DRM_INFO("AST 1100 detected\n");
|
||||
break;
|
||||
case 0x0100:
|
||||
ast->chip = AST2200;
|
||||
DRM_INFO("AST 2200 detected\n");
|
||||
break;
|
||||
case 0x0000:
|
||||
ast->chip = AST2150;
|
||||
DRM_INFO("AST 2150 detected\n");
|
||||
break;
|
||||
default:
|
||||
ast->chip = AST2100;
|
||||
DRM_INFO("AST 2100 detected\n");
|
||||
break;
|
||||
}
|
||||
ast->vga2_clone = false;
|
||||
} else {
|
||||
ast->chip = AST2000;
|
||||
DRM_INFO("AST 2000 detected\n");
|
||||
if (dev->pdev->revision >= 0x40) {
|
||||
ast->chip = AST2500;
|
||||
drm_info(dev, "AST 2500 detected\n");
|
||||
} else if (dev->pdev->revision >= 0x30) {
|
||||
ast->chip = AST2400;
|
||||
drm_info(dev, "AST 2400 detected\n");
|
||||
} else if (dev->pdev->revision >= 0x20) {
|
||||
ast->chip = AST2300;
|
||||
drm_info(dev, "AST 2300 detected\n");
|
||||
} else if (dev->pdev->revision >= 0x10) {
|
||||
switch (scu_rev & 0x0300) {
|
||||
case 0x0200:
|
||||
ast->chip = AST1100;
|
||||
drm_info(dev, "AST 1100 detected\n");
|
||||
break;
|
||||
case 0x0100:
|
||||
ast->chip = AST2200;
|
||||
drm_info(dev, "AST 2200 detected\n");
|
||||
break;
|
||||
case 0x0000:
|
||||
ast->chip = AST2150;
|
||||
drm_info(dev, "AST 2150 detected\n");
|
||||
break;
|
||||
default:
|
||||
ast->chip = AST2100;
|
||||
drm_info(dev, "AST 2100 detected\n");
|
||||
break;
|
||||
}
|
||||
ast->vga2_clone = false;
|
||||
} else {
|
||||
ast->chip = AST2000;
|
||||
drm_info(dev, "AST 2000 detected\n");
|
||||
}
|
||||
|
||||
/* Check if we support wide screen */
|
||||
switch (ast->chip) {
|
||||
case AST1180:
|
||||
ast->support_wide_screen = true;
|
||||
break;
|
||||
case AST2000:
|
||||
ast->support_wide_screen = false;
|
||||
break;
|
||||
|
@ -256,13 +248,13 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
|
|||
/* Print stuff for diagnostic purposes */
|
||||
switch(ast->tx_chip_type) {
|
||||
case AST_TX_SIL164:
|
||||
DRM_INFO("Using Sil164 TMDS transmitter\n");
|
||||
drm_info(dev, "Using Sil164 TMDS transmitter\n");
|
||||
break;
|
||||
case AST_TX_DP501:
|
||||
DRM_INFO("Using DP501 DisplayPort transmitter\n");
|
||||
drm_info(dev, "Using DP501 DisplayPort transmitter\n");
|
||||
break;
|
||||
default:
|
||||
DRM_INFO("Analog VGA only\n");
|
||||
drm_info(dev, "Analog VGA only\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -270,7 +262,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
|
|||
static int ast_get_dram_info(struct drm_device *dev)
|
||||
{
|
||||
struct device_node *np = dev->pdev->dev.of_node;
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap;
|
||||
uint32_t denum, num, div, ref_pll, dsel;
|
||||
|
||||
|
@ -396,7 +388,7 @@ static const struct drm_mode_config_funcs ast_mode_funcs = {
|
|||
|
||||
static u32 ast_get_vram_info(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u8 jreg;
|
||||
u32 vram_size;
|
||||
ast_open_key(ast);
|
||||
|
@ -451,7 +443,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
* and higher).
|
||||
*/
|
||||
if (!(pci_resource_flags(dev->pdev, 2) & IORESOURCE_IO)) {
|
||||
DRM_INFO("platform has no IO space, trying MMIO\n");
|
||||
drm_info(dev, "platform has no IO space, trying MMIO\n");
|
||||
ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
|
||||
}
|
||||
|
||||
|
@ -469,15 +461,13 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
if (need_post)
|
||||
ast_post_gpu(dev);
|
||||
|
||||
if (ast->chip != AST1180) {
|
||||
ret = ast_get_dram_info(dev);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
ast->vram_size = ast_get_vram_info(dev);
|
||||
DRM_INFO("dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n",
|
||||
ast->mclk, ast->dram_type,
|
||||
ast->dram_bus_width, ast->vram_size);
|
||||
}
|
||||
ret = ast_get_dram_info(dev);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
ast->vram_size = ast_get_vram_info(dev);
|
||||
drm_info(dev, "dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n",
|
||||
ast->mclk, ast->dram_type,
|
||||
ast->dram_bus_width, ast->vram_size);
|
||||
|
||||
ret = ast_mm_init(ast);
|
||||
if (ret)
|
||||
|
@ -496,8 +486,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
ast->chip == AST2200 ||
|
||||
ast->chip == AST2300 ||
|
||||
ast->chip == AST2400 ||
|
||||
ast->chip == AST2500 ||
|
||||
ast->chip == AST1180) {
|
||||
ast->chip == AST2500) {
|
||||
dev->mode_config.max_width = 1920;
|
||||
dev->mode_config.max_height = 2048;
|
||||
} else {
|
||||
|
@ -520,7 +509,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
|
||||
void ast_driver_unload(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
|
||||
/* enable standard VGA decode */
|
||||
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);
|
||||
|
|
|
@ -566,14 +566,15 @@ static void
|
|||
ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
struct ast_private *ast = plane->dev->dev_private;
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
struct drm_plane_state *state = plane->state;
|
||||
struct drm_gem_vram_object *gbo;
|
||||
s64 gpu_addr;
|
||||
|
||||
gbo = drm_gem_vram_of_gem(state->fb->obj[0]);
|
||||
gpu_addr = drm_gem_vram_offset(gbo);
|
||||
if (WARN_ON_ONCE(gpu_addr < 0))
|
||||
if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
|
||||
return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
|
||||
|
||||
ast_set_offset_reg(ast, state->fb);
|
||||
|
@ -586,7 +587,7 @@ static void
|
|||
ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
struct ast_private *ast = plane->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(plane->dev);
|
||||
|
||||
ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
|
||||
}
|
||||
|
@ -620,6 +621,7 @@ static int
|
|||
ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
|
||||
struct drm_plane_state *new_state)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_framebuffer *fb = new_state->fb;
|
||||
struct drm_crtc *crtc = new_state->crtc;
|
||||
struct drm_gem_vram_object *gbo;
|
||||
|
@ -630,11 +632,11 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
if (!crtc || !fb)
|
||||
return 0;
|
||||
|
||||
if (WARN_ON_ONCE(fb->width > AST_MAX_HWC_WIDTH) ||
|
||||
WARN_ON_ONCE(fb->height > AST_MAX_HWC_HEIGHT))
|
||||
if (drm_WARN_ON_ONCE(dev, fb->width > AST_MAX_HWC_WIDTH) ||
|
||||
drm_WARN_ON_ONCE(dev, fb->height > AST_MAX_HWC_HEIGHT))
|
||||
return -EINVAL; /* BUG: didn't test in atomic_check() */
|
||||
|
||||
ast = crtc->dev->dev_private;
|
||||
ast = to_ast_private(dev);
|
||||
|
||||
gbo = drm_gem_vram_of_gem(fb->obj[0]);
|
||||
src = drm_gem_vram_vmap(gbo);
|
||||
|
@ -703,10 +705,11 @@ static void
|
|||
ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_plane_state *state = plane->state;
|
||||
struct drm_crtc *crtc = state->crtc;
|
||||
struct drm_framebuffer *fb = state->fb;
|
||||
struct ast_private *ast = plane->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(plane->dev);
|
||||
struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
|
||||
struct drm_gem_vram_object *gbo;
|
||||
s64 off;
|
||||
|
@ -719,7 +722,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
|
|||
/* A new cursor image was installed. */
|
||||
gbo = ast->cursor.gbo[ast->cursor.next_index];
|
||||
off = drm_gem_vram_offset(gbo);
|
||||
if (WARN_ON_ONCE(off < 0))
|
||||
if (drm_WARN_ON_ONCE(dev, off < 0))
|
||||
return; /* Bug: we didn't pin cursor HW BO to VRAM. */
|
||||
ast_cursor_set_base(ast, off);
|
||||
|
||||
|
@ -739,7 +742,7 @@ static void
|
|||
ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
struct ast_private *ast = plane->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(plane->dev);
|
||||
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00);
|
||||
}
|
||||
|
@ -767,10 +770,7 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = {
|
|||
|
||||
static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
struct ast_private *ast = crtc->dev->dev_private;
|
||||
|
||||
if (ast->chip == AST1180)
|
||||
return;
|
||||
struct ast_private *ast = to_ast_private(crtc->dev);
|
||||
|
||||
/* TODO: Maybe control display signal generation with
|
||||
* Sync Enable (bit CR17.7).
|
||||
|
@ -793,16 +793,10 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
struct ast_private *ast = crtc->dev->dev_private;
|
||||
struct ast_crtc_state *ast_state;
|
||||
const struct drm_format_info *format;
|
||||
bool succ;
|
||||
|
||||
if (ast->chip == AST1180) {
|
||||
DRM_ERROR("AST 1180 modesetting not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!state->enable)
|
||||
return 0; /* no mode checks if CRTC is being disabled */
|
||||
|
||||
|
@ -824,7 +818,7 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
|||
static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct ast_private *ast = crtc->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(crtc->dev);
|
||||
|
||||
ast_open_key(ast);
|
||||
}
|
||||
|
@ -833,7 +827,7 @@ static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
|
|||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
struct ast_crtc_state *ast_state;
|
||||
const struct drm_format_info *format;
|
||||
struct ast_vbios_mode_info *vbios_mode_info;
|
||||
|
@ -907,8 +901,9 @@ static struct drm_crtc_state *
|
|||
ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
|
||||
{
|
||||
struct ast_crtc_state *new_ast_state, *ast_state;
|
||||
struct drm_device *dev = crtc->dev;
|
||||
|
||||
if (WARN_ON(!crtc->state))
|
||||
if (drm_WARN_ON(dev, !crtc->state))
|
||||
return NULL;
|
||||
|
||||
new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL);
|
||||
|
@ -946,7 +941,7 @@ static const struct drm_crtc_funcs ast_crtc_funcs = {
|
|||
|
||||
static int ast_crtc_init(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
struct ast_crtc *crtc;
|
||||
int ret;
|
||||
|
||||
|
@ -975,7 +970,7 @@ static int ast_crtc_init(struct drm_device *dev)
|
|||
|
||||
static int ast_encoder_init(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
struct drm_encoder *encoder = &ast->encoder;
|
||||
int ret;
|
||||
|
||||
|
@ -995,7 +990,7 @@ static int ast_encoder_init(struct drm_device *dev)
|
|||
static int ast_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct ast_connector *ast_connector = to_ast_connector(connector);
|
||||
struct ast_private *ast = connector->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(connector->dev);
|
||||
struct edid *edid;
|
||||
int ret;
|
||||
bool flags = false;
|
||||
|
@ -1026,7 +1021,7 @@ static int ast_get_modes(struct drm_connector *connector)
|
|||
static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct ast_private *ast = connector->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(connector->dev);
|
||||
int flags = MODE_NOMODE;
|
||||
uint32_t jtemp;
|
||||
|
||||
|
@ -1044,7 +1039,7 @@ static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
|
|||
|
||||
if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
|
||||
(ast->chip == AST2300) || (ast->chip == AST2400) ||
|
||||
(ast->chip == AST2500) || (ast->chip == AST1180)) {
|
||||
(ast->chip == AST2500)) {
|
||||
if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
|
||||
return MODE_OK;
|
||||
|
||||
|
@ -1114,7 +1109,7 @@ static int ast_connector_init(struct drm_device *dev)
|
|||
connector = &ast_connector->base;
|
||||
ast_connector->i2c = ast_i2c_create(dev);
|
||||
if (!ast_connector->i2c)
|
||||
DRM_ERROR("failed to add ddc bus for connector\n");
|
||||
drm_err(dev, "failed to add ddc bus for connector\n");
|
||||
|
||||
drm_connector_init_with_ddc(dev, connector,
|
||||
&ast_connector_funcs,
|
||||
|
@ -1137,7 +1132,7 @@ static int ast_connector_init(struct drm_device *dev)
|
|||
/* allocate cursor cache and pin at start of VRAM */
|
||||
static int ast_cursor_init(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
size_t size, i;
|
||||
struct drm_gem_vram_object *gbo;
|
||||
int ret;
|
||||
|
@ -1175,7 +1170,7 @@ static int ast_cursor_init(struct drm_device *dev)
|
|||
|
||||
static void ast_cursor_fini(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
size_t i;
|
||||
struct drm_gem_vram_object *gbo;
|
||||
|
||||
|
@ -1188,7 +1183,7 @@ static void ast_cursor_fini(struct drm_device *dev)
|
|||
|
||||
int ast_mode_init(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
int ret;
|
||||
|
||||
memset(&ast->primary_plane, 0, sizeof(ast->primary_plane));
|
||||
|
@ -1198,7 +1193,7 @@ int ast_mode_init(struct drm_device *dev)
|
|||
ARRAY_SIZE(ast_primary_plane_formats),
|
||||
NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
DRM_ERROR("ast: drm_universal_plane_init() failed: %d\n", ret);
|
||||
drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_plane_helper_add(&ast->primary_plane,
|
||||
|
@ -1210,7 +1205,7 @@ int ast_mode_init(struct drm_device *dev)
|
|||
ARRAY_SIZE(ast_cursor_plane_formats),
|
||||
NULL, DRM_PLANE_TYPE_CURSOR, NULL);
|
||||
if (ret) {
|
||||
DRM_ERROR("drm_universal_plane_failed(): %d\n", ret);
|
||||
drm_err(dev, "drm_universal_plane_failed(): %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_plane_helper_add(&ast->cursor_plane,
|
||||
|
@ -1232,7 +1227,7 @@ void ast_mode_fini(struct drm_device *dev)
|
|||
static int get_clock(void *i2c_priv)
|
||||
{
|
||||
struct ast_i2c_chan *i2c = i2c_priv;
|
||||
struct ast_private *ast = i2c->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(i2c->dev);
|
||||
uint32_t val, val2, count, pass;
|
||||
|
||||
count = 0;
|
||||
|
@ -1254,7 +1249,7 @@ static int get_clock(void *i2c_priv)
|
|||
static int get_data(void *i2c_priv)
|
||||
{
|
||||
struct ast_i2c_chan *i2c = i2c_priv;
|
||||
struct ast_private *ast = i2c->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(i2c->dev);
|
||||
uint32_t val, val2, count, pass;
|
||||
|
||||
count = 0;
|
||||
|
@ -1276,7 +1271,7 @@ static int get_data(void *i2c_priv)
|
|||
static void set_clock(void *i2c_priv, int clock)
|
||||
{
|
||||
struct ast_i2c_chan *i2c = i2c_priv;
|
||||
struct ast_private *ast = i2c->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(i2c->dev);
|
||||
int i;
|
||||
u8 ujcrb7, jtemp;
|
||||
|
||||
|
@ -1292,7 +1287,7 @@ static void set_clock(void *i2c_priv, int clock)
|
|||
static void set_data(void *i2c_priv, int data)
|
||||
{
|
||||
struct ast_i2c_chan *i2c = i2c_priv;
|
||||
struct ast_private *ast = i2c->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(i2c->dev);
|
||||
int i;
|
||||
u8 ujcrb7, jtemp;
|
||||
|
||||
|
@ -1332,7 +1327,7 @@ static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
|
|||
i2c->bit.getscl = get_clock;
|
||||
ret = i2c_bit_add_bus(&i2c->adapter);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to register bit i2c\n");
|
||||
drm_err(dev, "Failed to register bit i2c\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
|
@ -1440,7 +1435,7 @@ static int ast_cursor_move(struct drm_crtc *crtc,
|
|||
int x, int y)
|
||||
{
|
||||
struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
|
||||
struct ast_private *ast = crtc->dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(crtc->dev);
|
||||
struct drm_gem_vram_object *gbo;
|
||||
int x_offset, y_offset;
|
||||
u8 *dst, *sig;
|
||||
|
|
|
@ -39,7 +39,7 @@ static void ast_post_chip_2500(struct drm_device *dev);
|
|||
|
||||
void ast_enable_vga(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
|
||||
ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01);
|
||||
ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01);
|
||||
|
@ -47,7 +47,7 @@ void ast_enable_vga(struct drm_device *dev)
|
|||
|
||||
void ast_enable_mmio(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
|
||||
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
|
||||
}
|
||||
|
@ -55,16 +55,12 @@ void ast_enable_mmio(struct drm_device *dev)
|
|||
|
||||
bool ast_is_vga_enabled(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u8 ch;
|
||||
|
||||
if (ast->chip == AST1180) {
|
||||
/* TODO 1180 */
|
||||
} else {
|
||||
ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
|
||||
return !!(ch & 0x01);
|
||||
}
|
||||
return false;
|
||||
ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
|
||||
|
||||
return !!(ch & 0x01);
|
||||
}
|
||||
|
||||
static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
|
||||
|
@ -74,7 +70,7 @@ static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
|
|||
static void
|
||||
ast_set_def_ext_reg(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u8 i, index, reg;
|
||||
const u8 *ext_reg_info;
|
||||
|
||||
|
@ -276,7 +272,7 @@ static void cbrdlli_ast2150(struct ast_private *ast, int busw)
|
|||
|
||||
static void ast_init_dram_reg(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u8 j;
|
||||
u32 data, temp, i;
|
||||
const struct ast_dramstruct *dram_reg_info;
|
||||
|
@ -370,7 +366,7 @@ static void ast_init_dram_reg(struct drm_device *dev)
|
|||
void ast_post_gpu(struct drm_device *dev)
|
||||
{
|
||||
u32 reg;
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
|
||||
pci_read_config_dword(ast->dev->pdev, 0x04, ®);
|
||||
reg |= 0x3;
|
||||
|
@ -1600,7 +1596,7 @@ static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
|
|||
|
||||
static void ast_post_chip_2300(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
struct ast2300_dram_param param;
|
||||
u32 temp;
|
||||
u8 reg;
|
||||
|
@ -2032,7 +2028,7 @@ static bool ast_dram_init_2500(struct ast_private *ast)
|
|||
|
||||
void ast_post_chip_2500(struct drm_device *dev)
|
||||
{
|
||||
struct ast_private *ast = dev->dev_private;
|
||||
struct ast_private *ast = to_ast_private(dev);
|
||||
u32 temp;
|
||||
u8 reg;
|
||||
|
||||
|
@ -2071,7 +2067,7 @@ void ast_post_chip_2500(struct drm_device *dev)
|
|||
}
|
||||
|
||||
if (!ast_dram_init_2500(ast))
|
||||
DRM_ERROR("DRAM init failed !\n");
|
||||
drm_err(dev, "DRAM init failed !\n");
|
||||
|
||||
temp = ast_mindwm(ast, 0x1e6e2040);
|
||||
ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
|
||||
|
|
|
@ -44,7 +44,7 @@ int ast_mm_init(struct ast_private *ast)
|
|||
ast->vram_size);
|
||||
if (IS_ERR(vmm)) {
|
||||
ret = PTR_ERR(vmm);
|
||||
DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
|
||||
drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,16 +29,21 @@ static void bochs_plane_update(struct bochs_device *bochs,
|
|||
struct drm_plane_state *state)
|
||||
{
|
||||
struct drm_gem_vram_object *gbo;
|
||||
s64 gpu_addr;
|
||||
|
||||
if (!state->fb || !bochs->stride)
|
||||
return;
|
||||
|
||||
gbo = drm_gem_vram_of_gem(state->fb->obj[0]);
|
||||
gpu_addr = drm_gem_vram_offset(gbo);
|
||||
if (WARN_ON_ONCE(gpu_addr < 0))
|
||||
return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
|
||||
|
||||
bochs_hw_setbase(bochs,
|
||||
state->crtc_x,
|
||||
state->crtc_y,
|
||||
state->fb->pitches[0],
|
||||
state->fb->offsets[0] + gbo->bo.offset);
|
||||
state->fb->offsets[0] + gpu_addr);
|
||||
bochs_hw_setformat(bochs, state->fb->format);
|
||||
}
|
||||
|
||||
|
|
|
@ -443,9 +443,14 @@ static void adv7511_hpd_work(struct work_struct *work)
|
|||
|
||||
if (adv7511->connector.status != status) {
|
||||
adv7511->connector.status = status;
|
||||
if (status == connector_status_disconnected)
|
||||
cec_phys_addr_invalidate(adv7511->cec_adap);
|
||||
drm_kms_helper_hotplug_event(adv7511->connector.dev);
|
||||
|
||||
if (adv7511->connector.dev) {
|
||||
if (status == connector_status_disconnected)
|
||||
cec_phys_addr_invalidate(adv7511->cec_adap);
|
||||
drm_kms_helper_hotplug_event(adv7511->connector.dev);
|
||||
} else {
|
||||
drm_bridge_hpd_notify(&adv7511->bridge, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,11 +594,10 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
|
|||
* ADV75xx helpers
|
||||
*/
|
||||
|
||||
static int adv7511_get_modes(struct adv7511 *adv7511,
|
||||
struct drm_connector *connector)
|
||||
static struct edid *adv7511_get_edid(struct adv7511 *adv7511,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
unsigned int count;
|
||||
|
||||
/* Reading the EDID only works if the device is powered */
|
||||
if (!adv7511->powered) {
|
||||
|
@ -612,15 +616,25 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
|
|||
if (!adv7511->powered)
|
||||
__adv7511_power_off(adv7511);
|
||||
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
count = drm_add_edid_modes(connector, edid);
|
||||
|
||||
adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
|
||||
drm_detect_hdmi_monitor(edid));
|
||||
|
||||
cec_s_phys_addr_from_edid(adv7511->cec_adap, edid);
|
||||
|
||||
return edid;
|
||||
}
|
||||
|
||||
static int adv7511_get_modes(struct adv7511 *adv7511,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
unsigned int count;
|
||||
|
||||
edid = adv7511_get_edid(adv7511, connector);
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
count = drm_add_edid_modes(connector, edid);
|
||||
|
||||
kfree(edid);
|
||||
|
||||
return count;
|
||||
|
@ -652,7 +666,8 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
|
|||
if (status == connector_status_connected && hpd && adv7511->powered) {
|
||||
regcache_mark_dirty(adv7511->regmap);
|
||||
adv7511_power_on(adv7511);
|
||||
adv7511_get_modes(adv7511, connector);
|
||||
if (connector)
|
||||
adv7511_get_modes(adv7511, connector);
|
||||
if (adv7511->status == connector_status_connected)
|
||||
status = connector_status_disconnected;
|
||||
} else {
|
||||
|
@ -774,7 +789,10 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
|
|||
adv7511->f_tmds = mode->clock;
|
||||
}
|
||||
|
||||
/* Connector funcs */
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DRM Connector Operations
|
||||
*/
|
||||
|
||||
static struct adv7511 *connector_to_adv7511(struct drm_connector *connector)
|
||||
{
|
||||
return container_of(connector, struct adv7511, connector);
|
||||
|
@ -818,7 +836,40 @@ static const struct drm_connector_funcs adv7511_connector_funcs = {
|
|||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
};
|
||||
|
||||
/* Bridge funcs */
|
||||
static int adv7511_connector_init(struct adv7511 *adv)
|
||||
{
|
||||
struct drm_bridge *bridge = &adv->bridge;
|
||||
int ret;
|
||||
|
||||
if (!bridge->encoder) {
|
||||
DRM_ERROR("Parent encoder object not found");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (adv->i2c_main->irq)
|
||||
adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||
else
|
||||
adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
|
||||
DRM_CONNECTOR_POLL_DISCONNECT;
|
||||
|
||||
ret = drm_connector_init(bridge->dev, &adv->connector,
|
||||
&adv7511_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA);
|
||||
if (ret < 0) {
|
||||
DRM_ERROR("Failed to initialize connector with drm\n");
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(&adv->connector,
|
||||
&adv7511_connector_helper_funcs);
|
||||
drm_connector_attach_encoder(&adv->connector, bridge->encoder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DRM Bridge Operations
|
||||
*/
|
||||
|
||||
static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge)
|
||||
{
|
||||
return container_of(bridge, struct adv7511, bridge);
|
||||
|
@ -851,35 +902,14 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge,
|
|||
enum drm_bridge_attach_flags flags)
|
||||
{
|
||||
struct adv7511 *adv = bridge_to_adv7511(bridge);
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
|
||||
DRM_ERROR("Fix bridge driver to make connector optional!");
|
||||
return -EINVAL;
|
||||
if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
|
||||
ret = adv7511_connector_init(adv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!bridge->encoder) {
|
||||
DRM_ERROR("Parent encoder object not found");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (adv->i2c_main->irq)
|
||||
adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||
else
|
||||
adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
|
||||
DRM_CONNECTOR_POLL_DISCONNECT;
|
||||
|
||||
ret = drm_connector_init(bridge->dev, &adv->connector,
|
||||
&adv7511_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to initialize connector with drm\n");
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(&adv->connector,
|
||||
&adv7511_connector_helper_funcs);
|
||||
drm_connector_attach_encoder(&adv->connector, bridge->encoder);
|
||||
|
||||
if (adv->type == ADV7533 || adv->type == ADV7535)
|
||||
ret = adv7533_attach_dsi(adv);
|
||||
|
||||
|
@ -890,11 +920,38 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static enum drm_connector_status adv7511_bridge_detect(struct drm_bridge *bridge)
|
||||
{
|
||||
struct adv7511 *adv = bridge_to_adv7511(bridge);
|
||||
|
||||
return adv7511_detect(adv, NULL);
|
||||
}
|
||||
|
||||
static struct edid *adv7511_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct adv7511 *adv = bridge_to_adv7511(bridge);
|
||||
|
||||
return adv7511_get_edid(adv, connector);
|
||||
}
|
||||
|
||||
static void adv7511_bridge_hpd_notify(struct drm_bridge *bridge,
|
||||
enum drm_connector_status status)
|
||||
{
|
||||
struct adv7511 *adv = bridge_to_adv7511(bridge);
|
||||
|
||||
if (status == connector_status_disconnected)
|
||||
cec_phys_addr_invalidate(adv->cec_adap);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs adv7511_bridge_funcs = {
|
||||
.enable = adv7511_bridge_enable,
|
||||
.disable = adv7511_bridge_disable,
|
||||
.mode_set = adv7511_bridge_mode_set,
|
||||
.attach = adv7511_bridge_attach,
|
||||
.detect = adv7511_bridge_detect,
|
||||
.get_edid = adv7511_bridge_get_edid,
|
||||
.hpd_notify = adv7511_bridge_hpd_notify,
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
@ -1223,6 +1280,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
|
|||
goto err_unregister_cec;
|
||||
|
||||
adv7511->bridge.funcs = &adv7511_bridge_funcs;
|
||||
adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
|
||||
| DRM_BRIDGE_OP_HPD;
|
||||
adv7511->bridge.of_node = dev->of_node;
|
||||
|
||||
drm_bridge_add(&adv7511->bridge);
|
||||
|
|
|
@ -588,6 +588,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
anx6345_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
|
@ -944,6 +944,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
|
@ -663,6 +663,7 @@ static int cdns_dsi_bridge_attach(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
|
||||
|
|
|
@ -317,6 +317,7 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge)
|
|||
}
|
||||
|
||||
static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock > 165000)
|
||||
|
|
|
@ -818,6 +818,7 @@ static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct nwl_dsi *dsi = bridge_to_dsi(bridge);
|
||||
|
|
|
@ -873,6 +873,7 @@ static inline struct sii9234 *bridge_to_sii9234(struct drm_bridge *bridge)
|
|||
}
|
||||
|
||||
static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock > MHL1_MAX_CLK)
|
||||
|
|
|
@ -2244,6 +2244,7 @@ static int sii8620_is_packing_required(struct sii8620 *ctx,
|
|||
}
|
||||
|
||||
static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct sii8620 *ctx = bridge_to_sii8620(bridge);
|
||||
|
|
|
@ -29,7 +29,7 @@ struct simple_bridge {
|
|||
|
||||
const struct simple_bridge_info *info;
|
||||
|
||||
struct i2c_adapter *ddc;
|
||||
struct drm_bridge *next_bridge;
|
||||
struct regulator *vdd;
|
||||
struct gpio_desc *enable;
|
||||
};
|
||||
|
@ -52,29 +52,28 @@ static int simple_bridge_get_modes(struct drm_connector *connector)
|
|||
struct edid *edid;
|
||||
int ret;
|
||||
|
||||
if (!sbridge->ddc)
|
||||
goto fallback;
|
||||
if (sbridge->next_bridge->ops & DRM_BRIDGE_OP_EDID) {
|
||||
edid = drm_bridge_get_edid(sbridge->next_bridge, connector);
|
||||
if (!edid)
|
||||
DRM_INFO("EDID read failed. Fallback to standard modes\n");
|
||||
} else {
|
||||
edid = NULL;
|
||||
}
|
||||
|
||||
edid = drm_get_edid(connector, sbridge->ddc);
|
||||
if (!edid) {
|
||||
DRM_INFO("EDID readout failed, falling back to standard modes\n");
|
||||
goto fallback;
|
||||
/*
|
||||
* In case we cannot retrieve the EDIDs (missing or broken DDC
|
||||
* bus from the next bridge), fallback on the XGA standards and
|
||||
* prefer a mode pretty much anyone can handle.
|
||||
*/
|
||||
ret = drm_add_modes_noedid(connector, 1920, 1200);
|
||||
drm_set_preferred_mode(connector, 1024, 768);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
ret = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
return ret;
|
||||
|
||||
fallback:
|
||||
/*
|
||||
* In case we cannot retrieve the EDIDs (broken or missing i2c
|
||||
* bus), fallback on the XGA standards
|
||||
*/
|
||||
ret = drm_add_modes_noedid(connector, 1920, 1200);
|
||||
|
||||
/* And prefer a mode pretty much anyone can handle */
|
||||
drm_set_preferred_mode(connector, 1024, 768);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -88,16 +87,7 @@ simple_bridge_connector_detect(struct drm_connector *connector, bool force)
|
|||
{
|
||||
struct simple_bridge *sbridge = drm_connector_to_simple_bridge(connector);
|
||||
|
||||
/*
|
||||
* Even if we have an I2C bus, we can't assume that the cable
|
||||
* is disconnected if drm_probe_ddc fails. Some cables don't
|
||||
* wire the DDC pins, or the I2C bus might not be working at
|
||||
* all.
|
||||
*/
|
||||
if (sbridge->ddc && drm_probe_ddc(sbridge->ddc))
|
||||
return connector_status_connected;
|
||||
|
||||
return connector_status_unknown;
|
||||
return drm_bridge_detect(sbridge->next_bridge);
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs simple_bridge_con_funcs = {
|
||||
|
@ -115,10 +105,13 @@ static int simple_bridge_attach(struct drm_bridge *bridge,
|
|||
struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge);
|
||||
int ret;
|
||||
|
||||
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
|
||||
DRM_ERROR("Fix bridge driver to make connector optional!");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = drm_bridge_attach(bridge->encoder, sbridge->next_bridge, bridge,
|
||||
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
|
||||
return 0;
|
||||
|
||||
if (!bridge->encoder) {
|
||||
DRM_ERROR("Missing encoder\n");
|
||||
|
@ -130,14 +123,13 @@ static int simple_bridge_attach(struct drm_bridge *bridge,
|
|||
ret = drm_connector_init_with_ddc(bridge->dev, &sbridge->connector,
|
||||
&simple_bridge_con_funcs,
|
||||
sbridge->info->connector_type,
|
||||
sbridge->ddc);
|
||||
sbridge->next_bridge->ddc);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to initialize connector\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_connector_attach_encoder(&sbridge->connector,
|
||||
bridge->encoder);
|
||||
drm_connector_attach_encoder(&sbridge->connector, bridge->encoder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -172,31 +164,10 @@ static const struct drm_bridge_funcs simple_bridge_bridge_funcs = {
|
|||
.disable = simple_bridge_disable,
|
||||
};
|
||||
|
||||
static struct i2c_adapter *simple_bridge_retrieve_ddc(struct device *dev)
|
||||
{
|
||||
struct device_node *phandle, *remote;
|
||||
struct i2c_adapter *ddc;
|
||||
|
||||
remote = of_graph_get_remote_node(dev->of_node, 1, -1);
|
||||
if (!remote)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0);
|
||||
of_node_put(remote);
|
||||
if (!phandle)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
ddc = of_get_i2c_adapter_by_node(phandle);
|
||||
of_node_put(phandle);
|
||||
if (!ddc)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
return ddc;
|
||||
}
|
||||
|
||||
static int simple_bridge_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct simple_bridge *sbridge;
|
||||
struct device_node *remote;
|
||||
|
||||
sbridge = devm_kzalloc(&pdev->dev, sizeof(*sbridge), GFP_KERNEL);
|
||||
if (!sbridge)
|
||||
|
@ -205,6 +176,20 @@ static int simple_bridge_probe(struct platform_device *pdev)
|
|||
|
||||
sbridge->info = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
/* Get the next bridge in the pipeline. */
|
||||
remote = of_graph_get_remote_node(pdev->dev.of_node, 1, -1);
|
||||
if (!remote)
|
||||
return -EINVAL;
|
||||
|
||||
sbridge->next_bridge = of_drm_find_bridge(remote);
|
||||
of_node_put(remote);
|
||||
|
||||
if (!sbridge->next_bridge) {
|
||||
dev_dbg(&pdev->dev, "Next bridge not found, deferring probe\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
/* Get the regulator and GPIO resources. */
|
||||
sbridge->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
|
||||
if (IS_ERR(sbridge->vdd)) {
|
||||
int ret = PTR_ERR(sbridge->vdd);
|
||||
|
@ -222,18 +207,7 @@ static int simple_bridge_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(sbridge->enable);
|
||||
}
|
||||
|
||||
sbridge->ddc = simple_bridge_retrieve_ddc(&pdev->dev);
|
||||
if (IS_ERR(sbridge->ddc)) {
|
||||
if (PTR_ERR(sbridge->ddc) == -ENODEV) {
|
||||
dev_dbg(&pdev->dev,
|
||||
"No i2c bus specified. Disabling EDID readout\n");
|
||||
sbridge->ddc = NULL;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n");
|
||||
return PTR_ERR(sbridge->ddc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register the bridge. */
|
||||
sbridge->bridge.funcs = &simple_bridge_bridge_funcs;
|
||||
sbridge->bridge.of_node = pdev->dev.of_node;
|
||||
sbridge->bridge.timings = sbridge->info->timings;
|
||||
|
@ -249,9 +223,6 @@ static int simple_bridge_remove(struct platform_device *pdev)
|
|||
|
||||
drm_bridge_remove(&sbridge->bridge);
|
||||
|
||||
if (sbridge->ddc)
|
||||
i2c_put_adapter(sbridge->ddc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -181,6 +181,7 @@ struct dw_hdmi {
|
|||
|
||||
struct mutex mutex; /* for state below and previous_mode */
|
||||
enum drm_connector_force force; /* mutex-protected force state */
|
||||
struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
|
||||
bool disabled; /* DRM has disabled our bridge */
|
||||
bool bridge_is_on; /* indicates the bridge is on */
|
||||
bool rxsense; /* rxsense state */
|
||||
|
@ -1241,10 +1242,9 @@ void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
|
|||
EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
|
||||
|
||||
/* Filter out invalid setups to avoid configuring SCDC and scrambling */
|
||||
static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi)
|
||||
static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
|
||||
const struct drm_display_info *display)
|
||||
{
|
||||
struct drm_display_info *display = &hdmi->connector.display_info;
|
||||
|
||||
/* Completely disable SCDC support for older controllers */
|
||||
if (hdmi->version < 0x200a)
|
||||
return false;
|
||||
|
@ -1282,12 +1282,13 @@ static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi)
|
|||
* helper should called right before enabling the TMDS Clock and Data in
|
||||
* the PHY configuration callback.
|
||||
*/
|
||||
void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi)
|
||||
void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi,
|
||||
const struct drm_display_info *display)
|
||||
{
|
||||
unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
|
||||
|
||||
/* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
|
||||
if (dw_hdmi_support_scdc(hdmi)) {
|
||||
if (dw_hdmi_support_scdc(hdmi, display)) {
|
||||
if (mtmdsclock > HDMI14_MAX_TMDSCLK)
|
||||
drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1);
|
||||
else
|
||||
|
@ -1490,7 +1491,8 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_phy_configure(struct dw_hdmi *hdmi)
|
||||
static int hdmi_phy_configure(struct dw_hdmi *hdmi,
|
||||
const struct drm_display_info *display)
|
||||
{
|
||||
const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
|
||||
const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
|
||||
|
@ -1500,7 +1502,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
|
|||
|
||||
dw_hdmi_phy_power_off(hdmi);
|
||||
|
||||
dw_hdmi_set_high_tmds_clock_ratio(hdmi);
|
||||
dw_hdmi_set_high_tmds_clock_ratio(hdmi, display);
|
||||
|
||||
/* Leave low power consumption mode by asserting SVSRET. */
|
||||
if (phy->has_svsret)
|
||||
|
@ -1514,7 +1516,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
|
|||
|
||||
/* Write to the PHY as configured by the platform */
|
||||
if (pdata->configure_phy)
|
||||
ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
|
||||
ret = pdata->configure_phy(hdmi, pdata->priv_data, mpixelclock);
|
||||
else
|
||||
ret = phy->configure(hdmi, pdata, mpixelclock);
|
||||
if (ret) {
|
||||
|
@ -1531,7 +1533,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
|
|||
}
|
||||
|
||||
static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
||||
struct drm_display_mode *mode)
|
||||
const struct drm_display_info *display,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
|
@ -1540,7 +1543,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
|||
dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
|
||||
dw_hdmi_phy_sel_interface_control(hdmi, 0);
|
||||
|
||||
ret = hdmi_phy_configure(hdmi);
|
||||
ret = hdmi_phy_configure(hdmi, display);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1628,18 +1631,18 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
|
|||
HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
|
||||
}
|
||||
|
||||
static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
||||
static void hdmi_config_AVI(struct dw_hdmi *hdmi,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct hdmi_avi_infoframe frame;
|
||||
u8 val;
|
||||
|
||||
/* Initialise info frame from DRM mode */
|
||||
drm_hdmi_avi_infoframe_from_display_mode(&frame,
|
||||
&hdmi->connector, mode);
|
||||
drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
|
||||
|
||||
if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
|
||||
drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector,
|
||||
mode,
|
||||
drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode,
|
||||
hdmi->hdmi_data.rgb_limited_range ?
|
||||
HDMI_QUANTIZATION_RANGE_LIMITED :
|
||||
HDMI_QUANTIZATION_RANGE_FULL);
|
||||
|
@ -1756,14 +1759,14 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
|||
}
|
||||
|
||||
static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
|
||||
struct drm_display_mode *mode)
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct hdmi_vendor_infoframe frame;
|
||||
u8 buffer[10];
|
||||
ssize_t err;
|
||||
|
||||
err = drm_hdmi_vendor_infoframe_from_display_mode(&frame,
|
||||
&hdmi->connector,
|
||||
err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, connector,
|
||||
mode);
|
||||
if (err < 0)
|
||||
/*
|
||||
|
@ -1809,9 +1812,10 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
|
|||
HDMI_FC_DATAUTO0_VSD_MASK);
|
||||
}
|
||||
|
||||
static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
|
||||
static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi,
|
||||
const struct drm_connector *connector)
|
||||
{
|
||||
const struct drm_connector_state *conn_state = hdmi->connector.state;
|
||||
const struct drm_connector_state *conn_state = connector->state;
|
||||
struct hdmi_drm_infoframe frame;
|
||||
u8 buffer[30];
|
||||
ssize_t err;
|
||||
|
@ -1845,10 +1849,11 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
|
|||
}
|
||||
|
||||
static void hdmi_av_composer(struct dw_hdmi *hdmi,
|
||||
const struct drm_display_info *display,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
u8 inv_val, bytes;
|
||||
struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi;
|
||||
const struct drm_hdmi_info *hdmi_info = &display->hdmi;
|
||||
struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
|
||||
int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
|
||||
unsigned int vdisplay, hdisplay;
|
||||
|
@ -1881,7 +1886,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
|
|||
|
||||
/* Set up HDMI_FC_INVIDCONF */
|
||||
inv_val = (hdmi->hdmi_data.hdcp_enable ||
|
||||
(dw_hdmi_support_scdc(hdmi) &&
|
||||
(dw_hdmi_support_scdc(hdmi, display) &&
|
||||
(vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
|
||||
hdmi_info->scdc.scrambling.low_rates)) ?
|
||||
HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
|
||||
|
@ -1949,7 +1954,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
|
|||
}
|
||||
|
||||
/* Scrambling Control */
|
||||
if (dw_hdmi_support_scdc(hdmi)) {
|
||||
if (dw_hdmi_support_scdc(hdmi, display)) {
|
||||
if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
|
||||
hdmi_info->scdc.scrambling.low_rates) {
|
||||
/*
|
||||
|
@ -2112,7 +2117,9 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
|
|||
HDMI_IH_MUTE_FC_STAT2);
|
||||
}
|
||||
|
||||
static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
||||
static int dw_hdmi_setup(struct dw_hdmi *hdmi,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -2137,10 +2144,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
|||
hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
|
||||
hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
|
||||
|
||||
if (hdmi->plat_data->input_bus_format)
|
||||
hdmi->hdmi_data.enc_in_bus_format =
|
||||
hdmi->plat_data->input_bus_format;
|
||||
else if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
|
||||
if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
|
||||
hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
|
||||
/* TOFIX: Get input encoding from plat data or fallback to none */
|
||||
|
@ -2162,10 +2166,12 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
|||
hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
|
||||
|
||||
/* HDMI Initialization Step B.1 */
|
||||
hdmi_av_composer(hdmi, mode);
|
||||
hdmi_av_composer(hdmi, &connector->display_info, mode);
|
||||
|
||||
/* HDMI Initializateion Step B.2 */
|
||||
ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
|
||||
ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
|
||||
&connector->display_info,
|
||||
&hdmi->previous_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
hdmi->phy.enabled = true;
|
||||
|
@ -2186,9 +2192,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
|||
dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
|
||||
|
||||
/* HDMI Initialization Step F - Configure AVI InfoFrame */
|
||||
hdmi_config_AVI(hdmi, mode);
|
||||
hdmi_config_vendor_specific_infoframe(hdmi, mode);
|
||||
hdmi_config_drm_infoframe(hdmi);
|
||||
hdmi_config_AVI(hdmi, connector, mode);
|
||||
hdmi_config_vendor_specific_infoframe(hdmi, connector, mode);
|
||||
hdmi_config_drm_infoframe(hdmi, connector);
|
||||
} else {
|
||||
dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
|
||||
}
|
||||
|
@ -2257,7 +2263,12 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
|
|||
static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
|
||||
{
|
||||
hdmi->bridge_is_on = true;
|
||||
dw_hdmi_setup(hdmi, &hdmi->previous_mode);
|
||||
|
||||
/*
|
||||
* The curr_conn field is guaranteed to be valid here, as this function
|
||||
* is only be called when !hdmi->disabled.
|
||||
*/
|
||||
dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
|
||||
}
|
||||
|
||||
static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
|
||||
|
@ -2312,11 +2323,8 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
|
|||
hdmi->rxsense);
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
|
||||
static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
|
||||
{
|
||||
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
|
||||
connector);
|
||||
enum drm_connector_status result;
|
||||
|
||||
mutex_lock(&hdmi->mutex);
|
||||
|
@ -2339,30 +2347,56 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
|
|||
return result;
|
||||
}
|
||||
|
||||
static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
|
||||
if (!hdmi->ddc)
|
||||
return NULL;
|
||||
|
||||
edid = drm_get_edid(connector, hdmi->ddc);
|
||||
if (!edid) {
|
||||
dev_dbg(hdmi->dev, "failed to get edid\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
|
||||
edid->width_cm, edid->height_cm);
|
||||
|
||||
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
|
||||
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
|
||||
|
||||
return edid;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DRM Connector Operations
|
||||
*/
|
||||
|
||||
static enum drm_connector_status
|
||||
dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
|
||||
connector);
|
||||
return dw_hdmi_detect(hdmi);
|
||||
}
|
||||
|
||||
static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
|
||||
connector);
|
||||
struct edid *edid;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (!hdmi->ddc)
|
||||
edid = dw_hdmi_get_edid(hdmi, connector);
|
||||
if (!edid)
|
||||
return 0;
|
||||
|
||||
edid = drm_get_edid(connector, hdmi->ddc);
|
||||
if (edid) {
|
||||
dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
|
||||
edid->width_cm, edid->height_cm);
|
||||
|
||||
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
|
||||
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
|
||||
ret = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
} else {
|
||||
dev_dbg(hdmi->dev, "failed to get edid\n");
|
||||
}
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
|
||||
ret = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2433,6 +2467,59 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
|
|||
.atomic_check = dw_hdmi_connector_atomic_check,
|
||||
};
|
||||
|
||||
static int dw_hdmi_connector_create(struct dw_hdmi *hdmi)
|
||||
{
|
||||
struct drm_connector *connector = &hdmi->connector;
|
||||
struct cec_connector_info conn_info;
|
||||
struct cec_notifier *notifier;
|
||||
|
||||
if (hdmi->version >= 0x200a)
|
||||
connector->ycbcr_420_allowed =
|
||||
hdmi->plat_data->ycbcr_420_allowed;
|
||||
else
|
||||
connector->ycbcr_420_allowed = false;
|
||||
|
||||
connector->interlace_allowed = 1;
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
||||
drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
|
||||
|
||||
drm_connector_init_with_ddc(hdmi->bridge.dev, connector,
|
||||
&dw_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA,
|
||||
hdmi->ddc);
|
||||
|
||||
/*
|
||||
* drm_connector_attach_max_bpc_property() requires the
|
||||
* connector to have a state.
|
||||
*/
|
||||
drm_atomic_helper_connector_reset(connector);
|
||||
|
||||
drm_connector_attach_max_bpc_property(connector, 8, 16);
|
||||
|
||||
if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
|
||||
drm_object_attach_property(&connector->base,
|
||||
connector->dev->mode_config.hdr_output_metadata_property, 0);
|
||||
|
||||
drm_connector_attach_encoder(connector, hdmi->bridge.encoder);
|
||||
|
||||
cec_fill_conn_info_from_drm(&conn_info, connector);
|
||||
|
||||
notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
|
||||
if (!notifier)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&hdmi->cec_notifier_mutex);
|
||||
hdmi->cec_notifier = notifier;
|
||||
mutex_unlock(&hdmi->cec_notifier_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DRM Bridge Operations
|
||||
*/
|
||||
|
||||
/*
|
||||
* Possible output formats :
|
||||
* - MEDIA_BUS_FMT_UYYVYY16_0_5X48,
|
||||
|
@ -2708,51 +2795,11 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
|
|||
enum drm_bridge_attach_flags flags)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
struct drm_encoder *encoder = bridge->encoder;
|
||||
struct drm_connector *connector = &hdmi->connector;
|
||||
struct cec_connector_info conn_info;
|
||||
struct cec_notifier *notifier;
|
||||
|
||||
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
|
||||
DRM_ERROR("Fix bridge driver to make connector optional!");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
|
||||
return 0;
|
||||
|
||||
connector->interlace_allowed = 1;
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
||||
drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
|
||||
|
||||
drm_connector_init_with_ddc(bridge->dev, connector,
|
||||
&dw_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA,
|
||||
hdmi->ddc);
|
||||
|
||||
/*
|
||||
* drm_connector_attach_max_bpc_property() requires the
|
||||
* connector to have a state.
|
||||
*/
|
||||
drm_atomic_helper_connector_reset(connector);
|
||||
|
||||
drm_connector_attach_max_bpc_property(connector, 8, 16);
|
||||
|
||||
if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
|
||||
drm_object_attach_property(&connector->base,
|
||||
connector->dev->mode_config.hdr_output_metadata_property, 0);
|
||||
|
||||
drm_connector_attach_encoder(connector, encoder);
|
||||
|
||||
cec_fill_conn_info_from_drm(&conn_info, connector);
|
||||
|
||||
notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
|
||||
if (!notifier)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&hdmi->cec_notifier_mutex);
|
||||
hdmi->cec_notifier = notifier;
|
||||
mutex_unlock(&hdmi->cec_notifier_mutex);
|
||||
|
||||
return 0;
|
||||
return dw_hdmi_connector_create(hdmi);
|
||||
}
|
||||
|
||||
static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
|
||||
|
@ -2767,18 +2814,20 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
|
|||
|
||||
static enum drm_mode_status
|
||||
dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
struct drm_connector *connector = &hdmi->connector;
|
||||
const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
|
||||
enum drm_mode_status mode_status = MODE_OK;
|
||||
|
||||
/* We don't support double-clocked modes */
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
return MODE_BAD;
|
||||
|
||||
if (hdmi->plat_data->mode_valid)
|
||||
mode_status = hdmi->plat_data->mode_valid(connector, mode);
|
||||
if (pdata->mode_valid)
|
||||
mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info,
|
||||
mode);
|
||||
|
||||
return mode_status;
|
||||
}
|
||||
|
@ -2797,28 +2846,52 @@ static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
|
|||
mutex_unlock(&hdmi->mutex);
|
||||
}
|
||||
|
||||
static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
|
||||
static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_state)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
|
||||
mutex_lock(&hdmi->mutex);
|
||||
hdmi->disabled = true;
|
||||
hdmi->curr_conn = NULL;
|
||||
dw_hdmi_update_power(hdmi);
|
||||
dw_hdmi_update_phy_mask(hdmi);
|
||||
mutex_unlock(&hdmi->mutex);
|
||||
}
|
||||
|
||||
static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
|
||||
static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_state)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
struct drm_atomic_state *state = old_state->base.state;
|
||||
struct drm_connector *connector;
|
||||
|
||||
connector = drm_atomic_get_new_connector_for_encoder(state,
|
||||
bridge->encoder);
|
||||
|
||||
mutex_lock(&hdmi->mutex);
|
||||
hdmi->disabled = false;
|
||||
hdmi->curr_conn = connector;
|
||||
dw_hdmi_update_power(hdmi);
|
||||
dw_hdmi_update_phy_mask(hdmi);
|
||||
mutex_unlock(&hdmi->mutex);
|
||||
}
|
||||
|
||||
static enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
|
||||
return dw_hdmi_detect(hdmi);
|
||||
}
|
||||
|
||||
static struct edid *dw_hdmi_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
|
||||
return dw_hdmi_get_edid(hdmi, connector);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
|
@ -2828,12 +2901,18 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
|
|||
.atomic_check = dw_hdmi_bridge_atomic_check,
|
||||
.atomic_get_output_bus_fmts = dw_hdmi_bridge_atomic_get_output_bus_fmts,
|
||||
.atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts,
|
||||
.enable = dw_hdmi_bridge_enable,
|
||||
.disable = dw_hdmi_bridge_disable,
|
||||
.atomic_enable = dw_hdmi_bridge_atomic_enable,
|
||||
.atomic_disable = dw_hdmi_bridge_atomic_disable,
|
||||
.mode_set = dw_hdmi_bridge_mode_set,
|
||||
.mode_valid = dw_hdmi_bridge_mode_valid,
|
||||
.detect = dw_hdmi_bridge_detect,
|
||||
.get_edid = dw_hdmi_bridge_get_edid,
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* IRQ Handling
|
||||
*/
|
||||
|
||||
static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
|
||||
{
|
||||
struct dw_hdmi_i2c *i2c = hdmi->i2c;
|
||||
|
@ -2943,10 +3022,18 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
|
||||
enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
|
||||
? connector_status_connected
|
||||
: connector_status_disconnected;
|
||||
|
||||
dev_dbg(hdmi->dev, "EVENT=%s\n",
|
||||
phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
|
||||
if (hdmi->bridge.dev)
|
||||
status == connector_status_connected ?
|
||||
"plugin" : "plugout");
|
||||
|
||||
if (hdmi->bridge.dev) {
|
||||
drm_helper_hpd_irq_event(hdmi->bridge.dev);
|
||||
drm_bridge_hpd_notify(&hdmi->bridge, status);
|
||||
}
|
||||
}
|
||||
|
||||
hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
|
||||
|
@ -3292,16 +3379,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
|||
|
||||
hdmi->bridge.driver_private = hdmi;
|
||||
hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
|
||||
hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
|
||||
| DRM_BRIDGE_OP_HPD;
|
||||
#ifdef CONFIG_OF
|
||||
hdmi->bridge.of_node = pdev->dev.of_node;
|
||||
#endif
|
||||
|
||||
if (hdmi->version >= 0x200a)
|
||||
hdmi->connector.ycbcr_420_allowed =
|
||||
hdmi->plat_data->ycbcr_420_allowed;
|
||||
else
|
||||
hdmi->connector.ycbcr_420_allowed = false;
|
||||
|
||||
memset(&pdevinfo, 0, sizeof(pdevinfo));
|
||||
pdevinfo.parent = dev;
|
||||
pdevinfo.id = PLATFORM_DEVID_AUTO;
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_of.h>
|
||||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#define HWVER_131 0x31333100 /* IP version 1.31 */
|
||||
|
||||
|
@ -924,6 +923,7 @@ static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
|
|||
|
||||
static enum drm_mode_status
|
||||
dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
|
||||
|
|
|
@ -1306,6 +1306,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
|
|||
}
|
||||
|
||||
static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct tc_data *tc = bridge_to_tc(bridge);
|
||||
|
|
|
@ -529,6 +529,7 @@ static int tc358768_bridge_attach(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
tc358768_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct tc358768_priv *priv = bridge_to_tc358768(bridge);
|
||||
|
|
|
@ -51,6 +51,7 @@ static int thc63_attach(struct drm_bridge *bridge,
|
|||
}
|
||||
|
||||
static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct thc63_dev *thc63 = to_thc63(bridge);
|
||||
|
|
|
@ -51,11 +51,15 @@ static int tfp410_get_modes(struct drm_connector *connector)
|
|||
struct edid *edid;
|
||||
int ret;
|
||||
|
||||
edid = drm_bridge_get_edid(dvi->next_bridge, connector);
|
||||
if (IS_ERR_OR_NULL(edid)) {
|
||||
if (edid != ERR_PTR(-ENOTSUPP))
|
||||
if (dvi->next_bridge->ops & DRM_BRIDGE_OP_EDID) {
|
||||
edid = drm_bridge_get_edid(dvi->next_bridge, connector);
|
||||
if (!edid)
|
||||
DRM_INFO("EDID read failed. Fallback to standard modes\n");
|
||||
} else {
|
||||
edid = NULL;
|
||||
}
|
||||
|
||||
if (!edid) {
|
||||
/*
|
||||
* No EDID, fallback on the XGA standard modes and prefer a mode
|
||||
* pretty much anything can handle.
|
||||
|
@ -188,6 +192,7 @@ static void tfp410_disable(struct drm_bridge *bridge)
|
|||
}
|
||||
|
||||
static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock < 25000)
|
||||
|
@ -220,7 +225,7 @@ static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c)
|
|||
struct device_node *ep;
|
||||
u32 pclk_sample = 0;
|
||||
u32 bus_width = 24;
|
||||
s32 deskew = 0;
|
||||
u32 deskew = 0;
|
||||
|
||||
/* Start with defaults. */
|
||||
*timings = tfp410_default_timings;
|
||||
|
@ -274,12 +279,12 @@ static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c)
|
|||
}
|
||||
|
||||
/* Get the setup and hold time from vendor-specific properties. */
|
||||
of_property_read_u32(dvi->dev->of_node, "ti,deskew", (u32 *)&deskew);
|
||||
if (deskew < -4 || deskew > 3)
|
||||
of_property_read_u32(dvi->dev->of_node, "ti,deskew", &deskew);
|
||||
if (deskew > 7)
|
||||
return -EINVAL;
|
||||
|
||||
timings->setup_time_ps = min(0, 1200 - 350 * deskew);
|
||||
timings->hold_time_ps = min(0, 1300 + 350 * deskew);
|
||||
timings->setup_time_ps = 1200 - 350 * ((s32)deskew - 4);
|
||||
timings->hold_time_ps = max(0, 1300 + 350 * ((s32)deskew - 4));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -506,7 +506,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
|
|||
}
|
||||
|
||||
bridge = drm_bridge_chain_get_first_bridge(encoder);
|
||||
ret = drm_bridge_chain_mode_valid(bridge, mode);
|
||||
ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info,
|
||||
mode);
|
||||
if (ret != MODE_OK) {
|
||||
DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
|
||||
return ret;
|
||||
|
|
|
@ -377,6 +377,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
|
|||
* drm_bridge_chain_mode_valid - validate the mode against all bridges in the
|
||||
* encoder chain.
|
||||
* @bridge: bridge control structure
|
||||
* @info: display info against which the mode shall be validated
|
||||
* @mode: desired mode to be validated
|
||||
*
|
||||
* Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
|
||||
|
@ -390,6 +391,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
|
|||
*/
|
||||
enum drm_mode_status
|
||||
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
|
@ -404,7 +406,7 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
|
|||
if (!bridge->funcs->mode_valid)
|
||||
continue;
|
||||
|
||||
ret = bridge->funcs->mode_valid(bridge, mode);
|
||||
ret = bridge->funcs->mode_valid(bridge, info, mode);
|
||||
if (ret != MODE_OK)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1086,16 +1088,16 @@ EXPORT_SYMBOL_GPL(drm_bridge_get_modes);
|
|||
*
|
||||
* If the bridge supports output EDID retrieval, as reported by the
|
||||
* DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to
|
||||
* get the EDID and return it. Otherwise return ERR_PTR(-ENOTSUPP).
|
||||
* get the EDID and return it. Otherwise return NULL.
|
||||
*
|
||||
* RETURNS:
|
||||
* The retrieved EDID on success, or an error pointer otherwise.
|
||||
* The retrieved EDID on success, or NULL otherwise.
|
||||
*/
|
||||
struct edid *drm_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
if (!(bridge->ops & DRM_BRIDGE_OP_EDID))
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
return NULL;
|
||||
|
||||
return bridge->funcs->get_edid(bridge, connector);
|
||||
}
|
||||
|
|
|
@ -376,6 +376,24 @@ static ssize_t edid_write(struct file *file, const char __user *ubuf,
|
|||
return (ret) ? ret : len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the min and max vrr vfreq through the connector's debugfs file.
|
||||
* Example usage: cat /sys/kernel/debug/dri/0/DP-1/vrr_range
|
||||
*/
|
||||
static int vrr_range_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_connector *connector = m->private;
|
||||
|
||||
if (connector->status != connector_status_connected)
|
||||
return -ENODEV;
|
||||
|
||||
seq_printf(m, "Min: %u\n", (u8)connector->display_info.monitor_range.min_vfreq);
|
||||
seq_printf(m, "Max: %u\n", (u8)connector->display_info.monitor_range.max_vfreq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(vrr_range);
|
||||
|
||||
static const struct file_operations drm_edid_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = edid_open,
|
||||
|
@ -413,6 +431,10 @@ void drm_debugfs_connector_add(struct drm_connector *connector)
|
|||
/* edid */
|
||||
debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root, connector,
|
||||
&drm_edid_fops);
|
||||
|
||||
/* vrr range */
|
||||
debugfs_create_file("vrr_range", S_IRUGO, root, connector,
|
||||
&vrr_range_fops);
|
||||
}
|
||||
|
||||
void drm_debugfs_connector_remove(struct drm_connector *connector)
|
||||
|
|
|
@ -5360,7 +5360,7 @@ void drm_set_preferred_mode(struct drm_connector *connector,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_set_preferred_mode);
|
||||
|
||||
static bool is_hdmi2_sink(struct drm_connector *connector)
|
||||
static bool is_hdmi2_sink(const struct drm_connector *connector)
|
||||
{
|
||||
/*
|
||||
* FIXME: sil-sii8620 doesn't have a connector around when
|
||||
|
@ -5445,7 +5445,7 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
|
||||
|
||||
static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
|
||||
static u8 drm_mode_hdmi_vic(const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
bool has_hdmi_infoframe = connector ?
|
||||
|
@ -5461,7 +5461,7 @@ static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
|
|||
return drm_match_hdmi_mode(mode);
|
||||
}
|
||||
|
||||
static u8 drm_mode_cea_vic(struct drm_connector *connector,
|
||||
static u8 drm_mode_cea_vic(const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
u8 vic;
|
||||
|
@ -5499,7 +5499,7 @@ static u8 drm_mode_cea_vic(struct drm_connector *connector,
|
|||
*/
|
||||
int
|
||||
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
enum hdmi_picture_aspect picture_aspect;
|
||||
|
@ -5646,7 +5646,7 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorspace);
|
|||
*/
|
||||
void
|
||||
drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode,
|
||||
enum hdmi_quantization_range rgb_quant_range)
|
||||
{
|
||||
|
@ -5750,7 +5750,7 @@ s3d_structure_from_display_mode(const struct drm_display_mode *mode)
|
|||
*/
|
||||
int
|
||||
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -274,6 +274,18 @@ const struct drm_format_info *__drm_format_info(u32 format)
|
|||
{ .format = DRM_FORMAT_YUV420_10BIT, .depth = 0,
|
||||
.num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2,
|
||||
.is_yuv = true },
|
||||
{ .format = DRM_FORMAT_NV15, .depth = 0,
|
||||
.num_planes = 2, .char_per_block = { 5, 5, 0 },
|
||||
.block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
|
||||
.vsub = 2, .is_yuv = true },
|
||||
{ .format = DRM_FORMAT_Q410, .depth = 0,
|
||||
.num_planes = 3, .char_per_block = { 2, 2, 2 },
|
||||
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
|
||||
.vsub = 0, .is_yuv = true },
|
||||
{ .format = DRM_FORMAT_Q401, .depth = 0,
|
||||
.num_planes = 3, .char_per_block = { 2, 2, 2 },
|
||||
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
|
||||
.vsub = 0, .is_yuv = true },
|
||||
};
|
||||
|
||||
unsigned int i;
|
||||
|
|
|
@ -281,6 +281,15 @@ u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_gem_vram_mmap_offset);
|
||||
|
||||
static u64 drm_gem_vram_pg_offset(struct drm_gem_vram_object *gbo)
|
||||
{
|
||||
/* Keep TTM behavior for now, remove when drivers are audited */
|
||||
if (WARN_ON_ONCE(!gbo->bo.mem.mm_node))
|
||||
return 0;
|
||||
|
||||
return gbo->bo.mem.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_gem_vram_offset() - \
|
||||
Returns a GEM VRAM object's offset in video memory
|
||||
|
@ -297,7 +306,7 @@ s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo)
|
|||
{
|
||||
if (WARN_ON_ONCE(!gbo->pin_count))
|
||||
return (s64)-ENODEV;
|
||||
return gbo->bo.offset;
|
||||
return drm_gem_vram_pg_offset(gbo) << PAGE_SHIFT;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_vram_offset);
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
|
|||
bool full;
|
||||
void *tr;
|
||||
|
||||
if (!dbidev->enabled)
|
||||
if (WARN_ON(!fb))
|
||||
return;
|
||||
|
||||
if (!drm_dev_enter(fb->dev, &idx))
|
||||
|
@ -314,6 +314,9 @@ void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
|
|||
struct drm_plane_state *state = pipe->plane.state;
|
||||
struct drm_rect rect;
|
||||
|
||||
if (!pipe->crtc.state->active)
|
||||
return;
|
||||
|
||||
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
|
||||
mipi_dbi_fb_dirty(state->fb, &rect);
|
||||
}
|
||||
|
@ -325,9 +328,8 @@ EXPORT_SYMBOL(mipi_dbi_pipe_update);
|
|||
* @crtc_state: CRTC state
|
||||
* @plane_state: Plane state
|
||||
*
|
||||
* This function sets &mipi_dbi->enabled, flushes the whole framebuffer and
|
||||
* enables the backlight. Drivers can use this in their
|
||||
* &drm_simple_display_pipe_funcs->enable callback.
|
||||
* Flushes the whole framebuffer and enables the backlight. Drivers can use this
|
||||
* in their &drm_simple_display_pipe_funcs->enable callback.
|
||||
*
|
||||
* Note: Drivers which don't use mipi_dbi_pipe_update() because they have custom
|
||||
* framebuffer flushing, can't use this function since they both use the same
|
||||
|
@ -349,7 +351,6 @@ void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
|
|||
if (!drm_dev_enter(&dbidev->drm, &idx))
|
||||
return;
|
||||
|
||||
dbidev->enabled = true;
|
||||
mipi_dbi_fb_dirty(fb, &rect);
|
||||
backlight_enable(dbidev->backlight);
|
||||
|
||||
|
@ -390,13 +391,8 @@ void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)
|
|||
{
|
||||
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
|
||||
|
||||
if (!dbidev->enabled)
|
||||
return;
|
||||
|
||||
DRM_DEBUG_KMS("\n");
|
||||
|
||||
dbidev->enabled = false;
|
||||
|
||||
if (dbidev->backlight)
|
||||
backlight_disable(dbidev->backlight);
|
||||
else
|
||||
|
|
|
@ -305,11 +305,6 @@ static inline struct drm_mm_node *rb_hole_addr_to_node(struct rb_node *rb)
|
|||
return rb_entry_safe(rb, struct drm_mm_node, rb_hole_addr);
|
||||
}
|
||||
|
||||
static inline u64 rb_hole_size(struct rb_node *rb)
|
||||
{
|
||||
return rb_entry(rb, struct drm_mm_node, rb_hole_size)->hole_size;
|
||||
}
|
||||
|
||||
static struct drm_mm_node *best_hole(struct drm_mm *mm, u64 size)
|
||||
{
|
||||
struct rb_node *rb = mm->holes_size.rb_root.rb_node;
|
||||
|
@ -330,7 +325,12 @@ static struct drm_mm_node *best_hole(struct drm_mm *mm, u64 size)
|
|||
return best;
|
||||
}
|
||||
|
||||
static struct drm_mm_node *find_hole(struct drm_mm *mm, u64 addr)
|
||||
static bool usable_hole_addr(struct rb_node *rb, u64 size)
|
||||
{
|
||||
return rb && rb_hole_addr_to_node(rb)->subtree_max_hole >= size;
|
||||
}
|
||||
|
||||
static struct drm_mm_node *find_hole_addr(struct drm_mm *mm, u64 addr, u64 size)
|
||||
{
|
||||
struct rb_node *rb = mm->holes_addr.rb_node;
|
||||
struct drm_mm_node *node = NULL;
|
||||
|
@ -338,6 +338,9 @@ static struct drm_mm_node *find_hole(struct drm_mm *mm, u64 addr)
|
|||
while (rb) {
|
||||
u64 hole_start;
|
||||
|
||||
if (!usable_hole_addr(rb, size))
|
||||
break;
|
||||
|
||||
node = rb_hole_addr_to_node(rb);
|
||||
hole_start = __drm_mm_hole_node_start(node);
|
||||
|
||||
|
@ -363,10 +366,10 @@ first_hole(struct drm_mm *mm,
|
|||
return best_hole(mm, size);
|
||||
|
||||
case DRM_MM_INSERT_LOW:
|
||||
return find_hole(mm, start);
|
||||
return find_hole_addr(mm, start, size);
|
||||
|
||||
case DRM_MM_INSERT_HIGH:
|
||||
return find_hole(mm, end);
|
||||
return find_hole_addr(mm, end, size);
|
||||
|
||||
case DRM_MM_INSERT_EVICT:
|
||||
return list_first_entry_or_null(&mm->hole_stack,
|
||||
|
@ -376,82 +379,39 @@ first_hole(struct drm_mm *mm,
|
|||
}
|
||||
|
||||
/**
|
||||
* next_hole_high_addr - returns next hole for a DRM_MM_INSERT_HIGH mode request
|
||||
* @entry: previously selected drm_mm_node
|
||||
* @size: size of the a hole needed for the request
|
||||
* DECLARE_NEXT_HOLE_ADDR - macro to declare next hole functions
|
||||
* @name: name of function to declare
|
||||
* @first: first rb member to traverse (either rb_left or rb_right).
|
||||
* @last: last rb member to traverse (either rb_right or rb_left).
|
||||
*
|
||||
* This function will verify whether left subtree of @entry has hole big enough
|
||||
* to fit the requtested size. If so, it will return previous node of @entry or
|
||||
* else it will return parent node of @entry
|
||||
*
|
||||
* It will also skip the complete left subtree if subtree_max_hole of that
|
||||
* subtree is same as the subtree_max_hole of the @entry.
|
||||
*
|
||||
* Returns:
|
||||
* previous node of @entry if left subtree of @entry can serve the request or
|
||||
* else return parent of @entry
|
||||
* This macro declares a function to return the next hole of the addr rb tree.
|
||||
* While traversing the tree we take the searched size into account and only
|
||||
* visit branches with potential big enough holes.
|
||||
*/
|
||||
static struct drm_mm_node *
|
||||
next_hole_high_addr(struct drm_mm_node *entry, u64 size)
|
||||
{
|
||||
struct rb_node *rb_node, *left_rb_node, *parent_rb_node;
|
||||
struct drm_mm_node *left_node;
|
||||
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
rb_node = &entry->rb_hole_addr;
|
||||
if (rb_node->rb_left) {
|
||||
left_rb_node = rb_node->rb_left;
|
||||
parent_rb_node = rb_parent(rb_node);
|
||||
left_node = rb_entry(left_rb_node,
|
||||
struct drm_mm_node, rb_hole_addr);
|
||||
if (left_node->subtree_max_hole < size &&
|
||||
parent_rb_node && parent_rb_node->rb_left != rb_node)
|
||||
return rb_hole_addr_to_node(parent_rb_node);
|
||||
}
|
||||
|
||||
return rb_hole_addr_to_node(rb_prev(rb_node));
|
||||
#define DECLARE_NEXT_HOLE_ADDR(name, first, last) \
|
||||
static struct drm_mm_node *name(struct drm_mm_node *entry, u64 size) \
|
||||
{ \
|
||||
struct rb_node *parent, *node = &entry->rb_hole_addr; \
|
||||
\
|
||||
if (!entry || RB_EMPTY_NODE(node)) \
|
||||
return NULL; \
|
||||
\
|
||||
if (usable_hole_addr(node->first, size)) { \
|
||||
node = node->first; \
|
||||
while (usable_hole_addr(node->last, size)) \
|
||||
node = node->last; \
|
||||
return rb_hole_addr_to_node(node); \
|
||||
} \
|
||||
\
|
||||
while ((parent = rb_parent(node)) && node == parent->first) \
|
||||
node = parent; \
|
||||
\
|
||||
return rb_hole_addr_to_node(parent); \
|
||||
}
|
||||
|
||||
/**
|
||||
* next_hole_low_addr - returns next hole for a DRM_MM_INSERT_LOW mode request
|
||||
* @entry: previously selected drm_mm_node
|
||||
* @size: size of the a hole needed for the request
|
||||
*
|
||||
* This function will verify whether right subtree of @entry has hole big enough
|
||||
* to fit the requtested size. If so, it will return next node of @entry or
|
||||
* else it will return parent node of @entry
|
||||
*
|
||||
* It will also skip the complete right subtree if subtree_max_hole of that
|
||||
* subtree is same as the subtree_max_hole of the @entry.
|
||||
*
|
||||
* Returns:
|
||||
* next node of @entry if right subtree of @entry can serve the request or
|
||||
* else return parent of @entry
|
||||
*/
|
||||
static struct drm_mm_node *
|
||||
next_hole_low_addr(struct drm_mm_node *entry, u64 size)
|
||||
{
|
||||
struct rb_node *rb_node, *right_rb_node, *parent_rb_node;
|
||||
struct drm_mm_node *right_node;
|
||||
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
rb_node = &entry->rb_hole_addr;
|
||||
if (rb_node->rb_right) {
|
||||
right_rb_node = rb_node->rb_right;
|
||||
parent_rb_node = rb_parent(rb_node);
|
||||
right_node = rb_entry(right_rb_node,
|
||||
struct drm_mm_node, rb_hole_addr);
|
||||
if (right_node->subtree_max_hole < size &&
|
||||
parent_rb_node && parent_rb_node->rb_right != rb_node)
|
||||
return rb_hole_addr_to_node(parent_rb_node);
|
||||
}
|
||||
|
||||
return rb_hole_addr_to_node(rb_next(rb_node));
|
||||
}
|
||||
DECLARE_NEXT_HOLE_ADDR(next_hole_high_addr, rb_left, rb_right)
|
||||
DECLARE_NEXT_HOLE_ADDR(next_hole_low_addr, rb_right, rb_left)
|
||||
|
||||
static struct drm_mm_node *
|
||||
next_hole(struct drm_mm *mm,
|
||||
|
@ -502,7 +462,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
|
|||
return -ENOSPC;
|
||||
|
||||
/* Find the relevant hole to add our node to */
|
||||
hole = find_hole(mm, node->start);
|
||||
hole = find_hole_addr(mm, node->start, 0);
|
||||
if (!hole)
|
||||
return -ENOSPC;
|
||||
|
||||
|
|
|
@ -114,7 +114,9 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
|
|||
}
|
||||
|
||||
bridge = drm_bridge_chain_get_first_bridge(encoder);
|
||||
ret = drm_bridge_chain_mode_valid(bridge, mode);
|
||||
ret = drm_bridge_chain_mode_valid(bridge,
|
||||
&connector->display_info,
|
||||
mode);
|
||||
if (ret != MODE_OK) {
|
||||
/* There is also no point in continuing for crtc check
|
||||
* here. */
|
||||
|
|
|
@ -1379,6 +1379,7 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
|
|||
}
|
||||
|
||||
static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
/* TDA19988 dotclock can go up to 165MHz */
|
||||
|
|
|
@ -145,7 +145,8 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs =
|
|||
};
|
||||
|
||||
static enum drm_mode_status
|
||||
imx6q_hdmi_mode_valid(struct drm_connector *con,
|
||||
imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock < 13500)
|
||||
|
@ -158,7 +159,8 @@ imx6q_hdmi_mode_valid(struct drm_connector *con,
|
|||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
imx6dl_hdmi_mode_valid(struct drm_connector *con,
|
||||
imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock < 13500)
|
||||
|
|
|
@ -297,7 +297,7 @@ static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi,
|
|||
|
||||
/* Setup PHY bandwidth modes */
|
||||
static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
|
||||
struct drm_display_mode *mode)
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct meson_drm *priv = dw_hdmi->priv;
|
||||
unsigned int pixel_clock = mode->clock;
|
||||
|
@ -427,7 +427,8 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
|
|||
}
|
||||
|
||||
static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
||||
struct drm_display_mode *mode)
|
||||
const struct drm_display_info *display,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
|
||||
struct meson_drm *priv = dw_hdmi->priv;
|
||||
|
@ -496,7 +497,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
|||
/* Disable clock, fifo, fifo_wr */
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
|
||||
|
||||
dw_hdmi_set_high_tmds_clock_ratio(hdmi);
|
||||
dw_hdmi_set_high_tmds_clock_ratio(hdmi, display);
|
||||
|
||||
msleep(100);
|
||||
|
||||
|
@ -630,11 +631,13 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
dw_hdmi_mode_valid(struct drm_connector *connector,
|
||||
dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *display_info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct meson_drm *priv = connector->dev->dev_private;
|
||||
bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
|
||||
struct meson_dw_hdmi *dw_hdmi = data;
|
||||
struct meson_drm *priv = dw_hdmi->priv;
|
||||
bool is_hdmi2_sink = display_info->hdmi.scdc.supported;
|
||||
unsigned int phy_freq;
|
||||
unsigned int vclk_freq;
|
||||
unsigned int venc_freq;
|
||||
|
@ -645,10 +648,10 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
|
|||
DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
|
||||
|
||||
/* If sink does not support 540MHz, reject the non-420 HDMI2 modes */
|
||||
if (connector->display_info.max_tmds_clock &&
|
||||
mode->clock > connector->display_info.max_tmds_clock &&
|
||||
!drm_mode_is_420_only(&connector->display_info, mode) &&
|
||||
!drm_mode_is_420_also(&connector->display_info, mode))
|
||||
if (display_info->max_tmds_clock &&
|
||||
mode->clock > display_info->max_tmds_clock &&
|
||||
!drm_mode_is_420_only(display_info, mode) &&
|
||||
!drm_mode_is_420_also(display_info, mode))
|
||||
return MODE_BAD;
|
||||
|
||||
/* Check against non-VIC supported modes */
|
||||
|
@ -665,9 +668,9 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
|
|||
vclk_freq = mode->clock;
|
||||
|
||||
/* For 420, pixel clock is half unlike venc clock */
|
||||
if (drm_mode_is_420_only(&connector->display_info, mode) ||
|
||||
if (drm_mode_is_420_only(display_info, mode) ||
|
||||
(!is_hdmi2_sink &&
|
||||
drm_mode_is_420_also(&connector->display_info, mode)))
|
||||
drm_mode_is_420_also(display_info, mode)))
|
||||
vclk_freq /= 2;
|
||||
|
||||
/* TMDS clock is pixel_clock * 10 */
|
||||
|
@ -682,9 +685,9 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
|
|||
|
||||
/* VENC double pixels for 1080i, 720p and YUV420 modes */
|
||||
if (meson_venc_hdmi_venc_repeat(vic) ||
|
||||
drm_mode_is_420_only(&connector->display_info, mode) ||
|
||||
drm_mode_is_420_only(display_info, mode) ||
|
||||
(!is_hdmi2_sink &&
|
||||
drm_mode_is_420_also(&connector->display_info, mode)))
|
||||
drm_mode_is_420_also(display_info, mode)))
|
||||
venc_freq *= 2;
|
||||
|
||||
vclk_freq = max(venc_freq, hdmi_freq);
|
||||
|
@ -692,7 +695,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
|
|||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
venc_freq /= 2;
|
||||
|
||||
dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
|
||||
dev_dbg(dw_hdmi->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
|
||||
__func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
|
||||
|
||||
return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq);
|
||||
|
@ -1065,6 +1068,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
|
|||
|
||||
/* Bridge / Connector */
|
||||
|
||||
dw_plat_data->priv_data = meson_dw_hdmi;
|
||||
dw_plat_data->mode_valid = dw_hdmi_mode_valid;
|
||||
dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops;
|
||||
dw_plat_data->phy_name = "meson_dw_hdmi_phy";
|
||||
|
|
|
@ -434,6 +434,7 @@ static int dpi_bridge_attach(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
dpi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
|
||||
|
|
|
@ -140,6 +140,7 @@ static int sdi_bridge_attach(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
sdi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
|
||||
|
|
|
@ -548,6 +548,7 @@ static int venc_bridge_attach(struct drm_bridge *bridge,
|
|||
|
||||
static enum drm_mode_status
|
||||
venc_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
switch (venc_get_videomode(mode)) {
|
||||
|
|
|
@ -479,7 +479,6 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi)
|
|||
if (ret < 0) {
|
||||
dev_err(dev, "mipi_dsi_attach failed. Is host ready?\n");
|
||||
drm_panel_remove(&ctx->panel);
|
||||
backlight_device_unregister(ctx->bl_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -687,6 +687,7 @@ static const struct panel_desc auo_b101aw03 = {
|
|||
.width = 223,
|
||||
.height = 125,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing auo_b101ean01_timing = {
|
||||
|
@ -1296,6 +1297,60 @@ static const struct panel_desc cdtech_s043wq26h_ct7 = {
|
|||
.bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
|
||||
};
|
||||
|
||||
/* S070PWS19HP-FC21 2017/04/22 */
|
||||
static const struct drm_display_mode cdtech_s070pws19hp_fc21_mode = {
|
||||
.clock = 51200,
|
||||
.hdisplay = 1024,
|
||||
.hsync_start = 1024 + 160,
|
||||
.hsync_end = 1024 + 160 + 20,
|
||||
.htotal = 1024 + 160 + 20 + 140,
|
||||
.vdisplay = 600,
|
||||
.vsync_start = 600 + 12,
|
||||
.vsync_end = 600 + 12 + 3,
|
||||
.vtotal = 600 + 12 + 3 + 20,
|
||||
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
|
||||
};
|
||||
|
||||
static const struct panel_desc cdtech_s070pws19hp_fc21 = {
|
||||
.modes = &cdtech_s070pws19hp_fc21_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 6,
|
||||
.size = {
|
||||
.width = 154,
|
||||
.height = 86,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
|
||||
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
|
||||
.connector_type = DRM_MODE_CONNECTOR_DPI,
|
||||
};
|
||||
|
||||
/* S070SWV29HG-DC44 2017/09/21 */
|
||||
static const struct drm_display_mode cdtech_s070swv29hg_dc44_mode = {
|
||||
.clock = 33300,
|
||||
.hdisplay = 800,
|
||||
.hsync_start = 800 + 210,
|
||||
.hsync_end = 800 + 210 + 2,
|
||||
.htotal = 800 + 210 + 2 + 44,
|
||||
.vdisplay = 480,
|
||||
.vsync_start = 480 + 22,
|
||||
.vsync_end = 480 + 22 + 2,
|
||||
.vtotal = 480 + 22 + 2 + 21,
|
||||
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
|
||||
};
|
||||
|
||||
static const struct panel_desc cdtech_s070swv29hg_dc44 = {
|
||||
.modes = &cdtech_s070swv29hg_dc44_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 6,
|
||||
.size = {
|
||||
.width = 154,
|
||||
.height = 86,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
|
||||
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
|
||||
.connector_type = DRM_MODE_CONNECTOR_DPI,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode cdtech_s070wv95_ct16_mode = {
|
||||
.clock = 35000,
|
||||
.hdisplay = 800,
|
||||
|
@ -1340,6 +1395,7 @@ static const struct panel_desc chunghwa_claa070wp03xg = {
|
|||
.width = 94,
|
||||
.height = 150,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
|
||||
|
@ -1362,6 +1418,7 @@ static const struct panel_desc chunghwa_claa101wa01a = {
|
|||
.width = 220,
|
||||
.height = 120,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode chunghwa_claa101wb01_mode = {
|
||||
|
@ -1384,6 +1441,7 @@ static const struct panel_desc chunghwa_claa101wb01 = {
|
|||
.width = 223,
|
||||
.height = 125,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode dataimage_scf0700c48ggu18_mode = {
|
||||
|
@ -1573,6 +1631,7 @@ static const struct panel_desc edt_et057090dhu = {
|
|||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
|
||||
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode edt_etm0700g0dh6_mode = {
|
||||
|
@ -2055,6 +2114,7 @@ static const struct panel_desc innolux_n156bge_l21 = {
|
|||
.width = 344,
|
||||
.height = 193,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode innolux_p120zdg_bf1_mode = {
|
||||
|
@ -3001,6 +3061,7 @@ static const struct panel_desc samsung_ltn101nt05 = {
|
|||
.width = 223,
|
||||
.height = 125,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode samsung_ltn140at29_301_mode = {
|
||||
|
@ -3326,6 +3387,18 @@ static const struct panel_desc tianma_tm070jdhg30 = {
|
|||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct panel_desc tianma_tm070jvhg33 = {
|
||||
.timings = &tianma_tm070jdhg30_timing,
|
||||
.num_timings = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 150,
|
||||
.height = 94,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct display_timing tianma_tm070rvhg71_timing = {
|
||||
.pixelclock = { 27700000, 29200000, 39600000 },
|
||||
.hactive = { 800, 800, 800 },
|
||||
|
@ -3674,6 +3747,12 @@ static const struct of_device_id platform_of_match[] = {
|
|||
}, {
|
||||
.compatible = "cdtech,s043wq26h-ct7",
|
||||
.data = &cdtech_s043wq26h_ct7,
|
||||
}, {
|
||||
.compatible = "cdtech,s070pws19hp-fc21",
|
||||
.data = &cdtech_s070pws19hp_fc21,
|
||||
}, {
|
||||
.compatible = "cdtech,s070swv29hg-dc44",
|
||||
.data = &cdtech_s070swv29hg_dc44,
|
||||
}, {
|
||||
.compatible = "cdtech,s070wv95-ct16",
|
||||
.data = &cdtech_s070wv95_ct16,
|
||||
|
@ -3923,6 +4002,9 @@ static const struct of_device_id platform_of_match[] = {
|
|||
}, {
|
||||
.compatible = "tianma,tm070jdhg30",
|
||||
.data = &tianma_tm070jdhg30,
|
||||
}, {
|
||||
.compatible = "tianma,tm070jvhg33",
|
||||
.data = &tianma_tm070jvhg33,
|
||||
}, {
|
||||
.compatible = "tianma,tm070rvhg71",
|
||||
.data = &tianma_tm070rvhg71,
|
||||
|
|
|
@ -134,7 +134,6 @@ struct qxl_memslot {
|
|||
uint64_t start_phys_addr;
|
||||
uint64_t size;
|
||||
uint64_t high_bits;
|
||||
uint64_t gpu_offset;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -307,10 +306,9 @@ qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
|
|||
(bo->tbo.mem.mem_type == TTM_PL_VRAM)
|
||||
? &qdev->main_slot : &qdev->surfaces_slot;
|
||||
|
||||
WARN_ON_ONCE((bo->tbo.offset & slot->gpu_offset) != slot->gpu_offset);
|
||||
/* TODO - need to hold one of the locks to read bo->tbo.mem.start */
|
||||
|
||||
/* TODO - need to hold one of the locks to read tbo.offset */
|
||||
return slot->high_bits | (bo->tbo.offset - slot->gpu_offset + offset);
|
||||
return slot->high_bits | ((bo->tbo.mem.start << PAGE_SHIFT) + offset);
|
||||
}
|
||||
|
||||
/* qxl_display.c */
|
||||
|
|
|
@ -87,11 +87,10 @@ static void setup_slot(struct qxl_device *qdev,
|
|||
high_bits <<= (64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits));
|
||||
slot->high_bits = high_bits;
|
||||
|
||||
DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx, gpu_offset 0x%lx\n",
|
||||
DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx\n",
|
||||
slot->index, slot->name,
|
||||
(unsigned long)slot->start_phys_addr,
|
||||
(unsigned long)slot->size,
|
||||
(unsigned long)slot->gpu_offset);
|
||||
(unsigned long)slot->size);
|
||||
}
|
||||
|
||||
void qxl_reinit_memslots(struct qxl_device *qdev)
|
||||
|
|
|
@ -48,11 +48,6 @@ static inline void qxl_bo_unreserve(struct qxl_bo *bo)
|
|||
ttm_bo_unreserve(&bo->tbo);
|
||||
}
|
||||
|
||||
static inline u64 qxl_bo_gpu_offset(struct qxl_bo *bo)
|
||||
{
|
||||
return bo->tbo.offset;
|
||||
}
|
||||
|
||||
static inline unsigned long qxl_bo_size(struct qxl_bo *bo)
|
||||
{
|
||||
return bo->tbo.num_pages << PAGE_SHIFT;
|
||||
|
|
|
@ -51,11 +51,6 @@ static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev)
|
|||
static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
||||
struct ttm_mem_type_manager *man)
|
||||
{
|
||||
struct qxl_device *qdev = qxl_get_qdev(bdev);
|
||||
unsigned int gpu_offset_shift =
|
||||
64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits + 8);
|
||||
struct qxl_memslot *slot;
|
||||
|
||||
switch (type) {
|
||||
case TTM_PL_SYSTEM:
|
||||
/* System memory */
|
||||
|
@ -66,11 +61,7 @@ static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
|||
case TTM_PL_VRAM:
|
||||
case TTM_PL_PRIV:
|
||||
/* "On-card" video ram */
|
||||
slot = (type == TTM_PL_VRAM) ?
|
||||
&qdev->main_slot : &qdev->surfaces_slot;
|
||||
slot->gpu_offset = (uint64_t)type << gpu_offset_shift;
|
||||
man->func = &ttm_bo_manager_func;
|
||||
man->gpu_offset = slot->gpu_offset;
|
||||
man->flags = TTM_MEMTYPE_FLAG_FIXED |
|
||||
TTM_MEMTYPE_FLAG_MAPPABLE;
|
||||
man->available_caching = TTM_PL_MASK_CACHING;
|
||||
|
|
|
@ -2828,6 +2828,7 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size
|
|||
extern void radeon_program_register_sequence(struct radeon_device *rdev,
|
||||
const u32 *registers,
|
||||
const u32 array_size);
|
||||
struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev);
|
||||
|
||||
/*
|
||||
* vm
|
||||
|
|
|
@ -90,7 +90,21 @@ static inline void radeon_bo_unreserve(struct radeon_bo *bo)
|
|||
*/
|
||||
static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo)
|
||||
{
|
||||
return bo->tbo.offset;
|
||||
struct radeon_device *rdev;
|
||||
u64 start = 0;
|
||||
|
||||
rdev = radeon_get_rdev(bo->tbo.bdev);
|
||||
|
||||
switch (bo->tbo.mem.mem_type) {
|
||||
case TTM_PL_TT:
|
||||
start = rdev->mc.gtt_start;
|
||||
break;
|
||||
case TTM_PL_VRAM:
|
||||
start = rdev->mc.vram_start;
|
||||
break;
|
||||
}
|
||||
|
||||
return (bo->tbo.mem.start << PAGE_SHIFT) + start;
|
||||
}
|
||||
|
||||
static inline unsigned long radeon_bo_size(struct radeon_bo *bo)
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
|
||||
static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
|
||||
|
||||
static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
|
||||
struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
|
||||
{
|
||||
struct radeon_mman *mman;
|
||||
struct radeon_device *rdev;
|
||||
|
@ -82,7 +82,6 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
|||
break;
|
||||
case TTM_PL_TT:
|
||||
man->func = &ttm_bo_manager_func;
|
||||
man->gpu_offset = rdev->mc.gtt_start;
|
||||
man->available_caching = TTM_PL_MASK_CACHING;
|
||||
man->default_caching = TTM_PL_FLAG_CACHED;
|
||||
man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
|
||||
|
@ -104,7 +103,6 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
|||
case TTM_PL_VRAM:
|
||||
/* "On-card" video ram */
|
||||
man->func = &ttm_bo_manager_func;
|
||||
man->gpu_offset = rdev->mc.vram_start;
|
||||
man->flags = TTM_MEMTYPE_FLAG_FIXED |
|
||||
TTM_MEMTYPE_FLAG_MAPPABLE;
|
||||
man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
|
||||
|
|
|
@ -38,7 +38,8 @@ static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = {
|
|||
};
|
||||
|
||||
static enum drm_mode_status
|
||||
rcar_hdmi_mode_valid(struct drm_connector *connector,
|
||||
rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
/*
|
||||
|
@ -51,8 +52,7 @@ rcar_hdmi_mode_valid(struct drm_connector *connector,
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi,
|
||||
const struct dw_hdmi_plat_data *pdata,
|
||||
static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data,
|
||||
unsigned long mpixelclock)
|
||||
{
|
||||
const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params;
|
||||
|
|
|
@ -220,7 +220,8 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
|
|||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
|
||||
dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
|
||||
|
@ -311,7 +312,8 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun
|
|||
};
|
||||
|
||||
static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
|
||||
struct drm_display_mode *mode)
|
||||
const struct drm_display_info *display,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
|
||||
|
||||
|
|
|
@ -1041,13 +1041,12 @@ static int prepare_igt_frag(struct drm_mm *mm,
|
|||
{
|
||||
unsigned int size = 4096;
|
||||
unsigned int i;
|
||||
u64 ret = -EINVAL;
|
||||
|
||||
for (i = 0; i < num_insert; i++) {
|
||||
if (!expect_insert(mm, &nodes[i], size, 0, i,
|
||||
mode) != 0) {
|
||||
pr_err("%s insert failed\n", mode->name);
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1057,8 +1056,7 @@ static int prepare_igt_frag(struct drm_mm *mm,
|
|||
drm_mm_remove_node(&nodes[i]);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1070,21 +1068,16 @@ static u64 get_insert_time(struct drm_mm *mm,
|
|||
unsigned int size = 8192;
|
||||
ktime_t start;
|
||||
unsigned int i;
|
||||
u64 ret = -EINVAL;
|
||||
|
||||
start = ktime_get();
|
||||
for (i = 0; i < num_insert; i++) {
|
||||
if (!expect_insert(mm, &nodes[i], size, 0, i, mode) != 0) {
|
||||
pr_err("%s insert failed\n", mode->name);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ktime_to_ns(ktime_sub(ktime_get(), start));
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
return ktime_to_ns(ktime_sub(ktime_get(), start));
|
||||
}
|
||||
|
||||
static int igt_frag(void *ignored)
|
||||
|
@ -1119,17 +1112,17 @@ static int igt_frag(void *ignored)
|
|||
continue;
|
||||
|
||||
ret = prepare_igt_frag(&mm, nodes, insert_size, mode);
|
||||
if (!ret)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
insert_time1 = get_insert_time(&mm, insert_size,
|
||||
nodes + insert_size, mode);
|
||||
if (insert_time1 < 0)
|
||||
if (insert_time1 == 0)
|
||||
goto err;
|
||||
|
||||
insert_time2 = get_insert_time(&mm, (insert_size * 2),
|
||||
nodes + insert_size * 2, mode);
|
||||
if (insert_time2 < 0)
|
||||
if (insert_time2 == 0)
|
||||
goto err;
|
||||
|
||||
pr_info("%s fragmented insert of %u and %u insertions took %llu and %llu nsecs\n",
|
||||
|
@ -1981,16 +1974,6 @@ static int __igt_once(unsigned int mode)
|
|||
}
|
||||
|
||||
memset(&node, 0, sizeof(node));
|
||||
err = drm_mm_insert_node_generic(&mm, &node,
|
||||
2, 0, 0,
|
||||
mode | DRM_MM_INSERT_ONCE);
|
||||
if (!err) {
|
||||
pr_err("Unexpectedly inserted the node into the wrong hole: node.start=%llx\n",
|
||||
node.start);
|
||||
err = -EINVAL;
|
||||
goto err_node;
|
||||
}
|
||||
|
||||
err = drm_mm_insert_node_generic(&mm, &node, 2, 0, 0, mode);
|
||||
if (err) {
|
||||
pr_err("Could not insert the node into the available hole!\n");
|
||||
|
@ -1998,7 +1981,6 @@ static int __igt_once(unsigned int mode)
|
|||
goto err_hi;
|
||||
}
|
||||
|
||||
err_node:
|
||||
drm_mm_remove_node(&node);
|
||||
err_hi:
|
||||
drm_mm_remove_node(&rsvd_hi);
|
||||
|
|
|
@ -31,7 +31,8 @@ sun8i_dw_hdmi_encoder_helper_funcs = {
|
|||
};
|
||||
|
||||
static enum drm_mode_status
|
||||
sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
|
||||
sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock > 297000)
|
||||
|
@ -41,7 +42,8 @@ sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
|
|||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
|
||||
sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -176,7 +176,8 @@ struct sun8i_hdmi_phy {
|
|||
};
|
||||
|
||||
struct sun8i_dw_hdmi_quirks {
|
||||
enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
|
||||
enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode);
|
||||
unsigned int set_rate : 1;
|
||||
unsigned int use_drm_infoframe : 1;
|
||||
|
|
|
@ -341,7 +341,8 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
|
|||
}
|
||||
|
||||
static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
|
||||
struct drm_display_mode *mode)
|
||||
const struct drm_display_info *display,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
|
||||
u32 val = 0;
|
||||
|
|
|
@ -89,9 +89,6 @@ static void ili9225_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
|
|||
bool full;
|
||||
void *tr;
|
||||
|
||||
if (!dbidev->enabled)
|
||||
return;
|
||||
|
||||
if (!drm_dev_enter(fb->dev, &idx))
|
||||
return;
|
||||
|
||||
|
@ -167,6 +164,9 @@ static void ili9225_pipe_update(struct drm_simple_display_pipe *pipe,
|
|||
struct drm_plane_state *state = pipe->plane.state;
|
||||
struct drm_rect rect;
|
||||
|
||||
if (!pipe->crtc.state->active)
|
||||
return;
|
||||
|
||||
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
|
||||
ili9225_fb_dirty(state->fb, &rect);
|
||||
}
|
||||
|
@ -275,7 +275,6 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
|
|||
|
||||
ili9225_command(dbi, ILI9225_DISPLAY_CONTROL_1, 0x1017);
|
||||
|
||||
dbidev->enabled = true;
|
||||
ili9225_fb_dirty(fb, &rect);
|
||||
out_exit:
|
||||
drm_dev_exit(idx);
|
||||
|
@ -295,16 +294,11 @@ static void ili9225_pipe_disable(struct drm_simple_display_pipe *pipe)
|
|||
* unplug.
|
||||
*/
|
||||
|
||||
if (!dbidev->enabled)
|
||||
return;
|
||||
|
||||
ili9225_command(dbi, ILI9225_DISPLAY_CONTROL_1, 0x0000);
|
||||
msleep(50);
|
||||
ili9225_command(dbi, ILI9225_POWER_CONTROL_2, 0x0007);
|
||||
msleep(50);
|
||||
ili9225_command(dbi, ILI9225_POWER_CONTROL_1, 0x0a02);
|
||||
|
||||
dbidev->enabled = false;
|
||||
}
|
||||
|
||||
static int ili9225_dbi_command(struct mipi_dbi *dbi, u8 *cmd, u8 *par,
|
||||
|
|
|
@ -88,7 +88,6 @@ struct repaper_epd {
|
|||
u8 *line_buffer;
|
||||
void *current_frame;
|
||||
|
||||
bool enabled;
|
||||
bool cleared;
|
||||
bool partial;
|
||||
};
|
||||
|
@ -538,9 +537,6 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
|
|||
int idx, ret = 0;
|
||||
u8 *buf = NULL;
|
||||
|
||||
if (!epd->enabled)
|
||||
return 0;
|
||||
|
||||
if (!drm_dev_enter(fb->dev, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -786,7 +782,6 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
|
|||
*/
|
||||
repaper_write_val(spi, 0x02, 0x04);
|
||||
|
||||
epd->enabled = true;
|
||||
epd->partial = false;
|
||||
out_exit:
|
||||
drm_dev_exit(idx);
|
||||
|
@ -805,13 +800,8 @@ static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
|
|||
* unplug.
|
||||
*/
|
||||
|
||||
if (!epd->enabled)
|
||||
return;
|
||||
|
||||
DRM_DEBUG_DRIVER("\n");
|
||||
|
||||
epd->enabled = false;
|
||||
|
||||
/* Nothing frame */
|
||||
for (line = 0; line < epd->height; line++)
|
||||
repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
|
||||
|
@ -859,6 +849,9 @@ static void repaper_pipe_update(struct drm_simple_display_pipe *pipe,
|
|||
struct drm_plane_state *state = pipe->plane.state;
|
||||
struct drm_rect rect;
|
||||
|
||||
if (!pipe->crtc.state->active)
|
||||
return;
|
||||
|
||||
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
|
||||
repaper_fb_dirty(state->fb);
|
||||
}
|
||||
|
|
|
@ -118,9 +118,6 @@ static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
|
|||
struct mipi_dbi *dbi = &dbidev->dbi;
|
||||
int start, end, idx, ret = 0;
|
||||
|
||||
if (!dbidev->enabled)
|
||||
return;
|
||||
|
||||
if (!drm_dev_enter(fb->dev, &idx))
|
||||
return;
|
||||
|
||||
|
@ -161,6 +158,9 @@ static void st7586_pipe_update(struct drm_simple_display_pipe *pipe,
|
|||
struct drm_plane_state *state = pipe->plane.state;
|
||||
struct drm_rect rect;
|
||||
|
||||
if (!pipe->crtc.state->active)
|
||||
return;
|
||||
|
||||
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
|
||||
st7586_fb_dirty(state->fb, &rect);
|
||||
}
|
||||
|
@ -237,7 +237,6 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
|
|||
|
||||
msleep(100);
|
||||
|
||||
dbidev->enabled = true;
|
||||
st7586_fb_dirty(fb, &rect);
|
||||
|
||||
mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
|
||||
|
@ -258,11 +257,7 @@ static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe)
|
|||
|
||||
DRM_DEBUG_KMS("\n");
|
||||
|
||||
if (!dbidev->enabled)
|
||||
return;
|
||||
|
||||
mipi_dbi_command(&dbidev->dbi, MIPI_DCS_SET_DISPLAY_OFF);
|
||||
dbidev->enabled = false;
|
||||
}
|
||||
|
||||
static const u32 st7586_formats[] = {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <sound/hdmi-codec.h>
|
||||
|
||||
struct drm_connector;
|
||||
struct drm_display_info;
|
||||
struct drm_display_mode;
|
||||
struct drm_encoder;
|
||||
struct dw_hdmi;
|
||||
|
@ -114,7 +114,8 @@ struct dw_hdmi_phy_config {
|
|||
|
||||
struct dw_hdmi_phy_ops {
|
||||
int (*init)(struct dw_hdmi *hdmi, void *data,
|
||||
struct drm_display_mode *mode);
|
||||
const struct drm_display_info *display,
|
||||
const struct drm_display_mode *mode);
|
||||
void (*disable)(struct dw_hdmi *hdmi, void *data);
|
||||
enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
|
||||
void (*update_hpd)(struct dw_hdmi *hdmi, void *data,
|
||||
|
@ -124,13 +125,22 @@ struct dw_hdmi_phy_ops {
|
|||
|
||||
struct dw_hdmi_plat_data {
|
||||
struct regmap *regm;
|
||||
enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode);
|
||||
unsigned long input_bus_format;
|
||||
|
||||
unsigned long input_bus_encoding;
|
||||
bool use_drm_infoframe;
|
||||
bool ycbcr_420_allowed;
|
||||
|
||||
/*
|
||||
* Private data passed to all the .mode_valid() and .configure_phy()
|
||||
* callback functions.
|
||||
*/
|
||||
void *priv_data;
|
||||
|
||||
/* Platform-specific mode validation (optional). */
|
||||
enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode);
|
||||
|
||||
/* Vendor PHY support */
|
||||
const struct dw_hdmi_phy_ops *phy_ops;
|
||||
const char *phy_name;
|
||||
|
@ -141,8 +151,7 @@ struct dw_hdmi_plat_data {
|
|||
const struct dw_hdmi_mpll_config *mpll_cfg;
|
||||
const struct dw_hdmi_curr_ctrl *cur_ctr;
|
||||
const struct dw_hdmi_phy_config *phy_config;
|
||||
int (*configure_phy)(struct dw_hdmi *hdmi,
|
||||
const struct dw_hdmi_plat_data *pdata,
|
||||
int (*configure_phy)(struct dw_hdmi *hdmi, void *data,
|
||||
unsigned long mpixelclock);
|
||||
};
|
||||
|
||||
|
@ -166,7 +175,8 @@ void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status);
|
|||
void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca);
|
||||
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
|
||||
void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
|
||||
void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi);
|
||||
void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi,
|
||||
const struct drm_display_info *display);
|
||||
|
||||
/* PHY configuration */
|
||||
void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
struct drm_bridge;
|
||||
struct drm_bridge_timings;
|
||||
struct drm_connector;
|
||||
struct drm_display_info;
|
||||
struct drm_panel;
|
||||
struct edid;
|
||||
struct i2c_adapter;
|
||||
|
@ -112,6 +113,7 @@ struct drm_bridge_funcs {
|
|||
* drm_mode_status Enum
|
||||
*/
|
||||
enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode);
|
||||
|
||||
/**
|
||||
|
@ -836,6 +838,7 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
|
|||
struct drm_display_mode *adjusted_mode);
|
||||
enum drm_mode_status
|
||||
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode);
|
||||
void drm_bridge_chain_disable(struct drm_bridge *bridge);
|
||||
void drm_bridge_chain_post_disable(struct drm_bridge *bridge);
|
||||
|
|
|
@ -1457,6 +1457,14 @@ drm_dp_alternate_scrambler_reset_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
|
|||
DP_ALTERNATE_SCRAMBLER_RESET_CAP;
|
||||
}
|
||||
|
||||
/* Ignore MSA timing for Adaptive Sync support on DP 1.4 */
|
||||
static inline bool
|
||||
drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
|
||||
{
|
||||
return dpcd[DP_DOWN_STREAM_PORT_COUNT] &
|
||||
DP_MSA_TIMING_PAR_IGNORED;
|
||||
}
|
||||
|
||||
/*
|
||||
* DisplayPort AUX channel
|
||||
*/
|
||||
|
|
|
@ -361,11 +361,11 @@ drm_load_edid_firmware(struct drm_connector *connector)
|
|||
|
||||
int
|
||||
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode);
|
||||
int
|
||||
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode);
|
||||
|
||||
void
|
||||
|
@ -378,7 +378,7 @@ drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame,
|
|||
|
||||
void
|
||||
drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode,
|
||||
enum hdmi_quantization_range rgb_quant_range);
|
||||
|
||||
|
|
|
@ -94,11 +94,6 @@ struct mipi_dbi_dev {
|
|||
*/
|
||||
struct drm_display_mode mode;
|
||||
|
||||
/**
|
||||
* @enabled: Pipeline is enabled
|
||||
*/
|
||||
bool enabled;
|
||||
|
||||
/**
|
||||
* @tx_buf: Buffer used for transfer (copy clip rect area)
|
||||
*/
|
||||
|
|
|
@ -236,6 +236,12 @@ extern "C" {
|
|||
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
|
||||
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
|
||||
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
|
||||
/*
|
||||
* 2 plane YCbCr
|
||||
* index 0 = Y plane, [39:0] Y3:Y2:Y1:Y0 little endian
|
||||
* index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
|
||||
*/
|
||||
#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
|
||||
|
||||
/*
|
||||
* 2 plane YCbCr MSB aligned
|
||||
|
@ -265,6 +271,22 @@ extern "C" {
|
|||
*/
|
||||
#define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */
|
||||
|
||||
/* 3 plane non-subsampled (444) YCbCr
|
||||
* 16 bits per component, but only 10 bits are used and 6 bits are padded
|
||||
* index 0: Y plane, [15:0] Y:x [10:6] little endian
|
||||
* index 1: Cb plane, [15:0] Cb:x [10:6] little endian
|
||||
* index 2: Cr plane, [15:0] Cr:x [10:6] little endian
|
||||
*/
|
||||
#define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0')
|
||||
|
||||
/* 3 plane non-subsampled (444) YCrCb
|
||||
* 16 bits per component, but only 10 bits are used and 6 bits are padded
|
||||
* index 0: Y plane, [15:0] Y:x [10:6] little endian
|
||||
* index 1: Cr plane, [15:0] Cr:x [10:6] little endian
|
||||
* index 2: Cb plane, [15:0] Cb:x [10:6] little endian
|
||||
*/
|
||||
#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1')
|
||||
|
||||
/*
|
||||
* 3 plane YCbCr
|
||||
* index 0: Y plane, [7:0] Y
|
||||
|
@ -892,6 +914,18 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
|
|||
*/
|
||||
#define AFBC_FORMAT_MOD_BCH (1ULL << 11)
|
||||
|
||||
/* AFBC uncompressed storage mode
|
||||
*
|
||||
* Indicates that the buffer is using AFBC uncompressed storage mode.
|
||||
* In this mode all superblock payloads in the buffer use the uncompressed
|
||||
* storage mode, which is usually only used for data which cannot be compressed.
|
||||
* The buffer layout is the same as for AFBC buffers without USM set, this only
|
||||
* affects the storage mode of the individual superblocks. Note that even a
|
||||
* buffer without USM set may use uncompressed storage mode for some or all
|
||||
* superblocks, USM just guarantees it for all.
|
||||
*/
|
||||
#define AFBC_FORMAT_MOD_USM (1ULL << 12)
|
||||
|
||||
/*
|
||||
* Arm 16x16 Block U-Interleaved modifier
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue
Block a user