aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/host1x
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2013-09-26 10:09:43 -0400
committerThierry Reding <treding@nvidia.com>2013-10-31 04:20:09 -0400
commitc1bef81fe75bb0d6df9ee21f70eb39c0d854a8cc (patch)
tree8a104988b608fffd2d7332b6b77c9e302439d0e1 /drivers/gpu/host1x
parentd77563ff5615f730457ce2bc333053bbaca909b4 (diff)
drm/tegra: gr2d: Miscellaneous cleanups
Rework the address table code for the host1x firewall. The previous implementation allocated a bitfield but didn't check for a valid pointer so it could potentially crash. Instead, embed a static bitmap within the gr2d structure to avoid the allocation and use the Linux bitmap API to reduce code complexity. Don't annotate the driver's .remove() function __exit. Even if built in the driver can be unloaded via sysfs, so .remove() needs to stick around after initialization. Also remove the explicit initialization of the driver's .owner field to THIS_MODULE because that's now handled by the driver core. Furthermore make an error message more consistent with other subdrivers, index the syncpts array for better readability, remove a gratuituous newline and reorder some variable declarations to make the code easier to read. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/host1x')
-rw-r--r--drivers/gpu/host1x/drm/gr2d.c100
1 files changed, 49 insertions, 51 deletions
diff --git a/drivers/gpu/host1x/drm/gr2d.c b/drivers/gpu/host1x/drm/gr2d.c
index 8d9a10f52d81..e91b184ced30 100644
--- a/drivers/gpu/host1x/drm/gr2d.c
+++ b/drivers/gpu/host1x/drm/gr2d.c
@@ -25,11 +25,14 @@
25#include "host1x_client.h" 25#include "host1x_client.h"
26#include "syncpt.h" 26#include "syncpt.h"
27 27
28#define GR2D_NUM_REGS 0x4d
29
28struct gr2d { 30struct gr2d {
29 struct host1x_client client; 31 struct host1x_client client;
30 struct clk *clk;
31 struct host1x_channel *channel; 32 struct host1x_channel *channel;
32 unsigned long *addr_regs; 33 struct clk *clk;
34
35 DECLARE_BITMAP(addr_regs, GR2D_NUM_REGS);
33}; 36};
34 37
35static inline struct gr2d *to_gr2d(struct host1x_client *client) 38static inline struct gr2d *to_gr2d(struct host1x_client *client)
@@ -37,8 +40,6 @@ static inline struct gr2d *to_gr2d(struct host1x_client *client)
37 return container_of(client, struct gr2d, client); 40 return container_of(client, struct gr2d, client);
38} 41}
39 42
40static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 reg);
41
42static int gr2d_client_init(struct host1x_client *client, 43static int gr2d_client_init(struct host1x_client *client,
43 struct drm_device *drm) 44 struct drm_device *drm)
44{ 45{
@@ -56,7 +57,6 @@ static int gr2d_open_channel(struct host1x_client *client,
56 struct gr2d *gr2d = to_gr2d(client); 57 struct gr2d *gr2d = to_gr2d(client);
57 58
58 context->channel = host1x_channel_get(gr2d->channel); 59 context->channel = host1x_channel_get(gr2d->channel);
59
60 if (!context->channel) 60 if (!context->channel)
61 return -ENOMEM; 61 return -ENOMEM;
62 62
@@ -87,11 +87,35 @@ static struct host1x_bo *host1x_bo_lookup(struct drm_device *drm,
87 return &bo->base; 87 return &bo->base;
88} 88}
89 89
90static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset)
91{
92 struct gr2d *gr2d = dev_get_drvdata(dev);
93
94 switch (class) {
95 case HOST1X_CLASS_HOST1X:
96 if (offset == 0x2b)
97 return 1;
98
99 break;
100
101 case HOST1X_CLASS_GR2D:
102 case HOST1X_CLASS_GR2D_SB:
103 if (offset >= GR2D_NUM_REGS)
104 break;
105
106 if (test_bit(offset, gr2d->addr_regs))
107 return 1;
108
109 break;
110 }
111
112 return 0;
113}
114
90static int gr2d_submit(struct tegra_drm_context *context, 115static int gr2d_submit(struct tegra_drm_context *context,
91 struct drm_tegra_submit *args, struct drm_device *drm, 116 struct drm_tegra_submit *args, struct drm_device *drm,
92 struct drm_file *file) 117 struct drm_file *file)
93{ 118{
94 struct host1x_job *job;
95 unsigned int num_cmdbufs = args->num_cmdbufs; 119 unsigned int num_cmdbufs = args->num_cmdbufs;
96 unsigned int num_relocs = args->num_relocs; 120 unsigned int num_relocs = args->num_relocs;
97 unsigned int num_waitchks = args->num_waitchks; 121 unsigned int num_waitchks = args->num_waitchks;
@@ -102,6 +126,7 @@ static int gr2d_submit(struct tegra_drm_context *context,
102 struct drm_tegra_waitchk __user *waitchks = 126 struct drm_tegra_waitchk __user *waitchks =
103 (void * __user)(uintptr_t)args->waitchks; 127 (void * __user)(uintptr_t)args->waitchks;
104 struct drm_tegra_syncpt syncpt; 128 struct drm_tegra_syncpt syncpt;
129 struct host1x_job *job;
105 int err; 130 int err;
106 131
107 /* We don't yet support other than one syncpt_incr struct per submit */ 132 /* We don't yet support other than one syncpt_incr struct per submit */
@@ -205,54 +230,25 @@ static struct host1x_client_ops gr2d_client_ops = {
205 .submit = gr2d_submit, 230 .submit = gr2d_submit,
206}; 231};
207 232
208static void gr2d_init_addr_reg_map(struct device *dev, struct gr2d *gr2d)
209{
210 const u32 gr2d_addr_regs[] = {0x1a, 0x1b, 0x26, 0x2b, 0x2c, 0x2d, 0x31,
211 0x32, 0x48, 0x49, 0x4a, 0x4b, 0x4c};
212 unsigned long *bitmap;
213 int i;
214
215 bitmap = devm_kzalloc(dev, DIV_ROUND_UP(256, BITS_PER_BYTE),
216 GFP_KERNEL);
217
218 for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); ++i) {
219 u32 reg = gr2d_addr_regs[i];
220 bitmap[BIT_WORD(reg)] |= BIT_MASK(reg);
221 }
222
223 gr2d->addr_regs = bitmap;
224}
225
226static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 reg)
227{
228 struct gr2d *gr2d = dev_get_drvdata(dev);
229
230 switch (class) {
231 case HOST1X_CLASS_HOST1X:
232 return reg == 0x2b;
233 case HOST1X_CLASS_GR2D:
234 case HOST1X_CLASS_GR2D_SB:
235 reg &= 0xff;
236 if (gr2d->addr_regs[BIT_WORD(reg)] & BIT_MASK(reg))
237 return 1;
238 default:
239 return 0;
240 }
241}
242
243static const struct of_device_id gr2d_match[] = { 233static const struct of_device_id gr2d_match[] = {
244 { .compatible = "nvidia,tegra30-gr2d" }, 234 { .compatible = "nvidia,tegra30-gr2d" },
245 { .compatible = "nvidia,tegra20-gr2d" }, 235 { .compatible = "nvidia,tegra20-gr2d" },
246 { }, 236 { },
247}; 237};
248 238
239static const u32 gr2d_addr_regs[] = {
240 0x1a, 0x1b, 0x26, 0x2b, 0x2c, 0x2d, 0x31, 0x32,
241 0x48, 0x49, 0x4a, 0x4b, 0x4c
242};
243
249static int gr2d_probe(struct platform_device *pdev) 244static int gr2d_probe(struct platform_device *pdev)
250{ 245{
246 struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent);
251 struct device *dev = &pdev->dev; 247 struct device *dev = &pdev->dev;
252 struct tegra_drm *tegra = host1x_get_drm_data(dev->parent);
253 int err;
254 struct gr2d *gr2d = NULL;
255 struct host1x_syncpt **syncpts; 248 struct host1x_syncpt **syncpts;
249 struct gr2d *gr2d;
250 unsigned int i;
251 int err;
256 252
257 gr2d = devm_kzalloc(dev, sizeof(*gr2d), GFP_KERNEL); 253 gr2d = devm_kzalloc(dev, sizeof(*gr2d), GFP_KERNEL);
258 if (!gr2d) 254 if (!gr2d)
@@ -296,14 +292,16 @@ static int gr2d_probe(struct platform_device *pdev)
296 return err; 292 return err;
297 } 293 }
298 294
299 gr2d_init_addr_reg_map(dev, gr2d); 295 /* initialize address register map */
296 for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); i++)
297 set_bit(gr2d_addr_regs[i], gr2d->addr_regs);
300 298
301 platform_set_drvdata(pdev, gr2d); 299 platform_set_drvdata(pdev, gr2d);
302 300
303 return 0; 301 return 0;
304} 302}
305 303
306static int __exit gr2d_remove(struct platform_device *pdev) 304static int gr2d_remove(struct platform_device *pdev)
307{ 305{
308 struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent); 306 struct tegra_drm *tegra = host1x_get_drm_data(pdev->dev.parent);
309 struct gr2d *gr2d = platform_get_drvdata(pdev); 307 struct gr2d *gr2d = platform_get_drvdata(pdev);
@@ -312,7 +310,8 @@ static int __exit gr2d_remove(struct platform_device *pdev)
312 310
313 err = host1x_unregister_client(tegra, &gr2d->client); 311 err = host1x_unregister_client(tegra, &gr2d->client);
314 if (err < 0) { 312 if (err < 0) {
315 dev_err(&pdev->dev, "failed to unregister client: %d\n", err); 313 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
314 err);
316 return err; 315 return err;
317 } 316 }
318 317
@@ -326,11 +325,10 @@ static int __exit gr2d_remove(struct platform_device *pdev)
326} 325}
327 326
328struct platform_driver tegra_gr2d_driver = { 327struct platform_driver tegra_gr2d_driver = {
329 .probe = gr2d_probe,
330 .remove = __exit_p(gr2d_remove),
331 .driver = { 328 .driver = {
332 .owner = THIS_MODULE,
333 .name = "gr2d", 329 .name = "gr2d",
334 .of_match_table = gr2d_match, 330 .of_match_table = gr2d_match,
335 } 331 },
332 .probe = gr2d_probe,
333 .remove = gr2d_remove,
336}; 334};