Commit 6c94804f authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2017-10-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

Quick 4.15 misc pull for the build fix:

Cross-subsystem Changes:
- piles an piles of misc/trivial patches all over, some more from
  outreachy applicants

Core Changes:
- build fix for the bridge/of cleanup (Maarten)
- fix vblank count in arm_vblank_event (Ville)
- some kerneldoc typo fixes from Thierry

Driver Changes:
- vc4: Fix T-format tiling scanout, cleanup clock divider w/a (Anholt)
- sun4i: small cleanups and improved code comments all over (Chen-Yu
  Tsai)

* tag 'drm-misc-next-2017-10-16' of git://anongit.freedesktop.org/drm/drm-misc: (21 commits)
  drm/via: use ARRAY_SIZE
  drm/gma500: use ARRAY_SIZE
  drm/sun4i: hdmi: Move PAD_CTRL1 setting to mode_set function
  drm/sun4i: hdmi: Document PAD_CTRL1 output invert bits
  drm/sun4i: backend: Add comment explaining why registers are cleared
  drm/sun4i: backend: Use drm_fb_cma_get_gem_addr() to get display memory
  drm/sun4i: backend: Create regmap after access is possible
  drm/sun4i: don't add components that are already in the queue
  drm/vc4: Fix pitch setup for T-format scanout.
  drm/vc4: Move the DSI clock divider workaround closer to the clock call.
  drm: Replace kzalloc with kcalloc
  drm/tinydrm: Remove explicit .best_encoder assignment
  drm/tinydrm: Replace dev_error with DRM_DEV_ERROR
  drm/drm_of: Move drm_of_panel_bridge_remove_function into header.
  drm/atomic-helper: Fix reference to drm_crtc_send_vblank_event()
  drm/atomic-helper: Fix typo
  drm: Add missing __user annotation to drm_syncobj_array_find()
  drm/rockchip: add PINCTRL dependency for LVDS
  drm/kirin: Checking for IS_ERR() instead of NULL
  driver:gpu: return -ENOMEM on allocation failure.
  ...
