#include "rockchip_drm_fb.h"
#include "rockchip_drm_fbdev.h"
#include "rockchip_drm_gem.h"
-#include "rockchip_drm_rga.h"
#define DRIVER_NAME "rockchip"
#define DRIVER_DESC "RockChip Soc DRM"
return NULL;
}
+static
+struct drm_connector *find_connector_by_bridge(struct drm_device *drm_dev,
+ struct device_node *node)
+{
+ struct device_node *np_encoder, *np_connector;
+ struct drm_encoder *encoder;
+ struct drm_connector *connector = NULL;
+ struct device_node *port, *endpoint;
+ bool encoder_bridge = false;
+ bool found_connector = false;
+
+ np_encoder = of_graph_get_remote_port_parent(node);
+ if (!np_encoder || !of_device_is_available(np_encoder))
+ goto err_put_encoder;
+ drm_for_each_encoder(encoder, drm_dev) {
+ if (encoder->port == np_encoder && encoder->bridge) {
+ encoder_bridge = true;
+ break;
+ }
+ }
+ if (!encoder_bridge) {
+ dev_err(drm_dev->dev, "can't found encoder bridge!\n");
+ goto err_put_encoder;
+ }
+ port = of_graph_get_port_by_id(np_encoder, 1);
+ if (!port) {
+ dev_err(drm_dev->dev, "can't found port point!\n");
+ goto err_put_encoder;
+ }
+ for_each_child_of_node(port, endpoint) {
+ np_connector = of_graph_get_remote_port_parent(endpoint);
+ if (!np_connector) {
+ dev_err(drm_dev->dev,
+ "can't found connector node, please init!\n");
+ goto err_put_port;
+ }
+ if (!of_device_is_available(np_connector)) {
+ of_node_put(np_connector);
+ np_connector = NULL;
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (!np_connector) {
+ dev_err(drm_dev->dev, "can't found available connector node!\n");
+ goto err_put_port;
+ }
+
+ drm_for_each_connector(connector, drm_dev) {
+ if (connector->port == np_connector) {
+ found_connector = true;
+ break;
+ }
+ }
+
+ if (!found_connector)
+ connector = NULL;
+
+ of_node_put(np_connector);
+err_put_port:
+ of_node_put(port);
+err_put_encoder:
+ of_node_put(np_encoder);
+
+ return connector;
+}
+
void rockchip_free_loader_memory(struct drm_device *drm)
{
struct rockchip_drm_private *private = drm->dev_private;
crtc = find_crtc_by_node(drm_dev, connect);
connector = find_connector_by_node(drm_dev, connect);
+ if (!connector)
+ connector = find_connector_by_bridge(drm_dev, connect);
if (!crtc || !connector) {
dev_warn(drm_dev->dev,
"No available crtc or connector for display");
struct drm_plane_state *primary_state;
struct drm_display_mode *mode = NULL;
const struct drm_connector_helper_funcs *funcs;
+ const struct drm_encoder_helper_funcs *encoder_funcs;
bool is_crtc_enabled = true;
int hdisplay, vdisplay;
int fb_width, fb_height;
if (funcs->loader_protect)
funcs->loader_protect(connector, true);
connector->loader_protect = true;
+ encoder_funcs = conn_state->best_encoder->helper_private;
+ if (encoder_funcs->loader_protect)
+ encoder_funcs->loader_protect(conn_state->best_encoder, true);
+ conn_state->best_encoder->loader_protect = true;
num_modes = connector->funcs->fill_modes(connector, 4096, 4096);
if (!num_modes) {
dev_err(drm_dev->dev, "connector[%s] can't found any modes\n",
if (funcs->loader_protect)
funcs->loader_protect(connector, false);
connector->loader_protect = false;
+ if (encoder_funcs->loader_protect)
+ encoder_funcs->loader_protect(conn_state->best_encoder, false);
+ conn_state->best_encoder->loader_protect = false;
return ret;
}
struct rockchip_drm_private *priv = drm_dev->dev_private;
int ret;
+ if (!priv->domain)
+ return 0;
+
mutex_lock(&priv->mm_lock);
ret = drm_mm_dump_table(s, &priv->mm);
}
#endif
+static int rockchip_drm_create_properties(struct drm_device *dev)
+{
+ struct drm_property *prop;
+ struct rockchip_drm_private *private = dev->dev_private;
+ const struct drm_prop_enum_list cabc_mode_enum_list[] = {
+ { ROCKCHIP_DRM_CABC_MODE_DISABLE, "Disable" },
+ { ROCKCHIP_DRM_CABC_MODE_NORMAL, "Normal" },
+ { ROCKCHIP_DRM_CABC_MODE_LOWPOWER, "LowPower" },
+ { ROCKCHIP_DRM_CABC_MODE_USERSPACE, "Userspace" },
+ };
+
+ prop = drm_property_create_enum(dev, 0, "CABC_MODE", cabc_mode_enum_list,
+ ARRAY_SIZE(cabc_mode_enum_list));
+
+ private->cabc_mode_property = prop;
+
+ prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "CABC_LUT", 0);
+ if (!prop)
+ return -ENOMEM;
+ private->cabc_lut_property = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CABC_STAGE_UP", 0, 512);
+ if (!prop)
+ return -ENOMEM;
+ private->cabc_stage_up_property = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CABC_STAGE_DOWN", 0, 255);
+ if (!prop)
+ return -ENOMEM;
+ private->cabc_stage_down_property = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CABC_GLOBAL_DN", 0, 255);
+ if (!prop)
+ return -ENOMEM;
+ private->cabc_global_dn_property = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CABC_CALC_PIXEL_NUM", 0, 1000);
+ if (!prop)
+ return -ENOMEM;
+ private->cabc_calc_pixel_num_property = prop;
+
+ return 0;
+}
+
static int rockchip_drm_bind(struct device *dev)
{
struct drm_device *drm_dev;
drm_mode_config_init(drm_dev);
rockchip_drm_mode_config_init(drm_dev);
+ rockchip_drm_create_properties(drm_dev);
ret = rockchip_drm_init_iommu(drm_dev);
if (ret)
DRM_IOCTL_DEF_DRV(ROCKCHIP_GEM_CPU_RELEASE,
rockchip_gem_cpu_release_ioctl,
DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(ROCKCHIP_RGA_GET_VER, rockchip_rga_get_ver_ioctl,
- DRM_AUTH | DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(ROCKCHIP_RGA_SET_CMDLIST,
- rockchip_rga_set_cmdlist_ioctl,
- DRM_AUTH | DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(ROCKCHIP_RGA_EXEC, rockchip_rga_exec_ioctl,
- DRM_AUTH | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(ROCKCHIP_GEM_GET_PHYS, rockchip_gem_get_phys_ioctl,
+ DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
};
static const struct file_operations rockchip_drm_driver_fops = {
.gem_prime_vmap = rockchip_gem_prime_vmap,
.gem_prime_vunmap = rockchip_gem_prime_vunmap,
.gem_prime_mmap = rockchip_gem_mmap_buf,
+ .gem_prime_begin_cpu_access = rockchip_gem_prime_begin_cpu_access,
+ .gem_prime_end_cpu_access = rockchip_gem_prime_end_cpu_access,
#ifdef CONFIG_DEBUG_FS
.debugfs_init = rockchip_drm_debugfs_init,
.debugfs_cleanup = rockchip_drm_debugfs_cleanup,
of_node_put(port);
}
+ port = of_parse_phandle(np, "backlight", 0);
+ if (port && of_device_is_available(port)) {
+ component_match_add(dev, &match, compare_of, port);
+ of_node_put(port);
+ }
+
return component_master_add_with_match(dev, &rockchip_drm_ops, match);
}