drm: i915 gvt, amdgpu, ast, rcar-du, meson + core fixes.
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJcAKgKAAoJEAx081l5xIa+0PgP/A+2bvrs6EgLQHAmdyJtuAzp /qeip9RtQG15rmgkzYucRgeTqmIwDHduCJDp7TcJ94Lial2FzBH5o8gRfqcOatgg Ury7/MwAOEg4omYxpuRP1qlZkK0wkEZiDT5aWYlYRFZI1+qsL28vdYyA1KflBNLS ZbGGB1DOIjtT1NGG4/cMGTd8iGM8cQIDzeKra6ZlTdDA3fARLBrf4bQCuphu7Eqv z2n0ZSEmGlvOWEAE4GR3nG3Uu32F6wCKdwWRG+/GLhRRFb8GdXZ3uriZXswdMNwt I1pIgHGHcpAGqD6IyHKtoBPlBs1Xs+VL1QwqHkN5hGniF32szBpCKOAPIxhLfJ7w S6clk/kauzdlzOI/t31LjKLME9a/mn95wxzridNTv2SmksEmNoNhvsEeXEoMjs2m s4CcJTyt5tbRqwXlWQg5DWkBAyNqNI1EkoDJRmefN+rW33m6x79r0RFcv57E8Sbs VyaLelyNyOcPm8Tqanko5o9RTQ56sZTNR4aOXVVrxSOBa7iJnK+h/kMeCn8TJDsT i8ftCzpco5uycxDgunw+lPoj9rnzuB7i2MgbEb2rOz3Mj8TH/WQnb1YWlUWPejuG ClAVjwWJAEy26MdGpMy0XUVtvgJK0h5hvnSA9yXAZjkJzA8LtbV82Nexu2MsEt02 DiTPOpSgtSyxC4CLZ2G3 =2Pvh -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2018-11-30' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Dave Airlie: "This weeks instalment of fixes. Looks fairly like business as usual and everything seems to rolling along. There was one MST fix applied and reverted in the misc tree, but otherwise nothing too strange in here. core: - incorrect master setting on error fix i915: - only GVT fixes this week: * one MOCS register load * rpm lock fix * use after free rcar-du: - regression fix for group start amdgpu: - DP MST fix - GPUVM fix for huge pages - RLC fix for vega20 ast: - fix EDID reading stability - ioreg free fix meson: - sleep in irq fix - vblank fixes - array boundary fix" * tag 'drm-fixes-2018-11-30' of git://anongit.freedesktop.org/drm/drm: drm/ast: fixed reading monitor EDID not stable issue drm/ast: Fix incorrect free on ioregs Revert "drm/dp_mst: Skip validating ports during destruction, just ref" drm/amdgpu: Add delay after enable RLC ucode drm/amdgpu: Avoid endless loop in GPUVM fragment processing drm/amdgpu: Cast to uint64_t before left shift drm/meson: add support for 1080p25 mode drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut() drm/meson: Enable fast_io in meson_dw_hdmi_regmap_config drm/meson: Fixes for drm_crtc_vblank_on/off support drm: set is_master to 0 upon drm_new_set_master() failure drm/dp_mst: Skip validating ports during destruction, just ref drm: rcar-du: Fix DU3 start/stop on M3-N drm/amd/dm: Understand why attaching path/tile properties are needed drm/amd/dm: Don't forget to attach MST encoders drm/i915/gvt: Avoid use-after-free iterating the gtt list drm/i915/gvt: ensure gpu is powered before do i915_gem_gtt_insert drm/i915/gvt: not to touch undefined MOCS registers
This commit is contained in:
commit
570a37437c
|
@ -181,7 +181,7 @@ static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev,
|
|||
|
||||
if (level == adev->vm_manager.root_level)
|
||||
/* For the root directory */
|
||||
return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift;
|
||||
return round_up(adev->vm_manager.max_pfn, 1ULL << shift) >> shift;
|
||||
else if (level != AMDGPU_VM_PTB)
|
||||
/* Everything in between */
|
||||
return 512;
|
||||
|
@ -1656,9 +1656,11 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
|
|||
if (!amdgpu_vm_pt_descendant(adev, &cursor))
|
||||
return -ENOENT;
|
||||
continue;
|
||||
} else if (frag >= parent_shift) {
|
||||
} else if (frag >= parent_shift &&
|
||||
cursor.level - 1 != adev->vm_manager.root_level) {
|
||||
/* If the fragment size is even larger than the parent
|
||||
* shift we should go up one level and check it again.
|
||||
* shift we should go up one level and check it again
|
||||
* unless one level up is the root level.
|
||||
*/
|
||||
if (!amdgpu_vm_pt_ancestor(&cursor))
|
||||
return -ENOENT;
|
||||
|
@ -1666,10 +1668,10 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
|
|||
}
|
||||
|
||||
/* Looks good so far, calculate parameters for the update */
|
||||
incr = AMDGPU_GPU_PAGE_SIZE << shift;
|
||||
incr = (uint64_t)AMDGPU_GPU_PAGE_SIZE << shift;
|
||||
mask = amdgpu_vm_entries_mask(adev, cursor.level);
|
||||
pe_start = ((cursor.pfn >> shift) & mask) * 8;
|
||||
entry_end = (mask + 1) << shift;
|
||||
entry_end = (uint64_t)(mask + 1) << shift;
|
||||
entry_end += cursor.pfn & ~(entry_end - 1);
|
||||
entry_end = min(entry_end, end);
|
||||
|
||||
|
@ -1682,7 +1684,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
|
|||
flags | AMDGPU_PTE_FRAG(frag));
|
||||
|
||||
pe_start += nptes * 8;
|
||||
dst += nptes * AMDGPU_GPU_PAGE_SIZE << shift;
|
||||
dst += (uint64_t)nptes * AMDGPU_GPU_PAGE_SIZE << shift;
|
||||
|
||||
frag_start = upd_end;
|
||||
if (frag_start >= frag_end) {
|
||||
|
|
|
@ -2440,12 +2440,13 @@ static void gfx_v9_0_rlc_start(struct amdgpu_device *adev)
|
|||
#endif
|
||||
|
||||
WREG32_FIELD15(GC, 0, RLC_CNTL, RLC_ENABLE_F32, 1);
|
||||
udelay(50);
|
||||
|
||||
/* carrizo do enable cp interrupt after cp inited */
|
||||
if (!(adev->flags & AMD_IS_APU))
|
||||
if (!(adev->flags & AMD_IS_APU)) {
|
||||
gfx_v9_0_enable_gui_idle_interrupt(adev, true);
|
||||
|
||||
udelay(50);
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
#ifdef AMDGPU_RLC_DEBUG_RETRY
|
||||
/* RLC_GPM_GENERAL_6 : RLC Ucode version */
|
||||
|
|
|
@ -342,10 +342,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|||
master->connector_id);
|
||||
|
||||
aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master);
|
||||
drm_connector_attach_encoder(&aconnector->base,
|
||||
&aconnector->mst_encoder->base);
|
||||
|
||||
/*
|
||||
* TODO: understand why this one is needed
|
||||
*/
|
||||
drm_object_attach_property(
|
||||
&connector->base,
|
||||
dev->mode_config.path_property,
|
||||
|
|
|
@ -583,7 +583,8 @@ void ast_driver_unload(struct drm_device *dev)
|
|||
drm_mode_config_cleanup(dev);
|
||||
|
||||
ast_mm_fini(ast);
|
||||
pci_iounmap(dev->pdev, ast->ioregs);
|
||||
if (ast->ioregs != ast->regs + AST_IO_MM_OFFSET)
|
||||
pci_iounmap(dev->pdev, ast->ioregs);
|
||||
pci_iounmap(dev->pdev, ast->regs);
|
||||
kfree(ast);
|
||||
}
|
||||
|
|
|
@ -973,9 +973,21 @@ static int get_clock(void *i2c_priv)
|
|||
{
|
||||
struct ast_i2c_chan *i2c = i2c_priv;
|
||||
struct ast_private *ast = i2c->dev->dev_private;
|
||||
uint32_t val;
|
||||
uint32_t val, val2, count, pass;
|
||||
|
||||
count = 0;
|
||||
pass = 0;
|
||||
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
|
||||
do {
|
||||
val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
|
||||
if (val == val2) {
|
||||
pass++;
|
||||
} else {
|
||||
pass = 0;
|
||||
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
|
||||
}
|
||||
} while ((pass < 5) && (count++ < 0x10000));
|
||||
|
||||
val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4;
|
||||
return val & 1 ? 1 : 0;
|
||||
}
|
||||
|
||||
|
@ -983,9 +995,21 @@ static int get_data(void *i2c_priv)
|
|||
{
|
||||
struct ast_i2c_chan *i2c = i2c_priv;
|
||||
struct ast_private *ast = i2c->dev->dev_private;
|
||||
uint32_t val;
|
||||
uint32_t val, val2, count, pass;
|
||||
|
||||
count = 0;
|
||||
pass = 0;
|
||||
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
|
||||
do {
|
||||
val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
|
||||
if (val == val2) {
|
||||
pass++;
|
||||
} else {
|
||||
pass = 0;
|
||||
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
|
||||
}
|
||||
} while ((pass < 5) && (count++ < 0x10000));
|
||||
|
||||
val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5;
|
||||
return val & 1 ? 1 : 0;
|
||||
}
|
||||
|
||||
|
@ -998,7 +1022,7 @@ static void set_clock(void *i2c_priv, int clock)
|
|||
|
||||
for (i = 0; i < 0x10000; i++) {
|
||||
ujcrb7 = ((clock & 0x01) ? 0 : 1);
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfe, ujcrb7);
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
|
||||
jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
|
||||
if (ujcrb7 == jtemp)
|
||||
break;
|
||||
|
@ -1014,7 +1038,7 @@ static void set_data(void *i2c_priv, int data)
|
|||
|
||||
for (i = 0; i < 0x10000; i++) {
|
||||
ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfb, ujcrb7);
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
|
||||
jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
|
||||
if (ujcrb7 == jtemp)
|
||||
break;
|
||||
|
|
|
@ -142,6 +142,7 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
|
|||
|
||||
lockdep_assert_held_once(&dev->master_mutex);
|
||||
|
||||
WARN_ON(fpriv->is_master);
|
||||
old_master = fpriv->master;
|
||||
fpriv->master = drm_master_create(dev);
|
||||
if (!fpriv->master) {
|
||||
|
@ -170,6 +171,7 @@ out_err:
|
|||
/* drop references and restore old master on failure */
|
||||
drm_master_put(&fpriv->master);
|
||||
fpriv->master = old_master;
|
||||
fpriv->is_master = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -61,10 +61,12 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
|
|||
}
|
||||
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
mmio_hw_access_pre(dev_priv);
|
||||
ret = i915_gem_gtt_insert(&dev_priv->ggtt.vm, node,
|
||||
size, I915_GTT_PAGE_SIZE,
|
||||
I915_COLOR_UNEVICTABLE,
|
||||
start, end, flags);
|
||||
mmio_hw_access_post(dev_priv);
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
if (ret)
|
||||
gvt_err("fail to alloc %s gm space from host\n",
|
||||
|
|
|
@ -2447,10 +2447,11 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
|
|||
|
||||
static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct intel_gvt_partial_pte *pos;
|
||||
struct intel_gvt_partial_pte *pos, *next;
|
||||
|
||||
list_for_each_entry(pos,
|
||||
&vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list, list) {
|
||||
list_for_each_entry_safe(pos, next,
|
||||
&vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list,
|
||||
list) {
|
||||
gvt_dbg_mm("partial PTE update on hold 0x%lx : 0x%llx\n",
|
||||
pos->offset, pos->data);
|
||||
kfree(pos);
|
||||
|
|
|
@ -158,6 +158,8 @@ static void load_render_mocs(struct drm_i915_private *dev_priv)
|
|||
int ring_id, i;
|
||||
|
||||
for (ring_id = 0; ring_id < ARRAY_SIZE(regs); ring_id++) {
|
||||
if (!HAS_ENGINE(dev_priv, ring_id))
|
||||
continue;
|
||||
offset.reg = regs[ring_id];
|
||||
for (i = 0; i < GEN9_MOCS_SIZE; i++) {
|
||||
gen9_render_mocs.control_table[ring_id][i] =
|
||||
|
|
|
@ -45,6 +45,7 @@ struct meson_crtc {
|
|||
struct drm_crtc base;
|
||||
struct drm_pending_vblank_event *event;
|
||||
struct meson_drm *priv;
|
||||
bool enabled;
|
||||
};
|
||||
#define to_meson_crtc(x) container_of(x, struct meson_crtc, base)
|
||||
|
||||
|
@ -80,8 +81,7 @@ static const struct drm_crtc_funcs meson_crtc_funcs = {
|
|||
|
||||
};
|
||||
|
||||
static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_state)
|
||||
static void meson_crtc_enable(struct drm_crtc *crtc)
|
||||
{
|
||||
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
|
||||
struct drm_crtc_state *crtc_state = crtc->state;
|
||||
|
@ -101,6 +101,22 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||
writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
|
||||
priv->io_base + _REG(VPP_MISC));
|
||||
|
||||
drm_crtc_vblank_on(crtc);
|
||||
|
||||
meson_crtc->enabled = true;
|
||||
}
|
||||
|
||||
static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_state)
|
||||
{
|
||||
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
|
||||
struct meson_drm *priv = meson_crtc->priv;
|
||||
|
||||
DRM_DEBUG_DRIVER("\n");
|
||||
|
||||
if (!meson_crtc->enabled)
|
||||
meson_crtc_enable(crtc);
|
||||
|
||||
priv->viu.osd1_enabled = true;
|
||||
}
|
||||
|
||||
|
@ -110,6 +126,8 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
|
||||
struct meson_drm *priv = meson_crtc->priv;
|
||||
|
||||
drm_crtc_vblank_off(crtc);
|
||||
|
||||
priv->viu.osd1_enabled = false;
|
||||
priv->viu.osd1_commit = false;
|
||||
|
||||
|
@ -124,6 +142,8 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||
|
||||
crtc->state->event = NULL;
|
||||
}
|
||||
|
||||
meson_crtc->enabled = false;
|
||||
}
|
||||
|
||||
static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
|
||||
|
@ -132,6 +152,9 @@ static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
|
|||
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
|
||||
unsigned long flags;
|
||||
|
||||
if (crtc->state->enable && !meson_crtc->enabled)
|
||||
meson_crtc_enable(crtc);
|
||||
|
||||
if (crtc->state->event) {
|
||||
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
|
||||
|
||||
|
|
|
@ -706,6 +706,7 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
|
|||
.reg_read = meson_dw_hdmi_reg_read,
|
||||
.reg_write = meson_dw_hdmi_reg_write,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static bool meson_hdmi_connector_is_available(struct device *dev)
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
*/
|
||||
|
||||
/* HHI Registers */
|
||||
#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
|
||||
#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
|
||||
#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
|
||||
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
|
||||
|
@ -714,6 +715,7 @@ struct meson_hdmi_venc_vic_mode {
|
|||
{ 5, &meson_hdmi_encp_mode_1080i60 },
|
||||
{ 20, &meson_hdmi_encp_mode_1080i50 },
|
||||
{ 32, &meson_hdmi_encp_mode_1080p24 },
|
||||
{ 33, &meson_hdmi_encp_mode_1080p50 },
|
||||
{ 34, &meson_hdmi_encp_mode_1080p30 },
|
||||
{ 31, &meson_hdmi_encp_mode_1080p50 },
|
||||
{ 16, &meson_hdmi_encp_mode_1080p60 },
|
||||
|
@ -1530,10 +1532,12 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
|
|||
void meson_venc_enable_vsync(struct meson_drm *priv)
|
||||
{
|
||||
writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL));
|
||||
regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
|
||||
}
|
||||
|
||||
void meson_venc_disable_vsync(struct meson_drm *priv)
|
||||
{
|
||||
regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
|
||||
writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
|
||||
}
|
||||
|
||||
|
|
|
@ -184,18 +184,18 @@ void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
|
|||
if (lut_sel == VIU_LUT_OSD_OETF) {
|
||||
writel(0, priv->io_base + _REG(addr_port));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
|
||||
writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
|
||||
writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
|
||||
writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
|
@ -211,18 +211,18 @@ void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
|
|||
} else if (lut_sel == VIU_LUT_OSD_EOTF) {
|
||||
writel(0, priv->io_base + _REG(addr_port));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
|
||||
writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
|
||||
writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
|
||||
writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
|
||||
priv->io_base + _REG(data_port));
|
||||
|
||||
|
|
|
@ -202,10 +202,25 @@ void rcar_du_group_put(struct rcar_du_group *rgrp)
|
|||
|
||||
static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
|
||||
{
|
||||
struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
|
||||
struct rcar_du_device *rcdu = rgrp->dev;
|
||||
|
||||
rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
|
||||
start ? DSYSR_DEN : DSYSR_DRES);
|
||||
/*
|
||||
* Group start/stop is controlled by the DRES and DEN bits of DSYSR0
|
||||
* for the first group and DSYSR2 for the second group. On most DU
|
||||
* instances, this maps to the first CRTC of the group, and we can just
|
||||
* use rcar_du_crtc_dsysr_clr_set() to access the correct DSYSR. On
|
||||
* M3-N, however, DU2 doesn't exist, but DSYSR2 does. We thus need to
|
||||
* access the register directly using group read/write.
|
||||
*/
|
||||
if (rcdu->info->channels_mask & BIT(rgrp->index * 2)) {
|
||||
struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
|
||||
|
||||
rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
|
||||
start ? DSYSR_DEN : DSYSR_DRES);
|
||||
} else {
|
||||
rcar_du_group_write(rgrp, DSYSR,
|
||||
start ? DSYSR_DEN : DSYSR_DRES);
|
||||
}
|
||||
}
|
||||
|
||||
void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
|
||||
|
|
Loading…
Reference in New Issue