parents 787e1b74 2e20c9dd
...@@ -1704,7 +1704,7 @@ crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc) ...@@ -1704,7 +1704,7 @@ crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc)
* drm_atomic_helper_commit_cleanup_done(). * drm_atomic_helper_commit_cleanup_done().
* *
* This is all implemented by in drm_atomic_helper_commit(), giving drivers a * 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 * The tracking of asynchronously executed and still pending commits is done
* using the core structure &drm_crtc_commit. * using the core structure &drm_crtc_commit.
...@@ -1819,7 +1819,7 @@ EXPORT_SYMBOL(drm_atomic_helper_setup_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 * 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 * @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 * 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 * This is part of the atomic helper support for nonblocking commits, see
* drm_atomic_helper_setup_commit() for an overview. * drm_atomic_helper_setup_commit() for an overview.
......
...@@ -562,12 +562,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, ...@@ -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 * Allocate space for the backup of all (non-pointer) encoder and
* connector data. * 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); sizeof(struct drm_crtc *), GFP_KERNEL);
if (!save_encoder_crtcs) if (!save_encoder_crtcs)
return -ENOMEM; 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); sizeof(struct drm_encoder *), GFP_KERNEL);
if (!save_connector_encoders) { if (!save_connector_encoders) {
kfree(save_encoder_crtcs); kfree(save_encoder_crtcs);
......
...@@ -2266,7 +2266,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, ...@@ -2266,7 +2266,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
if (modes[n] == NULL) if (modes[n] == NULL)
return best_score; return best_score;
crtcs = kzalloc(fb_helper->connector_count * crtcs = kcalloc(fb_helper->connector_count,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
if (!crtcs) if (!crtcs)
return best_score; return best_score;
......
...@@ -262,36 +262,3 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, ...@@ -262,36 +262,3 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge); 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);
...@@ -354,7 +354,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -354,7 +354,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
/* Find current connectors for CRTC */ /* Find current connectors for CRTC */
num_connectors = get_connectors_for_crtc(crtc, NULL, 0); num_connectors = get_connectors_for_crtc(crtc, NULL, 0);
BUG_ON(num_connectors == 0); BUG_ON(num_connectors == 0);
connector_list = kzalloc(num_connectors * sizeof(*connector_list), connector_list = kcalloc(num_connectors, sizeof(*connector_list),
GFP_KERNEL); GFP_KERNEL);
if (!connector_list) if (!connector_list)
return -ENOMEM; return -ENOMEM;
......
...@@ -845,7 +845,8 @@ static int drm_syncobj_array_wait(struct drm_device *dev, ...@@ -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, 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) struct drm_syncobj ***syncobjs_out)
{ {
uint32_t i, *handles; uint32_t i, *handles;
......
...@@ -854,7 +854,7 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, ...@@ -854,7 +854,7 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
assert_spin_locked(&dev->event_lock); assert_spin_locked(&dev->event_lock);
e->pipe = pipe; 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; e->event.crtc_id = crtc->base.id;
list_add_tail(&e->base.link, &dev->vblank_event_list); list_add_tail(&e->base.link, &dev->vblank_event_list);
} }
......
...@@ -237,7 +237,7 @@ static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr) ...@@ -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); gct = kmalloc(sizeof(*gct) * vbt.panel_count, GFP_KERNEL);
if (!gct) if (!gct)
return -1; return -ENOMEM;
gct_virtual = ioremap(addr + sizeof(vbt), gct_virtual = ioremap(addr + sizeof(vbt),
sizeof(*gct) * vbt.panel_count); sizeof(*gct) * vbt.panel_count);
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_intel_sdvo_regs.h" #include "psb_intel_sdvo_regs.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
#include <linux/kernel.h>
#define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)
#define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)
...@@ -62,8 +63,6 @@ static const char *tv_format_names[] = { ...@@ -62,8 +63,6 @@ static const char *tv_format_names[] = {
"SECAM_60" "SECAM_60"
}; };
#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names))
struct psb_intel_sdvo { struct psb_intel_sdvo {
struct gma_encoder base; struct gma_encoder base;
...@@ -148,7 +147,7 @@ struct psb_intel_sdvo_connector { ...@@ -148,7 +147,7 @@ struct psb_intel_sdvo_connector {
int force_audio; int force_audio;
/* This contains all current supported TV format */ /* 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; int format_supported_num;
struct drm_property *tv_format; struct drm_property *tv_format;
...@@ -1709,7 +1708,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector, ...@@ -1709,7 +1708,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector,
} }
if (property == psb_intel_sdvo_connector->tv_format) { if (property == psb_intel_sdvo_connector->tv_format) {
if (val >= TV_FORMAT_NUM) if (val >= ARRAY_SIZE(tv_format_names))
return -EINVAL; return -EINVAL;
if (psb_intel_sdvo->tv_format_index == 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 ...@@ -2269,7 +2268,7 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s
return false; return false;
psb_intel_sdvo_connector->format_supported_num = 0; 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)) if (format_map & (1 << i))
psb_intel_sdvo_connector->tv_format_supported[psb_intel_sdvo_connector->format_supported_num++] = i; psb_intel_sdvo_connector->tv_format_supported[psb_intel_sdvo_connector->format_supported_num++] = i;
......
...@@ -237,8 +237,8 @@ static int kirin_drm_platform_probe(struct platform_device *pdev) ...@@ -237,8 +237,8 @@ static int kirin_drm_platform_probe(struct platform_device *pdev)
} }
remote = of_graph_get_remote_node(np, 0, 0); remote = of_graph_get_remote_node(np, 0, 0);
if (IS_ERR(remote)) if (!remote)
return PTR_ERR(remote); return -ENODEV;
drm_of_component_match_add(dev, &match, compare_of, remote); drm_of_component_match_add(dev, &match, compare_of, remote);
of_node_put(remote); of_node_put(remote);
......
...@@ -60,6 +60,7 @@ config ROCKCHIP_INNO_HDMI ...@@ -60,6 +60,7 @@ config ROCKCHIP_INNO_HDMI
config ROCKCHIP_LVDS config ROCKCHIP_LVDS
bool "Rockchip LVDS support" bool "Rockchip LVDS support"
depends on DRM_ROCKCHIP depends on DRM_ROCKCHIP
depends on PINCTRL
help help
Choose this option to enable support for Rockchip LVDS controllers. Choose this option to enable support for Rockchip LVDS controllers.
Rockchip rk3288 SoC has LVDS TX Controller can be used, and it Rockchip rk3288 SoC has LVDS TX Controller can be used, and it
......
...@@ -209,22 +209,11 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, ...@@ -209,22 +209,11 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
{ {
struct drm_plane_state *state = plane->state; struct drm_plane_state *state = plane->state;
struct drm_framebuffer *fb = state->fb; struct drm_framebuffer *fb = state->fb;
struct drm_gem_cma_object *gem;
u32 lo_paddr, hi_paddr; u32 lo_paddr, hi_paddr;
dma_addr_t 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); DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
/* Write the 32 lower bits of the address (in bits) */ /* 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, ...@@ -369,13 +358,6 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
if (IS_ERR(regs)) if (IS_ERR(regs))
return PTR_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); backend->reset = devm_reset_control_get(dev, NULL);
if (IS_ERR(backend->reset)) { if (IS_ERR(backend->reset)) {
dev_err(dev, "Couldn't get our reset line\n"); 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, ...@@ -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); 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) for (i = 0x800; i < 0x1000; i += 4)
regmap_write(backend->engine.regs, i, 0); regmap_write(backend->engine.regs, i, 0);
......
...@@ -226,6 +226,18 @@ struct endpoint_list { ...@@ -226,6 +226,18 @@ struct endpoint_list {
struct list_head 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, static int sun4i_drv_add_endpoints(struct device *dev,
struct list_head *endpoints, struct list_head *endpoints,
struct component_match **match, struct component_match **match,
...@@ -292,6 +304,10 @@ static int sun4i_drv_add_endpoints(struct device *dev, ...@@ -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 */ /* Add downstream nodes to the queue */
endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
if (!endpoint) { if (!endpoint) {
......
...@@ -72,6 +72,11 @@ ...@@ -72,6 +72,11 @@
#define SUN4I_HDMI_PAD_CTRL1_HALVE_CLK BIT(6) #define SUN4I_HDMI_PAD_CTRL1_HALVE_CLK BIT(6)
#define SUN4I_HDMI_PAD_CTRL1_REG_AMP(n) (((n) & 7) << 3) #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_REG 0x208
#define SUN4I_HDMI_PLL_CTRL_PLL_EN BIT(31) #define SUN4I_HDMI_PLL_CTRL_PLL_EN BIT(31)
#define SUN4I_HDMI_PLL_CTRL_BWS BIT(30) #define SUN4I_HDMI_PLL_CTRL_BWS BIT(30)
......
...@@ -144,6 +144,22 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, ...@@ -144,6 +144,22 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC, writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC,
hdmi->base + SUN4I_HDMI_UNKNOWN_REG); 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 */ /* Setup timing registers */
writel(SUN4I_HDMI_VID_TIMING_X(mode->hdisplay) | writel(SUN4I_HDMI_VID_TIMING_X(mode->hdisplay) |
SUN4I_HDMI_VID_TIMING_Y(mode->vdisplay), SUN4I_HDMI_VID_TIMING_Y(mode->vdisplay),
...@@ -489,16 +505,6 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, ...@@ -489,16 +505,6 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
writel(hdmi->variant->pad_ctrl0_init_val, writel(hdmi->variant->pad_ctrl0_init_val,
hdmi->base + SUN4I_HDMI_PAD_CTRL0_REG); 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 = readl(hdmi->base + SUN4I_HDMI_PLL_CTRL_REG);
reg &= SUN4I_HDMI_PLL_CTRL_DIV_MASK; reg &= SUN4I_HDMI_PLL_CTRL_DIV_MASK;
reg |= hdmi->variant->pll_ctrl_init_val; reg |= hdmi->variant->pll_ctrl_init_val;
......
...@@ -51,7 +51,6 @@ static int tinydrm_connector_get_modes(struct drm_connector *connector) ...@@ -51,7 +51,6 @@ static int tinydrm_connector_get_modes(struct drm_connector *connector)
static const struct drm_connector_helper_funcs tinydrm_connector_hfuncs = { static const struct drm_connector_helper_funcs tinydrm_connector_hfuncs = {
.get_modes = tinydrm_connector_get_modes, .get_modes = tinydrm_connector_get_modes,
.best_encoder = drm_atomic_helper_best_encoder,
}; };
static enum drm_connector_status static enum drm_connector_status
......
...@@ -31,7 +31,7 @@ static int mi0283qt_init(struct mipi_dbi *mipi) ...@@ -31,7 +31,7 @@ static int mi0283qt_init(struct mipi_dbi *mipi)
ret = regulator_enable(mipi->regulator); ret = regulator_enable(mipi->regulator);
if (ret) { 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; return ret;
} }
...@@ -42,7 +42,7 @@ static int mi0283qt_init(struct mipi_dbi *mipi) ...@@ -42,7 +42,7 @@ static int mi0283qt_init(struct mipi_dbi *mipi)
mipi_dbi_hw_reset(mipi); mipi_dbi_hw_reset(mipi);
ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET); ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
if (ret) { 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); regulator_disable(mipi->regulator);
return ret; return ret;
} }
...@@ -174,13 +174,13 @@ static int mi0283qt_probe(struct spi_device *spi) ...@@ -174,13 +174,13 @@ static int mi0283qt_probe(struct spi_device *spi)
mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(mipi->reset)) { 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); return PTR_ERR(mipi->reset);
} }
dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW); dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
if (IS_ERR(dc)) { 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); return PTR_ERR(dc);
} }
......
...@@ -474,8 +474,7 @@ static void repaper_get_temperature(struct repaper_epd *epd) ...@@ -474,8 +474,7 @@ static void repaper_get_temperature(struct repaper_epd *epd)
ret = thermal_zone_get_temp(epd->thermal, &temperature); ret = thermal_zone_get_temp(epd->thermal, &temperature);
if (ret) { if (ret) {
dev_err(&epd->spi->dev, "Failed to get temperature (%d)\n", DRM_DEV_ERROR(&epd->spi->dev, "Failed to get temperature (%d)\n", ret);
ret);
return; return;
} }
...@@ -630,7 +629,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb, ...@@ -630,7 +629,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb,
mutex_unlock(&tdev->dirty_lock); mutex_unlock(&tdev->dirty_lock);
if (ret) 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); kfree(buf);
return ret; return ret;
...@@ -704,7 +703,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -704,7 +703,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
} }
if (!i) { 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); power_off(epd);
return; return;
} }
...@@ -726,9 +725,9 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -726,9 +725,9 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
ret = repaper_read_val(spi, 0x0f); ret = repaper_read_val(spi, 0x0f);
if (ret < 0 || !(ret & 0x80)) { if (ret < 0 || !(ret & 0x80)) {
if (ret < 0) 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 else
dev_err(dev, "panel is reported broken\n"); DRM_DEV_ERROR(dev, "panel is reported broken\n");
power_off(epd); power_off(epd);
return; return;
} }
...@@ -768,7 +767,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -768,7 +767,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
/* check DC/DC */ /* check DC/DC */
ret = repaper_read_val(spi, 0x0f); ret = repaper_read_val(spi, 0x0f);
if (ret < 0) { 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); power_off(epd);
return; return;
} }
...@@ -780,7 +779,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -780,7 +779,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
} }
if (!dc_ok) { if (!dc_ok) {
dev_err(dev, "dc/dc failed\n"); DRM_DEV_ERROR(dev, "dc/dc failed\n");
power_off(epd); power_off(epd);
return; return;
} }
...@@ -960,7 +959,7 @@ static int repaper_probe(struct spi_device *spi) ...@@ -960,7 +959,7 @@ static int repaper_probe(struct spi_device *spi)
if (IS_ERR(epd->panel_on)) { if (IS_ERR(epd->panel_on)) {
ret = PTR_ERR(epd->panel_on); ret = PTR_ERR(epd->panel_on);
if (ret != -EPROBE_DEFER) 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; return ret;
} }
...@@ -968,7 +967,7 @@ static int repaper_probe(struct spi_device *spi) ...@@ -968,7 +967,7 @@ static int repaper_probe(struct spi_device *spi)
if (IS_ERR(epd->discharge)) { if (IS_ERR(epd->discharge)) {
ret = PTR_ERR(epd->discharge); ret = PTR_ERR(epd->discharge);
if (ret != -EPROBE_DEFER) 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; return ret;
} }
...@@ -976,7 +975,7 @@ static int repaper_probe(struct spi_device *spi) ...@@ -976,7 +975,7 @@ static int repaper_probe(struct spi_device *spi)
if (IS_ERR(epd->reset)) { if (IS_ERR(epd->reset)) {
ret = PTR_ERR(epd->reset); ret = PTR_ERR(epd->reset);
if (ret != -EPROBE_DEFER) 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; return ret;
} }
...@@ -984,7 +983,7 @@ static int repaper_probe(struct spi_device *spi) ...@@ -984,7 +983,7 @@ static int repaper_probe(struct spi_device *spi)
if (IS_ERR(epd->busy)) { if (IS_ERR(epd->busy)) {
ret = PTR_ERR(epd->busy); ret = PTR_ERR(epd->busy);
if (ret != -EPROBE_DEFER) 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; return ret;
} }
...@@ -992,8 +991,7 @@ static int repaper_probe(struct spi_device *spi) ...@@ -992,8 +991,7 @@ static int repaper_probe(struct spi_device *spi)
&thermal_zone)) { &thermal_zone)) {
epd->thermal = thermal_zone_get_zone_by_name(thermal_zone); epd->thermal = thermal_zone_get_zone_by_name(thermal_zone);
if (IS_ERR(epd->thermal)) { if (IS_ERR(epd->thermal)) {
dev_err(dev, "Failed to get thermal zone: %s\n", DRM_DEV_ERROR(dev, "Failed to get thermal zone: %s\n", thermal_zone);
thermal_zone);
return PTR_ERR(epd->thermal); return PTR_ERR(epd->thermal);
} }
} }
...@@ -1034,7 +1032,7 @@ static int repaper_probe(struct spi_device *spi) ...@@ -1034,7 +1032,7 @@ static int repaper_probe(struct spi_device *spi)
if (IS_ERR(epd->border)) { if (IS_ERR(epd->border)) {
ret = PTR_ERR(epd->border); ret = PTR_ERR(epd->border);
if (ret != -EPROBE_DEFER) 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; return ret;
} }
......
...@@ -188,7 +188,7 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -188,7 +188,7 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
mipi_dbi_hw_reset(mipi); mipi_dbi_hw_reset(mipi);
ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f); ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
if (ret) { if (ret) {
dev_err(dev, "Error sending command %d\n", ret); DRM_DEV_ERROR(dev, "Error sending command %d\n", ret);
return; return;
} }
...@@ -355,13 +355,13 @@ static int st7586_probe(struct spi_device *spi) ...@@ -355,13 +355,13 @@ static int st7586_probe(struct spi_device *spi)
mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(mipi->reset)) { 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); return PTR_ERR(mipi->reset);
} }
a0 = devm_gpiod_get(dev, "a0", GPIOD_OUT_LOW); a0 = devm_gpiod_get(dev, "a0", GPIOD_OUT_LOW);
if (IS_ERR(a0)) { 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); return PTR_ERR(a0);
} }
......
...@@ -859,11 +859,7 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder, ...@@ -859,11 +859,7 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
pll_clock = parent_rate / divider; pll_clock = parent_rate / divider;
pixel_clock_hz = pll_clock / dsi->divider; pixel_clock_hz = pll_clock / dsi->divider;
/* Round up the clk_set_rate() request slightly, since adjusted_mode->clock = pixel_clock_hz / 1000;
* PLLD_DSI1 is an integer divider and its rate selection will
* never round up.
*/
adjusted_mode->clock = pixel_clock_hz / 1000 + 1;
/* Given the new pixel clock, adjust HFP to keep vrefresh the same. */ /* Given the new pixel clock, adjust HFP to keep vrefresh the same. */
adjusted_mode->htotal = adjusted_mode->clock * mode->htotal / adjusted_mode->htotal = adjusted_mode->clock * mode->htotal /
...@@ -901,7 +897,11 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) ...@@ -901,7 +897,11 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
vc4_dsi_dump_regs(dsi); 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); ret = clk_set_rate(dsi->pll_phy_clock, phy_clock);
if (ret) { if (ret) {
dev_err(&dsi->pdev->dev, dev_err(&dsi->pdev->dev,
......
...@@ -547,14 +547,24 @@ static int vc4_plane_mode_set(struct drm_plane *plane, ...@@ -547,14 +547,24 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
tiling = SCALER_CTL0_TILING_LINEAR; tiling = SCALER_CTL0_TILING_LINEAR;
pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH);
break; 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; tiling = SCALER_CTL0_TILING_256B_OR_T;
pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET), pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET) |
VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L), VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L) |
VC4_SET_FIELD((vc4_state->src_w[0] + 31) >> 5, VC4_SET_FIELD(tiles_w, SCALER_PITCH0_TILE_WIDTH_R));
SCALER_PITCH0_TILE_WIDTH_R));
break; break;
}
default: default:
DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx", DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx",
(long long)fb->modifier); (long long)fb->modifier);
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <drm/drm_legacy.h> #include <drm/drm_legacy.h>
#include "via_verifier.h" #include "via_verifier.h"
#include "via_drv.h" #include "via_drv.h"
#include <linux/kernel.h>
typedef enum { typedef enum {
state_command, state_command,
...@@ -1102,10 +1103,7 @@ setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size) ...@@ -1102,10 +1103,7 @@ setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
void via_init_command_verifier(void) void via_init_command_verifier(void)
{ {
setup_hazard_table(init_table1, table1, setup_hazard_table(init_table1, table1, ARRAY_SIZE(init_table1));
sizeof(init_table1) / sizeof(hz_init_t)); setup_hazard_table(init_table2, table2, ARRAY_SIZE(init_table2));
setup_hazard_table(init_table2, table2, setup_hazard_table(init_table3, table3, ARRAY_SIZE(init_table3));
sizeof(init_table2) / sizeof(hz_init_t));
setup_hazard_table(init_table3, table3,
sizeof(init_table3) / sizeof(hz_init_t));
} }
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
#define __DRM_OF_H__ #define __DRM_OF_H__
#include <linux/of_graph.h> #include <linux/of_graph.h>
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
#include <drm/drm_bridge.h>
#endif
struct component_master_ops; struct component_master_ops;
struct component_match; struct component_match;
...@@ -29,8 +32,6 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, ...@@ -29,8 +32,6 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
int port, int endpoint, int port, int endpoint,
struct drm_panel **panel, struct drm_panel **panel,
struct drm_bridge **bridge); struct drm_bridge **bridge);
int drm_of_panel_bridge_remove(const struct device_node *np,
int port, int endpoint);
#else #else
static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
struct device_node *port) struct device_node *port)
...@@ -67,13 +68,35 @@ static inline int drm_of_find_panel_or_bridge(const struct device_node *np, ...@@ -67,13 +68,35 @@ static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
{ {
return -EINVAL; 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, static inline int drm_of_panel_bridge_remove(const struct device_node *np,
int port, int endpoint) 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; return -EINVAL;
}
#endif #endif
}
static inline int drm_of_encoder_active_endpoint_id(struct device_node *node, static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,
struct drm_encoder *encoder) struct drm_encoder *encoder)
......
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