提交 6c94804f 编写于 作者: D 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.
  ...
......@@ -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.
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -37,6 +37,7 @@
#include "psb_drv.h"
#include "psb_intel_sdvo_regs.h"
#include "psb_intel_reg.h"
#include <linux/kernel.h>
#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;
......
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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)
......
......@@ -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;
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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,
......
......@@ -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);
......
......@@ -34,6 +34,7 @@
#include <drm/drm_legacy.h>
#include "via_verifier.h"
#include "via_drv.h"
#include <linux/kernel.h>
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));
}
......@@ -2,6 +2,9 @@
#define __DRM_OF_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_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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册