return 0;
}
-static int tegra_dc_drm_init(struct host1x_client *client,
- struct drm_device *drm)
+static int tegra_dc_init(struct host1x_client *client)
{
- struct tegra_dc *dc = host1x_client_to_dc(client);
+ struct tegra_drm_client *drm = to_tegra_drm_client(client);
+ struct tegra_dc *dc = tegra_drm_client_to_dc(drm);
int err;
- dc->pipe = drm->mode_config.num_crtc;
+ dc->pipe = drm->drm->mode_config.num_crtc;
- drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs);
+ drm_crtc_init(drm->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, dc);
+ err = tegra_dc_rgb_init(drm->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, dc);
+ err = tegra_dc_add_planes(drm->drm, dc);
if (err < 0)
return err;
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
- err = tegra_dc_debugfs_init(dc, drm->primary);
+ err = tegra_dc_debugfs_init(dc, drm->drm->primary);
if (err < 0)
dev_err(dc->dev, "debugfs setup failed: %d\n", err);
}
return 0;
}
-static int tegra_dc_drm_exit(struct host1x_client *client)
+static int tegra_dc_exit(struct host1x_client *client)
{
- struct tegra_dc *dc = host1x_client_to_dc(client);
+ struct tegra_drm_client *drm = to_tegra_drm_client(client);
+ struct tegra_dc *dc = tegra_drm_client_to_dc(drm);
int err;
devm_free_irq(dc->dev, dc->irq, dc);
}
static const struct host1x_client_ops dc_client_ops = {
- .drm_init = tegra_dc_drm_init,
- .drm_exit = tegra_dc_drm_exit,
+ .init = tegra_dc_init,
+ .exit = tegra_dc_exit,
};
static int tegra_dc_probe(struct platform_device *pdev)
return -ENXIO;
}
- INIT_LIST_HEAD(&dc->client.list);
- dc->client.ops = &dc_client_ops;
- dc->client.dev = &pdev->dev;
+ INIT_LIST_HEAD(&dc->client.base.list);
+ dc->client.base.ops = &dc_client_ops;
+ dc->client.base.dev = &pdev->dev;
err = tegra_dc_rgb_probe(dc);
if (err < 0 && err != -ENODEV) {
return err;
}
- err = host1x_register_client(tegra, &dc->client);
+ err = host1x_register_client(tegra, &dc->client.base);
if (err < 0) {
dev_err(&pdev->dev, "failed to register host1x client: %d\n",
err);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;
- err = host1x_unregister_client(tegra, &dc->client);
+ err = host1x_unregister_client(tegra, &dc->client.base);
if (err < 0) {
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
err);
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) {
- if (client->ops && client->ops->drm_init) {
- int err = client->ops->drm_init(client, drm);
+ 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",
int tegra_drm_exit(struct tegra_drm *tegra)
{
- struct platform_device *pdev = to_platform_device(tegra->dev);
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->drm_exit) {
- int err = client->ops->drm_exit(client);
+ 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",
mutex_unlock(&tegra->clients_lock);
+ pdev = to_platform_device(tegra->dev);
drm_platform_exit(&tegra_drm_driver, pdev);
tegra->drm = NULL;
struct tegra_drm *tegra = drm->dev_private;
struct drm_tegra_open_channel *args = data;
struct tegra_drm_context *context;
- struct host1x_client *client;
+ struct tegra_drm_client *client;
int err = -ENODEV;
context = kzalloc(sizeof(*context), GFP_KERNEL);
if (!context)
return -ENOMEM;
- list_for_each_entry(client, &tegra->clients, list)
- if (client->class == args->client) {
+ list_for_each_entry(client, &tegra->clients, base.list)
+ if (client->base.class == args->client) {
err = client->ops->open_channel(client, context);
if (err)
break;
- context->client = client;
list_add(&context->list, &fpriv->contexts);
args->context = (uintptr_t)context;
+ context->client = client;
return 0;
}
if (!tegra_drm_file_owns_context(fpriv, context))
return -ENODEV;
- if (args->index >= context->client->num_syncpts)
+ if (args->index >= context->client->base.num_syncpts)
return -EINVAL;
- syncpt = context->client->syncpts[args->index];
+ syncpt = context->client->base.syncpts[args->index];
args->id = host1x_syncpt_id(syncpt);
return 0;
struct tegra_fbdev *fbdev;
};
-struct host1x_client;
+struct tegra_drm_client;
struct tegra_drm_context {
- struct host1x_client *client;
+ struct tegra_drm_client *client;
struct host1x_channel *channel;
struct list_head list;
};
-struct host1x_client_ops {
- int (*drm_init)(struct host1x_client *client, struct drm_device *drm);
- int (*drm_exit)(struct host1x_client *client);
- int (*open_channel)(struct host1x_client *client,
+struct tegra_drm_client_ops {
+ int (*open_channel)(struct tegra_drm_client *client,
struct tegra_drm_context *context);
void (*close_channel)(struct tegra_drm_context *context);
int (*submit)(struct tegra_drm_context *context,
struct drm_file *file);
};
-struct host1x_client {
- struct tegra_drm *tegra;
- struct device *dev;
-
- const struct host1x_client_ops *ops;
-
- enum host1x_class class;
- struct host1x_channel *channel;
-
- struct host1x_syncpt **syncpts;
- unsigned int num_syncpts;
+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)
+{
+ return container_of(client, struct tegra_drm_client, base);
+}
+
extern int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm);
extern int tegra_drm_exit(struct tegra_drm *tegra);
struct tegra_output;
struct tegra_dc {
- struct host1x_client client;
+ struct tegra_drm_client client;
struct device *dev;
spinlock_t lock;
struct drm_pending_vblank_event *event;
};
-static inline struct tegra_dc *host1x_client_to_dc(struct host1x_client *client)
+static inline struct tegra_dc *
+tegra_drm_client_to_dc(struct tegra_drm_client *client)
{
return container_of(client, struct tegra_dc, client);
}
#define GR2D_NUM_REGS 0x4d
struct gr2d {
- struct host1x_client client;
+ struct tegra_drm_client client;
struct host1x_channel *channel;
struct clk *clk;
DECLARE_BITMAP(addr_regs, GR2D_NUM_REGS);
};
-static inline struct gr2d *to_gr2d(struct host1x_client *client)
+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,
- struct drm_device *drm)
+static int gr2d_client_init(struct host1x_client *client)
{
return 0;
}
return 0;
}
-static int gr2d_open_channel(struct host1x_client *client,
+static const struct host1x_client_ops gr2d_client_ops = {
+ .init = gr2d_client_init,
+ .exit = gr2d_client_exit,
+};
+
+static int gr2d_open_channel(struct tegra_drm_client *client,
struct tegra_drm_context *context)
{
struct gr2d *gr2d = to_gr2d(client);
job->num_relocs = args->num_relocs;
job->num_waitchk = args->num_waitchks;
job->client = (u32)args->context;
- job->class = context->client->class;
+ job->class = context->client->base.class;
job->serialize = true;
while (num_cmdbufs) {
if (args->timeout && args->timeout < 10000)
job->timeout = args->timeout;
- err = host1x_job_pin(job, context->client->dev);
+ err = host1x_job_pin(job, context->client->base.dev);
if (err)
goto fail;
return err;
}
-static struct host1x_client_ops gr2d_client_ops = {
- .drm_init = gr2d_client_init,
- .drm_exit = gr2d_client_exit,
+static const struct tegra_drm_client_ops gr2d_ops = {
.open_channel = gr2d_open_channel,
.close_channel = gr2d_close_channel,
.submit = gr2d_submit,
return -ENOMEM;
}
- gr2d->client.ops = &gr2d_client_ops;
- gr2d->client.dev = dev;
- gr2d->client.class = HOST1X_CLASS_GR2D;
- gr2d->client.syncpts = syncpts;
- gr2d->client.num_syncpts = 1;
+ 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;
+ gr2d->client.ops = &gr2d_ops;
- err = host1x_register_client(tegra, &gr2d->client);
+ err = host1x_register_client(tegra, &gr2d->client.base);
if (err < 0) {
dev_err(dev, "failed to register host1x client: %d\n", err);
return err;
unsigned int i;
int err;
- err = host1x_unregister_client(tegra, &gr2d->client);
+ err = host1x_unregister_client(tegra, &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.num_syncpts; i++)
- host1x_syncpt_free(gr2d->client.syncpts[i]);
+ 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);
#include "host1x_client.h"
struct tegra_hdmi {
- struct host1x_client client;
+ struct tegra_drm_client client;
struct tegra_output output;
struct device *dev;
};
static inline struct tegra_hdmi *
-host1x_client_to_hdmi(struct host1x_client *client)
+tegra_drm_client_to_hdmi(struct tegra_drm_client *client)
{
return container_of(client, struct tegra_hdmi, client);
}
return 0;
}
-static int tegra_hdmi_drm_init(struct host1x_client *client,
- struct drm_device *drm)
+static int tegra_hdmi_init(struct host1x_client *client)
{
- struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
+ struct tegra_drm_client *drm = to_tegra_drm_client(client);
+ struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm);
int err;
hdmi->output.type = TEGRA_OUTPUT_HDMI;
hdmi->output.dev = client->dev;
hdmi->output.ops = &hdmi_ops;
- err = tegra_output_init(drm, &hdmi->output);
+ err = tegra_output_init(drm->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->primary);
+ err = tegra_hdmi_debugfs_init(hdmi, drm->drm->primary);
if (err < 0)
dev_err(client->dev, "debugfs setup failed: %d\n", err);
}
return 0;
}
-static int tegra_hdmi_drm_exit(struct host1x_client *client)
+static int tegra_hdmi_exit(struct host1x_client *client)
{
- struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
+ struct tegra_drm_client *drm = to_tegra_drm_client(client);
+ struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm);
int err;
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
}
static const struct host1x_client_ops hdmi_client_ops = {
- .drm_init = tegra_hdmi_drm_init,
- .drm_exit = tegra_hdmi_drm_exit,
+ .init = tegra_hdmi_init,
+ .exit = tegra_hdmi_exit,
};
static int tegra_hdmi_probe(struct platform_device *pdev)
hdmi->irq = err;
- hdmi->client.ops = &hdmi_client_ops;
- INIT_LIST_HEAD(&hdmi->client.list);
- hdmi->client.dev = &pdev->dev;
+ INIT_LIST_HEAD(&hdmi->client.base.list);
+ hdmi->client.base.ops = &hdmi_client_ops;
+ hdmi->client.base.dev = &pdev->dev;
- err = host1x_register_client(tegra, &hdmi->client);
+ err = host1x_register_client(tegra, &hdmi->client.base);
if (err < 0) {
dev_err(&pdev->dev, "failed to register host1x client: %d\n",
err);
struct tegra_hdmi *hdmi = platform_get_drvdata(pdev);
int err;
- err = host1x_unregister_client(tegra, &hdmi->client);
+ err = host1x_unregister_client(tegra, &hdmi->client.base);
if (err < 0) {
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
err);
HOST1X_CLASS_GR2D_SB = 0x52,
};
+struct host1x_client;
+
+struct host1x_client_ops {
+ int (*init)(struct host1x_client *client);
+ int (*exit)(struct host1x_client *client);
+};
+
+struct host1x_client {
+ struct list_head list;
+ struct device *dev;
+
+ const struct host1x_client_ops *ops;
+
+ enum host1x_class class;
+ struct host1x_channel *channel;
+
+ struct host1x_syncpt **syncpts;
+ unsigned int num_syncpts;
+};
+
#endif