diff options
Diffstat (limited to 'drivers/gpu/host1x/drm')
-rw-r--r-- | drivers/gpu/host1x/drm/bus.c | 76 | ||||
-rw-r--r-- | drivers/gpu/host1x/drm/dc.c | 30 | ||||
-rw-r--r-- | drivers/gpu/host1x/drm/drm.c | 347 | ||||
-rw-r--r-- | drivers/gpu/host1x/drm/drm.h | 31 | ||||
-rw-r--r-- | drivers/gpu/host1x/drm/gr2d.c | 60 | ||||
-rw-r--r-- | drivers/gpu/host1x/drm/hdmi.c | 28 |
6 files changed, 271 insertions, 301 deletions
diff --git a/drivers/gpu/host1x/drm/bus.c b/drivers/gpu/host1x/drm/bus.c new file mode 100644 index 000000000000..565f8f7b9a47 --- /dev/null +++ b/drivers/gpu/host1x/drm/bus.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2013 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "drm.h" + +static int drm_host1x_set_busid(struct drm_device *dev, + struct drm_master *master) +{ + const char *device = dev_name(dev->dev); + const char *driver = dev->driver->name; + const char *bus = dev->dev->bus->name; + int length; + + master->unique_len = strlen(bus) + 1 + strlen(device); + master->unique_size = master->unique_len; + + master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL); + if (!master->unique) + return -ENOMEM; + + snprintf(master->unique, master->unique_len + 1, "%s:%s", bus, device); + + length = strlen(driver) + 1 + master->unique_len; + + dev->devname = kmalloc(length + 1, GFP_KERNEL); + if (!dev->devname) + return -ENOMEM; + + snprintf(dev->devname, length + 1, "%s@%s", driver, master->unique); + + return 0; +} + +static struct drm_bus drm_host1x_bus = { + .bus_type = DRIVER_BUS_HOST1X, + .set_busid = drm_host1x_set_busid, +}; + +int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device) +{ + struct drm_device *drm; + int ret; + + INIT_LIST_HEAD(&driver->device_list); + driver->bus = &drm_host1x_bus; + + drm = drm_dev_alloc(driver, &device->dev); + if (!drm) + return -ENOMEM; + + ret = drm_dev_register(drm, 0); + if (ret) + goto err_free; + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, + driver->major, driver->minor, driver->patchlevel, + driver->date, drm->primary->index); + + return 0; + +err_free: + drm_dev_free(drm); + return ret; +} + +void drm_host1x_exit(struct drm_driver *driver, struct host1x_device *device) +{ + struct tegra_drm *tegra = dev_get_drvdata(&device->dev); + + drm_put_dev(tegra->drm); +} diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c index 5106df08f046..588d4ba0d8cf 100644 --- a/drivers/gpu/host1x/drm/dc.c +++ b/drivers/gpu/host1x/drm/dc.c @@ -11,7 +11,6 @@ #include <linux/clk/tegra.h> #include <linux/debugfs.h> -#include "host1x_client.h" #include "dc.h" #include "drm.h" #include "gem.h" @@ -1040,28 +1039,28 @@ static int tegra_dc_debugfs_exit(struct tegra_dc *dc) static int tegra_dc_init(struct host1x_client *client) { - struct tegra_drm_client *drm = to_tegra_drm_client(client); - struct tegra_dc *dc = tegra_drm_client_to_dc(drm); + struct tegra_drm *tegra = dev_get_drvdata(client->parent); + struct tegra_dc *dc = host1x_client_to_dc(client); int err; - dc->pipe = drm->drm->mode_config.num_crtc; + dc->pipe = tegra->drm->mode_config.num_crtc; - drm_crtc_init(drm->drm, &dc->base, &tegra_crtc_funcs); + drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs); drm_mode_crtc_set_gamma_size(&dc->base, 256); drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); - err = tegra_dc_rgb_init(drm->drm, dc); + err = tegra_dc_rgb_init(tegra->drm, dc); if (err < 0 && err != -ENODEV) { dev_err(dc->dev, "failed to initialize RGB output: %d\n", err); return err; } - err = tegra_dc_add_planes(drm->drm, dc); + err = tegra_dc_add_planes(tegra->drm, dc); if (err < 0) return err; if (IS_ENABLED(CONFIG_DEBUG_FS)) { - err = tegra_dc_debugfs_init(dc, drm->drm->primary); + err = tegra_dc_debugfs_init(dc, tegra->drm->primary); if (err < 0) dev_err(dc->dev, "debugfs setup failed: %d\n", err); } @@ -1079,8 +1078,7 @@ static int tegra_dc_init(struct host1x_client *client) static int tegra_dc_exit(struct host1x_client *client) { - struct tegra_drm_client *drm = to_tegra_drm_client(client); - struct tegra_dc *dc = tegra_drm_client_to_dc(drm); + struct tegra_dc *dc = host1x_client_to_dc(client); int err; devm_free_irq(dc->dev, dc->irq, dc); @@ -1107,7 +1105,6 @@ static const struct host1x_client_ops dc_client_ops = { static int tegra_dc_probe(struct platform_device *pdev) { - struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent); struct resource *regs; struct tegra_dc *dc; int err; @@ -1141,9 +1138,9 @@ static int tegra_dc_probe(struct platform_device *pdev) return -ENXIO; } - INIT_LIST_HEAD(&dc->client.base.list); - dc->client.base.ops = &dc_client_ops; - dc->client.base.dev = &pdev->dev; + INIT_LIST_HEAD(&dc->client.list); + dc->client.ops = &dc_client_ops; + dc->client.dev = &pdev->dev; err = tegra_dc_rgb_probe(dc); if (err < 0 && err != -ENODEV) { @@ -1151,7 +1148,7 @@ static int tegra_dc_probe(struct platform_device *pdev) return err; } - err = host1x_register_client(tegra, &dc->client.base); + err = host1x_client_register(&dc->client); if (err < 0) { dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); @@ -1165,11 +1162,10 @@ static int tegra_dc_probe(struct platform_device *pdev) static int tegra_dc_remove(struct platform_device *pdev) { - struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent); struct tegra_dc *dc = platform_get_drvdata(pdev); int err; - err = host1x_unregister_client(tegra, &dc->client.base); + err = host1x_client_unregister(&dc->client); if (err < 0) { dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", err); diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c index 1abcdbc7f4cd..c2db409bbd63 100644 --- a/drivers/gpu/host1x/drm/drm.c +++ b/drivers/gpu/host1x/drm/drm.c @@ -7,7 +7,8 @@ * published by the Free Software Foundation. */ -#include "host1x_client.h" +#include <linux/host1x.h> + #include "drm.h" #include "gem.h" @@ -22,239 +23,25 @@ struct tegra_drm_file { struct list_head contexts; }; -struct host1x_subdev { - struct host1x_client *client; - struct device_node *np; - struct list_head list; -}; - -static int host1x_subdev_add(struct tegra_drm *tegra, struct device_node *np) -{ - struct host1x_subdev *subdev; - - subdev = kzalloc(sizeof(*subdev), GFP_KERNEL); - if (!subdev) - return -ENOMEM; - - INIT_LIST_HEAD(&subdev->list); - subdev->np = of_node_get(np); - - list_add_tail(&subdev->list, &tegra->subdevs); - - return 0; -} - -static int host1x_subdev_register(struct tegra_drm *tegra, - struct host1x_subdev *subdev, - struct host1x_client *client) -{ - mutex_lock(&tegra->subdevs_lock); - list_del_init(&subdev->list); - list_add_tail(&subdev->list, &tegra->active); - subdev->client = client; - mutex_unlock(&tegra->subdevs_lock); - - return 0; -} - -static int host1x_subdev_unregister(struct tegra_drm *tegra, - struct host1x_subdev *subdev) -{ - mutex_lock(&tegra->subdevs_lock); - list_del_init(&subdev->list); - mutex_unlock(&tegra->subdevs_lock); - - of_node_put(subdev->np); - kfree(subdev); - - return 0; -} - -static int tegra_parse_dt(struct tegra_drm *tegra) -{ - static const char * const compat[] = { - "nvidia,tegra20-dc", - "nvidia,tegra20-hdmi", - "nvidia,tegra20-gr2d", - "nvidia,tegra30-dc", - "nvidia,tegra30-hdmi", - "nvidia,tegra30-gr2d", - }; - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(compat); i++) { - struct device_node *np; - - for_each_child_of_node(tegra->dev->of_node, np) { - if (of_device_is_compatible(np, compat[i]) && - of_device_is_available(np)) { - err = host1x_subdev_add(tegra, np); - if (err < 0) - return err; - } - } - } - - return 0; -} - -int tegra_drm_alloc(struct platform_device *pdev) +static int tegra_drm_load(struct drm_device *drm, unsigned long flags) { + struct host1x_device *device = to_host1x_device(drm->dev); struct tegra_drm *tegra; int err; - tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); + tegra = kzalloc(sizeof(*tegra), GFP_KERNEL); if (!tegra) return -ENOMEM; - mutex_init(&tegra->subdevs_lock); - INIT_LIST_HEAD(&tegra->subdevs); - INIT_LIST_HEAD(&tegra->active); + dev_set_drvdata(drm->dev, tegra); mutex_init(&tegra->clients_lock); INIT_LIST_HEAD(&tegra->clients); - tegra->dev = &pdev->dev; - - err = tegra_parse_dt(tegra); - if (err < 0) { - dev_err(&pdev->dev, "failed to parse DT: %d\n", err); - return err; - } - - host1x_set_drm_data(&pdev->dev, tegra); - - return 0; -} - -int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm) -{ - struct host1x_client *client; - int err; - - mutex_lock(&tegra->clients_lock); - - list_for_each_entry(client, &tegra->clients, list) { - struct tegra_drm_client *tdc = to_tegra_drm_client(client); - - /* associate client with DRM device */ - tdc->drm = drm; - - if (client->ops && client->ops->init) { - err = client->ops->init(client); - if (err < 0) { - dev_err(tegra->dev, - "DRM setup failed for %s: %d\n", - dev_name(client->dev), err); - mutex_unlock(&tegra->clients_lock); - return err; - } - } - } - - mutex_unlock(&tegra->clients_lock); - - return 0; -} - -int tegra_drm_exit(struct tegra_drm *tegra) -{ - struct host1x_client *client; - struct platform_device *pdev; - int err; - - if (!tegra->drm) - return 0; - - mutex_lock(&tegra->clients_lock); - - list_for_each_entry_reverse(client, &tegra->clients, list) { - if (client->ops && client->ops->exit) { - err = client->ops->exit(client); - if (err < 0) { - dev_err(tegra->dev, - "DRM cleanup failed for %s: %d\n", - dev_name(client->dev), err); - mutex_unlock(&tegra->clients_lock); - return err; - } - } - } - - mutex_unlock(&tegra->clients_lock); - - pdev = to_platform_device(tegra->dev); - drm_platform_exit(&tegra_drm_driver, pdev); - tegra->drm = NULL; - - return 0; -} - -int host1x_register_client(struct tegra_drm *tegra, - struct host1x_client *client) -{ - struct host1x_subdev *subdev, *tmp; - int err; - - mutex_lock(&tegra->clients_lock); - list_add_tail(&client->list, &tegra->clients); - mutex_unlock(&tegra->clients_lock); - - list_for_each_entry_safe(subdev, tmp, &tegra->subdevs, list) - if (subdev->np == client->dev->of_node) - host1x_subdev_register(tegra, subdev, client); - - if (list_empty(&tegra->subdevs)) { - struct platform_device *pdev = to_platform_device(tegra->dev); - - err = drm_platform_init(&tegra_drm_driver, pdev); - if (err < 0) { - dev_err(tegra->dev, "drm_platform_init(): %d\n", err); - return err; - } - } - - return 0; -} - -int host1x_unregister_client(struct tegra_drm *tegra, - struct host1x_client *client) -{ - struct host1x_subdev *subdev, *tmp; - int err; - - list_for_each_entry_safe(subdev, tmp, &tegra->active, list) { - if (subdev->client == client) { - err = tegra_drm_exit(tegra); - if (err < 0) { - dev_err(tegra->dev, "tegra_drm_exit(): %d\n", - err); - return err; - } - - host1x_subdev_unregister(tegra, subdev); - break; - } - } - - mutex_lock(&tegra->clients_lock); - list_del_init(&client->list); - mutex_unlock(&tegra->clients_lock); - - return 0; -} - -static int tegra_drm_load(struct drm_device *drm, unsigned long flags) -{ - struct tegra_drm *tegra; - int err; - - tegra = host1x_get_drm_data(drm->dev); drm->dev_private = tegra; tegra->drm = drm; drm_mode_config_init(drm); - err = tegra_drm_init(tegra, drm); + err = host1x_device_init(device); if (err < 0) return err; @@ -280,9 +67,16 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) static int tegra_drm_unload(struct drm_device *drm) { + struct host1x_device *device = to_host1x_device(drm->dev); + int err; + drm_kms_helper_poll_fini(drm); tegra_drm_fb_exit(drm); + err = host1x_device_exit(device); + if (err < 0) + return err; + drm_mode_config_cleanup(drm); return 0; @@ -370,10 +164,11 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data, static int tegra_syncpt_read(struct drm_device *drm, void *data, struct drm_file *file) { + struct host1x *host = dev_get_drvdata(drm->dev->parent); struct drm_tegra_syncpt_read *args = data; - struct host1x *host = dev_get_drvdata(drm->dev); - struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id); + struct host1x_syncpt *sp; + sp = host1x_syncpt_get(host, args->id); if (!sp) return -EINVAL; @@ -384,10 +179,11 @@ static int tegra_syncpt_read(struct drm_device *drm, void *data, static int tegra_syncpt_incr(struct drm_device *drm, void *data, struct drm_file *file) { + struct host1x *host1x = dev_get_drvdata(drm->dev->parent); struct drm_tegra_syncpt_incr *args = data; - struct host1x *host = dev_get_drvdata(drm->dev); - struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id); + struct host1x_syncpt *sp; + sp = host1x_syncpt_get(host1x, args->id); if (!sp) return -EINVAL; @@ -397,10 +193,11 @@ static int tegra_syncpt_incr(struct drm_device *drm, void *data, static int tegra_syncpt_wait(struct drm_device *drm, void *data, struct drm_file *file) { + struct host1x *host1x = dev_get_drvdata(drm->dev->parent); struct drm_tegra_syncpt_wait *args = data; - struct host1x *host = dev_get_drvdata(drm->dev); - struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id); + struct host1x_syncpt *sp; + sp = host1x_syncpt_get(host1x, args->id); if (!sp) return -EINVAL; @@ -422,7 +219,7 @@ static int tegra_open_channel(struct drm_device *drm, void *data, if (!context) return -ENOMEM; - list_for_each_entry(client, &tegra->clients, base.list) + list_for_each_entry(client, &tegra->clients, list) if (client->base.class == args->client) { err = client->ops->open_channel(client, context); if (err) @@ -441,8 +238,8 @@ static int tegra_open_channel(struct drm_device *drm, void *data, static int tegra_close_channel(struct drm_device *drm, void *data, struct drm_file *file) { - struct drm_tegra_close_channel *args = data; struct tegra_drm_file *fpriv = file->driver_priv; + struct drm_tegra_close_channel *args = data; struct tegra_drm_context *context; context = tegra_drm_get_context(args->context); @@ -652,3 +449,97 @@ struct drm_driver tegra_drm_driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, }; + +int tegra_drm_register_client(struct tegra_drm *tegra, + struct tegra_drm_client *client) +{ + mutex_lock(&tegra->clients_lock); + list_add_tail(&client->list, &tegra->clients); + mutex_unlock(&tegra->clients_lock); + + return 0; +} + +int tegra_drm_unregister_client(struct tegra_drm *tegra, + struct tegra_drm_client *client) +{ + mutex_lock(&tegra->clients_lock); + list_del_init(&client->list); + mutex_unlock(&tegra->clients_lock); + + return 0; +} + +static int host1x_drm_probe(struct host1x_device *device) +{ + return drm_host1x_init(&tegra_drm_driver, device); +} + +static int host1x_drm_remove(struct host1x_device *device) +{ + drm_host1x_exit(&tegra_drm_driver, device); + + return 0; +} + +static const struct of_device_id host1x_drm_subdevs[] = { + { .compatible = "nvidia,tegra20-dc", }, + { .compatible = "nvidia,tegra20-hdmi", }, + { .compatible = "nvidia,tegra20-gr2d", }, + { .compatible = "nvidia,tegra30-dc", }, + { .compatible = "nvidia,tegra30-hdmi", }, + { .compatible = "nvidia,tegra30-gr2d", }, + { /* sentinel */ } +}; + +static struct host1x_driver host1x_drm_driver = { + .name = "drm", + .probe = host1x_drm_probe, + .remove = host1x_drm_remove, + .subdevs = host1x_drm_subdevs, +}; + +static int __init host1x_drm_init(void) +{ + int err; + + err = host1x_driver_register(&host1x_drm_driver); + if (err < 0) + return err; + + err = platform_driver_register(&tegra_dc_driver); + if (err < 0) + goto unregister_host1x; + + err = platform_driver_register(&tegra_hdmi_driver); + if (err < 0) + goto unregister_dc; + + err = platform_driver_register(&tegra_gr2d_driver); + if (err < 0) + goto unregister_hdmi; + + return 0; + +unregister_hdmi: + platform_driver_unregister(&tegra_hdmi_driver); +unregister_dc: + platform_driver_unregister(&tegra_dc_driver); +unregister_host1x: + host1x_driver_unregister(&host1x_drm_driver); + return err; +} +module_init(host1x_drm_init); + +static void __exit host1x_drm_exit(void) +{ + platform_driver_unregister(&tegra_gr2d_driver); + platform_driver_unregister(&tegra_hdmi_driver); + platform_driver_unregister(&tegra_dc_driver); + host1x_driver_unregister(&host1x_drm_driver); +} +module_exit(host1x_drm_exit); + +MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); +MODULE_DESCRIPTION("NVIDIA Tegra DRM driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h index 8c26c6b1f5e1..25522e23c7b8 100644 --- a/drivers/gpu/host1x/drm/drm.h +++ b/drivers/gpu/host1x/drm/drm.h @@ -32,11 +32,6 @@ struct tegra_fbdev { struct tegra_drm { struct drm_device *drm; - struct device *dev; - - struct mutex subdevs_lock; - struct list_head subdevs; - struct list_head active; struct mutex clients_lock; struct list_head clients; @@ -63,29 +58,29 @@ struct tegra_drm_client_ops { struct tegra_drm_client { struct host1x_client base; - struct drm_device *drm; + struct list_head list; const struct tegra_drm_client_ops *ops; }; static inline struct tegra_drm_client * -to_tegra_drm_client(struct host1x_client *client) +host1x_to_drm_client(struct host1x_client *client) { return container_of(client, struct tegra_drm_client, base); } +extern int tegra_drm_register_client(struct tegra_drm *tegra, + struct tegra_drm_client *client); +extern int tegra_drm_unregister_client(struct tegra_drm *tegra, + struct tegra_drm_client *client); + extern int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm); extern int tegra_drm_exit(struct tegra_drm *tegra); -extern int host1x_register_client(struct tegra_drm *tegra, - struct host1x_client *client); -extern int host1x_unregister_client(struct tegra_drm *tegra, - struct host1x_client *client); - struct tegra_output; struct tegra_dc { - struct tegra_drm_client client; + struct host1x_client client; struct device *dev; spinlock_t lock; @@ -109,7 +104,7 @@ struct tegra_dc { }; static inline struct tegra_dc * -tegra_drm_client_to_dc(struct tegra_drm_client *client) +host1x_client_to_dc(struct host1x_client *client) { return container_of(client, struct tegra_dc, client); } @@ -235,6 +230,10 @@ static inline int tegra_output_check_mode(struct tegra_output *output, return output ? -ENOSYS : -EINVAL; } +/* from bus.c */ +int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device); +void drm_host1x_exit(struct drm_driver *driver, struct host1x_device *device); + /* from rgb.c */ extern int tegra_dc_rgb_probe(struct tegra_dc *dc); extern int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc); @@ -252,6 +251,8 @@ extern int tegra_drm_fb_init(struct drm_device *drm); extern void tegra_drm_fb_exit(struct drm_device *drm); extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev); -extern struct drm_driver tegra_drm_driver; +extern struct platform_driver tegra_dc_driver; +extern struct platform_driver tegra_hdmi_driver; +extern struct platform_driver tegra_gr2d_driver; #endif /* HOST1X_DRM_H */ diff --git a/drivers/gpu/host1x/drm/gr2d.c b/drivers/gpu/host1x/drm/gr2d.c index dfb822428ca0..4e407e30da1c 100644 --- a/drivers/gpu/host1x/drm/gr2d.c +++ b/drivers/gpu/host1x/drm/gr2d.c @@ -16,7 +16,6 @@ #include <linux/clk.h> -#include "host1x_client.h" #include "drm.h" #include "gem.h" @@ -35,19 +34,45 @@ static inline struct gr2d *to_gr2d(struct tegra_drm_client *client) return container_of(client, struct gr2d, client); } -static int gr2d_client_init(struct host1x_client *client) +static int gr2d_init(struct host1x_client *client) { - return 0; + struct tegra_drm_client *drm = host1x_to_drm_client(client); + struct tegra_drm *tegra = dev_get_drvdata(client->parent); + struct gr2d *gr2d = to_gr2d(drm); + + gr2d->channel = host1x_channel_request(client->dev); + if (!gr2d->channel) + return -ENOMEM; + + client->syncpts[0] = host1x_syncpt_request(client->dev, false); + if (!client->syncpts[0]) { + host1x_channel_free(gr2d->channel); + return -ENOMEM; + } + + return tegra_drm_register_client(tegra, drm); } -static int gr2d_client_exit(struct host1x_client *client) +static int gr2d_exit(struct host1x_client *client) { + struct tegra_drm_client *drm = host1x_to_drm_client(client); + struct tegra_drm *tegra = dev_get_drvdata(client->parent); + struct gr2d *gr2d = to_gr2d(drm); + int err; + + err = tegra_drm_unregister_client(tegra, drm); + if (err < 0) + return err; + + host1x_syncpt_free(client->syncpts[0]); + host1x_channel_free(gr2d->channel); + return 0; } static const struct host1x_client_ops gr2d_client_ops = { - .init = gr2d_client_init, - .exit = gr2d_client_exit, + .init = gr2d_init, + .exit = gr2d_exit, }; static int gr2d_open_channel(struct tegra_drm_client *client, @@ -240,7 +265,6 @@ static const u32 gr2d_addr_regs[] = { static int gr2d_probe(struct platform_device *pdev) { - struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent); struct device *dev = &pdev->dev; struct host1x_syncpt **syncpts; struct gr2d *gr2d; @@ -267,25 +291,17 @@ static int gr2d_probe(struct platform_device *pdev) return err; } - gr2d->channel = host1x_channel_request(dev); - if (!gr2d->channel) - return -ENOMEM; - - *syncpts = host1x_syncpt_request(dev, false); - if (!(*syncpts)) { - host1x_channel_free(gr2d->channel); - return -ENOMEM; - } - INIT_LIST_HEAD(&gr2d->client.base.list); gr2d->client.base.ops = &gr2d_client_ops; gr2d->client.base.dev = dev; gr2d->client.base.class = HOST1X_CLASS_GR2D; gr2d->client.base.syncpts = syncpts; gr2d->client.base.num_syncpts = 1; + + INIT_LIST_HEAD(&gr2d->client.list); gr2d->client.ops = &gr2d_ops; - err = host1x_register_client(tegra, &gr2d->client.base); + err = host1x_client_register(&gr2d->client.base); if (err < 0) { dev_err(dev, "failed to register host1x client: %d\n", err); return err; @@ -302,22 +318,16 @@ static int gr2d_probe(struct platform_device *pdev) static int gr2d_remove(struct platform_device *pdev) { - struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent); struct gr2d *gr2d = platform_get_drvdata(pdev); - unsigned int i; int err; - err = host1x_unregister_client(tegra, &gr2d->client.base); + err = host1x_client_unregister(&gr2d->client.base); if (err < 0) { dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", err); return err; } - for (i = 0; i < gr2d->client.base.num_syncpts; i++) - host1x_syncpt_free(gr2d->client.base.syncpts[i]); - - host1x_channel_free(gr2d->channel); clk_disable_unprepare(gr2d->clk); return 0; diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c index a2370045993c..f5663d15670b 100644 --- a/drivers/gpu/host1x/drm/hdmi.c +++ b/drivers/gpu/host1x/drm/hdmi.c @@ -13,13 +13,12 @@ #include <linux/hdmi.h> #include <linux/regulator/consumer.h> -#include "host1x_client.h" #include "hdmi.h" #include "drm.h" #include "dc.h" struct tegra_hdmi { - struct tegra_drm_client client; + struct host1x_client client; struct tegra_output output; struct device *dev; @@ -43,7 +42,7 @@ struct tegra_hdmi { }; static inline struct tegra_hdmi * -tegra_drm_client_to_hdmi(struct tegra_drm_client *client) +host1x_client_to_hdmi(struct host1x_client *client) { return container_of(client, struct tegra_hdmi, client); } @@ -1118,22 +1117,22 @@ static int tegra_hdmi_debugfs_exit(struct tegra_hdmi *hdmi) static int tegra_hdmi_init(struct host1x_client *client) { - struct tegra_drm_client *drm = to_tegra_drm_client(client); - struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm); + struct tegra_drm *tegra = dev_get_drvdata(client->parent); + struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); int err; hdmi->output.type = TEGRA_OUTPUT_HDMI; hdmi->output.dev = client->dev; hdmi->output.ops = &hdmi_ops; - err = tegra_output_init(drm->drm, &hdmi->output); + err = tegra_output_init(tegra->drm, &hdmi->output); if (err < 0) { dev_err(client->dev, "output setup failed: %d\n", err); return err; } if (IS_ENABLED(CONFIG_DEBUG_FS)) { - err = tegra_hdmi_debugfs_init(hdmi, drm->drm->primary); + err = tegra_hdmi_debugfs_init(hdmi, tegra->drm->primary); if (err < 0) dev_err(client->dev, "debugfs setup failed: %d\n", err); } @@ -1143,8 +1142,7 @@ static int tegra_hdmi_init(struct host1x_client *client) static int tegra_hdmi_exit(struct host1x_client *client) { - struct tegra_drm_client *drm = to_tegra_drm_client(client); - struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm); + struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); int err; if (IS_ENABLED(CONFIG_DEBUG_FS)) { @@ -1176,7 +1174,6 @@ static const struct host1x_client_ops hdmi_client_ops = { static int tegra_hdmi_probe(struct platform_device *pdev) { - struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent); struct tegra_hdmi *hdmi; struct resource *regs; int err; @@ -1247,11 +1244,11 @@ static int tegra_hdmi_probe(struct platform_device *pdev) hdmi->irq = err; - INIT_LIST_HEAD(&hdmi->client.base.list); - hdmi->client.base.ops = &hdmi_client_ops; - hdmi->client.base.dev = &pdev->dev; + INIT_LIST_HEAD(&hdmi->client.list); + hdmi->client.ops = &hdmi_client_ops; + hdmi->client.dev = &pdev->dev; - err = host1x_register_client(tegra, &hdmi->client.base); + err = host1x_client_register(&hdmi->client); if (err < 0) { dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); @@ -1265,11 +1262,10 @@ static int tegra_hdmi_probe(struct platform_device *pdev) static int tegra_hdmi_remove(struct platform_device *pdev) { - struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent); struct tegra_hdmi *hdmi = platform_get_drvdata(pdev); int err; - err = host1x_unregister_client(tegra, &hdmi->client.base); + err = host1x_client_unregister(&hdmi->client); if (err < 0) { dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", err); |