mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
Two ttm fixes for ttm_tt_swapout(), one page-alignment and one overflow
fix for dma-buf, a drm_pending_vblank_event leak fix for drm, suspend/resume fixes for nouveau, one out-of-bounds access fix for gud, a use-after-free fix for vc4, a fence signaling fix, a race condition fix for sched, planes formats fixes for verisilicon, and add the blend mode property for loongson -----BEGIN PGP SIGNATURE----- iJUEABMJAB0WIQTkHFbLp4ejekA/qfgnX84Zoj2+dgUCaqvVAAAKCRAnX84Zoj2+ dtThAX9JC7SWXw+n4o9EUsxNqvlpviwe8AS7aJR++rq/sZM0an7zl0aCJu/E8p+/ JRkO+X8BfjE+2CX8RWKH63ed95vA+9DF8JfryBTSJiSz4forppFfwH7uovT3nqq2 eOon6nJQzg== =Utup -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2026-09-17' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes Two ttm fixes for ttm_tt_swapout(), one page-alignment and one overflow fix for dma-buf, a drm_pending_vblank_event leak fix for drm, suspend/resume fixes for nouveau, one out-of-bounds access fix for gud, a use-after-free fix for vc4, a fence signaling fix, a race condition fix for sched, planes formats fixes for verisilicon, and add the blend mode property for loongson Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <self@mripard.dev> Link: https://patch.msgid.link/aqvVENQ4ksJEIcdb@houat
This commit is contained in:
commit
71f370e9ee
|
|
@ -43,7 +43,7 @@ config UDMABUF
|
|||
config DMABUF_DEBUG
|
||||
bool "DMA-BUF debug checks"
|
||||
depends on DMA_SHARED_BUFFER
|
||||
default y if DEBUG
|
||||
default y if DEBUG_KERNEL
|
||||
help
|
||||
This option enables additional checks for DMA-BUF importers and
|
||||
exporters. Specifically it validates that importers do not peek at the
|
||||
|
|
|
|||
|
|
@ -5,16 +5,18 @@
|
|||
*/
|
||||
#include <linux/dma-buf-mapping.h>
|
||||
#include <linux/dma-resv.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/align.h>
|
||||
|
||||
#define MAX_SG_ENT_SZ ALIGN_DOWN(UINT_MAX, PAGE_SIZE)
|
||||
|
||||
static struct scatterlist *fill_sg_entry(struct scatterlist *sgl, size_t length,
|
||||
dma_addr_t addr)
|
||||
{
|
||||
unsigned int len, nents;
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
nents = DIV_ROUND_UP(length, UINT_MAX);
|
||||
for (i = 0; i < nents; i++) {
|
||||
len = min_t(size_t, length, UINT_MAX);
|
||||
while (length) {
|
||||
len = min(length, MAX_SG_ENT_SZ);
|
||||
length -= len;
|
||||
/*
|
||||
* DMABUF abuses scatterlist to create a scatterlist
|
||||
|
|
@ -24,8 +26,10 @@ static struct scatterlist *fill_sg_entry(struct scatterlist *sgl, size_t length,
|
|||
* does not require the CPU list for mapping or unmapping.
|
||||
*/
|
||||
sg_set_page(sgl, NULL, 0, 0);
|
||||
sg_dma_address(sgl) = addr + (dma_addr_t)i * UINT_MAX;
|
||||
sg_dma_address(sgl) = addr;
|
||||
sg_dma_len(sgl) = len;
|
||||
addr += len;
|
||||
/* Unconditionally advance. On last segment, this becomes NULL */
|
||||
sgl = sg_next(sgl);
|
||||
}
|
||||
|
||||
|
|
@ -40,15 +44,19 @@ static unsigned int calc_sg_nents(struct dma_iova_state *state,
|
|||
size_t i;
|
||||
|
||||
if (!state || !dma_use_iova(state)) {
|
||||
for (i = 0; i < nr_ranges; i++)
|
||||
nents += DIV_ROUND_UP(phys_vec[i].len, UINT_MAX);
|
||||
for (i = 0; i < nr_ranges; i++) {
|
||||
unsigned int added = DIV_ROUND_UP(phys_vec[i].len, MAX_SG_ENT_SZ);
|
||||
|
||||
if (check_add_overflow(nents, added, &nents))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* In IOVA case, there is only one SG entry which spans
|
||||
* for whole IOVA address space, but we need to make sure
|
||||
* that it fits sg->length, maybe we need more.
|
||||
*/
|
||||
nents = DIV_ROUND_UP(size, UINT_MAX);
|
||||
nents = DIV_ROUND_UP(size, MAX_SG_ENT_SZ);
|
||||
}
|
||||
|
||||
return nents;
|
||||
|
|
@ -95,9 +103,10 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
|
|||
size_t nr_ranges, size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
unsigned int nents, mapped_len = 0;
|
||||
struct dma_buf_dma *dma;
|
||||
struct scatterlist *sgl;
|
||||
size_t mapped_len = 0;
|
||||
unsigned int nents;
|
||||
dma_addr_t addr;
|
||||
size_t i;
|
||||
int ret;
|
||||
|
|
@ -133,6 +142,8 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
|
|||
}
|
||||
|
||||
nents = calc_sg_nents(dma->state, phys_vec, nr_ranges, size);
|
||||
|
||||
/* sg_alloc_table will cleanly fail and return -EINVAL if nents == 0 */
|
||||
ret = sg_alloc_table(&dma->sgt, nents, GFP_KERNEL | __GFP_ZERO);
|
||||
if (ret)
|
||||
goto err_free_state;
|
||||
|
|
|
|||
|
|
@ -1170,7 +1170,12 @@ const char __rcu *dma_fence_driver_name(struct dma_fence *fence)
|
|||
|
||||
/* RCU protection is required for safe access to returned string */
|
||||
ops = rcu_dereference(fence->ops);
|
||||
if (ops)
|
||||
|
||||
/*
|
||||
* Make load ordering irrelevant by checking both signaled state and ops
|
||||
* pointer and ops pointer is only set to NULL on newer implementations.
|
||||
*/
|
||||
if (!dma_fence_test_signaled_flag(fence) && ops)
|
||||
return (const char __rcu *)ops->get_driver_name(fence);
|
||||
else
|
||||
return (const char __rcu *)"detached-driver";
|
||||
|
|
@ -1203,7 +1208,12 @@ const char __rcu *dma_fence_timeline_name(struct dma_fence *fence)
|
|||
|
||||
/* RCU protection is required for safe access to returned string */
|
||||
ops = rcu_dereference(fence->ops);
|
||||
if (ops)
|
||||
|
||||
/*
|
||||
* Make load ordering irrelevant by checking both signaled state and ops
|
||||
* pointer and ops pointer is only set to NULL on newer implementations.
|
||||
*/
|
||||
if (!dma_fence_test_signaled_flag(fence) && ops)
|
||||
return (const char __rcu *)ops->get_timeline_name(fence);
|
||||
else
|
||||
return (const char __rcu *)"signaled-timeline";
|
||||
|
|
|
|||
|
|
@ -1462,10 +1462,12 @@ static int prepare_signaling(struct drm_device *dev,
|
|||
struct dma_fence *fence;
|
||||
struct drm_out_fence_state *f;
|
||||
|
||||
ret = -ENOMEM;
|
||||
|
||||
f = krealloc(*fence_state, sizeof(**fence_state) *
|
||||
(*num_fences + 1), GFP_KERNEL);
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
goto err_free_event;
|
||||
|
||||
memset(&f[*num_fences], 0, sizeof(*f));
|
||||
|
||||
|
|
@ -1474,12 +1476,12 @@ static int prepare_signaling(struct drm_device *dev,
|
|||
|
||||
fence = drm_crtc_create_fence(crtc);
|
||||
if (!fence)
|
||||
return -ENOMEM;
|
||||
goto err_free_event;
|
||||
|
||||
ret = setup_out_fence(&f[(*num_fences)++], fence);
|
||||
if (ret) {
|
||||
dma_fence_put(fence);
|
||||
return ret;
|
||||
goto err_free_event;
|
||||
}
|
||||
|
||||
crtc_state->event->base.fence = fence;
|
||||
|
|
@ -1535,6 +1537,11 @@ static int prepare_signaling(struct drm_device *dev,
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_event:
|
||||
drm_event_cancel_free(dev, &crtc_state->event->base);
|
||||
crtc_state->event = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void complete_signaling(struct drm_device *dev,
|
||||
|
|
|
|||
|
|
@ -482,6 +482,9 @@ int gud_plane_atomic_check(struct drm_plane *plane,
|
|||
if (!new_plane_state->visible)
|
||||
return 0;
|
||||
|
||||
if (gdrm->flags & GUD_DISPLAY_FLAG_FULL_UPDATE)
|
||||
new_plane_state->ignore_damage_clips = true;
|
||||
|
||||
if (old_plane_state->rotation != new_plane_state->rotation)
|
||||
crtc_state->mode_changed = true;
|
||||
|
||||
|
|
@ -562,8 +565,8 @@ int gud_plane_atomic_check(struct drm_plane *plane,
|
|||
goto out;
|
||||
}
|
||||
|
||||
req->properties[num_properties + i].prop = cpu_to_le16(prop);
|
||||
req->properties[num_properties + i].val = cpu_to_le64(val);
|
||||
req->properties[num_properties].prop = cpu_to_le16(prop);
|
||||
req->properties[num_properties].val = cpu_to_le64(val);
|
||||
num_properties++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_framebuffer.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
|
@ -765,7 +766,7 @@ int ls7a1000_cursor_plane_init(struct drm_device *ddev,
|
|||
|
||||
drm_plane_helper_add(plane, &ls7a1000_cursor_plane_helper_funcs);
|
||||
|
||||
return 0;
|
||||
return drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_COVERAGE));
|
||||
}
|
||||
|
||||
int ls7a2000_cursor_plane_init(struct drm_device *ddev,
|
||||
|
|
@ -790,5 +791,5 @@ int ls7a2000_cursor_plane_init(struct drm_device *ddev,
|
|||
|
||||
drm_plane_helper_add(plane, &ls7a2000_cursor_plane_helper_funcs);
|
||||
|
||||
return 0;
|
||||
return drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_COVERAGE));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ r535_fbsr_resume(struct nvkm_gsp *gsp)
|
|||
}
|
||||
|
||||
static int
|
||||
r535_fbsr_suspend(struct nvkm_gsp *gsp, bool runtime)
|
||||
r535_fbsr_suspend(struct nvkm_gsp *gsp)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &gsp->subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
|
|
|
|||
|
|
@ -1749,7 +1749,7 @@ r535_gsp_fini(struct nvkm_gsp *gsp, enum nvkm_suspend_state suspend)
|
|||
sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr;
|
||||
sr->sizeOfSuspendResumeData = len;
|
||||
|
||||
ret = rm->api->fbsr->suspend(gsp, suspend == NVKM_RUNTIME_SUSPEND);
|
||||
ret = rm->api->fbsr->suspend(gsp);
|
||||
if (ret) {
|
||||
nvkm_gsp_mem_dtor(&gsp->sr.meta);
|
||||
nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3);
|
||||
|
|
@ -1761,8 +1761,12 @@ r535_gsp_fini(struct nvkm_gsp *gsp, enum nvkm_suspend_state suspend)
|
|||
* TODO: Debug the GSP firmware / RPC handling to find out why
|
||||
* without this Turing (but none of the other architectures)
|
||||
* ends up resetting all channels after resume.
|
||||
* Additionally, runtime suspend on other architectures quickly
|
||||
* becomes unreliable without this sleep. If you're experiencing
|
||||
* issues with runtime suspend, try bumping this delay up and
|
||||
* sending a patch if it fixes your GPU.
|
||||
*/
|
||||
msleep(50);
|
||||
msleep(200);
|
||||
}
|
||||
|
||||
ret = r535_gsp_rpc_unloading_guest_driver(gsp, suspend);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ r570_fbsr_resume(struct nvkm_gsp *gsp)
|
|||
}
|
||||
|
||||
static int
|
||||
r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, bool runtime)
|
||||
r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size)
|
||||
{
|
||||
NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS *ctrl;
|
||||
struct nvkm_gsp_object memlist;
|
||||
|
|
@ -81,7 +81,7 @@ r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, bool runtim
|
|||
ctrl->hClient = gsp->internal.client.object.handle;
|
||||
ctrl->hSysMem = memlist.handle;
|
||||
ctrl->sysmemAddrOfSuspendResumeData = gsp->sr.meta.addr;
|
||||
ctrl->bEnteringGcoffState = runtime ? 1 : 0;
|
||||
ctrl->bEnteringGcoffState = 0;
|
||||
|
||||
ret = nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl);
|
||||
if (ret)
|
||||
|
|
@ -92,7 +92,7 @@ r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, bool runtim
|
|||
}
|
||||
|
||||
static int
|
||||
r570_fbsr_suspend(struct nvkm_gsp *gsp, bool runtime)
|
||||
r570_fbsr_suspend(struct nvkm_gsp *gsp)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &gsp->subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
|
|
@ -133,7 +133,7 @@ r570_fbsr_suspend(struct nvkm_gsp *gsp, bool runtime)
|
|||
return ret;
|
||||
|
||||
/* Initialise FBSR on RM. */
|
||||
ret = r570_fbsr_init(gsp, &gsp->sr.fbsr, size, runtime);
|
||||
ret = r570_fbsr_init(gsp, &gsp->sr.fbsr, size);
|
||||
if (ret) {
|
||||
nvkm_gsp_sg_free(device, &gsp->sr.fbsr);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -207,7 +207,8 @@ r570_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume)
|
|||
args->srInitArguments.bInPMTransition = 0;
|
||||
} else {
|
||||
args->srInitArguments.oldLevel = NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3;
|
||||
args->srInitArguments.flags = 0;
|
||||
args->srInitArguments.flags =
|
||||
GPU_STATE_FLAGS_PRESERVING | GPU_STATE_FLAGS_PM_TRANSITION;
|
||||
args->srInitArguments.bInPMTransition = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -523,6 +523,14 @@ typedef struct
|
|||
|
||||
#define NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3 (0x00000003U)
|
||||
|
||||
#define GPU_STATE_FLAGS_PRESERVING BIT(0) // GPU state is preserved
|
||||
#define GPU_STATE_FLAGS_VGA_TRANSITION BIT(1) // To be used with GPU_STATE_FLAGS_PRESERVING.
|
||||
#define GPU_STATE_FLAGS_PM_TRANSITION BIT(2) // To be used with GPU_STATE_FLAGS_PRESERVING.
|
||||
#define GPU_STATE_FLAGS_PM_SUSPEND BIT(3)
|
||||
#define GPU_STATE_FLAGS_PM_HIBERNATE BIT(4)
|
||||
#define GPU_STATE_FLAGS_GC6_TRANSITION BIT(5) // To be used with GPU_STATE_FLAGS_PRESERVING.
|
||||
#define GPU_STATE_FLAGS_FAST_UNLOAD BIT(6) // Used during windows restart, skips stateDestroy steps
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Magic for verification by secure ucode
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ struct nvkm_rm_api {
|
|||
} *device;
|
||||
|
||||
const struct nvkm_rm_api_fbsr {
|
||||
int (*suspend)(struct nvkm_gsp *, bool runtime);
|
||||
int (*suspend)(struct nvkm_gsp *);
|
||||
void (*resume)(struct nvkm_gsp *);
|
||||
} *fbsr;
|
||||
|
||||
|
|
|
|||
|
|
@ -559,9 +559,10 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
|
|||
*/
|
||||
smp_wmb();
|
||||
|
||||
spin_lock(&entity->lock);
|
||||
spsc_queue_pop(&entity->job_queue);
|
||||
|
||||
drm_sched_rq_pop_entity(entity);
|
||||
spin_unlock(&entity->lock);
|
||||
|
||||
/* Jobs and entities might have different lifecycles. Since we're
|
||||
* removing the job from the entities queue, set the jobs entity pointer
|
||||
|
|
@ -647,6 +648,9 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
|
|||
* Make sure to set the submit_ts first, to avoid a race.
|
||||
*/
|
||||
sched_job->submit_ts = submit_ts = ktime_get();
|
||||
|
||||
spin_lock(&entity->lock);
|
||||
|
||||
first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node);
|
||||
|
||||
/* first job wakes up scheduler */
|
||||
|
|
@ -657,5 +661,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
|
|||
if (sched)
|
||||
drm_sched_wakeup(sched);
|
||||
}
|
||||
|
||||
spin_unlock(&entity->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_sched_entity_push_job);
|
||||
|
|
|
|||
|
|
@ -257,19 +257,17 @@ static ktime_t drm_sched_entity_get_job_ts(struct drm_sched_entity *entity)
|
|||
struct drm_gpu_scheduler *
|
||||
drm_sched_rq_add_entity(struct drm_sched_entity *entity, ktime_t ts)
|
||||
{
|
||||
struct drm_sched_rq *rq = entity->rq;
|
||||
struct drm_gpu_scheduler *sched;
|
||||
struct drm_sched_rq *rq;
|
||||
|
||||
/* Add the entity to the run queue */
|
||||
spin_lock(&entity->lock);
|
||||
if (entity->stopped) {
|
||||
spin_unlock(&entity->lock);
|
||||
lockdep_assert_held(&entity->lock);
|
||||
|
||||
if (entity->stopped) {
|
||||
DRM_ERROR("Trying to push to a killed entity\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rq = entity->rq;
|
||||
spin_lock(&rq->lock);
|
||||
sched = rq->sched;
|
||||
|
||||
|
|
@ -289,7 +287,6 @@ drm_sched_rq_add_entity(struct drm_sched_entity *entity, ktime_t ts)
|
|||
drm_sched_rq_update_fifo_locked(entity, rq, ts);
|
||||
|
||||
spin_unlock(&rq->lock);
|
||||
spin_unlock(&entity->lock);
|
||||
|
||||
return sched;
|
||||
}
|
||||
|
|
@ -343,16 +340,17 @@ drm_sched_rq_next_rr_ts(struct drm_sched_rq *rq,
|
|||
*/
|
||||
void drm_sched_rq_pop_entity(struct drm_sched_entity *entity)
|
||||
{
|
||||
struct drm_sched_rq *rq = entity->rq;
|
||||
struct drm_sched_job *next_job;
|
||||
struct drm_sched_rq *rq;
|
||||
|
||||
lockdep_assert_held(&entity->lock);
|
||||
|
||||
spin_lock(&rq->lock);
|
||||
|
||||
/*
|
||||
* Update the entity's location in the min heap according to
|
||||
* the timestamp of the next job, if any.
|
||||
*/
|
||||
spin_lock(&entity->lock);
|
||||
rq = entity->rq;
|
||||
spin_lock(&rq->lock);
|
||||
next_job = drm_sched_entity_queue_peek(entity);
|
||||
if (next_job) {
|
||||
ktime_t ts;
|
||||
|
|
@ -375,8 +373,8 @@ void drm_sched_rq_pop_entity(struct drm_sched_entity *entity)
|
|||
drm_sched_entity_save_vruntime(entity, min_vruntime);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&rq->lock);
|
||||
spin_unlock(&entity->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1434,7 +1434,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
|
|||
|
||||
if (ttm_tt_is_populated(tt)) {
|
||||
ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags);
|
||||
if (!ret) {
|
||||
if (ret > 0) {
|
||||
spin_lock(&bdev->lru_lock);
|
||||
ttm_resource_del_bulk_move_unevictable(bo->resource, bo);
|
||||
ttm_resource_move_to_lru_tail(bo->resource);
|
||||
|
|
|
|||
|
|
@ -1188,7 +1188,7 @@ int vc4_kms_load(struct drm_device *dev)
|
|||
|
||||
drm_mode_config_reset(dev);
|
||||
|
||||
drm_kms_helper_poll_init(dev);
|
||||
drmm_kms_helper_poll_init(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_framebuffer.h>
|
||||
|
|
@ -267,6 +268,7 @@ struct drm_plane *vs_cursor_plane_init(struct drm_device *drm_dev,
|
|||
return plane;
|
||||
|
||||
drm_plane_helper_add(plane, &vs_cursor_plane_helper_funcs);
|
||||
drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_COVERAGE));
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,82 +10,50 @@
|
|||
#include "vs_dc_top_regs.h"
|
||||
#include "vs_hwdb.h"
|
||||
|
||||
static const u32 vs_formats_array_no_yuv444[] = {
|
||||
static const u32 vs_primary_formats_array_no_yuv444[] = {
|
||||
DRM_FORMAT_XRGB4444,
|
||||
DRM_FORMAT_XBGR4444,
|
||||
DRM_FORMAT_RGBX4444,
|
||||
DRM_FORMAT_BGRX4444,
|
||||
DRM_FORMAT_ARGB4444,
|
||||
DRM_FORMAT_ABGR4444,
|
||||
DRM_FORMAT_RGBA4444,
|
||||
DRM_FORMAT_BGRA4444,
|
||||
DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_XBGR1555,
|
||||
DRM_FORMAT_RGBX5551,
|
||||
DRM_FORMAT_BGRX5551,
|
||||
DRM_FORMAT_ARGB1555,
|
||||
DRM_FORMAT_ABGR1555,
|
||||
DRM_FORMAT_RGBA5551,
|
||||
DRM_FORMAT_BGRA5551,
|
||||
DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_BGR565,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_RGBX8888,
|
||||
DRM_FORMAT_BGRX8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_RGBA8888,
|
||||
DRM_FORMAT_BGRA8888,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_RGBA1010102,
|
||||
DRM_FORMAT_BGRA1010102,
|
||||
/* TODO: non-RGB formats */
|
||||
};
|
||||
|
||||
static const u32 vs_formats_array_with_yuv444[] = {
|
||||
static const u32 vs_primary_formats_array_with_yuv444[] = {
|
||||
DRM_FORMAT_XRGB4444,
|
||||
DRM_FORMAT_XBGR4444,
|
||||
DRM_FORMAT_RGBX4444,
|
||||
DRM_FORMAT_BGRX4444,
|
||||
DRM_FORMAT_ARGB4444,
|
||||
DRM_FORMAT_ABGR4444,
|
||||
DRM_FORMAT_RGBA4444,
|
||||
DRM_FORMAT_BGRA4444,
|
||||
DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_XBGR1555,
|
||||
DRM_FORMAT_RGBX5551,
|
||||
DRM_FORMAT_BGRX5551,
|
||||
DRM_FORMAT_ARGB1555,
|
||||
DRM_FORMAT_ABGR1555,
|
||||
DRM_FORMAT_RGBA5551,
|
||||
DRM_FORMAT_BGRA5551,
|
||||
DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_BGR565,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_RGBX8888,
|
||||
DRM_FORMAT_BGRX8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_RGBA8888,
|
||||
DRM_FORMAT_BGRA8888,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_RGBA1010102,
|
||||
DRM_FORMAT_BGRA1010102,
|
||||
/* TODO: non-RGB formats */
|
||||
};
|
||||
|
||||
static const struct vs_formats vs_formats_no_yuv444 = {
|
||||
.array = vs_formats_array_no_yuv444,
|
||||
.num = ARRAY_SIZE(vs_formats_array_no_yuv444)
|
||||
.primary_array = vs_primary_formats_array_no_yuv444,
|
||||
.primary_num = ARRAY_SIZE(vs_primary_formats_array_no_yuv444)
|
||||
};
|
||||
|
||||
static const struct vs_formats vs_formats_with_yuv444 = {
|
||||
.array = vs_formats_array_with_yuv444,
|
||||
.num = ARRAY_SIZE(vs_formats_array_with_yuv444)
|
||||
.primary_array = vs_primary_formats_array_with_yuv444,
|
||||
.primary_num = ARRAY_SIZE(vs_primary_formats_array_with_yuv444)
|
||||
};
|
||||
|
||||
static struct vs_chip_identity vs_chip_identities[] = {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <linux/types.h>
|
||||
|
||||
struct vs_formats {
|
||||
const u32 *array;
|
||||
unsigned int num;
|
||||
const u32 *primary_array;
|
||||
unsigned int primary_num;
|
||||
};
|
||||
|
||||
struct vs_chip_identity {
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ struct drm_plane *vs_primary_plane_init(struct drm_device *drm_dev, struct vs_dc
|
|||
|
||||
plane = drmm_universal_plane_alloc(drm_dev, struct drm_plane, dev, 0,
|
||||
&vs_primary_plane_funcs,
|
||||
dc->identity.formats->array,
|
||||
dc->identity.formats->num,
|
||||
dc->identity.formats->primary_array,
|
||||
dc->identity.formats->primary_num,
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -141,6 +141,9 @@ struct dma_fence_ops {
|
|||
* compute the name at runtime, without having it to store permanently
|
||||
* for each fence, or build a cache of some sort.
|
||||
*
|
||||
* The returned string is RCU protected and can be freed after the fence
|
||||
* signaled and a RCU grace period passed.
|
||||
*
|
||||
* This callback is mandatory.
|
||||
*/
|
||||
const char * (*get_driver_name)(struct dma_fence *fence);
|
||||
|
|
@ -153,6 +156,9 @@ struct dma_fence_ops {
|
|||
* having it to store permanently for each fence, or build a cache of
|
||||
* some sort.
|
||||
*
|
||||
* The returned string is RCU protected and can be freed after the fence
|
||||
* signaled and a RCU grace period passed.
|
||||
*
|
||||
* This callback is mandatory.
|
||||
*/
|
||||
const char * (*get_timeline_name)(struct dma_fence *fence);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user