Commit 6305d15e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-2021-01-29' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "Weekly fixes for graphics, nothing too major, nouveau has a few
  regression fixes for various fallout from header changes previously,
  vc4 has two fixes, two amdgpu, and a smattering of i915 fixes.

  All seems on course for a quieter rc7, fingers crossed.

  nouveau:
   - fix svm init conditions
   - fix nv50 modesetting regression
   - fix cursor plane modifiers
   - fix > 64x64 cursor regression

  vc4:
   - Fix LBM size calculation
   - Fix high resolutions for hvs5

  i915:
   - Fix ICL MG PHY vswing
   - Fix subplatform handling
   - Fix selftest memleak
   - Clear CACHE_MODE prior to clearing residuals
   - Always flush the active worker before returning from the wait
   - Always try to reserve GGTT address 0x0

  amdgpu:
   - Fix a fan control regression on some boards
   - Fix clang warning"

* tag 'drm-fixes-2021-01-29' of git://anongit.freedesktop.org/drm/drm:
  drm/nouveau/kms/gk104-gp1xx: Fix > 64x64 cursors
  drm/nouveau/kms/nv50-: Report max cursor size to userspace
  drivers/nouveau/kms/nv50-: Reject format modifiers for cursor planes
  drm/nouveau/svm: fail NOUVEAU_SVM_INIT ioctl on unsupported devices
  drm/nouveau/dispnv50: Restore pushing of all data.
  amdgpu: fix clang build warning
  Revert "drm/amdgpu/swsmu: drop set_fan_speed_percent (v2)"
  drm/i915/gt: Always try to reserve GGTT address 0x0
  drm/i915: Always flush the active worker before returning from the wait
  drm/i915/selftest: Fix potential memory leak
  drm/i915: Check for all subplatform bits
  drm/i915: Fix ICL MG PHY vswing handling
  drm/i915/gt: Clear CACHE_MODE prior to clearing residuals
  drm/vc4: Correct POS1_SCL for hvs5
  drm/vc4: Correct lbm size and calculation
  drm/nouveau/nvif: fix method count when pushing an array
