Commit 53fa7f7204c97dc0c86b99ff8365ad6a7b2ebd78

Authored by Thierry Reding
1 parent e1e906448d

drm/tegra: Introduce tegra_drm_client structure

This structure derives from host1x_client. DRM-specific fields are moved
from host1x_client to this structure, so that host1x_client can remain
agnostic of DRM.

Signed-off-by: Thierry Reding <treding@nvidia.com>

Showing 6 changed files with 114 additions and 83 deletions Side-by-side Diff

drivers/gpu/host1x/drm/dc.c
... ... @@ -1038,30 +1038,30 @@
1038 1038 return 0;
1039 1039 }
1040 1040  
1041   -static int tegra_dc_drm_init(struct host1x_client *client,
1042   - struct drm_device *drm)
  1041 +static int tegra_dc_init(struct host1x_client *client)
1043 1042 {
1044   - struct tegra_dc *dc = host1x_client_to_dc(client);
  1043 + struct tegra_drm_client *drm = to_tegra_drm_client(client);
  1044 + struct tegra_dc *dc = tegra_drm_client_to_dc(drm);
1045 1045 int err;
1046 1046  
1047   - dc->pipe = drm->mode_config.num_crtc;
  1047 + dc->pipe = drm->drm->mode_config.num_crtc;
1048 1048  
1049   - drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs);
  1049 + drm_crtc_init(drm->drm, &dc->base, &tegra_crtc_funcs);
1050 1050 drm_mode_crtc_set_gamma_size(&dc->base, 256);
1051 1051 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
1052 1052  
1053   - err = tegra_dc_rgb_init(drm, dc);
  1053 + err = tegra_dc_rgb_init(drm->drm, dc);
1054 1054 if (err < 0 && err != -ENODEV) {
1055 1055 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
1056 1056 return err;
1057 1057 }
1058 1058  
1059   - err = tegra_dc_add_planes(drm, dc);
  1059 + err = tegra_dc_add_planes(drm->drm, dc);
1060 1060 if (err < 0)
1061 1061 return err;
1062 1062  
1063 1063 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1064   - err = tegra_dc_debugfs_init(dc, drm->primary);
  1064 + err = tegra_dc_debugfs_init(dc, drm->drm->primary);
1065 1065 if (err < 0)
1066 1066 dev_err(dc->dev, "debugfs setup failed: %d\n", err);
1067 1067 }
1068 1068  
... ... @@ -1077,9 +1077,10 @@
1077 1077 return 0;
1078 1078 }
1079 1079  
1080   -static int tegra_dc_drm_exit(struct host1x_client *client)
  1080 +static int tegra_dc_exit(struct host1x_client *client)
1081 1081 {
1082   - struct tegra_dc *dc = host1x_client_to_dc(client);
  1082 + struct tegra_drm_client *drm = to_tegra_drm_client(client);
  1083 + struct tegra_dc *dc = tegra_drm_client_to_dc(drm);
1083 1084 int err;
1084 1085  
1085 1086 devm_free_irq(dc->dev, dc->irq, dc);
... ... @@ -1100,8 +1101,8 @@
1100 1101 }
1101 1102  
1102 1103 static const struct host1x_client_ops dc_client_ops = {
1103   - .drm_init = tegra_dc_drm_init,
1104   - .drm_exit = tegra_dc_drm_exit,
  1104 + .init = tegra_dc_init,
  1105 + .exit = tegra_dc_exit,
1105 1106 };
1106 1107  
1107 1108 static int tegra_dc_probe(struct platform_device *pdev)
... ... @@ -1140,9 +1141,9 @@
1140 1141 return -ENXIO;
1141 1142 }
1142 1143  
1143   - INIT_LIST_HEAD(&dc->client.list);
1144   - dc->client.ops = &dc_client_ops;
1145   - dc->client.dev = &pdev->dev;
  1144 + INIT_LIST_HEAD(&dc->client.base.list);
  1145 + dc->client.base.ops = &dc_client_ops;
  1146 + dc->client.base.dev = &pdev->dev;
1146 1147  
1147 1148 err = tegra_dc_rgb_probe(dc);
1148 1149 if (err < 0 && err != -ENODEV) {
... ... @@ -1150,7 +1151,7 @@
1150 1151 return err;
1151 1152 }
1152 1153  
1153   - err = host1x_register_client(tegra, &dc->client);
  1154 + err = host1x_register_client(tegra, &dc->client.base);
