mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
drm/rockchip: vop2: add support cubic lut from loader
Change-Id: I11d65477364dc9ff4fb34d038179d5702faeb484 Signed-off-by: Sandy Huang <hjc@rock-chips.com>
This commit is contained in:
@@ -329,9 +329,13 @@ static int init_loader_memory(struct drm_device *drm_dev)
|
||||
phys_addr_t start, size;
|
||||
u32 pg_size = PAGE_SIZE;
|
||||
struct resource res;
|
||||
int ret;
|
||||
int ret, idx;
|
||||
|
||||
node = of_parse_phandle(np, "logo-memory-region", 0);
|
||||
idx = of_property_match_string(np, "memory-region-names", "drm-logo");
|
||||
if (idx >= 0)
|
||||
node = of_parse_phandle(np, "memory-region", idx);
|
||||
else
|
||||
node = of_parse_phandle(np, "logo-memory-region", 0);
|
||||
if (!node)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -365,6 +369,33 @@ static int init_loader_memory(struct drm_device *drm_dev)
|
||||
logo->count = 1;
|
||||
private->logo = logo;
|
||||
|
||||
idx = of_property_match_string(np, "memory-region-names", "drm-cubic-lut");
|
||||
if (idx < 0)
|
||||
return 0;
|
||||
|
||||
node = of_parse_phandle(np, "memory-region", idx);
|
||||
if (!node)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = of_address_to_resource(node, 0, &res);
|
||||
if (ret)
|
||||
return ret;
|
||||
start = ALIGN_DOWN(res.start, pg_size);
|
||||
size = resource_size(&res);
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
private->cubic_lut_kvaddr = phys_to_virt(start);
|
||||
if (private->domain) {
|
||||
ret = iommu_map(private->domain, start, start, ALIGN(size, pg_size),
|
||||
IOMMU_WRITE | IOMMU_READ);
|
||||
if (ret) {
|
||||
dev_err(drm_dev->dev, "failed to create 1v1 mapping for cubic lut\n");
|
||||
goto err_free_logo;
|
||||
}
|
||||
}
|
||||
private->cubic_lut_dma_addr = start;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_logo:
|
||||
@@ -431,6 +462,7 @@ get_framebuffer_by_node(struct drm_device *drm_dev, struct device_node *node)
|
||||
static struct rockchip_drm_mode_set *
|
||||
of_parse_display_resource(struct drm_device *drm_dev, struct device_node *route)
|
||||
{
|
||||
struct rockchip_drm_private *private = drm_dev->dev_private;
|
||||
struct rockchip_drm_mode_set *set;
|
||||
struct device_node *connect;
|
||||
struct drm_framebuffer *fb;
|
||||
@@ -498,6 +530,11 @@ of_parse_display_resource(struct drm_device *drm_dev, struct device_node *route)
|
||||
if (!of_property_read_u32(route, "overscan,bottom_margin", &val))
|
||||
set->bottom_margin = val;
|
||||
|
||||
if (!of_property_read_u32(route, "cubic_lut,offset", &val)) {
|
||||
private->cubic_lut[crtc->index].enable = true;
|
||||
private->cubic_lut[crtc->index].offset = val;
|
||||
}
|
||||
|
||||
set->ratio = 1;
|
||||
if (!of_property_read_string(route, "logo,mode", &string) &&
|
||||
!strcmp(string, "fullscreen"))
|
||||
|
||||
@@ -159,6 +159,11 @@ struct rockchip_logo {
|
||||
int count;
|
||||
};
|
||||
|
||||
struct loader_cubic_lut {
|
||||
bool enable;
|
||||
u32 offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* Rockchip drm private structure.
|
||||
*
|
||||
@@ -202,6 +207,10 @@ struct rockchip_drm_private {
|
||||
* ignore restore_fbdev_mode_atomic when in logo on state
|
||||
*/
|
||||
bool loader_protect;
|
||||
|
||||
dma_addr_t cubic_lut_dma_addr;
|
||||
void *cubic_lut_kvaddr;
|
||||
struct loader_cubic_lut cubic_lut[ROCKCHIP_MAX_CRTC];
|
||||
};
|
||||
|
||||
#ifndef MODULE
|
||||
|
||||
@@ -2284,6 +2284,7 @@ static int vop2_crtc_atomic_cubic_lut_set(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_state)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct rockchip_drm_private *private = crtc->dev->dev_private;
|
||||
struct drm_color_lut *lut = vp->cubic_lut;
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
u32 *cubic_lut_kvaddr;
|
||||
@@ -2295,16 +2296,22 @@ static int vop2_crtc_atomic_cubic_lut_set(struct drm_crtc *crtc,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!vp->cubic_lut_gem_obj) {
|
||||
size_t size = (vp->cubic_lut_len + 1) / 2 * 16;
|
||||
if (!private->cubic_lut[vp->id].enable) {
|
||||
if (!vp->cubic_lut_gem_obj) {
|
||||
size_t size = (vp->cubic_lut_len + 1) / 2 * 16;
|
||||
|
||||
vp->cubic_lut_gem_obj = rockchip_gem_create_object(crtc->dev, size, true, 0);
|
||||
if (IS_ERR(vp->cubic_lut_gem_obj))
|
||||
return -ENOMEM;
|
||||
vp->cubic_lut_gem_obj = rockchip_gem_create_object(crtc->dev, size, true, 0);
|
||||
if (IS_ERR(vp->cubic_lut_gem_obj))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cubic_lut_kvaddr = (u32 *)vp->cubic_lut_gem_obj->kvaddr;
|
||||
cubic_lut_mst = vp->cubic_lut_gem_obj->dma_addr;
|
||||
} else {
|
||||
cubic_lut_kvaddr = private->cubic_lut[vp->id].offset + private->cubic_lut_kvaddr;
|
||||
cubic_lut_mst = private->cubic_lut[vp->id].offset + private->cubic_lut_dma_addr;
|
||||
}
|
||||
|
||||
cubic_lut_kvaddr = (u32 *)vp->cubic_lut_gem_obj->kvaddr;
|
||||
cubic_lut_mst = vp->cubic_lut_gem_obj->dma_addr;
|
||||
for (i = 0; i < vp->cubic_lut_len / 2; i++) {
|
||||
*cubic_lut_kvaddr++ = (lut[2 * i].red & 0xfff) +
|
||||
((lut[2 * i].green & 0xfff) << 12) +
|
||||
@@ -3438,6 +3445,7 @@ static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
struct rockchip_drm_private *private = crtc->dev->dev_private;
|
||||
|
||||
if (on == vp->loader_protect)
|
||||
return 0;
|
||||
@@ -3447,6 +3455,13 @@ static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on)
|
||||
vop2_set_system_status(vop2);
|
||||
vop2_initial(crtc);
|
||||
drm_crtc_vblank_on(crtc);
|
||||
if (private->cubic_lut[vp->id].enable) {
|
||||
dma_addr_t cubic_lut_mst;
|
||||
struct loader_cubic_lut *cubic_lut = &private->cubic_lut[vp->id];
|
||||
|
||||
cubic_lut_mst = cubic_lut->offset + private->cubic_lut_dma_addr;
|
||||
VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst);
|
||||
}
|
||||
vp->loader_protect = true;
|
||||
} else {
|
||||
vop2_crtc_atomic_disable(crtc, NULL);
|
||||
@@ -3636,12 +3651,14 @@ static int vop2_cubic_lut_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct drm_info_node *node = s->private;
|
||||
struct vop2 *vop2 = node->info_ent->data;
|
||||
struct rockchip_drm_private *private = vop2->drm_dev->dev_private;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < vop2->data->nr_vps; i++) {
|
||||
struct vop2_video_port *vp = &vop2->vps[i];
|
||||
|
||||
if (!vp->cubic_lut_gem_obj || !vp->cubic_lut || !vp->crtc.state->enable) {
|
||||
if ((!vp->cubic_lut_gem_obj && !private->cubic_lut[vp->id].enable) ||
|
||||
!vp->cubic_lut || !vp->crtc.state->enable) {
|
||||
DEBUG_PRINT("Video port%d cubic lut disabled\n", vp->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user