Merge tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm

Pull drm updates from Dave Airlie:
 "Highlights:

   - Core DRM had a lot of refactoring around managed drm resources to
     make drivers simpler.

   - Intel Tigerlake support is on by default

   - amdgpu now support p2p PCI buffer sharing and encrypted GPU memory

  Details:

  core:
   - uapi: error out EBUSY when existing master
   - uapi: rework SET/DROP MASTER permission handling
   - remove drm_pci.h
   - drm_pci* are now legacy
   - introduced managed DRM resources
   - subclassing support for drm_framebuffer
   - simple encoder helper
   - edid improvements
   - vblank + writeback documentation improved
   - drm/mm - optimise tree searches
   - port drivers to use devm_drm_dev_alloc

  dma-buf:
   - add flag for p2p buffer support

  mst:
   - ACT timeout improvements
   - remove drm_dp_mst_has_audio
   - don't use 2nd TX slot - spec recommends against it

  bridge:
   - dw-hdmi various improvements
   - chrontel ch7033 support
   - fix stack issues with old gcc

  hdmi:
   - add unpack function for drm infoframe

  fbdev:
   - misc fbdev driver fixes

  i915:
   - uapi: global sseu pinning
   - uapi: OA buffer polling
   - uapi: remove generated perf code
   - uapi: per-engine default property values in sysfs
   - Tigerlake GEN12 enabled.
   - Lots of gem refactoring
   - Tigerlake enablement patches
   - move to drm_device logging
   - Icelake gamma HW readout
   - push MST link retrain to hotplug work
   - bandwidth atomic helpers
   - ICL fixes
   - RPS/GT refactoring
   - Cherryview full-ppgtt support
   - i915 locking guidelines documented
   - require linear fb stride to be 512 multiple on gen9
   - Tigerlake SAGV support

  amdgpu:
   - uapi: encrypted GPU memory handling
   - uapi: add MEM_SYNC IB flag
   - p2p dma-buf support
   - export VRAM dma-bufs
   - FRU chip access support
   - RAS/SR-IOV updates
   - Powerplay locking fixes
   - VCN DPG (powergating) enablement
   - GFX10 clockgating fixes
   - DC fixes
   - GPU reset fixes
   - navi SDMA fix
   - expose FP16 for modesetting
   - DP 1.4 compliance fixes
   - gfx10 soft recovery
   - Improved Critical Thermal Faults handling
   - resizable BAR on gmc10

  amdkfd:
   - uapi: GWS resource management
   - track GPU memory per process
   - report PCI domain in topology

  radeon:
   - safe reg list generator fixes

  nouveau:
   - HD audio fixes on recent systems
   - vGPU detection (fail probe if we're on one, for now)
   - Interlaced mode fixes (mostly avoidance on Turing, which doesn't support it)
   - SVM improvements/fixes
   - NVIDIA format modifier support
   - Misc other fixes.

  adv7511:
   - HDMI SPDIF support

  ast:
   - allocate crtc state size
   - fix double assignment
   - fix suspend

  bochs:
   - drop connector register

  cirrus:
   - move to tiny drivers.

  exynos:
   - fix imported dma-buf mapping
   - enable runtime PM
   - fixes and cleanups

  mediatek:
   - DPI pin mode swap
   - config mipi_tx current/impedance

  lima:
   - devfreq + cooling device support
   - task handling improvements
   - runtime PM support

  pl111:
   - vexpress init improvements
   - fix module auto-load

  rcar-du:
   - DT bindings conversion to YAML
   - Planes zpos sanity check and fix
   - MAINTAINERS entry for LVDS panel driver

  mcde:
   - fix return value

  mgag200:
   - use managed config init

  stm:
   - read endpoints from DT

  vboxvideo:
   - use PCI managed functions
   - drop WC mtrr

  vkms:
   - enable cursor by default

  rockchip:
   - afbc support

  virtio:
   - various cleanups

  qxl:
   - fix cursor notify port

  hisilicon:
   - 128-byte stride alignment fix

  sun4i:
   - improved format handling"

* tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm: (1401 commits)
  drm/amd/display: Fix potential integer wraparound resulting in a hang
  drm/amd/display: drop cursor position check in atomic test
  drm/amdgpu: fix device attribute node create failed with multi gpu
  drm/nouveau: use correct conflicting framebuffer API
  drm/vblank: Fix -Wformat compile warnings on some arches
  drm/amdgpu: Sync with VM root BO when switching VM to CPU update mode
  drm/amd/display: Handle GPU reset for DC block
  drm/amdgpu: add apu flags (v2)
  drm/amd/powerpay: Disable gfxoff when setting manual mode on picasso and raven
  drm/amdgpu: fix pm sysfs node handling (v2)
  drm/amdgpu: move gpu_info parsing after common early init
  drm/amdgpu: move discovery gfx config fetching
  drm/nouveau/dispnv50: fix runtime pm imbalance on error
  drm/nouveau: fix runtime pm imbalance on error
  drm/nouveau: fix runtime pm imbalance on error
  drm/nouveau/debugfs: fix runtime pm imbalance on error
  drm/nouveau/nouveau/hmm: fix migrate zero page to GPU
  drm/nouveau/nouveau/hmm: fix nouveau_dmem_chunk allocations
  drm/nouveau/kms/nv50-: Share DP SST mode_valid() handling with MST
  drm/nouveau/kms/nv50-: Move 8BPC limit for MST into nv50_mstc_get_modes()
  ...
This commit is contained in:
Linus Torvalds
2020-06-02 15:04:15 -07:00
1191 changed files with 41152 additions and 20582 deletions

View File

@@ -27,6 +27,16 @@ config DRM_CDNS_DSI
Support Cadence DPI to DSI bridge. This is an internal
bridge and is meant to be directly embedded in a SoC.
config DRM_CHRONTEL_CH7033
tristate "Chrontel CH7033 Video Encoder"
depends on OF
select DRM_KMS_HELPER
help
Enable support for the Chrontel CH7033 VGA/DVI/HDMI Encoder, as
found in the Dell Wyse 3020 thin client.
If in doubt, say "N".
config DRM_DISPLAY_CONNECTOR
tristate "Display connector support"
depends on OF
@@ -58,6 +68,22 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
to DP++. This is used with the i.MX6 imx-ldb
driver. You are likely to say N here.
config DRM_NWL_MIPI_DSI
tristate "Northwest Logic MIPI DSI Host controller"
depends on DRM
depends on COMMON_CLK
depends on OF && HAS_IOMEM
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE
select GENERIC_PHY_MIPI_DPHY
select MFD_SYSCON
select MULTIPLEXER
select REGMAP_MMIO
help
This enables the Northwest Logic MIPI DSI Host controller as
for example found on NXP's i.MX8 Processors.
config DRM_NXP_PTN3460
tristate "NXP PTN3460 DP/LVDS bridge"
depends on OF

View File

@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o
obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
@@ -18,6 +19,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
obj-y += analogix/
obj-y += synopsys/

View File

@@ -6,7 +6,7 @@ config DRM_I2C_ADV7511
select REGMAP_I2C
select DRM_MIPI_DSI
help
Support for the Analog Device ADV7511(W)/13/33/35 HDMI encoders.
Support for the Analog Devices ADV7511(W)/13/33/35 HDMI encoders.
config DRM_I2C_ADV7511_AUDIO
bool "ADV7511 HDMI Audio driver"

View File

@@ -19,13 +19,15 @@ static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs,
{
switch (fs) {
case 32000:
*n = 4096;
case 48000:
case 96000:
case 192000:
*n = fs * 128 / 1000;
break;
case 44100:
*n = 6272;
break;
case 48000:
*n = 6144;
case 88200:
case 176400:
*n = fs * 128 / 900;
break;
}
@@ -119,6 +121,9 @@ int adv7511_hdmi_hw_params(struct device *dev, void *data,
audio_source = ADV7511_AUDIO_SOURCE_I2S;
i2s_format = ADV7511_I2S_FORMAT_LEFT_J;
break;
case HDMI_SPDIF:
audio_source = ADV7511_AUDIO_SOURCE_SPDIF;
break;
default:
return -EINVAL;
}
@@ -175,11 +180,21 @@ static int audio_startup(struct device *dev, void *data)
/* use Audio infoframe updated info */
regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1),
BIT(5), 0);
/* enable SPDIF receiver */
if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF)
regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG,
BIT(7), BIT(7));
return 0;
}
static void audio_shutdown(struct device *dev, void *data)
{
struct adv7511 *adv7511 = dev_get_drvdata(dev);
if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF)
regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG,
BIT(7), 0);
}
static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
@@ -213,6 +228,7 @@ static const struct hdmi_codec_pdata codec_data = {
.ops = &adv7511_codec_ops,
.max_i2s_channels = 2,
.i2s = 1,
.spdif = 1,
};
int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511)

