Commit d5152d35 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2020-03-17' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for 5.7:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
  - dp-mst: Remove register_connector callback, add drm_dp_destroy_connector
  - Changes to scnprintf on multiple instances

Driver Changes:
  - meson: Support for YUV420
  - panel: Support Ortustech COM37H3M, idk-1110wr and idk-2121wr,
           multiple dotclock fixes
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20200317082858.lubmvlmvoprn2tuh@gilmour.lan
parents 71fa42fa 6afe6929
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/advantech,idk-1110wr.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Advantech IDK-1110WR 10.1" WSVGA LVDS Display Panel
maintainers:
- Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
- Thierry Reding <thierry.reding@gmail.com>
allOf:
- $ref: lvds.yaml#
properties:
compatible:
items:
- const: advantech,idk-1110wr
- {} # panel-lvds, but not listed here to avoid false select
data-mapping:
const: jeida-24
width-mm:
const: 223
height-mm:
const: 125
panel-timing: true
port: true
additionalProperties: false
required:
- compatible
examples:
- |+
panel {
compatible = "advantech,idk-1110wr", "panel-lvds";
width-mm = <223>;
height-mm = <125>;
data-mapping = "jeida-24";
panel-timing {
/* 1024x600 @60Hz */
clock-frequency = <51200000>;
hactive = <1024>;
vactive = <600>;
hsync-len = <240>;
hfront-porch = <40>;
hback-porch = <40>;
vsync-len = <10>;
vfront-porch = <15>;
vback-porch = <10>;
};
port {
panel_in: endpoint {
remote-endpoint = <&lvds_encoder>;
};
};
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/advantech,idk-2121wr.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Advantech IDK-2121WR 21.5" Full-HD dual-LVDS panel
maintainers:
- Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
- Thierry Reding <thierry.reding@gmail.com>
description: |
The IDK-2121WR from Advantech is a Full-HD dual-LVDS panel.
A dual-LVDS interface is a dual-link connection with even pixels traveling
on one link, and with odd pixels traveling on the other link.
The panel expects odd pixels on the first port, and even pixels on the
second port, therefore the ports must be marked accordingly (with either
dual-lvds-odd-pixels or dual-lvds-even-pixels).
properties:
compatible:
items:
- const: advantech,idk-2121wr
- {} # panel-lvds, but not listed here to avoid false select
width-mm:
const: 476
height-mm:
const: 268
data-mapping:
const: vesa-24
panel-timing: true
ports:
type: object
properties:
port@0:
type: object
description: The sink for odd pixels.
properties:
reg:
const: 0
dual-lvds-odd-pixels: true
required:
- reg
- dual-lvds-odd-pixels
port@1:
type: object
description: The sink for even pixels.
properties:
reg:
const: 1
dual-lvds-even-pixels: true
required:
- reg
- dual-lvds-even-pixels
additionalProperties: false
required:
- compatible
- width-mm
- height-mm
- data-mapping
- panel-timing
- ports
examples:
- |+
panel-lvds {
compatible = "advantech,idk-2121wr", "panel-lvds";
width-mm = <476>;
height-mm = <268>;
data-mapping = "vesa-24";
panel-timing {
clock-frequency = <148500000>;
hactive = <1920>;
vactive = <1080>;
hsync-len = <44>;
hfront-porch = <88>;
hback-porch = <148>;
vfront-porch = <4>;
vback-porch = <36>;
vsync-len = <5>;
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dual-lvds-odd-pixels;
panel_in0: endpoint {
remote-endpoint = <&lvds0_out>;
};
};
port@1 {
reg = <1>;
dual-lvds-even-pixels;
panel_in1: endpoint {
remote-endpoint = <&lvds1_out>;
};
};
};
};
...
......@@ -34,7 +34,7 @@ additionalProperties: false
examples:
- |
dsi@ff450000 {
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
......
......@@ -34,7 +34,7 @@ additionalProperties: false
examples:
- |
dsi@ff450000 {
dsi {
#address-cells = <1>;
#size-cells = <0>;
reg = <0xff450000 0x1000>;
......
......@@ -40,10 +40,10 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
dsi@a0351000 {
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel {
panel@0 {
compatible = "hydis,hva40wv1", "novatek,nt35510";
reg = <0>;
vdd-supply = <&ab8500_ldo_aux4_reg>;
......
......@@ -39,7 +39,7 @@ required:
examples:
- |
dsi@0 {
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
......
......@@ -48,7 +48,7 @@ additionalProperties: false
examples:
- |
panel@0 {
panel {
compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
label = "osddisplay";
power-supply = <&vcc_supply>;
......
......@@ -50,7 +50,7 @@ required:
examples:
- |
mdss_dsi@fd922800 {
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
......
......@@ -42,7 +42,7 @@ required:
examples:
- |
dsi@0 {
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
......
......@@ -34,7 +34,7 @@ additionalProperties: false
examples:
- |
dsi@ff450000 {
dsi {
#address-cells = <1>;
#size-cells = <0>;
reg = <0xff450000 0x1000>;
......
......@@ -458,15 +458,9 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
drm_connector_put(connector);
}
static void dm_dp_mst_register_connector(struct drm_connector *connector)
{
drm_connector_register(connector);
}
static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
.add_connector = dm_dp_add_mst_connector,
.destroy_connector = dm_dp_destroy_mst_connector,
.register_connector = dm_dp_mst_register_connector
};
void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
......
This diff is collapsed.
......@@ -134,7 +134,7 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
shift, add);
}
/**
/*
* Core function to create a range of memory available for mapping by a
* non-root process.
*
......@@ -398,7 +398,7 @@ struct drm_local_map *drm_legacy_findmap(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_legacy_findmap);
/**
/*
* Ioctl to specify a range of memory that is available for mapping by a
* non-root process.
*
......@@ -499,7 +499,7 @@ int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Remove a map private from list and deallocate resources if the mapping
* isn't in use.
*
......@@ -659,7 +659,7 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data,
return ret;
}
/**
/*
* Cleanup after an error on one of the addbufs() functions.
*
* \param dev DRM device.
......@@ -694,7 +694,7 @@ static void drm_cleanup_buf_error(struct drm_device *dev,
}
#if IS_ENABLED(CONFIG_AGP)
/**
/*
* Add AGP buffers for DMA transfers.
*
* \param dev struct drm_device to which the buffers are to be added.
......@@ -1230,7 +1230,7 @@ static int drm_legacy_addbufs_sg(struct drm_device *dev,
return 0;
}
/**
/*
* Add buffers for DMA transfers (ioctl).
*
* \param inode device inode.
......@@ -1271,7 +1271,7 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data,
return ret;
}
/**
/*
* Get information about the buffer mappings.
*
* This was originally mean for debugging purposes, or by a sophisticated
......@@ -1362,7 +1362,7 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data,
return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf);
}
/**
/*
* Specifies a low and high water mark for buffer allocation
*
* \param inode device inode.
......@@ -1411,7 +1411,7 @@ int drm_legacy_markbufs(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Unreserve the buffers in list, previously reserved using drmDMA.
*
* \param inode device inode.
......@@ -1463,7 +1463,7 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Maps all of the DMA buffers into client-virtual space (ioctl).
*
* \param inode device inode.
......
......@@ -47,7 +47,7 @@ struct drm_ctx_list {
/** \name Context bitmap support */
/*@{*/
/**
/*
* Free a handle from the context bitmap.
*
* \param dev DRM device.
......@@ -68,7 +68,7 @@ void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
mutex_unlock(&dev->struct_mutex);
}
/**
/*
* Context bitmap allocation.
*
* \param dev DRM device.
......@@ -88,7 +88,7 @@ static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
return ret;
}
/**
/*
* Context bitmap initialization.
*
* \param dev DRM device.
......@@ -104,7 +104,7 @@ void drm_legacy_ctxbitmap_init(struct drm_device * dev)
idr_init(&dev->ctx_idr);
}
/**
/*
* Context bitmap cleanup.
*
* \param dev DRM device.
......@@ -163,7 +163,7 @@ void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
/** \name Per Context SAREA Support */
/*@{*/
/**
/*
* Get per-context SAREA.
*
* \param inode device inode.
......@@ -211,7 +211,7 @@ int drm_legacy_getsareactx(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Set per-context SAREA.
*
* \param inode device inode.
......@@ -263,7 +263,7 @@ int drm_legacy_setsareactx(struct drm_device *dev, void *data,
/** \name The actual DRM context handling routines */
/*@{*/
/**
/*
* Switch context.
*
* \param dev DRM device.
......@@ -290,7 +290,7 @@ static int drm_context_switch(struct drm_device * dev, int old, int new)
return 0;
}
/**
/*
* Complete context switch.
*
* \param dev DRM device.
......@@ -318,7 +318,7 @@ static int drm_context_switch_complete(struct drm_device *dev,
return 0;
}
/**
/*
* Reserve contexts.
*
* \param inode device inode.
......@@ -351,7 +351,7 @@ int drm_legacy_resctx(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Add context.
*
* \param inode device inode.
......@@ -404,7 +404,7 @@ int drm_legacy_addctx(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Get context.
*
* \param inode device inode.
......@@ -428,7 +428,7 @@ int drm_legacy_getctx(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Switch context.
*
* \param inode device inode.
......@@ -452,7 +452,7 @@ int drm_legacy_switchctx(struct drm_device *dev, void *data,
return drm_context_switch(dev, dev->last_context, ctx->handle);
}
/**
/*
* New context.
*
* \param inode device inode.
......@@ -478,7 +478,7 @@ int drm_legacy_newctx(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Remove context.
*
* \param inode device inode.
......
......@@ -2063,7 +2063,7 @@ ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,
* sideband messaging as drm_dp_dpcd_write() does for local
* devices via actual AUX CH.
*
* Return: 0 on success, negative error code on failure.
* Return: number of bytes written on success, negative error code on failure.
*/
ssize_t drm_dp_mst_dpcd_write(struct drm_dp_aux *aux,
unsigned int offset, void *buffer, size_t size)
......@@ -2092,7 +2092,10 @@ static int drm_dp_check_mstb_guid(struct drm_dp_mst_branch *mstb, u8 *guid)
}
}
return ret;
if (ret < 16 && ret > 0)
return -EPROTO;
return ret == 16 ? 0 : ret;
}
static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb,
......@@ -2175,7 +2178,7 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,
drm_connector_set_tile_property(port->connector);
}
mgr->cbs->register_connector(port->connector);
drm_connector_register(port->connector);
return;
error:
......@@ -2907,8 +2910,14 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
drm_dp_dump_link_address(reply);
ret = drm_dp_check_mstb_guid(mstb, reply->guid);
if (ret)
if (ret) {
char buf[64];
drm_dp_mst_rad_to_str(mstb->rad, mstb->lct, buf, sizeof(buf));
DRM_ERROR("GUID check on %s failed: %d\n",
buf, ret);
goto out;
}
for (i = 0; i < reply->nports; i++) {
port_mask |= BIT(reply->ports[i].port_number);
......@@ -3428,12 +3437,9 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
drm_dp_queue_down_tx(mgr, txmsg);
ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
if (ret > 0) {
if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
ret = -EIO;
else
ret = 0;
}
if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
ret = -EIO;
kfree(txmsg);
fail_put:
drm_dp_mst_topology_put_mstb(mstb);
......@@ -4667,11 +4673,23 @@ static void drm_dp_tx_work(struct work_struct *work)
mutex_unlock(&mgr->qlock);
}
static inline void drm_dp_destroy_connector(struct drm_dp_mst_port *port)
{
if (!port->connector)
return;
if (port->mgr->cbs->destroy_connector) {
port->mgr->cbs->destroy_connector(port->mgr, port->connector);
} else {
drm_connector_unregister(port->connector);
drm_connector_put(port->connector);
}
}
static inline void
drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
{
if (port->connector)
port->mgr->cbs->destroy_connector(port->mgr, port->connector);
drm_dp_destroy_connector(port);
drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE, port->mcs);
drm_dp_mst_put_port_malloc(port);
......
......@@ -4434,6 +4434,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
if (cea_revision(cea) >= 3) {
int i, start, end;
int sad_count;
if (cea_db_offsets(cea, &start, &end)) {
start = 0;
......@@ -4445,8 +4446,6 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
dbl = cea_db_payload_len(db);
switch (cea_db_tag(db)) {
int sad_count;
case AUDIO_BLOCK:
/* Audio Data Block, contains SADs */
sad_count = min(dbl / 3, 15 - total_sad_count);
......@@ -4938,6 +4937,47 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
}
}
static
void get_monitor_range(struct detailed_timing *timing,
void *info_monitor_range)
{
struct drm_monitor_range_info *monitor_range = info_monitor_range;
const struct detailed_non_pixel *data = &timing->data.other_data;
const struct detailed_data_monitor_range *range = &data->data.range;
if (!is_display_descriptor((const u8 *)timing, EDID_DETAIL_MONITOR_RANGE))
return;
/*
* Check for flag range limits only. If flag == 1 then
* no additional timing information provided.
* Default GTF, GTF Secondary curve and CVT are not
* supported
*/
if (range->flags != DRM_EDID_RANGE_LIMITS_ONLY_FLAG)
return;
monitor_range->min_vfreq = range->min_vfreq;
monitor_range->max_vfreq = range->max_vfreq;
}
static
void drm_get_monitor_range(struct drm_connector *connector,
const struct edid *edid)
{
struct drm_display_info *info = &connector->display_info;
if (!version_greater(edid, 1, 1))
return;
drm_for_each_detailed_block((u8 *)edid, get_monitor_range,
&info->monitor_range);
DRM_DEBUG_KMS("Supported Monitor Refresh rate range is %d Hz - %d Hz\n",
info->monitor_range.min_vfreq,
info->monitor_range.max_vfreq);
}
/* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
* all of the values which would have been set from EDID
*/
......@@ -4960,6 +5000,7 @@ drm_reset_display_info(struct drm_connector *connector)
memset(&info->hdmi, 0, sizeof(info->hdmi));
info->non_desktop = 0;
memset(&info->monitor_range, 0, sizeof(info->monitor_range));
}
u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
......@@ -4975,6 +5016,8 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
drm_get_monitor_range(connector, edid);
DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
if (edid->revision < 3)
......
......@@ -218,7 +218,7 @@ drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
struct drm_device *dev = obj->dev;
bool final = false;
if (WARN_ON(obj->handle_count == 0))
if (WARN_ON(READ_ONCE(obj->handle_count) == 0))
return;
/*
......
......@@ -46,7 +46,7 @@
static int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context);
/**
/*
* Take the heavyweight lock.
*
* \param lock lock pointer.
......@@ -93,7 +93,7 @@ int drm_lock_take(struct drm_lock_data *lock_data,
return 0;
}
/**
/*
* This takes a lock forcibly and hands it to context. Should ONLY be used
* inside *_unlock to give lock to kernel before calling *_dma_schedule.
*
......@@ -150,7 +150,7 @@ static int drm_legacy_lock_free(struct drm_lock_data *lock_data,
return 0;
}
/**
/*
* Lock ioctl.
*
* \param inode device inode.
......@@ -243,7 +243,7 @@ int drm_legacy_lock(struct drm_device *dev, void *data,
return 0;
}
/**
/*
* Unlock ioctl.
*
* \param inode device inode.
......@@ -275,7 +275,7 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, struct drm_file *file_
return 0;
}
/**
/*
* This function returns immediately and takes the hw lock
* with the kernel context if it is free, otherwise it gets the highest priority when and if
* it is eventually released.
......@@ -287,7 +287,6 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, struct drm_file *file_
* This should be sufficient to wait for GPU idle without
* having to worry about starvation.
*/
void drm_legacy_idlelock_take(struct drm_lock_data *lock_data)
{
int ret;
......
......@@ -405,10 +405,10 @@ next_hole(struct drm_mm *mm,
*/
int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
{
u64 end = node->start + node->size;
struct drm_mm_node *hole;
u64 hole_start, hole_end;
u64 adj_start, adj_end;
u64 end;
end = node->start + node->size;
if (unlikely(end <= node->start))
......
......@@ -228,7 +228,7 @@ static ssize_t modes_show(struct device *device,
mutex_lock(&connector->dev->mode_config.mutex);
list_for_each_entry(mode, &connector->modes, head) {
written += snprintf(buf + written, PAGE_SIZE - written, "%s\n",
written += scnprintf(buf + written, PAGE_SIZE - written, "%s\n",
mode->name);
}
mutex_unlock(&connector->dev->mode_config.mutex);
......
......@@ -102,7 +102,7 @@ static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma)
return tmp;
}
/**
/*
* \c fault method for AGP virtual memory.
*
* \param vma virtual memory area.
......@@ -192,7 +192,7 @@ static vm_fault_t drm_vm_fault(struct vm_fault *vmf)
}
#endif
/**
/*
* \c nopage method for shared virtual memory.
*
* \param vma virtual memory area.
......@@ -225,7 +225,7 @@ static vm_fault_t drm_vm_shm_fault(struct vm_fault *vmf)
return 0;
}
/**
/*
* \c close method for shared virtual memory.
*
* \param vma virtual memory area.
......@@ -294,7 +294,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
mutex_unlock(&dev->struct_mutex);
}
/**
/*
* \c fault method for DMA virtual memory.
*
* \param address access address.
......@@ -329,7 +329,7 @@ static vm_fault_t drm_vm_dma_fault(struct vm_fault *vmf)
return 0;
}
/**
/*
* \c fault method for scatter-gather virtual memory.
*
* \param address access address.
......@@ -435,7 +435,7 @@ static void drm_vm_close_locked(struct drm_device *dev,
}
}
/**
/*
* \c close method for all virtual memory types.
*
* \param vma virtual memory area.
......@@ -453,7 +453,7 @@ static void drm_vm_close(struct vm_area_struct *vma)
mutex_unlock(&dev->struct_mutex);
}
/**
/*
* mmap DMA memory.
*
* \param file_priv DRM file private.
......@@ -513,7 +513,7 @@ static resource_size_t drm_core_get_reg_ofs(struct drm_device *dev)
#endif
}
/**
/*
* mmap DMA memory.
*
* \param file_priv DRM file private.
......
......@@ -748,24 +748,8 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
return NULL;
}
static void intel_dp_register_mst_connector(struct drm_connector *connector)
{
drm_connector_register(connector);
}
static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_connector *connector)
{
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name);
drm_connector_unregister(connector);
drm_connector_put(connector);
}
static const struct drm_dp_mst_topology_cbs mst_cbs = {
.add_connector = intel_dp_add_mst_connector,
.register_connector = intel_dp_register_mst_connector,
.destroy_connector = intel_dp_destroy_mst_connector,
};
static struct intel_dp_mst_encoder *
......
This diff is collapsed.
......@@ -354,12 +354,17 @@ enum {
/* 2970 /1 /1 /1 /5 /2 => /1 /1 */
MESON_VCLK_HDMI_297000,
/* 5940 /1 /1 /2 /5 /1 => /1 /1 */
MESON_VCLK_HDMI_594000
MESON_VCLK_HDMI_594000,
/* 2970 /1 /1 /1 /5 /1 => /1 /2 */
MESON_VCLK_HDMI_594000_YUV420,
};
struct meson_vclk_params {
unsigned int pll_freq;
unsigned int phy_freq;
unsigned int vclk_freq;
unsigned int venc_freq;
unsigned int pixel_freq;
unsigned int pll_base_freq;
unsigned int pll_od1;
unsigned int pll_od2;
unsigned int pll_od3;
......@@ -367,8 +372,11 @@ struct meson_vclk_params {
unsigned int vclk_div;
} params[] = {
[MESON_VCLK_HDMI_ENCI_54000] = {
.pll_freq = 4320000,
.phy_freq = 270000,
.vclk_freq = 54000,
.venc_freq = 54000,
.pixel_freq = 54000,
.pll_base_freq = 4320000,
.pll_od1 = 4,
.pll_od2 = 4,
.pll_od3 = 1,
......@@ -376,8 +384,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_DDR_54000] = {
.pixel_freq = 54000,
.pll_base_freq = 4320000,
.pll_freq = 4320000,
.phy_freq = 270000,
.vclk_freq = 54000,
.venc_freq = 54000,
.pixel_freq = 27000,
.pll_od1 = 4,
.pll_od2 = 4,
.pll_od3 = 1,
......@@ -385,8 +396,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_DDR_148500] = {
.pixel_freq = 148500,
.pll_base_freq = 2970000,
.pll_freq = 2970000,
.phy_freq = 742500,
.vclk_freq = 148500,
.venc_freq = 148500,
.pixel_freq = 74250,
.pll_od1 = 4,
.pll_od2 = 1,
.pll_od3 = 1,
......@@ -394,8 +408,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_74250] = {
.pll_freq = 2970000,
.phy_freq = 742500,
.vclk_freq = 74250,
.venc_freq = 74250,
.pixel_freq = 74250,
.pll_base_freq = 2970000,
.pll_od1 = 2,
.pll_od2 = 2,
.pll_od3 = 2,
......@@ -403,8 +420,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_148500] = {
.pll_freq = 2970000,
.phy_freq = 1485000,
.vclk_freq = 148500,
.venc_freq = 148500,
.pixel_freq = 148500,
.pll_base_freq = 2970000,
.pll_od1 = 1,
.pll_od2 = 2,
.pll_od3 = 2,
......@@ -412,8 +432,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_297000] = {
.pll_freq = 5940000,
.phy_freq = 2970000,
.venc_freq = 297000,
.vclk_freq = 297000,
.pixel_freq = 297000,
.pll_base_freq = 5940000,
.pll_od1 = 2,
.pll_od2 = 1,
.pll_od3 = 1,
......@@ -421,14 +444,29 @@ struct meson_vclk_params {
.vclk_div = 2,
},
[MESON_VCLK_HDMI_594000] = {
.pll_freq = 5940000,
.phy_freq = 5940000,
.venc_freq = 594000,
.vclk_freq = 594000,
.pixel_freq = 594000,
.pll_base_freq = 5940000,
.pll_od1 = 1,
.pll_od2 = 1,
.pll_od3 = 2,
.vid_pll_div = VID_PLL_DIV_5,
.vclk_div = 1,
},
[MESON_VCLK_HDMI_594000_YUV420] = {
.pll_freq = 5940000,
.phy_freq = 2970000,
.venc_freq = 594000,
.vclk_freq = 594000,
.pixel_freq = 297000,
.pll_od1 = 2,
.pll_od2 = 1,
.pll_od3 = 1,
.vid_pll_div = VID_PLL_DIV_5,
.vclk_div = 1,
},
{ /* sentinel */ },
};
......@@ -701,6 +739,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
unsigned int od, m, frac, od1, od2, od3;
if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
/* OD2 goes to the PHY, and needs to be *10, so keep OD3=1 */
od3 = 1;
if (od < 4) {
od1 = 2;
......@@ -723,21 +762,28 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
}
enum drm_mode_status
meson_vclk_vic_supported_freq(unsigned int freq)
meson_vclk_vic_supported_freq(unsigned int phy_freq,
unsigned int vclk_freq)
{
int i;
DRM_DEBUG_DRIVER("freq = %d\n", freq);
DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n",
phy_freq, vclk_freq);
for (i = 0 ; params[i].pixel_freq ; ++i) {
DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
i, params[i].pixel_freq,
FREQ_1000_1001(params[i].pixel_freq));
DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
i, params[i].phy_freq,
FREQ_1000_1001(params[i].phy_freq/10)*10);
/* Match strict frequency */
if (freq == params[i].pixel_freq)
if (phy_freq == params[i].phy_freq &&
vclk_freq == params[i].vclk_freq)
return MODE_OK;
/* Match 1000/1001 variant */
if (freq == FREQ_1000_1001(params[i].pixel_freq))
if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
return MODE_OK;
}
......@@ -965,8 +1011,9 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
}
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
unsigned int vclk_freq, unsigned int venc_freq,
unsigned int dac_freq, bool hdmi_use_enci)
unsigned int phy_freq, unsigned int vclk_freq,
unsigned int venc_freq, unsigned int dac_freq,
bool hdmi_use_enci)
{
bool vic_alternate_clock = false;
unsigned int freq;
......@@ -986,7 +1033,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
* - venc_div = 1
* - encp encoder
*/
meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
meson_vclk_set(priv, phy_freq, 0, 0, 0,
VID_PLL_DIV_5, 2, 1, 1, false, false);
return;
}
......@@ -1008,9 +1055,11 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
}
for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
if (vclk_freq == params[freq].pixel_freq ||
vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) {
if (vclk_freq != params[freq].pixel_freq)
if ((phy_freq == params[freq].phy_freq ||
phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
(vclk_freq == params[freq].vclk_freq ||
vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
if (vclk_freq != params[freq].vclk_freq)
vic_alternate_clock = true;
else
vic_alternate_clock = false;
......@@ -1039,7 +1088,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
return;
}
meson_vclk_set(priv, params[freq].pll_base_freq,
meson_vclk_set(priv, params[freq].pll_freq,
params[freq].pll_od1, params[freq].pll_od2,
params[freq].pll_od3, params[freq].vid_pll_div,
params[freq].vclk_div, hdmi_tx_div, venc_div,
......
......@@ -25,10 +25,11 @@ enum {
enum drm_mode_status
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
enum drm_mode_status
meson_vclk_vic_supported_freq(unsigned int freq);
meson_vclk_vic_supported_freq(unsigned int phy_freq, unsigned int vclk_freq);
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
unsigned int vclk_freq, unsigned int venc_freq,
unsigned int dac_freq, bool hdmi_use_enci);
unsigned int phy_freq, unsigned int vclk_freq,
unsigned int venc_freq, unsigned int dac_freq,
bool hdmi_use_enci);
#endif /* __MESON_VCLK_H */
......@@ -946,7 +946,9 @@ bool meson_venc_hdmi_venc_repeat(int vic)
EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
struct drm_display_mode *mode)
unsigned int ycrcb_map,
bool yuv420_mode,
const struct drm_display_mode *mode)
{
union meson_hdmi_venc_mode *vmode = NULL;
union meson_hdmi_venc_mode vmode_dmt;
......@@ -1528,14 +1530,14 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
reg |= VPU_HDMI_INV_VSYNC;
/* Output data format: CbYCr */
reg |= VPU_HDMI_OUTPUT_CBYCR;
/* Output data format */
reg |= ycrcb_map;
/*
* Write rate to the async FIFO between VENC and HDMI.
* One write every 2 wr_clk.
*/
if (venc_repeat)
if (venc_repeat || yuv420_mode)
reg |= VPU_HDMI_WR_RATE(2);
/*
......
......@@ -60,7 +60,9 @@ extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc;
void meson_venci_cvbs_mode_set(struct meson_drm *priv,
struct meson_cvbs_enci_mode *mode);
void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
struct drm_display_mode *mode);
unsigned int ycrcb_map,
bool yuv420_mode,
const struct drm_display_mode *mode);
unsigned int meson_venci_get_field(struct meson_drm *priv);
void meson_venc_enable_vsync(struct meson_drm *priv);
......
......@@ -213,8 +213,10 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder,
meson_venci_cvbs_mode_set(priv, meson_mode->enci);
/* Setup 27MHz vclk2 for ENCI and VDAC */
meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS,
MESON_VCLK_CVBS, MESON_VCLK_CVBS, true);
meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
MESON_VCLK_CVBS, MESON_VCLK_CVBS,
MESON_VCLK_CVBS, MESON_VCLK_CVBS,
true);
}
}
......
......@@ -1256,23 +1256,6 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
}
}
static void
nv50_mstm_destroy_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_connector *connector)
{
struct nv50_mstc *mstc = nv50_mstc(connector);
drm_connector_unregister(&mstc->connector);
drm_connector_put(&mstc->connector);
}
static void
nv50_mstm_register_connector(struct drm_connector *connector)
{
drm_connector_register(connector);
}
static struct drm_connector *
nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_mst_port *port, const char *path)
......@@ -1291,8 +1274,6 @@ nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr *mgr,
static const struct drm_dp_mst_topology_cbs
nv50_mstm = {
.add_connector = nv50_mstm_add_connector,
.register_connector = nv50_mstm_register_connector,
.destroy_connector = nv50_mstm_destroy_connector,
};
void
......
......@@ -540,7 +540,7 @@ static int ili9322_enable(struct drm_panel *panel)
/* Serial RGB modes */
static const struct drm_display_mode srgb_320x240_mode = {
.clock = 2453500,
.clock = 24535,
.hdisplay = 320,
.hsync_start = 320 + 359,
.hsync_end = 320 + 359 + 1,
......@@ -554,7 +554,7 @@ static const struct drm_display_mode srgb_320x240_mode = {
};
static const struct drm_display_mode srgb_360x240_mode = {
.clock = 2700000,
.clock = 27000,
.hdisplay = 360,
.hsync_start = 360 + 35,
.hsync_end = 360 + 35 + 1,
......@@ -569,7 +569,7 @@ static const struct drm_display_mode srgb_360x240_mode = {
/* This is the only mode listed for parallel RGB in the datasheet */
static const struct drm_display_mode prgb_320x240_mode = {
.clock = 6400000,
.clock = 64000,
.hdisplay = 320,
.hsync_start = 320 + 38,
.hsync_end = 320 + 38 + 1,
......@@ -584,7 +584,7 @@ static const struct drm_display_mode prgb_320x240_mode = {
/* YUV modes */
static const struct drm_display_mode yuv_640x320_mode = {
.clock = 2454000,
.clock = 24540,
.hdisplay = 640,
.hsync_start = 640 + 252,
.hsync_end = 640 + 252 + 1,
......@@ -598,7 +598,7 @@ static const struct drm_display_mode yuv_640x320_mode = {
};
static const struct drm_display_mode yuv_720x360_mode = {
.clock = 2700000,
.clock = 27000,
.hdisplay = 720,
.hsync_start = 720 + 252,
.hsync_end = 720 + 252 + 1,
......@@ -613,7 +613,7 @@ static const struct drm_display_mode yuv_720x360_mode = {
/* BT.656 VGA mode, 640x480 */
static const struct drm_display_mode itu_r_bt_656_640_mode = {
.clock = 2454000,
.clock = 24540,
.hdisplay = 640,
.hsync_start = 640 + 3,
.hsync_end = 640 + 3 + 1,
......@@ -628,7 +628,7 @@ static const struct drm_display_mode itu_r_bt_656_640_mode = {
/* BT.656 D1 mode 720x480 */
static const struct drm_display_mode itu_r_bt_656_720_mode = {
.clock = 2700000,
.clock = 27000,
.hdisplay = 720,
.hsync_start = 720 + 3,
.hsync_end = 720 + 3 + 1,
......
......@@ -197,7 +197,7 @@ static int lg4573_enable(struct drm_panel *panel)
}
static const struct drm_display_mode default_mode = {
.clock = 27000,
.clock = 28341,
.hdisplay = 480,
.hsync_start = 480 + 10,
.hsync_end = 480 + 10 + 59,
......
......@@ -1019,7 +1019,7 @@ static const struct nt35510_config nt35510_hydis_hva40wv1 = {
*/
.mode = {
/* The internal pixel clock of the NT35510 is 20 MHz */
.clock = 20000000,
.clock = 20000,
.hdisplay = 480,
.hsync_start = 480 + 2, /* HFP = 2 */
.hsync_end = 480 + 2 + 0, /* HSync = 0 */
......
......@@ -2277,7 +2277,7 @@ static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
};
static const struct drm_display_mode logicpd_type_28_mode = {
.clock = 9000,
.clock = 9107,
.hdisplay = 480,
.hsync_start = 480 + 3,
.hsync_end = 480 + 3 + 42,
......@@ -2617,15 +2617,15 @@ static const struct panel_desc ontat_yx700wv03 = {
};
static const struct drm_display_mode ortustech_com37h3m_mode = {
.clock = 22153,
.clock = 22230,
.hdisplay = 480,
.hsync_start = 480 + 8,
.hsync_end = 480 + 8 + 10,
.htotal = 480 + 8 + 10 + 10,
.hsync_start = 480 + 40,
.hsync_end = 480 + 40 + 10,
.htotal = 480 + 40 + 10 + 40,
.vdisplay = 640,
.vsync_start = 640 + 4,
.vsync_end = 640 + 4 + 3,
.vtotal = 640 + 4 + 3 + 4,
.vsync_end = 640 + 4 + 2,
.vtotal = 640 + 4 + 2 + 4,
.vrefresh = 60,
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
......@@ -2666,6 +2666,7 @@ static const struct panel_desc ortustech_com43h4m85ulc = {
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
.connector_type = DRM_MODE_CONNECTOR_DPI,
};
static const struct drm_display_mode osddisplays_osd070t1718_19ts_mode = {
......
......@@ -48,7 +48,7 @@ struct acx424akp {
};
static const struct drm_display_mode sony_acx424akp_vid_mode = {
.clock = 330000,
.clock = 27234,
.hdisplay = 480,
.hsync_start = 480 + 15,
.hsync_end = 480 + 15 + 0,
......@@ -68,7 +68,7 @@ static const struct drm_display_mode sony_acx424akp_vid_mode = {
* command mode using the maximum HS frequency.
*/
static const struct drm_display_mode sony_acx424akp_cmd_mode = {
.clock = 420160,
.clock = 35478,
.hdisplay = 480,
.hsync_start = 480 + 154,
.hsync_end = 480 + 154 + 16,
......
......@@ -301,25 +301,8 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
return connector;
}
static void radeon_dp_register_mst_connector(struct drm_connector *connector)
{
drm_connector_register(connector);
}
static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_connector *connector)
{
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
DRM_DEBUG_KMS("\n");
}
static const struct drm_dp_mst_topology_cbs mst_cbs = {
.add_connector = radeon_dp_add_mst_connector,
.register_connector = radeon_dp_register_mst_connector,
.destroy_connector = radeon_dp_destroy_mst_connector,
};
static struct
......
......@@ -98,7 +98,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
if (of_property_read_u32(endpoint, "reg", &endpoint_id))
endpoint_id = 0;
if (rockchip_drm_endpoint_is_subdriver(endpoint) > 0)
/* if subdriver (> 0) or error case (< 0), ignore entry */
if (rockchip_drm_endpoint_is_subdriver(endpoint) != 0)
continue;
child_count++;
......
......@@ -45,7 +45,7 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
void *data = par;
u32 speed_hz;
int i, ret;
u16 *buf;
__be16 *buf;
buf = kmalloc(32 * sizeof(u16), GFP_KERNEL);
if (!buf)
......
......@@ -151,8 +151,6 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo,
struct ttm_bo_device *bdev = bo->bdev;
struct ttm_mem_type_manager *man;
dma_resv_assert_held(bo->base.resv);
if (!list_empty(&bo->lru))
return;
......@@ -604,7 +602,8 @@ static void ttm_bo_release(struct kref *kref)
*/
if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) {
bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT;
ttm_bo_move_to_lru_tail(bo, NULL);
ttm_bo_del_from_lru(bo);
ttm_bo_add_mem_to_lru(bo, &bo->mem);
}
kref_init(&bo->kref);
......
......@@ -604,7 +604,7 @@ static struct dma_pool *ttm_dma_pool_init(struct device *dev, gfp_t flags,
p = pool->name;
for (i = 0; i < ARRAY_SIZE(t); i++) {
if (type & t[i]) {
p += snprintf(p, sizeof(pool->name) - (p - pool->name),
p += scnprintf(p, sizeof(pool->name) - (p - pool->name),
"%s", n[i]);
}
}
......
......@@ -129,6 +129,7 @@ struct dw_hdmi_plat_data {
unsigned long input_bus_format;
unsigned long input_bus_encoding;
bool use_drm_infoframe;
bool ycbcr_420_allowed;
/* Vendor PHY support */
const struct dw_hdmi_phy_ops *phy_ops;
......
......@@ -254,6 +254,23 @@ enum drm_panel_orientation {
DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
};
/**
* struct drm_monitor_range_info - Panel's Monitor range in EDID for
* &drm_display_info
*
* This struct is used to store a frequency range supported by panel
* as parsed from EDID's detailed monitor range descriptor block.
*
* @min_vfreq: This is the min supported refresh rate in Hz from
* EDID's detailed monitor range.
* @max_vfreq: This is the max supported refresh rate in Hz from
* EDID's detailed monitor range
*/
struct drm_monitor_range_info {
u8 min_vfreq;
u8 max_vfreq;
};
/*
* This is a consolidated colorimetry list supported by HDMI and
* DP protocol standard. The respective connectors will register
......@@ -473,6 +490,11 @@ struct drm_display_info {
* @non_desktop: Non desktop display (HMD).
*/
bool non_desktop;
/**
* @monitor_range: Frequency range supported by monitor range descriptor
*/
struct drm_monitor_range_info monitor_range;
};
int drm_display_info_set_bus_formats(struct drm_display_info *info,
......
......@@ -479,7 +479,6 @@ struct drm_dp_mst_topology_mgr;
struct drm_dp_mst_topology_cbs {
/* create a connector for a port */
struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path);
void (*register_connector)(struct drm_connector *connector);
void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr,
struct drm_connector *connector);
};
......@@ -590,6 +589,11 @@ struct drm_dp_mst_topology_mgr {
*/
bool payload_id_table_cleared : 1;
/**
* @is_waiting_for_dwn_reply: whether we're waiting for a down reply.
*/
bool is_waiting_for_dwn_reply : 1;
/**
* @mst_primary: Pointer to the primary/first branch device.
*/
......@@ -619,11 +623,6 @@ struct drm_dp_mst_topology_mgr {
*/
struct mutex qlock;
/**
* @is_waiting_for_dwn_reply: indicate whether is waiting for down reply
*/
bool is_waiting_for_dwn_reply;
/**
* @tx_msg_downq: List of pending down replies.
*/
......
......@@ -91,6 +91,11 @@ struct detailed_data_string {
u8 str[13];
} __attribute__((packed));
#define DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG 0x00
#define DRM_EDID_RANGE_LIMITS_ONLY_FLAG 0x01
#define DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG 0x02
#define DRM_EDID_CVT_SUPPORT_FLAG 0x04
struct detailed_data_monitor_range {
u8 min_vfreq;
u8 max_vfreq;
......
......@@ -272,7 +272,7 @@ static inline bool drm_mm_node_allocated(const struct drm_mm_node *node)
*/
static inline bool drm_mm_initialized(const struct drm_mm *mm)
{
return mm->hole_stack.next;
return READ_ONCE(mm->hole_stack.next);
}
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment