diff options
Diffstat (limited to 'drivers/gpu')
69 files changed, 2832 insertions, 1329 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 9f019cd053e1..748b93d00184 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -12,7 +12,6 @@ menuconfig DRM select HDMI select FB_CMDLINE select I2C - select I2C_ALGOBIT select DMA_SHARED_BUFFER select SYNC_FILE # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 5fcd510f1abb..5341b6b242c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -13,6 +13,8 @@ config DRM_AMDGPU select DRM_TTM_HELPER select POWER_SUPPLY select HWMON + select I2C + select I2C_ALGOBIT select BACKLIGHT_CLASS_DEVICE select INTERVAL_TREE select DRM_BUDDY diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 7043d1c9ed8f..e3507dd6f82a 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -195,8 +195,8 @@ static int hdlcd_setup_mode_config(struct drm_device *drm) #ifdef CONFIG_DEBUG_FS static int hdlcd_show_underrun_count(struct seq_file *m, void *arg) { - struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_device *drm = node->minor->dev; + struct drm_debugfs_entry *entry = m->private; + struct drm_device *drm = entry->dev; struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm); seq_printf(m, "underrun : %d\n", atomic_read(&hdlcd->buffer_underrun_count)); @@ -208,8 +208,8 @@ static int hdlcd_show_underrun_count(struct seq_file *m, void *arg) static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) { - struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_device *drm = node->minor->dev; + struct drm_debugfs_entry *entry = m->private; + struct drm_device *drm = entry->dev; struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm); unsigned long clkrate = clk_get_rate(hdlcd->clk); unsigned long mode_clock = hdlcd->crtc.mode.crtc_clock * 1000; @@ -219,17 +219,10 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) return 0; } -static struct drm_info_list hdlcd_debugfs_list[] = { +static struct drm_debugfs_info hdlcd_debugfs_list[] = { { "interrupt_count", hdlcd_show_underrun_count, 0 }, { "clocks", hdlcd_show_pxlclock, 0 }, }; - -static void hdlcd_debugfs_init(struct drm_minor *minor) -{ - drm_debugfs_create_files(hdlcd_debugfs_list, - ARRAY_SIZE(hdlcd_debugfs_list), - minor->debugfs_root, minor); -} #endif DEFINE_DRM_GEM_DMA_FOPS(fops); @@ -237,9 +230,6 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver hdlcd_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, -#ifdef CONFIG_DEBUG_FS - .debugfs_init = hdlcd_debugfs_init, -#endif .fops = &fops, .name = "hdlcd", .desc = "ARM HDLCD Controller DRM", @@ -303,6 +293,10 @@ static int hdlcd_drm_bind(struct device *dev) drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); +#ifdef CONFIG_DEBUG_FS + drm_debugfs_add_files(drm, hdlcd_debugfs_list, ARRAY_SIZE(hdlcd_debugfs_list)); +#endif + ret = drm_dev_register(drm, 0); if (ret) goto err_register; diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig index d367a90cd3de..563fa7a3b546 100644 --- a/drivers/gpu/drm/ast/Kconfig +++ b/drivers/gpu/drm/ast/Kconfig @@ -4,6 +4,8 @@ config DRM_AST depends on DRM && PCI && MMU select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER + select I2C + select I2C_ALGOBIT help Say yes for experimental AST GPU driver. Do not enable this driver without having a working -modesetting, diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index 1708098fba6d..e8aae3cdc73d 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -357,15 +357,16 @@ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, return ERR_PTR(-ENOMEM); bridge = drm_panel_bridge_add_typed(panel, connector_type); - if (!IS_ERR(bridge)) { - *ptr = bridge; - devres_add(dev, ptr); - } else { + if (IS_ERR(bridge)) { devres_free(ptr); + return bridge; } bridge->pre_enable_prev_first = panel->prepare_prev_first; + *ptr = bridge; + devres_add(dev, ptr); + return bridge; } EXPORT_SYMBOL(devm_drm_panel_bridge_add_typed); diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index b4c8cab7158c..6e74de833466 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -450,8 +450,8 @@ static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc, int i, n = 0; int ret = 0; - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n", - crtc->base.id, crtc->name); + drm_dbg_atomic(dev, "[CRTC:%d:%s] calculating normalized zpos values\n", + crtc->base.id, crtc->name); states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL); if (!states) @@ -469,9 +469,8 @@ static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc, goto done; } states[n++] = plane_state; - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] processing zpos value %d\n", - plane->base.id, plane->name, - plane_state->zpos); + drm_dbg_atomic(dev, "[PLANE:%d:%s] processing zpos value %d\n", + plane->base.id, plane->name, plane_state->zpos); } sort(states, n, sizeof(*states), drm_atomic_state_zpos_cmp, NULL); @@ -480,8 +479,8 @@ static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc, plane = states[i]->plane; states[i]->normalized_zpos = i; - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] normalized zpos value %d\n", - plane->base.id, plane->name, i); + drm_dbg_atomic(dev, "[PLANE:%d:%s] normalized zpos value %d\n", + plane->base.id, plane->name, i); } crtc_state->zpos_changed = true; diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 1c7d936523df..19ae4a177ac3 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -128,14 +128,7 @@ static void drm_bridge_connector_hpd_cb(void *cb_data, drm_kms_helper_hotplug_event(dev); } -/** - * drm_bridge_connector_enable_hpd - Enable hot-plug detection for the connector - * @connector: The DRM bridge connector - * - * This function enables hot-plug detection for the given bridge connector. - * This is typically used by display drivers in their resume handler. - */ -void drm_bridge_connector_enable_hpd(struct drm_connector *connector) +static void drm_bridge_connector_enable_hpd(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); @@ -145,17 +138,8 @@ void drm_bridge_connector_enable_hpd(struct drm_connector *connector) drm_bridge_hpd_enable(hpd, drm_bridge_connector_hpd_cb, bridge_connector); } -EXPORT_SYMBOL_GPL(drm_bridge_connector_enable_hpd); -/** - * drm_bridge_connector_disable_hpd - Disable hot-plug detection for the - * connector - * @connector: The DRM bridge connector - * - * This function disables hot-plug detection for the given bridge connector. - * This is typically used by display drivers in their suspend handler. - */ -void drm_bridge_connector_disable_hpd(struct drm_connector *connector) +static void drm_bridge_connector_disable_hpd(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); @@ -164,7 +148,6 @@ void drm_bridge_connector_disable_hpd(struct drm_connector *connector) if (hpd) drm_bridge_hpd_disable(hpd); } -EXPORT_SYMBOL_GPL(drm_bridge_connector_disable_hpd); /* ----------------------------------------------------------------------------- * Bridge Connector Functions @@ -305,6 +288,8 @@ static int drm_bridge_connector_get_modes(struct drm_connector *connector) static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs = { .get_modes = drm_bridge_connector_get_modes, /* No need for .mode_valid(), the bridges are checked by the core. */ + .enable_hpd = drm_bridge_connector_enable_hpd, + .disable_hpd = drm_bridge_connector_disable_hpd, }; /* ----------------------------------------------------------------------------- @@ -387,10 +372,8 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, connector_type, ddc); drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); - if (bridge_connector->bridge_hpd) { + if (bridge_connector->bridge_hpd) connector->polled = DRM_CONNECTOR_POLL_HPD; - drm_bridge_connector_enable_hpd(connector); - } else if (bridge_connector->bridge_detect) connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 5ea237839439..4f643a490dc3 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -207,7 +207,7 @@ void drm_debugfs_create_files(const struct drm_info_list *files, int count, tmp->minor = minor; tmp->dent = debugfs_create_file(files[i].name, - S_IFREG | S_IRUGO, root, tmp, + 0444, root, tmp, &drm_debugfs_fops); tmp->info_ent = &files[i]; @@ -246,7 +246,7 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, dev->driver->debugfs_init(minor); list_for_each_entry_safe(entry, tmp, &dev->debugfs_list, list) { - debugfs_create_file(entry->file.name, S_IFREG | S_IRUGO, + debugfs_create_file(entry->file.name, 0444, minor->debugfs_root, entry, &drm_debugfs_entry_fops); list_del(&entry->list); } @@ -263,7 +263,7 @@ void drm_debugfs_late_register(struct drm_device *dev) return; list_for_each_entry_safe(entry, tmp, &dev->debugfs_list, list) { - debugfs_create_file(entry->file.name, S_IFREG | S_IRUGO, + debugfs_create_file(entry->file.name, 0444, minor->debugfs_root, entry, &drm_debugfs_entry_fops); list_del(&entry->list); } @@ -508,15 +508,15 @@ void drm_debugfs_connector_add(struct drm_connector *connector) connector->debugfs_entry = root; /* force */ - debugfs_create_file("force", S_IRUGO | S_IWUSR, root, connector, + debugfs_create_file("force", 0644, root, connector, &drm_connector_fops); /* edid */ - debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root, connector, + debugfs_create_file("edid_override", 0644, root, connector, &drm_edid_fops); /* vrr range */ - debugfs_create_file("vrr_range", S_IRUGO, root, connector, + debugfs_create_file("vrr_range", 0444, root, connector, &vrr_range_fops); /* max bpc */ diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index b3a731b9170a..427631706128 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1726,117 +1726,132 @@ unlock: } EXPORT_SYMBOL(drm_fb_helper_pan_display); -/* - * Allocates the backing storage and sets up the fbdev info structure through - * the ->fb_probe callback. - */ -static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, - int preferred_bpp) +static uint32_t drm_fb_helper_find_format(struct drm_fb_helper *fb_helper, const uint32_t *formats, + size_t format_count, uint32_t bpp, uint32_t depth) { - struct drm_client_dev *client = &fb_helper->client; struct drm_device *dev = fb_helper->dev; - struct drm_mode_config *config = &dev->mode_config; - int ret = 0; - int crtc_count = 0; - struct drm_connector_list_iter conn_iter; - struct drm_fb_helper_surface_size sizes; - struct drm_connector *connector; - struct drm_mode_set *mode_set; - int best_depth = 0; - - memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size)); - sizes.surface_depth = 24; - sizes.surface_bpp = 32; - sizes.fb_width = (u32)-1; - sizes.fb_height = (u32)-1; + uint32_t format; + size_t i; /* - * If driver picks 8 or 16 by default use that for both depth/bpp - * to begin with + * Do not consider YUV or other complicated formats + * for framebuffers. This means only legacy formats + * are supported (fmt->depth is a legacy field), but + * the framebuffer emulation can only deal with such + * formats, specifically RGB/BGA formats. */ - if (preferred_bpp != sizes.surface_bpp) - sizes.surface_depth = sizes.surface_bpp = preferred_bpp; + format = drm_mode_legacy_fb_format(bpp, depth); + if (!format) + goto err; - drm_connector_list_iter_begin(fb_helper->dev, &conn_iter); - drm_client_for_each_connector_iter(connector, &conn_iter) { - struct drm_cmdline_mode *cmdline_mode; + for (i = 0; i < format_count; ++i) { + if (formats[i] == format) + return format; + } - cmdline_mode = &connector->cmdline_mode; +err: + /* We found nothing. */ + drm_warn(dev, "bpp/depth value of %u/%u not supported\n", bpp, depth); - if (cmdline_mode->bpp_specified) { - switch (cmdline_mode->bpp) { - case 8: - sizes.surface_depth = sizes.surface_bpp = 8; - break; - case 15: - sizes.surface_depth = 15; - sizes.surface_bpp = 16; - break; - case 16: - sizes.surface_depth = sizes.surface_bpp = 16; - break; - case 24: - sizes.surface_depth = sizes.surface_bpp = 24; - break; - case 32: - sizes.surface_depth = 24; - sizes.surface_bpp = 32; - break; - } - break; - } + return DRM_FORMAT_INVALID; +} + +static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper *fb_helper, + const uint32_t *formats, size_t format_count, + unsigned int color_mode) +{ + struct drm_device *dev = fb_helper->dev; + uint32_t bpp, depth; + + switch (color_mode) { + case 1: + case 2: + case 4: + case 8: + case 16: + case 24: + bpp = depth = color_mode; + break; + case 15: + bpp = 16; + depth = 15; + break; + case 32: + bpp = 32; + depth = 24; + break; + default: + drm_info(dev, "unsupported color mode of %d\n", color_mode); + return DRM_FORMAT_INVALID; } - drm_connector_list_iter_end(&conn_iter); - /* - * If we run into a situation where, for example, the primary plane - * supports RGBA5551 (16 bpp, depth 15) but not RGB565 (16 bpp, depth - * 16) we need to scale down the depth of the sizes we request. - */ - mutex_lock(&client->modeset_mutex); + return drm_fb_helper_find_format(fb_helper, formats, format_count, bpp, depth); +} + +static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp, + struct drm_fb_helper_surface_size *sizes) +{ + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; + int crtc_count = 0; + struct drm_connector_list_iter conn_iter; + struct drm_connector *connector; + struct drm_mode_set *mode_set; + uint32_t surface_format = DRM_FORMAT_INVALID; + const struct drm_format_info *info; + + memset(sizes, 0, sizeof(*sizes)); + sizes->fb_width = (u32)-1; + sizes->fb_height = (u32)-1; + drm_client_for_each_modeset(mode_set, client) { struct drm_crtc *crtc = mode_set->crtc; struct drm_plane *plane = crtc->primary; - int j; drm_dbg_kms(dev, "test CRTC %u primary plane\n", drm_crtc_index(crtc)); - for (j = 0; j < plane->format_count; j++) { - const struct drm_format_info *fmt; - - fmt = drm_format_info(plane->format_types[j]); - - /* - * Do not consider YUV or other complicated formats - * for framebuffers. This means only legacy formats - * are supported (fmt->depth is a legacy field) but - * the framebuffer emulation can only deal with such - * formats, specifically RGB/BGA formats. - */ - if (fmt->depth == 0) - continue; - - /* We found a perfect fit, great */ - if (fmt->depth == sizes.surface_depth) { - best_depth = fmt->depth; - break; - } + drm_connector_list_iter_begin(fb_helper->dev, &conn_iter); + drm_client_for_each_connector_iter(connector, &conn_iter) { + struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode; - /* Skip depths above what we're looking for */ - if (fmt->depth > sizes.surface_depth) + if (!cmdline_mode->bpp_specified) continue; - /* Best depth found so far */ - if (fmt->depth > best_depth) - best_depth = fmt->depth; + surface_format = drm_fb_helper_find_color_mode_format(fb_helper, + plane->format_types, + plane->format_count, + cmdline_mode->bpp); + if (surface_format != DRM_FORMAT_INVALID) + break; /* found supported format */ } + drm_connector_list_iter_end(&conn_iter); + + if (surface_format != DRM_FORMAT_INVALID) + break; /* found supported format */ + + /* try preferred color mode */ + surface_format = drm_fb_helper_find_color_mode_format(fb_helper, + plane->format_types, + plane->format_count, + preferred_bpp); + if (surface_format != DRM_FORMAT_INVALID) + break; /* found supported format */ } - if (sizes.surface_depth != best_depth && best_depth) { - drm_info(dev, "requested bpp %d, scaled depth down to %d", - sizes.surface_bpp, best_depth); - sizes.surface_depth = best_depth; + + if (surface_format == DRM_FORMAT_INVALID) { + /* + * If none of the given color modes works, fall back + * to XRGB8888. Drivers are expected to provide this + * format for compatibility with legacy applications. + */ + drm_warn(dev, "No compatible format found\n"); + surface_format = |