1154 1155 if (err < 0) {
1155 1156 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1156 1157 err);
... ... @@ -1168,7 +1169,7 @@
1168 1169 struct tegra_dc *dc = platform_get_drvdata(pdev);
1169 1170 int err;
1170 1171  
1171   - err = host1x_unregister_client(tegra, &dc->client);
  1172 + err = host1x_unregister_client(tegra, &dc->client.base);
1172 1173 if (err < 0) {
1173 1174 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
1174 1175 err);
drivers/gpu/host1x/drm/drm.c
... ... @@ -131,12 +131,18 @@
131 131 int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm)
132 132 {
133 133 struct host1x_client *client;
  134 + int err;
134 135  
135 136 mutex_lock(&tegra->clients_lock);
136 137  
137 138 list_for_each_entry(client, &tegra->clients, list) {
138   - if (client->ops && client->ops->drm_init) {
139   - int err = client->ops->drm_init(client, drm);
  139 + struct tegra_drm_client *tdc = to_tegra_drm_client(client);
  140 +
  141 + /* associate client with DRM device */
  142 + tdc->drm = drm;
  143 +
  144 + if (client->ops && client->ops->init) {
  145 + err = client->ops->init(client);
140 146 if (err < 0) {
141 147 dev_err(tegra->dev,
142 148 "DRM setup failed for %s: %d\n",
143 149  
... ... @@ -154,8 +160,9 @@
154 160  
155 161 int tegra_drm_exit(struct tegra_drm *tegra)
156 162 {
157   - struct platform_device *pdev = to_platform_device(tegra->dev);
158 163 struct host1x_client *client;
  164 + struct platform_device *pdev;
  165 + int err;
159 166  
160 167 if (!tegra->drm)
161 168 return 0;
... ... @@ -163,8 +170,8 @@
163 170 mutex_lock(&tegra->clients_lock);
164 171  
165 172 list_for_each_entry_reverse(client, &tegra->clients, list) {
166   - if (client->ops && client->ops->drm_exit) {
167   - int err = client->ops->drm_exit(client);
  173 + if (client->ops && client->ops->exit) {
  174 + err = client->ops->exit(client);
168 175 if (err < 0) {
169 176 dev_err(tegra->dev,
170 177 "DRM cleanup failed for %s: %d\n",
... ... @@ -177,6 +184,7 @@
177 184  
178 185 mutex_unlock(&tegra->clients_lock);
179 186  
  187 + pdev = to_platform_device(tegra->dev);
180 188 drm_platform_exit(&tegra_drm_driver, pdev);
181 189 tegra->drm = NULL;
182 190  
183 191  
184 192  
185 193  
... ... @@ -409,22 +417,22 @@
409 417 struct tegra_drm *tegra = drm->dev_private;
410 418 struct drm_tegra_open_channel *args = data;
411 419 struct tegra_drm_context *context;
412   - struct host1x_client *client;
  420 + struct tegra_drm_client *client;
413 421 int err = -ENODEV;
414 422  
415 423 context = kzalloc(sizeof(*context), GFP_KERNEL);
416 424 if (!context)
417 425 return -ENOMEM;
418 426  
419   - list_for_each_entry(client, &tegra->clients, list)
420   - if (client->class == args->client) {
  427 + list_for_each_entry(client, &tegra->clients, base.list)
  428 + if (client->base.class == args->client) {
421 429 err = client->ops->open_channel(client, context);
422 430 if (err)
423 431 break;
424 432  
425   - context->client = client;
426 433 list_add(&context->list, &fpriv->contexts);
427 434 args->context = (uintptr_t)context;
  435 + context->client = client;
428 436 return 0;
429 437 }
430 438  
431 439  
... ... @@ -463,10 +471,10 @@
463 471 if (!tegra_drm_file_owns_context(fpriv, context))
464 472 return -ENODEV;
465 473  
466   - if (args->index >= context->client->num_syncpts)
  474 + if (args->index >= context->client->base.num_syncpts)
467 475 return -EINVAL;
468 476  
469   - syncpt = context->client->syncpts[args->index];
  477 + syncpt = context->client->base.syncpts[args->index];
470 478 args->id = host1x_syncpt_id(syncpt);
471 479  
472 480 return 0;
drivers/gpu/host1x/drm/drm.h
... ... @@ -44,18 +44,16 @@
44 44 struct tegra_fbdev *fbdev;
45 45 };
46 46  
47   -struct host1x_client;
  47 +struct tegra_drm_client;
48 48  
49 49 struct tegra_drm_context {
50   - struct host1x_client *client;
  50 + struct tegra_drm_client *client;
51 51 struct host1x_channel *channel;
52 52 struct list_head list;
53 53 };
54 54  
55   -struct host1x_client_ops {
56   - int (*drm_init)(struct host1x_client *client, struct drm_device *drm);
57   - int (*drm_exit)(struct host1x_client *client);
58   - int (*open_channel)(struct host1x_client *client,
  55 +struct tegra_drm_client_ops {
  56 + int (*open_channel)(struct tegra_drm_client *client,
59 57 struct tegra_drm_context *context);
60 58 void (*close_channel)(struct tegra_drm_context *context);
61 59 int (*submit)(struct tegra_drm_context *context,
62 60  
63 61  
... ... @@ -63,21 +61,19 @@
63 61 struct drm_file *file);
64 62 };
65 63  
66   -struct host1x_client {
67   - struct tegra_drm *tegra;
68   - struct device *dev;
  64 +struct tegra_drm_client {
  65 + struct host1x_client base;
  66 + struct drm_device *drm;
69 67  
70   - const struct host1x_client_ops *ops;
71   -
72   - enum host1x_class class;
73   - struct host1x_channel *channel;
74   -
75   - struct host1x_syncpt **syncpts;
76   - unsigned int num_syncpts;
77   -
78   - struct list_head list;
  68 + const struct tegra_drm_client_ops *ops;
79 69 };
80 70  
  71 +static inline struct tegra_drm_client *
  72 +to_tegra_drm_client(struct host1x_client *client)
  73 +{
  74 + return container_of(client, struct tegra_drm_client, base);
  75 +}
  76 +
81 77 extern int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm);
82 78 extern int tegra_drm_exit(struct tegra_drm *tegra);
83 79  
... ... @@ -89,7 +85,7 @@
89 85 struct tegra_output;
90 86  
91 87 struct tegra_dc {
92   - struct host1x_client client;
  88 + struct tegra_drm_client client;
93 89 struct device *dev;
94 90 spinlock_t lock;
95 91  
... ... @@ -112,7 +108,8 @@
112 108 struct drm_pending_vblank_event *event;
113 109 };
114 110  
115   -static inline struct tegra_dc *host1x_client_to_dc(struct host1x_client *client)
  111 +static inline struct tegra_dc *
  112 +tegra_drm_client_to_dc(struct tegra_drm_client *client)
116 113 {
117 114 return container_of(client, struct tegra_dc, client);
118 115 }
drivers/gpu/host1x/drm/gr2d.c
... ... @@ -27,20 +27,19 @@
27 27 #define GR2D_NUM_REGS 0x4d
28 28  
29 29 struct gr2d {
30   - struct host1x_client client;
  30 + struct tegra_drm_client client;
31 31 struct host1x_channel *channel;
32 32 struct clk *clk;
33 33  
34 34 DECLARE_BITMAP(addr_regs, GR2D_NUM_REGS);
35 35 };
36 36  
37   -static inline struct gr2d *to_gr2d(struct host1x_client *client)
  37 +static inline struct gr2d *to_gr2d(struct tegra_drm_client *client)
38 38 {
39 39 return container_of(client, struct gr2d, client);
40 40 }
41 41  
42   -static int gr2d_client_init(struct host1x_client *client,
43   - struct drm_device *drm)
  42 +static int gr2d_client_init(struct host1x_client *client)
44 43 {
45 44 return 0;
46 45 }
... ... @@ -50,7 +49,12 @@
50 49 return 0;
51 50 }
52 51  
53   -static int gr2d_open_channel(struct host1x_client *client,
  52 +static const struct host1x_client_ops gr2d_client_ops = {
  53 + .init = gr2d_client_init,
  54 + .exit = gr2d_client_exit,
  55 +};
  56 +
  57 +static int gr2d_open_channel(struct tegra_drm_client *client,
54 58 struct tegra_drm_context *context)
55 59 {
56 60 struct gr2d *gr2d = to_gr2d(client);
... ... @@ -140,7 +144,7 @@
140 144 job->num_relocs = args->num_relocs;
141 145 job->num_waitchk = args->num_waitchks;
142 146 job->client = (u32)args->context;
143   - job->class = context->client->class;
  147 + job->class = context->client->base.class;
144 148 job->serialize = true;
145 149  
146 150 while (num_cmdbufs) {
... ... @@ -201,7 +205,7 @@
201 205 if (args->timeout && args->timeout < 10000)
202 206 job->timeout = args->timeout;
203 207  
204   - err = host1x_job_pin(job, context->client->dev);
  208 + err = host1x_job_pin(job, context->client->base.dev);
205 209 if (err)
206 210 goto fail;
207 211  
... ... @@ -221,9 +225,7 @@
221 225 return err;
222 226 }
223 227  
224   -static struct host1x_client_ops gr2d_client_ops = {
225   - .drm_init = gr2d_client_init,
226   - .drm_exit = gr2d_client_exit,
  228 +static const struct tegra_drm_client_ops gr2d_ops = {
227 229 .open_channel = gr2d_open_channel,
228 230 .close_channel = gr2d_close_channel,
229 231 .submit = gr2d_submit,
230 232  
... ... @@ -279,13 +281,15 @@
279 281 return -ENOMEM;
280 282 }
281 283  
282   - gr2d->client.ops = &gr2d_client_ops;
283   - gr2d->client.dev = dev;
284   - gr2d->client.class = HOST1X_CLASS_GR2D;
285   - gr2d->client.syncpts = syncpts;
286   - gr2d->client.num_syncpts = 1;
  284 + INIT_LIST_HEAD(&gr2d->client.base.list);
  285 + gr2d->client.base.ops = &gr2d_client_ops;
  286 + gr2d->client.base.dev = dev;
  287 + gr2d->client.base.class = HOST1X_CLASS_GR2D;
  288 + gr2d->client.base.syncpts = syncpts;
  289 + gr2d->client.base.num_syncpts = 1;
  290 + gr2d->client.ops = &gr2d_ops;
287 291  
288   - err = host1x_register_client(tegra, &gr2d->client);
  292 + err = host1x_register_client(tegra, &gr2d->client.base);
289 293 if (err < 0) {
290 294 dev_err(dev, "failed to register host1x client: %d\n", err);
291 295 return err;
292 296  
... ... @@ -307,15 +311,15 @@
307 311 unsigned int i;
308 312 int err;
309 313  
310   - err = host1x_unregister_client(tegra, &gr2d->client);
  314 + err = host1x_unregister_client(tegra, &gr2d->client.base);
311 315 if (err < 0) {
312 316 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
313 317 err);
314 318 return err;
315 319 }
316 320  
317   - for (i = 0; i < gr2d->client.num_syncpts; i++)
318   - host1x_syncpt_free(gr2d->client.syncpts[i]);
  321 + for (i = 0; i < gr2d->client.base.num_syncpts; i++)
  322 + host1x_syncpt_free(gr2d->client.base.syncpts[i]);
319 323  
320 324 host1x_channel_free(gr2d->channel);
321 325 clk_disable_unprepare(gr2d->clk);
drivers/gpu/host1x/drm/hdmi.c
... ... @@ -19,7 +19,7 @@
19 19 #include "host1x_client.h"
20 20  
21 21 struct tegra_hdmi {
22   - struct host1x_client client;
  22 + struct tegra_drm_client client;
23 23 struct tegra_output output;
24 24 struct device *dev;
25 25  
... ... @@ -43,7 +43,7 @@
43 43 };
44 44  
45 45 static inline struct tegra_hdmi *
46   -host1x_client_to_hdmi(struct host1x_client *client)
  46 +tegra_drm_client_to_hdmi(struct tegra_drm_client *client)
47 47 {
48 48 return container_of(client, struct tegra_hdmi, client);
49 49 }
50 50  
51 51  
52 52  
... ... @@ -1116,24 +1116,24 @@
1116 1116 return 0;
1117 1117 }
1118 1118  
1119   -static int tegra_hdmi_drm_init(struct host1x_client *client,
1120   - struct drm_device *drm)
  1119 +static int tegra_hdmi_init(struct host1x_client *client)
1121 1120 {
1122   - struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
  1121 + struct tegra_drm_client *drm = to_tegra_drm_client(client);
  1122 + struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm);
1123 1123 int err;
1124 1124  
1125 1125 hdmi->output.type = TEGRA_OUTPUT_HDMI;
1126 1126 hdmi->output.dev = client->dev;
1127 1127 hdmi->output.ops = &hdmi_ops;
1128 1128  
1129   - err = tegra_output_init(drm, &hdmi->output);
  1129 + err = tegra_output_init(drm->drm, &hdmi->output);
1130 1130 if (err < 0) {
1131 1131 dev_err(client->dev, "output setup failed: %d\n", err);
1132 1132 return err;
1133 1133 }
1134 1134  
1135 1135 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1136   - err = tegra_hdmi_debugfs_init(hdmi, drm->primary);
  1136 + err = tegra_hdmi_debugfs_init(hdmi, drm->drm->primary);
1137 1137 if (err < 0)
1138 1138 dev_err(client->dev, "debugfs setup failed: %d\n", err);
1139 1139 }
1140 1140  
... ... @@ -1141,9 +1141,10 @@
1141 1141 return 0;
1142 1142 }
1143 1143  
1144   -static int tegra_hdmi_drm_exit(struct host1x_client *client)
  1144 +static int tegra_hdmi_exit(struct host1x_client *client)
1145 1145 {
1146   - struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
  1146 + struct tegra_drm_client *drm = to_tegra_drm_client(client);
  1147 + struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm);
1147 1148 int err;
1148 1149  
1149 1150 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
... ... @@ -1169,8 +1170,8 @@
1169 1170 }
1170 1171  
1171 1172 static const struct host1x_client_ops hdmi_client_ops = {
1172   - .drm_init = tegra_hdmi_drm_init,
1173   - .drm_exit = tegra_hdmi_drm_exit,
  1173 + .init = tegra_hdmi_init,
  1174 + .exit = tegra_hdmi_exit,
1174 1175 };
1175 1176  
1176 1177 static int tegra_hdmi_probe(struct platform_device *pdev)
1177 1178  
... ... @@ -1246,11 +1247,11 @@
1246 1247  
1247 1248 hdmi->irq = err;
1248 1249  
1249   - hdmi->client.ops = &hdmi_client_ops;
1250   - INIT_LIST_HEAD(&hdmi->client.list);
1251   - hdmi->client.dev = &pdev->dev;
  1250 + INIT_LIST_HEAD(&hdmi->client.base.list);
  1251 + hdmi->client.base.ops = &hdmi_client_ops;
  1252 + hdmi->client.base.dev = &pdev->dev;
1252 1253  
1253   - err = host1x_register_client(tegra, &hdmi->client);
  1254 + err = host1x_register_client(tegra, &hdmi->client.base);
1254 1255 if (err < 0) {
1255 1256 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1256 1257 err);
... ... @@ -1268,7 +1269,7 @@
1268 1269 struct tegra_hdmi *hdmi = platform_get_drvdata(pdev);
1269 1270 int err;
1270 1271  
1271   - err = host1x_unregister_client(tegra, &hdmi->client);
  1272 + err = host1x_unregister_client(tegra, &hdmi->client.base);
1272 1273 if (err < 0) {
1273 1274 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
1274 1275 err);
include/linux/host1x.h
... ... @@ -25,5 +25,25 @@
25 25 HOST1X_CLASS_GR2D_SB = 0x52,
26 26 };
27 27  
  28 +struct host1x_client;
  29 +
  30 +struct host1x_client_ops {
  31 + int (*init)(struct host1x_client *client);
  32 + int (*exit)(struct host1x_client *client);
  33 +};
  34 +
  35 +struct host1x_client {
  36 + struct list_head list;
  37 + struct device *dev;
  38 +
  39 + const struct host1x_client_ops *ops;
  40 +
  41 + enum host1x_class class;
  42 + struct host1x_channel *channel;
  43 +
  44 + struct host1x_syncpt **syncpts;
  45 + unsigned int num_syncpts;
  46 +};
  47 +
28 48 #endif