parents a9cbbb80 e0ecafed
......@@ -32,8 +32,8 @@ DCN30 = dcn30_init.o dcn30_hubbub.o dcn30_hubp.o dcn30_dpp.o dcn30_optc.o \
ifdef CONFIG_X86
CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -msse
CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -msse
CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -msse
CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -msse
endif
ifdef CONFIG_PPC64
......@@ -45,6 +45,8 @@ ifdef CONFIG_CC_IS_GCC
ifeq ($(call cc-ifversion, -lt, 0701, y), y)
IS_OLD_GCC = 1
endif
CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mhard-float
CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mhard-float
endif
ifdef CONFIG_X86
......
......@@ -14,7 +14,7 @@ DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \
dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o
ifdef CONFIG_X86
CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -msse
CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -msse
endif
ifdef CONFIG_PPC64
......@@ -25,6 +25,7 @@ ifdef CONFIG_CC_IS_GCC
ifeq ($(call cc-ifversion, -lt, 0701, y), y)
IS_OLD_GCC = 1
endif
CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mhard-float
endif
ifdef CONFIG_X86
......
......@@ -13,7 +13,7 @@
DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o
ifdef CONFIG_X86
CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -msse
CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -msse
endif
ifdef CONFIG_PPC64
......@@ -24,6 +24,7 @@ ifdef CONFIG_CC_IS_GCC
ifeq ($(call cc-ifversion, -lt, 0701, y), y)
IS_OLD_GCC = 1
endif
CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -mhard-float
endif
ifdef CONFIG_X86
......
......@@ -553,6 +553,7 @@ struct pptable_funcs {
*clock_req);
uint32_t (*get_fan_control_mode)(struct smu_context *smu);
int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode);
int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed);
int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed);
int (*set_xgmi_pstate)(struct smu_context *smu, uint32_t pstate);
int (*gfx_off_control)(struct smu_context *smu, bool enable);
......
......@@ -203,6 +203,9 @@ int
smu_v11_0_set_fan_control_mode(struct smu_context *smu,
uint32_t mode);
int
smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed);
int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
uint32_t speed);
......
......@@ -2151,19 +2151,14 @@ int smu_get_fan_speed_percent(struct smu_context *smu, uint32_t *speed)
int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
{
int ret = 0;
uint32_t rpm;
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
return -EOPNOTSUPP;
mutex_lock(&smu->mutex);
if (smu->ppt_funcs->set_fan_speed_rpm) {
if (speed > 100)
speed = 100;
rpm = speed * smu->fan_max_rpm / 100;
ret = smu->ppt_funcs->set_fan_speed_rpm(smu, rpm);
}
if (smu->ppt_funcs->set_fan_speed_percent)
ret = smu->ppt_funcs->set_fan_speed_percent(smu, speed);
mutex_unlock(&smu->mutex);
......
......@@ -2326,6 +2326,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
.gfx_off_control = smu_v11_0_gfx_off_control,
......
......@@ -2456,6 +2456,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
.gfx_off_control = smu_v11_0_gfx_off_control,
......
......@@ -2802,6 +2802,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
.gfx_off_control = smu_v11_0_gfx_off_control,
......
......@@ -1173,6 +1173,35 @@ smu_v11_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode)
return 0;
}
int
smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
{
struct amdgpu_device *adev = smu->adev;
uint32_t duty100, duty;
uint64_t tmp64;
if (speed > 100)
speed = 100;
if (smu_v11_0_auto_fan_control(smu, 0))
return -EINVAL;
duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
CG_FDO_CTRL1, FMAX_DUTY100);
if (!duty100)
return -EINVAL;
tmp64 = (uint64_t)speed * duty100;
do_div(tmp64, 100);
duty = (uint32_t)tmp64;
WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),
CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));
return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC);
}
int
smu_v11_0_set_fan_control_mode(struct smu_context *smu,
uint32_t mode)
......@@ -1181,7 +1210,7 @@ smu_v11_0_set_fan_control_mode(struct smu_context *smu,
switch (mode) {
case AMD_FAN_CTRL_NONE:
ret = smu_v11_0_set_fan_speed_rpm(smu, smu->fan_max_rpm);
ret = smu_v11_0_set_fan_speed_percent(smu, 100);
break;
case AMD_FAN_CTRL_MANUAL:
ret = smu_v11_0_auto_fan_control(smu, 0);
......
......@@ -2755,12 +2755,11 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
u32 val;
ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
/* The table does not have values for level 3 and level 9. */
if (level >= n_entries || level == 3 || level == 9) {
if (level >= n_entries) {
drm_dbg_kms(&dev_priv->drm,
"DDI translation not found for level %d. Using %d instead.",
level, n_entries - 2);
level = n_entries - 2;
level, n_entries - 1);
level = n_entries - 1;
}
/* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */
......
......@@ -390,6 +390,16 @@ static void emit_batch(struct i915_vma * const vma,
&cb_kernel_ivb,
desc_count);
/* Reset inherited context registers */
gen7_emit_pipeline_invalidate(&cmds);
batch_add(&cmds, MI_LOAD_REGISTER_IMM(2));
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7));
batch_add(&cmds, 0xffff0000);
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1));
batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
gen7_emit_pipeline_flush(&cmds);
/* Switch to the media pipeline and our base address */
gen7_emit_pipeline_invalidate(&cmds);
batch_add(&cmds, PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
batch_add(&cmds, MI_NOOP);
......@@ -399,9 +409,11 @@ static void emit_batch(struct i915_vma * const vma,
gen7_emit_state_base_address(&cmds, descriptors);
gen7_emit_pipeline_invalidate(&cmds);
/* Set the clear-residual kernel state */
gen7_emit_vfe_state(&cmds, bv, urb_size - 1, 0, 0);
gen7_emit_interface_descriptor_load(&cmds, descriptors, desc_count);
/* Execute the kernel on all HW threads */
for (i = 0; i < num_primitives(bv); i++)
gen7_emit_media_object(&cmds, i);
......
......@@ -526,16 +526,39 @@ static int init_ggtt(struct i915_ggtt *ggtt)
mutex_init(&ggtt->error_mutex);
if (ggtt->mappable_end) {
/* Reserve a mappable slot for our lockless error capture */
ret = drm_mm_insert_node_in_range(&ggtt->vm.mm,
&ggtt->error_capture,
PAGE_SIZE, 0,
I915_COLOR_UNEVICTABLE,
0, ggtt->mappable_end,
DRM_MM_INSERT_LOW);
if (ret)
return ret;
/*
* Reserve a mappable slot for our lockless error capture.
*
* We strongly prefer taking address 0x0 in order to protect
* other critical buffers against accidental overwrites,
* as writing to address 0 is a very common mistake.
*
* Since 0 may already be in use by the system (e.g. the BIOS
* framebuffer), we let the reservation fail quietly and hope
* 0 remains reserved always.
*
* If we fail to reserve 0, and then fail to find any space
* for an error-capture, remain silent. We can afford not
* to reserve an error_capture node as we have fallback
* paths, and we trust that 0 will remain reserved. However,
* the only likely reason for failure to insert is a driver
* bug, which we expect to cause other failures...
*/
ggtt->error_capture.size = I915_GTT_PAGE_SIZE;
ggtt->error_capture.color = I915_COLOR_UNEVICTABLE;
if (drm_mm_reserve_node(&ggtt->vm.mm, &ggtt->error_capture))
drm_mm_insert_node_in_range(&ggtt->vm.mm,
&ggtt->error_capture,
ggtt->error_capture.size, 0,
ggtt->error_capture.color,
0, ggtt->mappable_end,
DRM_MM_INSERT_LOW);
}
if (drm_mm_node_allocated(&ggtt->error_capture))
drm_dbg(&ggtt->vm.i915->drm,
"Reserved GGTT:[%llx, %llx] for use by error capture\n",
ggtt->error_capture.start,
ggtt->error_capture.start + ggtt->error_capture.size);
/*
* The upper portion of the GuC address space has a sizeable hole
......@@ -548,9 +571,9 @@ static int init_ggtt(struct i915_ggtt *ggtt)
/* Clear any non-preallocated blocks */
drm_mm_for_each_hole(entry, &ggtt->vm.mm, hole_start, hole_end) {
drm_dbg_kms(&ggtt->vm.i915->drm,
"clearing unused GTT space: [%lx, %lx]\n",
hole_start, hole_end);
drm_dbg(&ggtt->vm.i915->drm,
"clearing unused GTT space: [%lx, %lx]\n",
hole_start, hole_end);
ggtt->vm.clear_range(&ggtt->vm, hole_start,
hole_end - hole_start);
}
......
......@@ -631,24 +631,26 @@ static int flush_lazy_signals(struct i915_active *ref)
int __i915_active_wait(struct i915_active *ref, int state)
{
int err;
might_sleep();
if (!i915_active_acquire_if_busy(ref))
return 0;
/* Any fence added after the wait begins will not be auto-signaled */
err = flush_lazy_signals(ref);
i915_active_release(ref);
if (err)
return err;
if (i915_active_acquire_if_busy(ref)) {
int err;
if (!i915_active_is_idle(ref) &&
___wait_var_event(ref, i915_active_is_idle(ref),
state, 0, 0, schedule()))
return -EINTR;
err = flush_lazy_signals(ref);
i915_active_release(ref);
if (err)
return err;
if (___wait_var_event(ref, i915_active_is_idle(ref),
state, 0, 0, schedule()))
return -EINTR;
}
/*
* After the wait is complete, the caller may free the active.
* We have to flush any concurrent retirement before returning.
*/
flush_work(&ref->work);
return 0;
}
......
......@@ -1346,7 +1346,7 @@ intel_subplatform(const struct intel_runtime_info *info, enum intel_platform p)
{
const unsigned int pi = __platform_mask_index(info, p);
return info->platform_mask[pi] & INTEL_SUBPLATFORM_BITS;
return info->platform_mask[pi] & ((1 << INTEL_SUBPLATFORM_BITS) - 1);
}
static __always_inline bool
......
......@@ -1880,7 +1880,7 @@ static int igt_cs_tlb(void *arg)
vma = i915_vma_instance(out, vm, NULL);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
goto out_put_batch;
goto out_put_out;
}
err = i915_vma_pin(vma, 0, 0,
......
......@@ -88,7 +88,11 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
NVVAL(NV507C, SET_CONVERSION, OFS, 0x64));
} else {
PUSH_MTHD(push, NV507C, SET_PROCESSING,
NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE),
SET_CONVERSION,
NVVAL(NV507C, SET_CONVERSION, GAIN, 0) |
NVVAL(NV507C, SET_CONVERSION, OFS, 0));
}
PUSH_MTHD(push, NV507C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8);
......
......@@ -49,7 +49,11 @@ base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
NVVAL(NV827C, SET_CONVERSION, OFS, 0x64));
} else {
PUSH_MTHD(push, NV827C, SET_PROCESSING,
NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE),
SET_CONVERSION,
NVVAL(NV827C, SET_CONVERSION, GAIN, 0) |
NVVAL(NV827C, SET_CONVERSION, OFS, 0));
}
PUSH_MTHD(push, NV827C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8,
......
......@@ -2663,6 +2663,14 @@ nv50_display_create(struct drm_device *dev)
else
nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
if (disp->disp->object.oclass >= GK104_DISP) {
dev->mode_config.cursor_width = 256;
dev->mode_config.cursor_height = 256;
} else {
dev->mode_config.cursor_width = 64;
dev->mode_config.cursor_height = 64;
}
/* create crtc objects to represent the hw heads */
if (disp->disp->object.oclass >= GV100_DISP)
crtcs = nvif_rd32(&device->object, 0x610060) & 0xff;
......
......@@ -22,6 +22,7 @@
#include "head.h"
#include "core.h"
#include "nvif/push.h"
#include <nvif/push507c.h>
#include <nvhw/class/cl917d.h>
......@@ -73,6 +74,31 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
return 0;
}
static int
head917d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
ret = PUSH_WAIT(push, 5);
if (ret)
return ret;
PUSH_MTHD(push, NV917D, HEAD_SET_CONTROL_CURSOR(i),
NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) |
NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) |
NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) |
NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) |
NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) |
NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND),
HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8);
PUSH_MTHD(push, NV917D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle);
return 0;
}
int
head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
struct nv50_head_atom *asyh)
......@@ -101,7 +127,7 @@ head917d = {
.core_clr = head907d_core_clr,
.curs_layout = head917d_curs_layout,
.curs_format = head507d_curs_format,
.curs_set = head907d_curs_set,
.curs_set = head917d_curs_set,
.curs_clr = head907d_curs_clr,
.base = head917d_base,
.ovly = head907d_ovly,
......
......@@ -702,6 +702,11 @@ nv50_wndw_init(struct nv50_wndw *wndw)
nvif_notify_get(&wndw->notify);
}
static const u64 nv50_cursor_format_modifiers[] = {
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID,
};
int
nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
enum drm_plane_type type, const char *name, int index,
......@@ -713,6 +718,7 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
struct nvif_mmu *mmu = &drm->client.mmu;
struct nv50_disp *disp = nv50_disp(dev);
struct nv50_wndw *wndw;
const u64 *format_modifiers;
int nformat;
int ret;
......@@ -728,10 +734,13 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
for (nformat = 0; format[nformat]; nformat++);
ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw,
format, nformat,
nouveau_display(dev)->format_modifiers,
type, "%s-%d", name, index);
if (type == DRM_PLANE_TYPE_CURSOR)
format_modifiers = nv50_cursor_format_modifiers;
else
format_modifiers = nouveau_display(dev)->format_modifiers;
ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, format, nformat,
format_modifiers, type, "%s-%d", name, index);
if (ret) {
kfree(*pwndw);
*pwndw = NULL;
......
......@@ -66,6 +66,10 @@
#define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_ALPHA_BLEND (0x00000000)
#define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_PREMULT_ALPHA_BLEND (0x00000001)
#define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_XOR (0x00000002)
#define NV917D_HEAD_SET_OFFSET_CURSOR(a) (0x00000484 + (a)*0x00000300)
#define NV917D_HEAD_SET_OFFSET_CURSOR_ORIGIN 31:0
#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR(a) (0x0000048C + (a)*0x00000300)
#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR_HANDLE 31:0
#define NV917D_HEAD_SET_DITHER_CONTROL(a) (0x000004A0 + (a)*0x00000300)
#define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE 0:0
#define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE_DISABLE (0x00000000)
......
This diff is collapsed.
......@@ -315,6 +315,10 @@ nouveau_svmm_init(struct drm_device *dev, void *data,
struct drm_nouveau_svm_init *args = data;
int ret;
/* We need to fail if svm is disabled */
if (!cli->drm->svm)
return -ENOSYS;
/* Allocate tracking for SVM-enabled VMM. */
if (!(svmm = kzalloc(sizeof(*svmm), GFP_KERNEL)))
return -ENOMEM;
......
......@@ -620,11 +620,11 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
* for now we just allocate globally.
*/
if (!hvs->hvs5)
/* 96kB */
drm_mm_init(&hvs->lbm_mm, 0, 96 * 1024);
/* 48k words of 2x12-bit pixels */
drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024);
else
/* 70k words */
drm_mm_init(&hvs->lbm_mm, 0, 70 * 2 * 1024);
/* 60k words of 4x12-bit pixels */
drm_mm_init(&hvs->lbm_mm, 0, 60 * 1024);
/* Upload filter kernels. We only have the one for now, so we
* keep it around for the lifetime of the driver.
......
......@@ -437,6 +437,7 @@ static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
static u32 vc4_lbm_size(struct drm_plane_state *state)
{
struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev);
u32 pix_per_line;
u32 lbm;
......@@ -472,7 +473,11 @@ static u32 vc4_lbm_size(struct drm_plane_state *state)
lbm = pix_per_line * 16;
}
lbm = roundup(lbm, 32);
/* Align it to 64 or 128 (hvs5) bytes */
lbm = roundup(lbm, vc4->hvs->hvs5 ? 128 : 64);
/* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */
lbm /= vc4->hvs->hvs5 ? 4 : 2;
return lbm;
}
......@@ -912,9 +917,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
if (!vc4_state->is_unity) {
vc4_dlist_write(vc4_state,
VC4_SET_FIELD(vc4_state->crtc_w,
SCALER_POS1_SCL_WIDTH) |
SCALER5_POS1_SCL_WIDTH) |
VC4_SET_FIELD(vc4_state->crtc_h,
SCALER_POS1_SCL_HEIGHT));
SCALER5_POS1_SCL_HEIGHT));
}
/* Position Word 2: Source Image Size */
......
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