diff options
author | Dave Airlie <airlied@redhat.com> | 2020-03-19 04:00:48 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-03-19 04:01:58 +0300 |
commit | d5152d359505407ff648954b068fc912978f306b (patch) | |
tree | e1be5d3654c652ca2de0b792f7458104a2945fdf /drivers/gpu/drm | |
parent | 71fa42fac5d67773d83d6bc058d992a6226dbb01 (diff) | |
parent | 6afe6929964bca6847986d0507a555a041f07753 (diff) | |
download | linux-d5152d359505407ff648954b068fc912978f306b.tar.xz |
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: Dave Airlie <airlied@redhat.com>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20200317082858.lubmvlmvoprn2tuh@gilmour.lan
Diffstat (limited to 'drivers/gpu/drm')
29 files changed, 683 insertions, 213 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index a9108e46f517..e8208df420d9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -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, diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 9bad194cfd0a..f85c15ad8486 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1814,13 +1814,32 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; unsigned int vdisplay, hdisplay; - vmode->mtmdsclock = vmode->mpixelclock = mode->clock * 1000; + vmode->mpixelclock = mode->clock * 1000; dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); + vmode->mtmdsclock = vmode->mpixelclock; + + if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { + switch (hdmi_bus_fmt_color_depth( + hdmi->hdmi_data.enc_out_bus_format)) { + case 16: + vmode->mtmdsclock = vmode->mpixelclock * 2; + break; + case 12: + vmode->mtmdsclock = vmode->mpixelclock * 3 / 2; + break; + case 10: + vmode->mtmdsclock = vmode->mpixelclock * 5 / 4; + break; + } + } + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) vmode->mtmdsclock /= 2; + dev_dbg(hdmi->dev, "final tmdsclock = %d\n", vmode->mtmdsclock); + /* Set up HDMI_FC_INVIDCONF */ inv_val = (hdmi->hdmi_data.hdcp_enable || (dw_hdmi_support_scdc(hdmi) && @@ -2078,11 +2097,10 @@ 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; - /* TOFIX: Get input format from plat data or fallback to RGB888 */ if (hdmi->plat_data->input_bus_format) hdmi->hdmi_data.enc_in_bus_format = hdmi->plat_data->input_bus_format; - else + else 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 */ @@ -2092,8 +2110,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) else hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT; - /* TOFIX: Default to RGB888 output format */ - hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; + if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED) + hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; hdmi->hdmi_data.pix_repet_factor = 0; hdmi->hdmi_data.hdcp_enable = 0; @@ -2371,6 +2389,277 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = .atomic_check = dw_hdmi_connector_atomic_check, }; +/* + * Possible output formats : + * - MEDIA_BUS_FMT_UYYVYY16_0_5X48, + * - MEDIA_BUS_FMT_UYYVYY12_0_5X36, + * - MEDIA_BUS_FMT_UYYVYY10_0_5X30, + * - MEDIA_BUS_FMT_UYYVYY8_0_5X24, + * - MEDIA_BUS_FMT_YUV16_1X48, + * - MEDIA_BUS_FMT_RGB161616_1X48, + * - MEDIA_BUS_FMT_UYVY12_1X24, + * - MEDIA_BUS_FMT_YUV12_1X36, + * - MEDIA_BUS_FMT_RGB121212_1X36, + * - MEDIA_BUS_FMT_UYVY10_1X20, + * - MEDIA_BUS_FMT_YUV10_1X30, + * - MEDIA_BUS_FMT_RGB101010_1X30, + * - MEDIA_BUS_FMT_UYVY8_1X16, + * - MEDIA_BUS_FMT_YUV8_1X24, + * - MEDIA_BUS_FMT_RGB888_1X24, + */ + +/* Can return a maximum of 11 possible output formats for a mode/connector */ +#define MAX_OUTPUT_SEL_FORMATS 11 + +static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + unsigned int *num_output_fmts) +{ + struct drm_connector *conn = conn_state->connector; + struct drm_display_info *info = &conn->display_info; + struct drm_display_mode *mode = &crtc_state->mode; + u8 max_bpc = conn_state->max_requested_bpc; + bool is_hdmi2_sink = info->hdmi.scdc.supported || + (info->color_formats & DRM_COLOR_FORMAT_YCRCB420); + u32 *output_fmts; + unsigned int i = 0; + + *num_output_fmts = 0; + + output_fmts = kcalloc(MAX_OUTPUT_SEL_FORMATS, sizeof(*output_fmts), + GFP_KERNEL); + if (!output_fmts) + return NULL; + + /* If dw-hdmi is the only bridge, avoid negociating with ourselves */ + if (list_is_singular(&bridge->encoder->bridge_chain)) { + *num_output_fmts = 1; + output_fmts[0] = MEDIA_BUS_FMT_FIXED; + + return output_fmts; + } + + /* + * If the current mode enforces 4:2:0, force the output but format + * to 4:2:0 and do not add the YUV422/444/RGB formats + */ + if (conn->ycbcr_420_allowed && + (drm_mode_is_420_only(info, mode) || + (is_hdmi2_sink && drm_mode_is_420_also(info, mode)))) { + + /* Order bus formats from 16bit to 8bit if supported */ + if (max_bpc >= 16 && info->bpc == 16 && + (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY16_0_5X48; + + if (max_bpc >= 12 && info->bpc >= 12 && + (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY12_0_5X36; + + if (max_bpc >= 10 && info->bpc >= 10 && + (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; + + /* Default 8bit fallback */ + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; + + *num_output_fmts = i; + + return output_fmts; + } + + /* + * Order bus formats from 16bit to 8bit and from YUV422 to RGB + * if supported. In any case the default RGB888 format is added + */ + + if (max_bpc >= 16 && info->bpc == 16) { + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) + output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; + + output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; + } + + if (max_bpc >= 12 && info->bpc >= 12) { + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; + + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) + output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + + output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; + } + + if (max_bpc >= 10 && info->bpc >= 10) { + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) + output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + + output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + } + + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) + output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + + /* Default 8bit RGB fallback */ + output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + + *num_output_fmts = i; + + return output_fmts; +} + +/* + * Possible input formats : + * - MEDIA_BUS_FMT_RGB888_1X24 + * - MEDIA_BUS_FMT_YUV8_1X24 + * - MEDIA_BUS_FMT_UYVY8_1X16 + * - MEDIA_BUS_FMT_UYYVYY8_0_5X24 + * - MEDIA_BUS_FMT_RGB101010_1X30 + * - MEDIA_BUS_FMT_YUV10_1X30 + * - MEDIA_BUS_FMT_UYVY10_1X20 + * - MEDIA_BUS_FMT_UYYVYY10_0_5X30 + * - MEDIA_BUS_FMT_RGB121212_1X36 + * - MEDIA_BUS_FMT_YUV12_1X36 + * - MEDIA_BUS_FMT_UYVY12_1X24 + * - MEDIA_BUS_FMT_UYYVYY12_0_5X36 + * - MEDIA_BUS_FMT_RGB161616_1X48 + * - MEDIA_BUS_FMT_YUV16_1X48 + * - MEDIA_BUS_FMT_UYYVYY16_0_5X48 + */ + +/* Can return a maximum of 3 possible input formats for an output format */ +#define MAX_INPUT_SEL_FORMATS 3 + +static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts; + unsigned int i = 0; + + *num_input_fmts = 0; + + input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), + GFP_KERNEL); + if (!input_fmts) + return NULL; + + switch (output_fmt) { + /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */ + case MEDIA_BUS_FMT_FIXED: + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + break; + /* 8bit */ + case MEDIA_BUS_FMT_RGB888_1X24: + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + break; + case MEDIA_BUS_FMT_YUV8_1X24: + input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + break; + case MEDIA_BUS_FMT_UYVY8_1X16: + input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + break; + + /* 10bit */ + case MEDIA_BUS_FMT_RGB101010_1X30: + input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + break; + case MEDIA_BUS_FMT_YUV10_1X30: + input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + break; + case MEDIA_BUS_FMT_UYVY10_1X20: + input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + break; + + /* 12bit */ + case MEDIA_BUS_FMT_RGB121212_1X36: + input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; + input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; + break; + case MEDIA_BUS_FMT_YUV12_1X36: + input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; + input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; + break; + case MEDIA_BUS_FMT_UYVY12_1X24: + input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; + input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; + break; + + /* 16bit */ + case MEDIA_BUS_FMT_RGB161616_1X48: + input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; + input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; + break; + case MEDIA_BUS_FMT_YUV16_1X48: + input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; + input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; + break; + + /*YUV 4:2:0 */ + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + case MEDIA_BUS_FMT_UYYVYY12_0_5X36: + case MEDIA_BUS_FMT_UYYVYY16_0_5X48: + input_fmts[i++] = output_fmt; + break; + } + + *num_input_fmts = i; + + if (*num_input_fmts == 0) { + kfree(input_fmts); + input_fmts = NULL; + } + + return input_fmts; +} + +static int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + hdmi->hdmi_data.enc_out_bus_format = + bridge_state->output_bus_cfg.format; + + hdmi->hdmi_data.enc_in_bus_format = + bridge_state->input_bus_cfg.format; + + dev_dbg(hdmi->dev, "input format 0x%04x, output format 0x%04x\n", + bridge_state->input_bus_cfg.format, + bridge_state->output_bus_cfg.format); + + return 0; +} + static int dw_hdmi_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { @@ -2395,6 +2684,14 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge, 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); @@ -2479,8 +2776,14 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) } 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, + .atomic_reset = drm_atomic_helper_bridge_reset, .attach = dw_hdmi_bridge_attach, .detach = dw_hdmi_bridge_detach, + .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, .mode_set = dw_hdmi_bridge_mode_set, @@ -2949,6 +3252,12 @@ __dw_hdmi_probe(struct platform_device *pdev, 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; diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 19297e58b232..dcabf5698333 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -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. diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index 1f802d8e5681..c99be950bf17 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c @@ -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. diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 6c62ad8f4414..4b255e25e4a1 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -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); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index ad41764a4ebe..116451101426 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -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) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index a9e4a610445a..37627d06fb06 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -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; /* diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 2c79e8199e3c..f16eefbf2829 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c @@ -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; diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 47d5de9ca0a8..bc6e208949e8 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -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)) diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 2e83c3d72af9..939f0032aab1 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -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); diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 64619fe90046..aa88911bbc06 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -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. diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e08caca658c6..44f3fd251ca1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -748,24 +748,8 @@ err: 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 * diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 3bb7ffe5fc39..e8c94915a4fc 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -16,6 +16,7 @@ #include <drm/bridge/dw_hdmi.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_bridge.h> #include <drm/drm_device.h> #include <drm/drm_edid.h> #include <drm/drm_probe_helper.h> @@ -135,6 +136,7 @@ struct meson_dw_hdmi_data { struct meson_dw_hdmi { struct drm_encoder encoder; + struct drm_bridge bridge; struct dw_hdmi_plat_data dw_plat_data; struct meson_drm *priv; struct device *dev; @@ -148,9 +150,12 @@ struct meson_dw_hdmi { struct regulator *hdmi_supply; u32 irq_stat; struct dw_hdmi *hdmi; + unsigned long output_bus_fmt; }; #define encoder_to_meson_dw_hdmi(x) \ container_of(x, struct meson_dw_hdmi, encoder) +#define bridge_to_meson_dw_hdmi(x) \ + container_of(x, struct meson_dw_hdmi, bridge) static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, const char *compat) @@ -297,6 +302,10 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, struct meson_drm *priv = dw_hdmi->priv; unsigned int pixel_clock = mode->clock; + /* For 420, pixel clock is half unlike venc clock */ + if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + pixel_clock /= 2; + if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { if (pixel_clock >= 371250) { @@ -368,29 +377,40 @@ static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) } static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { struct meson_drm *priv = dw_hdmi->priv; int vic = drm_match_cea_mode(mode); + unsigned int phy_freq; unsigned int vclk_freq; unsigned int venc_freq; unsigned int hdmi_freq; vclk_freq = mode->clock; + /* For 420, pixel clock is half unlike venc clock */ + if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + vclk_freq /= 2; + + /* TMDS clock is pixel_clock * 10 */ + phy_freq = vclk_freq * 10; + if (!vic) { - meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq, - vclk_freq, vclk_freq, false); + meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq, + vclk_freq, vclk_freq, vclk_freq, false); return; } + /* 480i/576i needs global pixel doubling */ if (mode->flags & DRM_MODE_FLAG_DBLCLK) vclk_freq *= 2; venc_freq = vclk_freq; hdmi_freq = vclk_freq; - if (meson_venc_hdmi_venc_repeat(vic)) + /* VENC double pixels for 1080i, 720p and YUV420 modes */ + if (meson_venc_hdmi_venc_repeat(vic) || + dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) venc_freq *= 2; vclk_freq = max(venc_freq, hdmi_freq); @@ -398,11 +418,11 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2; - DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n", - vclk_freq, venc_freq, hdmi_freq, + DRM_DEBUG_DRIVER("vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", + phy_freq, vclk_freq, venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); - meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq, + meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq, venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); } @@ -437,8 +457,9 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, /* Enable normal output to PHY */ dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); - /* TMDS pattern setup (TOFIX Handle the YUV420 case) */ - if (mode->clock > 340000) { + /* TMDS pattern setup */ + if (mode->clock > 340000 && + dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_YUV8_1X24) { dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0); dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, @@ -613,6 +634,8 @@ dw_hdmi_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode) { struct meson_drm *priv = connector->dev->dev_private; + bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported; + unsigned int phy_freq; unsigned int vclk_freq; unsigned int venc_freq; unsigned int hdmi_freq; @@ -621,9 +644,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector, DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); - /* If sink max TMDS clock, we reject the 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) + 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)) return MODE_BAD; /* Check against non-VIC supported modes */ @@ -639,6 +664,15 @@ 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) || + (!is_hdmi2_sink && + drm_mode_is_420_also(&connector->display_info, mode))) + vclk_freq /= 2; + + /* TMDS clock is pixel_clock * 10 */ + phy_freq = vclk_freq * 10; + /* 480i/576i needs global pixel doubling */ if (mode->flags & DRM_MODE_FLAG_DBLCLK) vclk_freq *= 2; @@ -646,8 +680,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector, venc_freq = vclk_freq; hdmi_freq = vclk_freq; - /* VENC double pixels for 1080i and 720p modes */ - if (meson_venc_hdmi_venc_repeat(vic)) + /* 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) || + (!is_hdmi2_sink && + drm_mode_is_420_also(&connector->display_info, mode))) venc_freq *= 2; vclk_freq = max(venc_freq, hdmi_freq); @@ -655,14 +692,19 @@ 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 venc=%d hdmi=%d\n", __func__, - vclk_freq, venc_freq, hdmi_freq); + dev_dbg(connector->dev->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(vclk_freq); + return meson_vclk_vic_supported_freq(phy_freq, vclk_freq); } /* Encoder */ +static const u32 meson_dw_hdmi_out_bus_fmts[] = { + MEDIA_BUS_FMT_YUV8_1X24, + MEDIA_BUS_FMT_UYYVYY8_0_5X24, +}; + static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); @@ -672,16 +714,54 @@ static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = { .destroy = meson_venc_hdmi_encoder_destroy, }; -static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder, +static u32 * +meson_venc_hdmi_encoder_get_inp_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts = NULL; + int i; + + *num_input_fmts = 0; + + for (i = 0 ; i < ARRAY_SIZE(meson_dw_hdmi_out_bus_fmts) ; ++i) { + if (output_fmt == meson_dw_hdmi_out_bus_fmts[i]) { + *num_input_fmts = 1; + input_fmts = kcalloc(*num_input_fmts, + sizeof(*input_fmts), + GFP_KERNEL); + if (!input_fmts) + return NULL; + + input_fmts[0] = output_fmt; + + break; + } + } + + return input_fmts; +} + +static int meson_venc_hdmi_encoder_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); + + dw_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format; + + DRM_DEBUG_DRIVER("output_bus_fmt %lx\n", dw_hdmi->output_bus_fmt); + return 0; } -static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder) +static void meson_venc_hdmi_encoder_disable(struct drm_bridge *bridge) { - struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); + struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); struct meson_drm *priv = dw_hdmi->priv; DRM_DEBUG_DRIVER("\n"); @@ -693,9 +773,9 @@ static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder) writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); } -static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder) +static void meson_venc_hdmi_encoder_enable(struct drm_bridge *bridge) { - struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); + struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); struct meson_drm *priv = dw_hdmi->priv; DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); @@ -706,32 +786,47 @@ static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder) writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); } -static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static void meson_venc_hdmi_encoder_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) { - struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); + struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); struct meson_drm *priv = dw_hdmi->priv; int vic = drm_match_cea_mode(mode); + unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR; + bool yuv420_mode = false; DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); + if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { + ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; + yuv420_mode = true; + } + /* VENC + VENC-DVI Mode setup */ - meson_venc_hdmi_mode_set(priv, vic, mode); + meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode); /* VCLK Set clock */ dw_hdmi_set_vclk(dw_hdmi, mode); - /* Setup YUV444 to HDMI-TX, no 10bit diphering */ - writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); + if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + /* Setup YUV420 to HDMI-TX, no 10bit diphering */ + writel_relaxed(2 | (2 << 2), + priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); + else + /* Setup YUV444 to HDMI-TX, no 10bit diphering */ + writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); } -static const struct drm_encoder_helper_funcs - meson_venc_hdmi_encoder_helper_funcs = { - .atomic_check = meson_venc_hdmi_encoder_atomic_check, - .disable = meson_venc_hdmi_encoder_disable, - .enable = meson_venc_hdmi_encoder_enable, - .mode_set = meson_venc_hdmi_encoder_mode_set, +static const struct drm_bridge_funcs meson_venc_hdmi_encoder_bridge_funcs = { + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_get_input_bus_fmts = meson_venc_hdmi_encoder_get_inp_bus_fmts, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_check = meson_venc_hdmi_encoder_atomic_check, + .enable = meson_venc_hdmi_encoder_enable, + .disable = meson_venc_hdmi_encoder_disable, + .mode_set = meson_venc_hdmi_encoder_mode_set, }; /* DW HDMI Regmap */ @@ -852,6 +947,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, struct drm_device *drm = data; struct meson_drm *priv = drm->dev_private; struct dw_hdmi_plat_data *dw_plat_data; + struct drm_bridge *next_bridge; struct drm_encoder *encoder; struct resource *res; int irq; @@ -953,8 +1049,6 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, /* Encoder */ - drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs); - ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs, DRM_MODE_ENCODER_TMDS, "meson_hdmi"); if (ret) { @@ -962,6 +1056,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, return ret; } + meson_dw_hdmi->bridge.funcs = &meson_venc_hdmi_encoder_bridge_funcs; + drm_bridge_attach(encoder, &meson_dw_hdmi->bridge, NULL, 0); + encoder->possible_crtcs = BIT(0); DRM_DEBUG_DRIVER("encoder initialized\n"); @@ -974,8 +1071,8 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; dw_plat_data->phy_name = "meson_dw_hdmi_phy"; dw_plat_data->phy_data = meson_dw_hdmi; - dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; + dw_plat_data->ycbcr_420_allowed = true; if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || @@ -984,11 +1081,16 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, platform_set_drvdata(pdev, meson_dw_hdmi); - meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder, - &meson_dw_hdmi->dw_plat_data); + meson_dw_hdmi->hdmi = dw_hdmi_probe(pdev, + &meson_dw_hdmi->dw_plat_data); if (IS_ERR(meson_dw_hdmi->hdmi)) return PTR_ERR(meson_dw_hdmi->hdmi); + next_bridge = of_drm_find_bridge(pdev->dev.of_node); + if (next_bridge) + drm_bridge_attach(encoder, next_bridge, + &meson_dw_hdmi->bridge, 0); + DRM_DEBUG_DRIVER("HDMI controller initialized\n"); return 0; diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index f690793ae2d5..fdf26dac9fa8 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -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, diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h index b62125540aef..aed0ab2efa71 100644 --- a/drivers/gpu/drm/meson/meson_vclk.h +++ b/drivers/gpu/drm/meson/meson_vclk.h @@ -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 */ diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c index 4efd7864d5bf..f93c725b6f02 100644 --- a/drivers/gpu/drm/meson/meson_venc.c +++ b/drivers/gpu/drm/meson/meson_venc.c @@ -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); /* diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h index 576768bdd08d..9138255ffc9e 100644 --- a/drivers/gpu/drm/meson/meson_venc.h +++ b/drivers/gpu/drm/meson/meson_venc.h @@ -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); diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c index 1bd6b6d15ffb..541f9eb2a135 100644 --- a/drivers/gpu/drm/meson/meson_venc_cvbs.c +++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c @@ -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); } } diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 4e164ad8003f..4d1c58468dbc 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -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 diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c index f394d53a7da4..09935520e606 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c @@ -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, diff --git a/drivers/gpu/drm/panel/panel-lg-lg4573.c b/drivers/gpu/drm/panel/panel-lg-lg4573.c index b262b53dbd85..5907f2503755 100644 --- a/drivers/gpu/drm/panel/panel-lg-lg4573.c +++ b/drivers/gpu/drm/panel/panel-lg-lg4573.c @@ -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, diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35510.c b/drivers/gpu/drm/panel/panel-novatek-nt35510.c index b4c014126781..4a8fa908a2cf 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35510.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35510.c @@ -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 */ diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 7505b81ecb77..0ce81b1f36af 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -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 = { diff --git a/drivers/gpu/drm/panel/panel-sony-acx424akp.c b/drivers/gpu/drm/panel/panel-sony-acx424akp.c index de0abf76ae6f..c91e55b2d7a3 100644 --- a/drivers/gpu/drm/panel/panel-sony-acx424akp.c +++ b/drivers/gpu/drm/panel/panel-sony-acx424akp.c @@ -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, diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 5a9fb0ad175a..008308780443 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -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 diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index 3e2484985955..90784781e515 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -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++; diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c index 5084b38c1a71..532560aebb1e 100644 --- a/drivers/gpu/drm/tiny/ili9486.c +++ b/drivers/gpu/drm/tiny/ili9486.c @@ -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) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 6d1e91be9c78..9e07c3f75156 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -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); diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index bf876faea592..faefaaef7909 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -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]); } } |