diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 960944e82b9852bc45289731aca7b495783cc870..ae56d91433ff478e8e7f240bdc14aa57d25b22bf 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1704,7 +1704,7 @@ crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc) * drm_atomic_helper_commit_cleanup_done(). * * This is all implemented by in drm_atomic_helper_commit(), giving drivers a - * complete and esay-to-use default implementation of the atomic_commit() hook. + * complete and easy-to-use default implementation of the atomic_commit() hook. * * The tracking of asynchronously executed and still pending commits is done * using the core structure &drm_crtc_commit. @@ -1819,7 +1819,7 @@ EXPORT_SYMBOL(drm_atomic_helper_setup_commit); * This function waits for all preceeding commits that touch the same CRTC as * @old_state to both be committed to the hardware (as signalled by * drm_atomic_helper_commit_hw_done) and executed by the hardware (as signalled - * by calling drm_crtc_vblank_send_event() on the &drm_crtc_state.event). + * by calling drm_crtc_send_vblank_event() on the &drm_crtc_state.event). * * This is part of the atomic helper support for nonblocking commits, see * drm_atomic_helper_setup_commit() for an overview. diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index eab36a4606382dc18bdedf788b526d07a2b462b4..5a84c3bc915df4dd703ccaebc6c98dbde59e8a8b 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -562,12 +562,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, * Allocate space for the backup of all (non-pointer) encoder and * connector data. */ - save_encoder_crtcs = kzalloc(dev->mode_config.num_encoder * + save_encoder_crtcs = kcalloc(dev->mode_config.num_encoder, sizeof(struct drm_crtc *), GFP_KERNEL); if (!save_encoder_crtcs) return -ENOMEM; - save_connector_encoders = kzalloc(dev->mode_config.num_connector * + save_connector_encoders = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_encoder *), GFP_KERNEL); if (!save_connector_encoders) { kfree(save_encoder_crtcs); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 6a31d13f2f81deda566074ac75b12618ff9c75ec..116d1f1337c7e36da1622ffc88bfc6e218d461a3 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2266,7 +2266,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, if (modes[n] == NULL) return best_score; - crtcs = kzalloc(fb_helper->connector_count * + crtcs = kcalloc(fb_helper->connector_count, sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); if (!crtcs) return best_score; diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 7a36934ea5dbe55783bd89de86fd867f5c582756..4c191c050e7dac2093abdbfbbd4e18d1efb182b2 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -262,36 +262,3 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, return ret; } EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge); - -#ifdef CONFIG_DRM_PANEL_BRIDGE -/* - * drm_of_panel_bridge_remove - remove panel bridge - * @np: device tree node containing panel bridge output ports - * - * Remove the panel bridge of a given DT node's port and endpoint number - * - * Returns zero if successful, or one of the standard error codes if it fails. - */ -int drm_of_panel_bridge_remove(const struct device_node *np, - int port, int endpoint) -{ - struct drm_bridge *bridge; - struct device_node *remote; - - remote = of_graph_get_remote_node(np, port, endpoint); - if (!remote) - return -ENODEV; - - bridge = of_drm_find_bridge(remote); - drm_panel_bridge_remove(bridge); - - return 0; -} -#else -int drm_of_panel_bridge_remove(const struct device_node *np, - int port, int endpoint) -{ - return -EINVAL; -} -#endif -EXPORT_SYMBOL_GPL(drm_of_panel_bridge_remove); diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 06aee1741e96a78f91e582eda88e4c4bc94b3f13..759ed93f4ba8fdf3b8be604f745479ee27838d0b 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -354,7 +354,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, /* Find current connectors for CRTC */ num_connectors = get_connectors_for_crtc(crtc, NULL, 0); BUG_ON(num_connectors == 0); - connector_list = kzalloc(num_connectors * sizeof(*connector_list), + connector_list = kcalloc(num_connectors, sizeof(*connector_list), GFP_KERNEL); if (!connector_list) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 80b6151da9aebaec8fcd9a7e03aa3652b3af6e53..f776fc1cc543abf8e752a5133aaf1ca63fb2d8ff 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -845,7 +845,8 @@ static int drm_syncobj_array_wait(struct drm_device *dev, } static int drm_syncobj_array_find(struct drm_file *file_private, - void *user_handles, uint32_t count_handles, + void __user *user_handles, + uint32_t count_handles, struct drm_syncobj ***syncobjs_out) { uint32_t i, *handles; diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 810a93fc558b10f09103892234ada1ab65f18679..3af6c20ba03b8e839ff517a3c16657018a409d48 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -854,7 +854,7 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, assert_spin_locked(&dev->event_lock); e->pipe = pipe; - e->event.sequence = drm_vblank_count(dev, pipe); + e->event.sequence = drm_crtc_accurate_vblank_count(crtc) + 1; e->event.crtc_id = crtc->base.id; list_add_tail(&e->base.link, &dev->vblank_event_list); } diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c index d75ecb3bdee7464d4ce2092c1bebda753b733b84..1fa163373a4713bcf01eb6afc0990ef6bd64b2b5 100644 --- a/drivers/gpu/drm/gma500/mid_bios.c +++ b/drivers/gpu/drm/gma500/mid_bios.c @@ -237,7 +237,7 @@ static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr) gct = kmalloc(sizeof(*gct) * vbt.panel_count, GFP_KERNEL); if (!gct) - return -1; + return -ENOMEM; gct_virtual = ioremap(addr + sizeof(vbt), sizeof(*gct) * vbt.panel_count); diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index e787d376ba6716b4360c6e1175af6cae0e0b7c40..84507912be841b2709c1dc3652db190a6320e896 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -37,6 +37,7 @@ #include "psb_drv.h" #include "psb_intel_sdvo_regs.h" #include "psb_intel_reg.h" +#include #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) @@ -62,8 +63,6 @@ static const char *tv_format_names[] = { "SECAM_60" }; -#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) - struct psb_intel_sdvo { struct gma_encoder base; @@ -148,7 +147,7 @@ struct psb_intel_sdvo_connector { int force_audio; /* This contains all current supported TV format */ - u8 tv_format_supported[TV_FORMAT_NUM]; + u8 tv_format_supported[ARRAY_SIZE(tv_format_names)]; int format_supported_num; struct drm_property *tv_format; @@ -1709,7 +1708,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector, } if (property == psb_intel_sdvo_connector->tv_format) { - if (val >= TV_FORMAT_NUM) + if (val >= ARRAY_SIZE(tv_format_names)) return -EINVAL; if (psb_intel_sdvo->tv_format_index == @@ -2269,7 +2268,7 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s return false; psb_intel_sdvo_connector->format_supported_num = 0; - for (i = 0 ; i < TV_FORMAT_NUM; i++) + for (i = 0 ; i < ARRAY_SIZE(tv_format_names); i++) if (format_map & (1 << i)) psb_intel_sdvo_connector->tv_format_supported[psb_intel_sdvo_connector->format_supported_num++] = i; diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index c19ab4f91ae7a79b1612e9ad62bdd0a7ecea37cc..ddb0403f1975e690a415cdbeb3fa12aded8b5744 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -237,8 +237,8 @@ static int kirin_drm_platform_probe(struct platform_device *pdev) } remote = of_graph_get_remote_node(np, 0, 0); - if (IS_ERR(remote)) - return PTR_ERR(remote); + if (!remote) + return -ENODEV; drm_of_component_match_add(dev, &match, compare_of, remote); of_node_put(remote); diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index 0c31f0a27b9cbd3348ecad9c4acfb0134a1f8302..3c70c6224bd220df95537a814799045a7b20de7c 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -60,6 +60,7 @@ config ROCKCHIP_INNO_HDMI config ROCKCHIP_LVDS bool "Rockchip LVDS support" depends on DRM_ROCKCHIP + depends on PINCTRL help Choose this option to enable support for Rockchip LVDS controllers. Rockchip rk3288 SoC has LVDS TX Controller can be used, and it diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index ec5943627aa5be396ead89bd6871c64b75e9c3fd..4fefd8add714b5b3abf6116938867d0dd25596ed 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -209,22 +209,11 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *gem; u32 lo_paddr, hi_paddr; dma_addr_t paddr; - int bpp; - - /* Get the physical address of the buffer in memory */ - gem = drm_fb_cma_get_gem_obj(fb, 0); - - DRM_DEBUG_DRIVER("Using GEM @ %pad\n", &gem->paddr); - - /* Compute the start of the displayed memory */ - bpp = fb->format->cpp[0]; - paddr = gem->paddr + fb->offsets[0]; - paddr += (state->src_x >> 16) * bpp; - paddr += (state->src_y >> 16) * fb->pitches[0]; + /* Get the start of the displayed memory */ + paddr = drm_fb_cma_get_gem_addr(fb, state, 0); DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr); /* Write the 32 lower bits of the address (in bits) */ @@ -369,13 +358,6 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, if (IS_ERR(regs)) return PTR_ERR(regs); - backend->engine.regs = devm_regmap_init_mmio(dev, regs, - &sun4i_backend_regmap_config); - if (IS_ERR(backend->engine.regs)) { - dev_err(dev, "Couldn't create the backend regmap\n"); - return PTR_ERR(backend->engine.regs); - } - backend->reset = devm_reset_control_get(dev, NULL); if (IS_ERR(backend->reset)) { dev_err(dev, "Couldn't get our reset line\n"); @@ -421,9 +403,23 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, } } + backend->engine.regs = devm_regmap_init_mmio(dev, regs, + &sun4i_backend_regmap_config); + if (IS_ERR(backend->engine.regs)) { + dev_err(dev, "Couldn't create the backend regmap\n"); + return PTR_ERR(backend->engine.regs); + } + list_add_tail(&backend->engine.list, &drv->engine_list); - /* Reset the registers */ + /* + * Many of the backend's layer configuration registers have + * undefined default values. This poses a risk as we use + * regmap_update_bits in some places, and don't overwrite + * the whole register. + * + * Clear the registers here to have something predictable. + */ for (i = 0x800; i < 0x1000; i += 4) regmap_write(backend->engine.regs, i, 0); diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index a2012638d5f77a8d7c23cf32db2d8c3370904e99..b5879d4620d87d9d7532ecf1b7872aa26021f75c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -226,6 +226,18 @@ struct endpoint_list { struct list_head list; }; +static bool node_is_in_list(struct list_head *endpoints, + struct device_node *node) +{ + struct endpoint_list *endpoint; + + list_for_each_entry(endpoint, endpoints, list) + if (endpoint->node == node) + return true; + + return false; +} + static int sun4i_drv_add_endpoints(struct device *dev, struct list_head *endpoints, struct component_match **match, @@ -292,6 +304,10 @@ static int sun4i_drv_add_endpoints(struct device *dev, } } + /* skip downstream node if it is already in the queue */ + if (node_is_in_list(endpoints, remote)) + continue; + /* Add downstream nodes to the queue */ endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); if (!endpoint) { diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h index 9b97da39927e0b291b8cca70af823cd5a60d1191..b685ee11623d1036acc38d843e999b460680b46a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h @@ -72,6 +72,11 @@ #define SUN4I_HDMI_PAD_CTRL1_HALVE_CLK BIT(6) #define SUN4I_HDMI_PAD_CTRL1_REG_AMP(n) (((n) & 7) << 3) +/* These bits seem to invert the TMDS data channels */ +#define SUN4I_HDMI_PAD_CTRL1_INVERT_R BIT(2) +#define SUN4I_HDMI_PAD_CTRL1_INVERT_G BIT(1) +#define SUN4I_HDMI_PAD_CTRL1_INVERT_B BIT(0) + #define SUN4I_HDMI_PLL_CTRL_REG 0x208 #define SUN4I_HDMI_PLL_CTRL_PLL_EN BIT(31) #define SUN4I_HDMI_PLL_CTRL_BWS BIT(30) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 027b5608dbe6ca2779020bbe3ab605a8f5fe99ad..6ca6e6a74c4ac4f438b8303d3810b10566f3242d 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -144,6 +144,22 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC, hdmi->base + SUN4I_HDMI_UNKNOWN_REG); + /* + * Setup output pad (?) controls + * + * This is done here instead of at probe/bind time because + * the controller seems to toggle some of the bits on its own. + * + * We can't just initialize the register there, we need to + * protect the clock bits that have already been read out and + * cached by the clock framework. + */ + val = readl(hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG); + val &= SUN4I_HDMI_PAD_CTRL1_HALVE_CLK; + val |= hdmi->variant->pad_ctrl1_init_val; + writel(val, hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG); + val = readl(hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG); + /* Setup timing registers */ writel(SUN4I_HDMI_VID_TIMING_X(mode->hdisplay) | SUN4I_HDMI_VID_TIMING_Y(mode->vdisplay), @@ -489,16 +505,6 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, writel(hdmi->variant->pad_ctrl0_init_val, hdmi->base + SUN4I_HDMI_PAD_CTRL0_REG); - /* - * We can't just initialize the register there, we need to - * protect the clock bits that have already been read out and - * cached by the clock framework. - */ - reg = readl(hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG); - reg &= SUN4I_HDMI_PAD_CTRL1_HALVE_CLK; - reg |= hdmi->variant->pad_ctrl1_init_val; - writel(reg, hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG); - reg = readl(hdmi->base + SUN4I_HDMI_PLL_CTRL_REG); reg &= SUN4I_HDMI_PLL_CTRL_DIV_MASK; reg |= hdmi->variant->pll_ctrl_init_val; diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c index fc447c9a1a271c69617805cd956daab59a95ab98..f41fc506ff87f6d96b39f1122efa86e76b4399e3 100644 --- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c +++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c @@ -51,7 +51,6 @@ static int tinydrm_connector_get_modes(struct drm_connector *connector) static const struct drm_connector_helper_funcs tinydrm_connector_hfuncs = { .get_modes = tinydrm_connector_get_modes, - .best_encoder = drm_atomic_helper_best_encoder, }; static enum drm_connector_status diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c index 7fd26912f2bae2b6599676396e11679de22ba2c5..6a83b309325439d99c2514f441018a0806928851 100644 --- a/drivers/gpu/drm/tinydrm/mi0283qt.c +++ b/drivers/gpu/drm/tinydrm/mi0283qt.c @@ -31,7 +31,7 @@ static int mi0283qt_init(struct mipi_dbi *mipi) ret = regulator_enable(mipi->regulator); if (ret) { - dev_err(dev, "Failed to enable regulator %d\n", ret); + DRM_DEV_ERROR(dev, "Failed to enable regulator %d\n", ret); return ret; } @@ -42,7 +42,7 @@ static int mi0283qt_init(struct mipi_dbi *mipi) mipi_dbi_hw_reset(mipi); ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET); if (ret) { - dev_err(dev, "Error sending command %d\n", ret); + DRM_DEV_ERROR(dev, "Error sending command %d\n", ret); regulator_disable(mipi->regulator); return ret; } @@ -174,13 +174,13 @@ static int mi0283qt_probe(struct spi_device *spi) mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(mipi->reset)) { - dev_err(dev, "Failed to get gpio 'reset'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); return PTR_ERR(mipi->reset); } dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW); if (IS_ERR(dc)) { - dev_err(dev, "Failed to get gpio 'dc'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n"); return PTR_ERR(dc); } diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c index 340198f5afea3a657f852c0a5f4127b2522381d1..75740630c410624cc6012228e18ef3507f277180 100644 --- a/drivers/gpu/drm/tinydrm/repaper.c +++ b/drivers/gpu/drm/tinydrm/repaper.c @@ -474,8 +474,7 @@ static void repaper_get_temperature(struct repaper_epd *epd) ret = thermal_zone_get_temp(epd->thermal, &temperature); if (ret) { - dev_err(&epd->spi->dev, "Failed to get temperature (%d)\n", - ret); + DRM_DEV_ERROR(&epd->spi->dev, "Failed to get temperature (%d)\n", ret); return; } @@ -630,7 +629,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb, mutex_unlock(&tdev->dirty_lock); if (ret) - dev_err(fb->dev->dev, "Failed to update display (%d)\n", ret); + DRM_DEV_ERROR(fb->dev->dev, "Failed to update display (%d)\n", ret); kfree(buf); return ret; @@ -704,7 +703,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, } if (!i) { - dev_err(dev, "timeout waiting for panel to become ready.\n"); + DRM_DEV_ERROR(dev, "timeout waiting for panel to become ready.\n"); power_off(epd); return; } @@ -726,9 +725,9 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, ret = repaper_read_val(spi, 0x0f); if (ret < 0 || !(ret & 0x80)) { if (ret < 0) - dev_err(dev, "failed to read chip (%d)\n", ret); + DRM_DEV_ERROR(dev, "failed to read chip (%d)\n", ret); else - dev_err(dev, "panel is reported broken\n"); + DRM_DEV_ERROR(dev, "panel is reported broken\n"); power_off(epd); return; } @@ -768,7 +767,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, /* check DC/DC */ ret = repaper_read_val(spi, 0x0f); if (ret < 0) { - dev_err(dev, "failed to read chip (%d)\n", ret); + DRM_DEV_ERROR(dev, "failed to read chip (%d)\n", ret); power_off(epd); return; } @@ -780,7 +779,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, } if (!dc_ok) { - dev_err(dev, "dc/dc failed\n"); + DRM_DEV_ERROR(dev, "dc/dc failed\n"); power_off(epd); return; } @@ -960,7 +959,7 @@ static int repaper_probe(struct spi_device *spi) if (IS_ERR(epd->panel_on)) { ret = PTR_ERR(epd->panel_on); if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get gpio 'panel-on'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'panel-on'\n"); return ret; } @@ -968,7 +967,7 @@ static int repaper_probe(struct spi_device *spi) if (IS_ERR(epd->discharge)) { ret = PTR_ERR(epd->discharge); if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get gpio 'discharge'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'discharge'\n"); return ret; } @@ -976,7 +975,7 @@ static int repaper_probe(struct spi_device *spi) if (IS_ERR(epd->reset)) { ret = PTR_ERR(epd->reset); if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get gpio 'reset'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); return ret; } @@ -984,7 +983,7 @@ static int repaper_probe(struct spi_device *spi) if (IS_ERR(epd->busy)) { ret = PTR_ERR(epd->busy); if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get gpio 'busy'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'busy'\n"); return ret; } @@ -992,8 +991,7 @@ static int repaper_probe(struct spi_device *spi) &thermal_zone)) { epd->thermal = thermal_zone_get_zone_by_name(thermal_zone); if (IS_ERR(epd->thermal)) { - dev_err(dev, "Failed to get thermal zone: %s\n", - thermal_zone); + DRM_DEV_ERROR(dev, "Failed to get thermal zone: %s\n", thermal_zone); return PTR_ERR(epd->thermal); } } @@ -1034,7 +1032,7 @@ static int repaper_probe(struct spi_device *spi) if (IS_ERR(epd->border)) { ret = PTR_ERR(epd->border); if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get gpio 'border'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'border'\n"); return ret; } diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c index da9c0d83045f13101858cbeb141f9e7abc2b2434..0a2c60da5c0e4b806e8eee167d26bb01bd145954 100644 --- a/drivers/gpu/drm/tinydrm/st7586.c +++ b/drivers/gpu/drm/tinydrm/st7586.c @@ -188,7 +188,7 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe, mipi_dbi_hw_reset(mipi); ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f); if (ret) { - dev_err(dev, "Error sending command %d\n", ret); + DRM_DEV_ERROR(dev, "Error sending command %d\n", ret); return; } @@ -355,13 +355,13 @@ static int st7586_probe(struct spi_device *spi) mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(mipi->reset)) { - dev_err(dev, "Failed to get gpio 'reset'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); return PTR_ERR(mipi->reset); } a0 = devm_gpiod_get(dev, "a0", GPIOD_OUT_LOW); if (IS_ERR(a0)) { - dev_err(dev, "Failed to get gpio 'a0'\n"); + DRM_DEV_ERROR(dev, "Failed to get gpio 'a0'\n"); return PTR_ERR(a0); } diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 925c726ac69417d70a8027d2651ccecf6bdd17a5..554605af344e489c7e77b6032e60e0c90e6481b5 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -859,11 +859,7 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder, pll_clock = parent_rate / divider; pixel_clock_hz = pll_clock / dsi->divider; - /* Round up the clk_set_rate() request slightly, since - * PLLD_DSI1 is an integer divider and its rate selection will - * never round up. - */ - adjusted_mode->clock = pixel_clock_hz / 1000 + 1; + adjusted_mode->clock = pixel_clock_hz / 1000; /* Given the new pixel clock, adjust HFP to keep vrefresh the same. */ adjusted_mode->htotal = adjusted_mode->clock * mode->htotal / @@ -901,7 +897,11 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) vc4_dsi_dump_regs(dsi); } - phy_clock = pixel_clock_hz * dsi->divider; + /* Round up the clk_set_rate() request slightly, since + * PLLD_DSI1 is an integer divider and its rate selection will + * never round up. + */ + phy_clock = (pixel_clock_hz + 1000) * dsi->divider; ret = clk_set_rate(dsi->pll_phy_clock, phy_clock); if (ret) { dev_err(&dsi->pdev->dev, diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 2968b3ebb895714cb8c8faeaf40dff1c996f2259..3a767a038f725a995f125e708d3d3b491ddd5317 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -547,14 +547,24 @@ static int vc4_plane_mode_set(struct drm_plane *plane, tiling = SCALER_CTL0_TILING_LINEAR; pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); break; - case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: { + /* For T-tiled, the FB pitch is "how many bytes from + * one row to the next, such that pitch * tile_h == + * tile_size * tiles_per_row." + */ + u32 tile_size_shift = 12; /* T tiles are 4kb */ + u32 tile_h_shift = 5; /* 16 and 32bpp are 32 pixels high */ + u32 tiles_w = fb->pitches[0] >> (tile_size_shift - tile_h_shift); + tiling = SCALER_CTL0_TILING_256B_OR_T; - pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET), - VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L), - VC4_SET_FIELD((vc4_state->src_w[0] + 31) >> 5, - SCALER_PITCH0_TILE_WIDTH_R)); + pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET) | + VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L) | + VC4_SET_FIELD(tiles_w, SCALER_PITCH0_TILE_WIDTH_R)); break; + } + default: DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx", (long long)fb->modifier); diff --git a/drivers/gpu/drm/via/via_verifier.c b/drivers/gpu/drm/via/via_verifier.c index 0677bbf4ec7e3af5300e923ebb99b2593dd7b6e1..fb2609434df7c30118d95616abbe3ed4ad38aa04 100644 --- a/drivers/gpu/drm/via/via_verifier.c +++ b/drivers/gpu/drm/via/via_verifier.c @@ -34,6 +34,7 @@ #include #include "via_verifier.h" #include "via_drv.h" +#include typedef enum { state_command, @@ -1102,10 +1103,7 @@ setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size) void via_init_command_verifier(void) { - setup_hazard_table(init_table1, table1, - sizeof(init_table1) / sizeof(hz_init_t)); - setup_hazard_table(init_table2, table2, - sizeof(init_table2) / sizeof(hz_init_t)); - setup_hazard_table(init_table3, table3, - sizeof(init_table3) / sizeof(hz_init_t)); + setup_hazard_table(init_table1, table1, ARRAY_SIZE(init_table1)); + setup_hazard_table(init_table2, table2, ARRAY_SIZE(init_table2)); + setup_hazard_table(init_table3, table3, ARRAY_SIZE(init_table3)); } diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 390966e4a308bb4536ab908df7a1f6e87bcac6b3..d20ec4e0431dd31544390e1a1441fc4b6f28a773 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -2,6 +2,9 @@ #define __DRM_OF_H__ #include +#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) +#include +#endif struct component_master_ops; struct component_match; @@ -29,8 +32,6 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, int port, int endpoint, struct drm_panel **panel, struct drm_bridge **bridge); -int drm_of_panel_bridge_remove(const struct device_node *np, - int port, int endpoint); #else static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, struct device_node *port) @@ -67,13 +68,35 @@ static inline int drm_of_find_panel_or_bridge(const struct device_node *np, { return -EINVAL; } +#endif +/* + * drm_of_panel_bridge_remove - remove panel bridge + * @np: device tree node containing panel bridge output ports + * + * Remove the panel bridge of a given DT node's port and endpoint number + * + * Returns zero if successful, or one of the standard error codes if it fails. + */ static inline int drm_of_panel_bridge_remove(const struct device_node *np, int port, int endpoint) { +#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) + struct drm_bridge *bridge; + struct device_node *remote; + + remote = of_graph_get_remote_node(np, port, endpoint); + if (!remote) + return -ENODEV; + + bridge = of_drm_find_bridge(remote); + drm_panel_bridge_remove(bridge); + + return 0; +#else return -EINVAL; -} #endif +} static inline int drm_of_encoder_active_endpoint_id(struct device_node *node, struct drm_encoder *encoder)