View File

@@ -0,0 +1,620 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Chrontel CH7033 Video Encoder Driver
*
* Copyright (C) 2019,2020 Lubomir Rintel
*/
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
/* Page 0, Register 0x07 */
enum {
DRI_PD = BIT(3),
IO_PD = BIT(5),
};
/* Page 0, Register 0x08 */
enum {
DRI_PDDRI = GENMASK(7, 4),
PDDAC = GENMASK(3, 1),
PANEN = BIT(0),
};
/* Page 0, Register 0x09 */
enum {
DPD = BIT(7),
GCKOFF = BIT(6),
TV_BP = BIT(5),
SCLPD = BIT(4),
SDPD = BIT(3),
VGA_PD = BIT(2),
HDBKPD = BIT(1),
HDMI_PD = BIT(0),
};
/* Page 0, Register 0x0a */
enum {
MEMINIT = BIT(7),
MEMIDLE = BIT(6),
MEMPD = BIT(5),
STOP = BIT(4),
LVDS_PD = BIT(3),
HD_DVIB = BIT(2),
HDCP_PD = BIT(1),
MCU_PD = BIT(0),
};
/* Page 0, Register 0x18 */
enum {
IDF = GENMASK(7, 4),
INTEN = BIT(3),
SWAP = GENMASK(2, 0),
};
enum {
BYTE_SWAP_RGB = 0,
BYTE_SWAP_RBG = 1,
BYTE_SWAP_GRB = 2,
BYTE_SWAP_GBR = 3,
BYTE_SWAP_BRG = 4,
BYTE_SWAP_BGR = 5,
};
/* Page 0, Register 0x19 */
enum {
HPO_I = BIT(5),
VPO_I = BIT(4),
DEPO_I = BIT(3),
CRYS_EN = BIT(2),
GCLKFREQ = GENMASK(2, 0),
};
/* Page 0, Register 0x2e */
enum {
HFLIP = BIT(7),
VFLIP = BIT(6),
DEPO_O = BIT(5),
HPO_O = BIT(4),
VPO_O = BIT(3),
TE = GENMASK(2, 0),
};
/* Page 0, Register 0x2b */
enum {
SWAPS = GENMASK(7, 4),
VFMT = GENMASK(3, 0),
};
/* Page 0, Register 0x54 */
enum {
COMP_BP = BIT(7),
DAC_EN_T = BIT(6),
HWO_HDMI_HI = GENMASK(5, 3),
HOO_HDMI_HI = GENMASK(2, 0),
};
/* Page 0, Register 0x57 */
enum {
FLDSEN = BIT(7),
VWO_HDMI_HI = GENMASK(5, 3),
VOO_HDMI_HI = GENMASK(2, 0),
};
/* Page 0, Register 0x7e */
enum {
HDMI_LVDS_SEL = BIT(7),
DE_GEN = BIT(6),
PWM_INDEX_HI = BIT(5),
USE_DE = BIT(4),
R_INT = GENMASK(3, 0),
};
/* Page 1, Register 0x07 */
enum {
BPCKSEL = BIT(7),
DRI_CMFB_EN = BIT(6),
CEC_PUEN = BIT(5),
CEC_T = BIT(3),
CKINV = BIT(2),
CK_TVINV = BIT(1),
DRI_CKS2 = BIT(0),
};
/* Page 1, Register 0x08 */
enum {
DACG = BIT(6),
DACKTST = BIT(5),
DEDGEB = BIT(4),
SYO = BIT(3),
DRI_IT_LVDS = GENMASK(2, 1),
DISPON = BIT(0),
};
/* Page 1, Register 0x0c */
enum {
DRI_PLL_CP = GENMASK(7, 6),
DRI_PLL_DIVSEL = BIT(5),
DRI_PLL_N1_1 = BIT(4),
DRI_PLL_N1_0 = BIT(3),
DRI_PLL_N3_1 = BIT(2),
DRI_PLL_N3_0 = BIT(1),
DRI_PLL_CKTSTEN = BIT(0),
};
/* Page 1, Register 0x6b */
enum {
VCO3CS = GENMASK(7, 6),
ICPGBK2_0 = GENMASK(5, 3),
DRI_VCO357SC = BIT(2),
PDPLL2 = BIT(1),
DRI_PD_SER = BIT(0),
};
/* Page 1, Register 0x6c */
enum {
PLL2N11 = GENMASK(7, 4),
PLL2N5_4 = BIT(3),
PLL2N5_TOP = BIT(2),
DRI_PLL_PD = BIT(1),
PD_I2CM = BIT(0),
};
/* Page 3, Register 0x28 */
enum {
DIFF_EN = GENMASK(7, 6),
CORREC_EN = GENMASK(5, 4),
VGACLK_BP = BIT(3),
HM_LV_SEL = BIT(2),
HD_VGA_SEL = BIT(1),
};
/* Page 3, Register 0x2a */
enum {
LVDSCLK_BP = BIT(7),
HDTVCLK_BP = BIT(6),
HDMICLK_BP = BIT(5),
HDTV_BP = BIT(4),
HDMI_BP = BIT(3),
THRWL = GENMASK(2, 0),
};
/* Page 4, Register 0x52 */
enum {
PGM_ARSTB = BIT(7),
MCU_ARSTB = BIT(6),
MCU_RETB = BIT(2),
RESETIB = BIT(1),
RESETDB = BIT(0),
};
struct ch7033_priv {
struct regmap *regmap;
struct drm_bridge *next_bridge;
struct drm_bridge bridge;
struct drm_connector connector;
};
#define conn_to_ch7033_priv(x) \
container_of(x, struct ch7033_priv, connector)
#define bridge_to_ch7033_priv(x) \
container_of(x, struct ch7033_priv, bridge)
static enum drm_connector_status ch7033_connector_detect(
struct drm_connector *connector, bool force)
{
struct ch7033_priv *priv = conn_to_ch7033_priv(connector);
return drm_bridge_detect(priv->next_bridge);
}
static const struct drm_connector_funcs ch7033_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = ch7033_connector_detect,
.destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static int ch7033_connector_get_modes(struct drm_connector *connector)
{
struct ch7033_priv *priv = conn_to_ch7033_priv(connector);
struct edid *edid;
int ret;
edid = drm_bridge_get_edid(priv->next_bridge, connector);
drm_connector_update_edid_property(connector, edid);
if (edid) {
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
} else {
ret = drm_add_modes_noedid(connector, 1920, 1080);
drm_set_preferred_mode(connector, 1024, 768);
}
return ret;
}
static struct drm_encoder *ch7033_connector_best_encoder(
struct drm_connector *connector)
{
struct ch7033_priv *priv = conn_to_ch7033_priv(connector);
return priv->bridge.encoder;
}
static const struct drm_connector_helper_funcs ch7033_connector_helper_funcs = {
.get_modes = ch7033_connector_get_modes,
.best_encoder = ch7033_connector_best_encoder,
};
static void ch7033_hpd_event(void *arg, enum drm_connector_status status)
{
struct ch7033_priv *priv = arg;
if (priv->bridge.dev)
drm_helper_hpd_irq_event(priv->connector.dev);
}
static int ch7033_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
struct drm_connector *connector = &priv->connector;
int ret;
ret = drm_bridge_attach(bridge->encoder, priv->next_bridge, bridge,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret)
return ret;
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
return 0;
if (priv->next_bridge->ops & DRM_BRIDGE_OP_DETECT) {
connector->polled = DRM_CONNECTOR_POLL_HPD;
} else {
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
}
if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD) {
drm_bridge_hpd_enable(priv->next_bridge, ch7033_hpd_event,
priv);
}
drm_connector_helper_add(connector,
&ch7033_connector_helper_funcs);
ret = drm_connector_init_with_ddc(bridge->dev, &priv->connector,
&ch7033_connector_funcs,
priv->next_bridge->type,
priv->next_bridge->ddc);
if (ret) {
DRM_ERROR("Failed to initialize connector\n");
return ret;
}
return drm_connector_attach_encoder(&priv->connector, bridge->encoder);
}
static void ch7033_bridge_detach(struct drm_bridge *bridge)
{
struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD)
drm_bridge_hpd_disable(priv->next_bridge);
drm_connector_cleanup(&priv->connector);
}
static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_mode *mode)
{
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
if (mode->hdisplay >= 1920)
return MODE_BAD_HVALUE;
if (mode->vdisplay >= 1080)
return MODE_BAD_VVALUE;
return MODE_OK;
}
static void ch7033_bridge_disable(struct drm_bridge *bridge)
{
struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
regmap_write(priv->regmap, 0x03, 0x04);
regmap_update_bits(priv->regmap, 0x52, RESETDB, 0x00);
}
static void ch7033_bridge_enable(struct drm_bridge *bridge)
{
struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
regmap_write(priv->regmap, 0x03, 0x04);
regmap_update_bits(priv->regmap, 0x52, RESETDB, RESETDB);
}
static void ch7033_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
{
struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
int hbporch = mode->hsync_start - mode->hdisplay;
int hsynclen = mode->hsync_end - mode->hsync_start;
int vbporch = mode->vsync_start - mode->vdisplay;
int vsynclen = mode->vsync_end - mode->vsync_start;
/*
* Page 4
*/
regmap_write(priv->regmap, 0x03, 0x04);
/* Turn everything off to set all the registers to their defaults. */
regmap_write(priv->regmap, 0x52, 0x00);
/* Bring I/O block up. */
regmap_write(priv->regmap, 0x52, RESETIB);
/*
* Page 0
*/
regmap_write(priv->regmap, 0x03, 0x00);
/* Bring up parts we need from the power down. */
regmap_update_bits(priv->regmap, 0x07, DRI_PD | IO_PD, 0);
regmap_update_bits(priv->regmap, 0x08, DRI_PDDRI | PDDAC | PANEN, 0);
regmap_update_bits(priv->regmap, 0x09, DPD | GCKOFF |
HDMI_PD | VGA_PD, 0);
regmap_update_bits(priv->regmap, 0x0a, HD_DVIB, 0);
/* Horizontal input timing. */
regmap_write(priv->regmap, 0x0b, (mode->htotal >> 8) << 3 |
(mode->hdisplay >> 8));
regmap_write(priv->regmap, 0x0c, mode->hdisplay);
regmap_write(priv->regmap, 0x0d, mode->htotal);
regmap_write(priv->regmap, 0x0e, (hsynclen >> 8) << 3 |
(hbporch >> 8));
regmap_write(priv->regmap, 0x0f, hbporch);
regmap_write(priv->regmap, 0x10, hsynclen);
/* Vertical input timing. */
regmap_write(priv->regmap, 0x11, (mode->vtotal >> 8) << 3 |
(mode->vdisplay >> 8));
regmap_write(priv->regmap, 0x12, mode->vdisplay);
regmap_write(priv->regmap, 0x13, mode->vtotal);
regmap_write(priv->regmap, 0x14, ((vsynclen >> 8) << 3) |
(vbporch >> 8));
regmap_write(priv->regmap, 0x15, vbporch);
regmap_write(priv->regmap, 0x16, vsynclen);
/* Input color swap. */
regmap_update_bits(priv->regmap, 0x18, SWAP, BYTE_SWAP_BGR);
/* Input clock and sync polarity. */
regmap_update_bits(priv->regmap, 0x19, 0x1, mode->clock >> 16);
regmap_update_bits(priv->regmap, 0x19, HPO_I | VPO_I | GCLKFREQ,
(mode->flags & DRM_MODE_FLAG_PHSYNC) ? HPO_I : 0 |
(mode->flags & DRM_MODE_FLAG_PVSYNC) ? VPO_I : 0 |
mode->clock >> 16);
regmap_write(priv->regmap, 0x1a, mode->clock >> 8);
regmap_write(priv->regmap, 0x1b, mode->clock);
/* Horizontal output timing. */
regmap_write(priv->regmap, 0x1f, (mode->htotal >> 8) << 3 |
(mode->hdisplay >> 8));
regmap_write(priv->regmap, 0x20, mode->hdisplay);
regmap_write(priv->regmap, 0x21, mode->htotal);
/* Vertical output timing. */
regmap_write(priv->regmap, 0x25, (mode->vtotal >> 8) << 3 |
(mode->vdisplay >> 8));
regmap_write(priv->regmap, 0x26, mode->vdisplay);
regmap_write(priv->regmap, 0x27, mode->vtotal);
/* VGA channel bypass */
regmap_update_bits(priv->regmap, 0x2b, VFMT, 9);
/* Output sync polarity. */
regmap_update_bits(priv->regmap, 0x2e, HPO_O | VPO_O,
(mode->flags & DRM_MODE_FLAG_PHSYNC) ? HPO_O : 0 |
(mode->flags & DRM_MODE_FLAG_PVSYNC) ? VPO_O : 0);
/* HDMI horizontal output timing. */
regmap_update_bits(priv->regmap, 0x54, HWO_HDMI_HI | HOO_HDMI_HI,
(hsynclen >> 8) << 3 |
(hbporch >> 8));
regmap_write(priv->regmap, 0x55, hbporch);
regmap_write(priv->regmap, 0x56, hsynclen);
/* HDMI vertical output timing. */
regmap_update_bits(priv->regmap, 0x57, VWO_HDMI_HI | VOO_HDMI_HI,
(vsynclen >> 8) << 3 |
(vbporch >> 8));
regmap_write(priv->regmap, 0x58, vbporch);
regmap_write(priv->regmap, 0x59, vsynclen);
/* Pick HDMI, not LVDS. */
regmap_update_bits(priv->regmap, 0x7e, HDMI_LVDS_SEL, HDMI_LVDS_SEL);
/*
* Page 1
*/
regmap_write(priv->regmap, 0x03, 0x01);
/* No idea what these do, but VGA is wobbly and blinky without them. */
regmap_update_bits(priv->regmap, 0x07, CKINV, CKINV);
regmap_update_bits(priv->regmap, 0x08, DISPON, DISPON);
/* DRI PLL */
regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_DIVSEL, DRI_PLL_DIVSEL);
if (mode->clock <= 40000) {
regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 |
DRI_PLL_N1_0 |
DRI_PLL_N3_1 |
DRI_PLL_N3_0,
0);
} else if (mode->clock < 80000) {
regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 |
DRI_PLL_N1_0 |
DRI_PLL_N3_1 |
DRI_PLL_N3_0,
DRI_PLL_N3_0 |
DRI_PLL_N1_0);
} else {
regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 |
DRI_PLL_N1_0 |
DRI_PLL_N3_1 |
DRI_PLL_N3_0,
DRI_PLL_N3_1 |
DRI_PLL_N1_1);
}
/* This seems to be color calibration for VGA. */
regmap_write(priv->regmap, 0x64, 0x29); /* LSB Blue */
regmap_write(priv->regmap, 0x65, 0x29); /* LSB Green */
regmap_write(priv->regmap, 0x66, 0x29); /* LSB Red */
regmap_write(priv->regmap, 0x67, 0x00); /* MSB Blue */
regmap_write(priv->regmap, 0x68, 0x00); /* MSB Green */
regmap_write(priv->regmap, 0x69, 0x00); /* MSB Red */
regmap_update_bits(priv->regmap, 0x6b, DRI_PD_SER, 0x00);
regmap_update_bits(priv->regmap, 0x6c, DRI_PLL_PD, 0x00);
/*
* Page 3
*/
regmap_write(priv->regmap, 0x03, 0x03);
/* More bypasses and apparently another HDMI/LVDS selector. */
regmap_update_bits(priv->regmap, 0x28, VGACLK_BP | HM_LV_SEL,
VGACLK_BP | HM_LV_SEL);
regmap_update_bits(priv->regmap, 0x2a, HDMICLK_BP | HDMI_BP,
HDMICLK_BP | HDMI_BP);
/*
* Page 4
*/
regmap_write(priv->regmap, 0x03, 0x04);
/* Output clock. */
regmap_write(priv->regmap, 0x10, mode->clock >> 16);
regmap_write(priv->regmap, 0x11, mode->clock >> 8);
regmap_write(priv->regmap, 0x12, mode->clock);
}
static const struct drm_bridge_funcs ch7033_bridge_funcs = {
.attach = ch7033_bridge_attach,
.detach = ch7033_bridge_detach,
.mode_valid = ch7033_bridge_mode_valid,
.disable = ch7033_bridge_disable,
.enable = ch7033_bridge_enable,
.mode_set = ch7033_bridge_mode_set,
};
static const struct regmap_config ch7033_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x7f,
};
static int ch7033_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct ch7033_priv *priv;
unsigned int val;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
dev_set_drvdata(dev, priv);
ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
&priv->next_bridge);
if (ret)
return ret;
priv->regmap = devm_regmap_init_i2c(client, &ch7033_regmap_config);
if (IS_ERR(priv->regmap)) {
dev_err(&client->dev, "regmap init failed\n");
return PTR_ERR(priv->regmap);
}
ret = regmap_read(priv->regmap, 0x00, &val);
if (ret < 0) {
dev_err(&client->dev, "error reading the model id: %d\n", ret);
return ret;
}
if ((val & 0xf7) != 0x56) {
dev_err(&client->dev, "the device is not a ch7033\n");
return -ENODEV;
}
regmap_write(priv->regmap, 0x03, 0x04);
ret = regmap_read(priv->regmap, 0x51, &val);
if (ret < 0) {
dev_err(&client->dev, "error reading the model id: %d\n", ret);
return ret;
}
if ((val & 0x0f) != 3) {
dev_err(&client->dev, "unknown revision %u\n", val);
return -ENODEV;
}
INIT_LIST_HEAD(&priv->bridge.list);
priv->bridge.funcs = &ch7033_bridge_funcs;
priv->bridge.of_node = dev->of_node;
drm_bridge_add(&priv->bridge);
dev_info(dev, "Chrontel CH7033 Video Encoder\n");
return 0;
}
static int ch7033_remove(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct ch7033_priv *priv = dev_get_drvdata(dev);
drm_bridge_remove(&priv->bridge);
return 0;
}
static const struct of_device_id ch7033_dt_ids[] = {
{ .compatible = "chrontel,ch7033", },
{ }
};
MODULE_DEVICE_TABLE(of, ch7033_dt_ids);
static const struct i2c_device_id ch7033_ids[] = {
{ "ch7033", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ch7033_ids);
static struct i2c_driver ch7033_driver = {
.probe = ch7033_probe,
.remove = ch7033_remove,
.driver = {
.name = "ch7033",
.of_match_table = of_match_ptr(ch7033_dt_ids),
},
.id_table = ch7033_ids,
};
module_i2c_driver(ch7033_driver);
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
MODULE_DESCRIPTION("Chrontel CH7033 Video Encoder Driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* NWL MIPI DSI host driver
*
* Copyright (C) 2017 NXP
* Copyright (C) 2019 Purism SPC
*/
#ifndef __NWL_DSI_H__
#define __NWL_DSI_H__
/* DSI HOST registers */
#define NWL_DSI_CFG_NUM_LANES 0x0
#define NWL_DSI_CFG_NONCONTINUOUS_CLK 0x4
#define NWL_DSI_CFG_T_PRE 0x8
#define NWL_DSI_CFG_T_POST 0xc
#define NWL_DSI_CFG_TX_GAP 0x10
#define NWL_DSI_CFG_AUTOINSERT_EOTP 0x14
#define NWL_DSI_CFG_EXTRA_CMDS_AFTER_EOTP 0x18
#define NWL_DSI_CFG_HTX_TO_COUNT 0x1c
#define NWL_DSI_CFG_LRX_H_TO_COUNT 0x20
#define NWL_DSI_CFG_BTA_H_TO_COUNT 0x24
#define NWL_DSI_CFG_TWAKEUP 0x28
#define NWL_DSI_CFG_STATUS_OUT 0x2c
#define NWL_DSI_RX_ERROR_STATUS 0x30
/* DSI DPI registers */
#define NWL_DSI_PIXEL_PAYLOAD_SIZE 0x200
#define NWL_DSI_PIXEL_FIFO_SEND_LEVEL 0x204
#define NWL_DSI_INTERFACE_COLOR_CODING 0x208
#define NWL_DSI_PIXEL_FORMAT 0x20c
#define NWL_DSI_VSYNC_POLARITY 0x210
#define NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW 0
#define NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH BIT(1)
#define NWL_DSI_HSYNC_POLARITY 0x214
#define NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW 0
#define NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH BIT(1)
#define NWL_DSI_VIDEO_MODE 0x218
#define NWL_DSI_HFP 0x21c
#define NWL_DSI_HBP 0x220
#define NWL_DSI_HSA 0x224
#define NWL_DSI_ENABLE_MULT_PKTS 0x228
#define NWL_DSI_VBP 0x22c
#define NWL_DSI_VFP 0x230
#define NWL_DSI_BLLP_MODE 0x234
#define NWL_DSI_USE_NULL_PKT_BLLP 0x238
#define NWL_DSI_VACTIVE 0x23c
#define NWL_DSI_VC 0x240
/* DSI APB PKT control */
#define NWL_DSI_TX_PAYLOAD 0x280
#define NWL_DSI_PKT_CONTROL 0x284
#define NWL_DSI_SEND_PACKET 0x288
#define NWL_DSI_PKT_STATUS 0x28c
#define NWL_DSI_PKT_FIFO_WR_LEVEL 0x290
#define NWL_DSI_PKT_FIFO_RD_LEVEL 0x294
#define NWL_DSI_RX_PAYLOAD 0x298
#define NWL_DSI_RX_PKT_HEADER 0x29c
/* DSI IRQ handling */
#define NWL_DSI_IRQ_STATUS 0x2a0
#define NWL_DSI_SM_NOT_IDLE BIT(0)
#define NWL_DSI_TX_PKT_DONE BIT(1)
#define NWL_DSI_DPHY_DIRECTION BIT(2)
#define NWL_DSI_TX_FIFO_OVFLW BIT(3)
#define NWL_DSI_TX_FIFO_UDFLW BIT(4)
#define NWL_DSI_RX_FIFO_OVFLW BIT(5)
#define NWL_DSI_RX_FIFO_UDFLW BIT(6)
#define NWL_DSI_RX_PKT_HDR_RCVD BIT(7)
#define NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD BIT(8)
#define NWL_DSI_BTA_TIMEOUT BIT(29)
#define NWL_DSI_LP_RX_TIMEOUT BIT(30)
#define NWL_DSI_HS_TX_TIMEOUT BIT(31)
#define NWL_DSI_IRQ_STATUS2 0x2a4
#define NWL_DSI_SINGLE_BIT_ECC_ERR BIT(0)
#define NWL_DSI_MULTI_BIT_ECC_ERR BIT(1)
#define NWL_DSI_CRC_ERR BIT(2)
#define NWL_DSI_IRQ_MASK 0x2a8
#define NWL_DSI_SM_NOT_IDLE_MASK BIT(0)
#define NWL_DSI_TX_PKT_DONE_MASK BIT(1)
#define NWL_DSI_DPHY_DIRECTION_MASK BIT(2)
#define NWL_DSI_TX_FIFO_OVFLW_MASK BIT(3)
#define NWL_DSI_TX_FIFO_UDFLW_MASK BIT(4)
#define NWL_DSI_RX_FIFO_OVFLW_MASK BIT(5)
#define NWL_DSI_RX_FIFO_UDFLW_MASK BIT(6)
#define NWL_DSI_RX_PKT_HDR_RCVD_MASK BIT(7)
#define NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD_MASK BIT(8)
#define NWL_DSI_BTA_TIMEOUT_MASK BIT(29)
#define NWL_DSI_LP_RX_TIMEOUT_MASK BIT(30)
#define NWL_DSI_HS_TX_TIMEOUT_MASK BIT(31)
#define NWL_DSI_IRQ_MASK2 0x2ac
#define NWL_DSI_SINGLE_BIT_ECC_ERR_MASK BIT(0)
#define NWL_DSI_MULTI_BIT_ECC_ERR_MASK BIT(1)
#define NWL_DSI_CRC_ERR_MASK BIT(2)
/*
* PKT_CONTROL format:
* [15: 0] - word count
* [17:16] - virtual channel
* [23:18] - data type
* [24] - LP or HS select (0 - LP, 1 - HS)
* [25] - perform BTA after packet is sent
* [26] - perform BTA only, no packet tx
*/
#define NWL_DSI_WC(x) FIELD_PREP(GENMASK(15, 0), (x))
#define NWL_DSI_TX_VC(x) FIELD_PREP(GENMASK(17, 16), (x))
#define NWL_DSI_TX_DT(x) FIELD_PREP(GENMASK(23, 18), (x))
#define NWL_DSI_HS_SEL(x) FIELD_PREP(GENMASK(24, 24), (x))
#define NWL_DSI_BTA_TX(x) FIELD_PREP(GENMASK(25, 25), (x))
#define NWL_DSI_BTA_NO_TX(x) FIELD_PREP(GENMASK(26, 26), (x))
/*
* RX_PKT_HEADER format:
* [15: 0] - word count
* [21:16] - data type
* [23:22] - virtual channel
*/
#define NWL_DSI_RX_DT(x) FIELD_GET(GENMASK(21, 16), (x))
#define NWL_DSI_RX_VC(x) FIELD_GET(GENMASK(23, 22), (x))
/* DSI Video mode */
#define NWL_DSI_VM_BURST_MODE_WITH_SYNC_PULSES 0
#define NWL_DSI_VM_NON_BURST_MODE_WITH_SYNC_EVENTS BIT(0)
#define NWL_DSI_VM_BURST_MODE BIT(1)
/* * DPI color coding */
#define NWL_DSI_DPI_16_BIT_565_PACKED 0
#define NWL_DSI_DPI_16_BIT_565_ALIGNED 1
#define NWL_DSI_DPI_16_BIT_565_SHIFTED 2
#define NWL_DSI_DPI_18_BIT_PACKED 3
#define NWL_DSI_DPI_18_BIT_ALIGNED 4
#define NWL_DSI_DPI_24_BIT 5
/* * DPI Pixel format */
#define NWL_DSI_PIXEL_FORMAT_16 0
#define NWL_DSI_PIXEL_FORMAT_18 BIT(0)
#define NWL_DSI_PIXEL_FORMAT_18L BIT(1)
#define NWL_DSI_PIXEL_FORMAT_24 (BIT(0) | BIT(1))
#endif /* __NWL_DSI_H__ */

View File

@@ -166,7 +166,7 @@ static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
*
* The connector type is set to @panel->connector_type, which must be set to a
* known type. Calling this function with a panel whose connector type is
* DRM_MODE_CONNECTOR_Unknown will return NULL.
* DRM_MODE_CONNECTOR_Unknown will return ERR_PTR(-EINVAL).
*
* See devm_drm_panel_bridge_add() for an automatically managed version of this
* function.
@@ -174,7 +174,7 @@ static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel)
{
if (WARN_ON(panel->connector_type == DRM_MODE_CONNECTOR_Unknown))
return NULL;
return ERR_PTR(-EINVAL);
return drm_panel_bridge_add_typed(panel, panel->connector_type);
}
@@ -265,7 +265,7 @@ struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
struct drm_panel *panel)
{
if (WARN_ON(panel->connector_type == DRM_MODE_CONNECTOR_Unknown))
return NULL;
return ERR_PTR(-EINVAL);
return devm_drm_panel_bridge_add_typed(dev, panel,
panel->connector_type);
@@ -311,6 +311,7 @@ EXPORT_SYMBOL(devm_drm_panel_bridge_add_typed);
/**
* drm_panel_bridge_connector - return the connector for the panel bridge
* @bridge: The drm_bridge.
*
* drm_panel_bridge creates the connector.
* This function gives external access to the connector.

View File

@@ -268,8 +268,6 @@ static int ps8640_probe(struct i2c_client *client)
if (!panel)
return -ENODEV;
panel->connector_type = DRM_MODE_CONNECTOR_eDP;
ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
if (IS_ERR(ps_bridge->panel_bridge))
return PTR_ERR(ps_bridge->panel_bridge);

View File

@@ -836,7 +836,8 @@ static int sii9234_init_resources(struct sii9234 *ctx,
ctx->supplies[3].supply = "cvcc12";
ret = devm_regulator_bulk_get(ctx->dev, 4, ctx->supplies);
if (ret) {
dev_err(ctx->dev, "regulator_bulk failed\n");
if (ret != -EPROBE_DEFER)
dev_err(ctx->dev, "regulator_bulk failed\n");
return ret;
}

View File

@@ -92,6 +92,12 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
{ 0x6756, 0x78ab, 0x2000, 0x0200 }
};
static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
{ 0x1b7c, 0x0000, 0x0000, 0x0020 },
{ 0x0000, 0x1b7c, 0x0000, 0x0020 },
{ 0x0000, 0x0000, 0x1b7c, 0x0020 }
};
struct hdmi_vmode {
bool mdataenablepolarity;
@@ -109,6 +115,7 @@ struct hdmi_data_info {
unsigned int pix_repet_factor;
unsigned int hdcp_enable;
struct hdmi_vmode video_mode;
bool rgb_limited_range;
};
struct dw_hdmi_i2c {
@@ -956,7 +963,14 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
static int is_color_space_conversion(struct dw_hdmi *hdmi)
{
return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format;
struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
bool is_input_rgb, is_output_rgb;
is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_in_bus_format);
is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_out_bus_format);
return (is_input_rgb != is_output_rgb) ||
(is_input_rgb && is_output_rgb && hdmi_data->rgb_limited_range);
}
static int is_color_space_decimation(struct dw_hdmi *hdmi)
@@ -983,28 +997,37 @@ static int is_color_space_interpolation(struct dw_hdmi *hdmi)
return 0;
}
static bool is_csc_needed(struct dw_hdmi *hdmi)
{
return is_color_space_conversion(hdmi) ||
is_color_space_decimation(hdmi) ||
is_color_space_interpolation(hdmi);
}
static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
{
const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
bool is_input_rgb, is_output_rgb;
unsigned i;
u32 csc_scale = 1;
if (is_color_space_conversion(hdmi)) {
if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
if (hdmi->hdmi_data.enc_out_encoding ==
V4L2_YCBCR_ENC_601)
csc_coeff = &csc_coeff_rgb_out_eitu601;
else
csc_coeff = &csc_coeff_rgb_out_eitu709;
} else if (hdmi_bus_fmt_is_rgb(
hdmi->hdmi_data.enc_in_bus_format)) {
if (hdmi->hdmi_data.enc_out_encoding ==
V4L2_YCBCR_ENC_601)
csc_coeff = &csc_coeff_rgb_in_eitu601;
else
csc_coeff = &csc_coeff_rgb_in_eitu709;
csc_scale = 0;
}
is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format);
is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format);
if (!is_input_rgb && is_output_rgb) {
if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
csc_coeff = &csc_coeff_rgb_out_eitu601;
else
csc_coeff = &csc_coeff_rgb_out_eitu709;
} else if (is_input_rgb && !is_output_rgb) {
if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
csc_coeff = &csc_coeff_rgb_in_eitu601;
else
csc_coeff = &csc_coeff_rgb_in_eitu709;
csc_scale = 0;
} else if (is_input_rgb && is_output_rgb &&
hdmi->hdmi_data.rgb_limited_range) {
csc_coeff = &csc_coeff_rgb_full_to_rgb_limited;
}
/* The CSC registers are sequential, alternating MSB then LSB */
@@ -1614,6 +1637,18 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
drm_hdmi_avi_infoframe_from_display_mode(&frame,
&hdmi->connector, mode);
if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector,
mode,
hdmi->hdmi_data.rgb_limited_range ?
HDMI_QUANTIZATION_RANGE_LIMITED :
HDMI_QUANTIZATION_RANGE_FULL);
} else {
frame.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
frame.ycc_quantization_range =
HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
}
if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
frame.colorspace = HDMI_COLORSPACE_YUV444;
else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
@@ -1654,8 +1689,6 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
}
frame.scan_mode = HDMI_SCAN_MODE_NONE;
/*
* The Designware IP uses a different byte format from standard
* AVI info frames, though generally the bits are in the correct
@@ -2010,18 +2043,19 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
/* Enable csc path */
if (is_color_space_conversion(hdmi)) {
if (is_csc_needed(hdmi)) {
hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
}
/* Enable color space conversion if needed */
if (is_color_space_conversion(hdmi))
hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
HDMI_MC_FLOWCTRL);
else
} else {
hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CSCCLK_DISABLE;
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
HDMI_MC_FLOWCTRL);
}
}
/* Workaround to clear the overflow condition */
@@ -2119,6 +2153,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
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.rgb_limited_range = hdmi->sink_is_hdmi &&
drm_default_rgb_quant_range(mode) ==
HDMI_QUANTIZATION_RANGE_LIMITED;
hdmi->hdmi_data.pix_repet_factor = 0;
hdmi->hdmi_data.hdcp_enable = 0;
hdmi->hdmi_data.video_mode.mdataenablepolarity = true;

View File

@@ -178,6 +178,8 @@ static int tc358768_clear_error(struct tc358768_priv *priv)
static void tc358768_write(struct tc358768_priv *priv, u32 reg, u32 val)
{
/* work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
int tmpval = val;
size_t count = 2;
if (priv->error)
@@ -187,7 +189,7 @@ static void tc358768_write(struct tc358768_priv *priv, u32 reg, u32 val)
if (reg < 0x100 || reg >= 0x600)
count = 1;
priv->error = regmap_bulk_write(priv->regmap, reg, &val, count);
priv->error = regmap_bulk_write(priv->regmap, reg, &tmpval, count);
}
static void tc358768_read(struct tc358768_priv *priv, u32 reg, u32 *val)