| 1 |
|
| 2 | |
| 3 | * Copyright (c) 2012-2015, NVIDIA Corporation.
|
| 4 |
|
| 5 |
|
| 6 | #ifndef HOST1X_DEV_H
|
| 7 | #define HOST1X_DEV_H
|
| 8 |
|
| 9 | #include <linux/device.h>
|
| 10 | #include <linux/iommu.h>
|
| 11 | #include <linux/iova.h>
|
| 12 | #include <linux/irqreturn.h>
|
| 13 | #include <linux/platform_device.h>
|
| 14 | #include <linux/reset.h>
|
| 15 |
|
| 16 | #include "cdma.h"
|
| 17 | #include "channel.h"
|
| 18 | #include "context.h"
|
| 19 | #include "intr.h"
|
| 20 | #include "job.h"
|
| 21 | #include "syncpt.h"
|
| 22 |
|
| 23 | struct host1x_syncpt;
|
| 24 | struct host1x_syncpt_base;
|
| 25 | struct host1x_channel;
|
| 26 | struct host1x_cdma;
|
| 27 | struct host1x_job;
|
| 28 | struct push_buffer;
|
| 29 | struct output;
|
| 30 | struct dentry;
|
| 31 |
|
| 32 | struct host1x_channel_ops {
|
| 33 | int (*init)(struct host1x_channel *channel, struct host1x *host,
|
| 34 | unsigned int id);
|
| 35 | int (*submit)(struct host1x_job *job);
|
| 36 | };
|
| 37 |
|
| 38 | struct host1x_cdma_ops {
|
| 39 | void (*start)(struct host1x_cdma *cdma);
|
| 40 | void (*stop)(struct host1x_cdma *cdma);
|
| 41 | void (*flush)(struct host1x_cdma *cdma);
|
| 42 | int (*timeout_init)(struct host1x_cdma *cdma);
|
| 43 | void (*timeout_destroy)(struct host1x_cdma *cdma);
|
| 44 | void (*freeze)(struct host1x_cdma *cdma);
|
| 45 | void (*resume)(struct host1x_cdma *cdma, u32 getptr);
|
| 46 | void (*timeout_cpu_incr)(struct host1x_cdma *cdma, u32 getptr,
|
| 47 | u32 syncpt_incrs, u32 syncval, u32 nr_slots);
|
| 48 | };
|
| 49 |
|
| 50 | struct host1x_pushbuffer_ops {
|
| 51 | void (*init)(struct push_buffer *pb);
|
| 52 | };
|
| 53 |
|
| 54 | struct host1x_debug_ops {
|
| 55 | void (*debug_init)(struct dentry *de);
|
| 56 | void (*show_channel_cdma)(struct host1x *host,
|
| 57 | struct host1x_channel *ch,
|
| 58 | struct output *o);
|
| 59 | void (*show_channel_fifo)(struct host1x *host,
|
| 60 | struct host1x_channel *ch,
|
| 61 | struct output *o);
|
| 62 | void (*show_mlocks)(struct host1x *host, struct output *output);
|
| 63 |
|
| 64 | };
|
| 65 |
|
| 66 | struct host1x_syncpt_ops {
|
| 67 | void (*restore)(struct host1x_syncpt *syncpt);
|
| 68 | void (*restore_wait_base)(struct host1x_syncpt *syncpt);
|
| 69 | void (*load_wait_base)(struct host1x_syncpt *syncpt);
|
| 70 | u32 (*load)(struct host1x_syncpt *syncpt);
|
| 71 | int (*cpu_incr)(struct host1x_syncpt *syncpt);
|
| 72 | void (*assign_to_channel)(struct host1x_syncpt *syncpt,
|
| 73 | struct host1x_channel *channel);
|
| 74 | void (*enable_protection)(struct host1x *host);
|
| 75 | };
|
| 76 |
|
| 77 | struct host1x_intr_ops {
|
| 78 | int (*init_host_sync)(struct host1x *host, u32 cpm);
|
| 79 | void (*set_syncpt_threshold)(
|
| 80 | struct host1x *host, unsigned int id, u32 thresh);
|
| 81 | void (*enable_syncpt_intr)(struct host1x *host, unsigned int id);
|
| 82 | void (*disable_syncpt_intr)(struct host1x *host, unsigned int id);
|
| 83 | void (*disable_all_syncpt_intrs)(struct host1x *host);
|
| 84 | int (*free_syncpt_irq)(struct host1x *host);
|
| 85 | irqreturn_t (*isr)(int irq, void *dev_id);
|
| 86 | };
|
| 87 |
|
| 88 | struct host1x_sid_entry {
|
| 89 | unsigned int base;
|
| 90 | unsigned int offset;
|
| 91 | unsigned int limit;
|
| 92 | };
|
| 93 |
|
| 94 | struct host1x_table_desc {
|
| 95 | unsigned int base;
|
| 96 | unsigned int count;
|
| 97 | };
|
| 98 |
|
| 99 | struct host1x_info {
|
| 100 | unsigned int nb_channels;
|
| 101 | unsigned int nb_pts;
|
| 102 | unsigned int nb_bases;
|
| 103 | unsigned int nb_mlocks;
|
| 104 | int (*init)(struct host1x *host1x);
|
| 105 | unsigned int sync_offset;
|
| 106 | u64 dma_mask;
|
| 107 | bool has_wide_gather;
|
| 108 | bool has_hypervisor;
|
| 109 | bool has_common;
|
| 110 | unsigned int num_sid_entries;
|
| 111 | const struct host1x_sid_entry *sid_table;
|
| 112 | struct host1x_table_desc streamid_vm_table;
|
| 113 | struct host1x_table_desc classid_vm_table;
|
| 114 | struct host1x_table_desc mmio_vm_table;
|
| 115 | |
| 116 | * On T20-T148, the boot chain may setup DC to increment syncpoints
|
| 117 | * 26/27 on VBLANK. As such we cannot use these syncpoints until
|
| 118 | * the display driver disables VBLANK increments.
|
| 119 |
|
| 120 | bool reserve_vblank_syncpts;
|
| 121 | |
| 122 | * On Tegra186, secure world applications may require access to
|
| 123 | * host1x during suspend/resume. To allow this, we need to leave
|
| 124 | * host1x not in reset.
|
| 125 |
|
| 126 | bool skip_reset_assert;
|
| 127 | };
|
| 128 |
|
| 129 | struct host1x {
|
| 130 | const struct host1x_info *info;
|
| 131 |
|
| 132 | void __iomem *regs;
|
| 133 | void __iomem *hv_regs;
|
| 134 | void __iomem *common_regs;
|
| 135 | int syncpt_irqs[8];
|
| 136 | int num_syncpt_irqs;
|
| 137 | struct host1x_syncpt *syncpt;
|
| 138 | struct host1x_syncpt_base *bases;
|
| 139 | struct device *dev;
|
| 140 | struct clk *clk;
|
| 141 | struct reset_control_bulk_data resets[2];
|
| 142 | unsigned int nresets;
|
| 143 |
|
| 144 | struct iommu_group *group;
|
| 145 | struct iommu_domain *domain;
|
| 146 | struct iova_domain iova;
|
| 147 | dma_addr_t iova_end;
|
| 148 |
|
| 149 | struct mutex intr_mutex;
|
| 150 |
|
| 151 | const struct host1x_syncpt_ops *syncpt_op;
|
| 152 | const struct host1x_intr_ops *intr_op;
|
| 153 | const struct host1x_channel_ops *channel_op;
|
| 154 | const struct host1x_cdma_ops *cdma_op;
|
| 155 | const struct host1x_pushbuffer_ops *cdma_pb_op;
|
| 156 | const struct host1x_debug_ops *debug_op;
|
| 157 |
|
| 158 | struct host1x_syncpt *nop_sp;
|
| 159 |
|
| 160 | struct mutex syncpt_mutex;
|
| 161 |
|
| 162 | struct host1x_channel_list channel_list;
|
| 163 | struct host1x_memory_context_list context_list;
|
| 164 |
|
| 165 | struct dentry *debugfs;
|
| 166 |
|
| 167 | struct mutex devices_lock;
|
| 168 | struct list_head devices;
|
| 169 |
|
| 170 | struct list_head list;
|
| 171 |
|
| 172 | struct device_dma_parameters dma_parms;
|
| 173 |
|
| 174 | struct host1x_bo_cache cache;
|
| 175 | };
|
| 176 |
|
| 177 | void host1x_common_writel(struct host1x *host1x, u32 v, u32 r);
|
| 178 | void host1x_hypervisor_writel(struct host1x *host1x, u32 v, u32 r);
|
| 179 | u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r);
|
| 180 | void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r);
|
| 181 | u32 host1x_sync_readl(struct host1x *host1x, u32 r);
|
| 182 | #ifdef CONFIG_64BIT
|
| 183 | u64 host1x_sync_readq(struct host1x *host1x, u32 r);
|
| 184 | #endif
|
| 185 | void host1x_ch_writel(struct host1x_channel *ch, u32 v, u32 r);
|
| 186 | u32 host1x_ch_readl(struct host1x_channel *ch, u32 r);
|
| 187 |
|
| 188 | static inline void host1x_hw_syncpt_restore(struct host1x *host,
|
| 189 | struct host1x_syncpt *sp)
|
| 190 | {
|
| 191 | host->syncpt_op->restore(sp);
|
| 192 | }
|
| 193 |
|
| 194 | static inline void host1x_hw_syncpt_restore_wait_base(struct host1x *host,
|
| 195 | struct host1x_syncpt *sp)
|
| 196 | {
|
| 197 | host->syncpt_op->restore_wait_base(sp);
|
| 198 | }
|
| 199 |
|
| 200 | static inline void host1x_hw_syncpt_load_wait_base(struct host1x *host,
|
| 201 | struct host1x_syncpt *sp)
|
| 202 | {
|
| 203 | host->syncpt_op->load_wait_base(sp);
|
| 204 | }
|
| 205 |
|
| 206 | static inline u32 host1x_hw_syncpt_load(struct host1x *host,
|
| 207 | struct host1x_syncpt *sp)
|
| 208 | {
|
| 209 | return host->syncpt_op->load(sp);
|
| 210 | }
|
| 211 |
|
| 212 | static inline int host1x_hw_syncpt_cpu_incr(struct host1x *host,
|
| 213 | struct host1x_syncpt *sp)
|
| 214 | {
|
| 215 | return host->syncpt_op->cpu_incr(sp);
|
| 216 | }
|
| 217 |
|
| 218 | static inline void host1x_hw_syncpt_assign_to_channel(
|
| 219 | struct host1x *host, struct host1x_syncpt *sp,
|
| 220 | struct host1x_channel *ch)
|
| 221 | {
|
| 222 | return host->syncpt_op->assign_to_channel(sp, ch);
|
| 223 | }
|
| 224 |
|
| 225 | static inline void host1x_hw_syncpt_enable_protection(struct host1x *host)
|
| 226 | {
|
| 227 | return host->syncpt_op->enable_protection(host);
|
| 228 | }
|
| 229 |
|
| 230 | static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm)
|
| 231 | {
|
| 232 | return host->intr_op->init_host_sync(host, cpm);
|
| 233 | }
|
| 234 |
|
| 235 | static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
|
| 236 | unsigned int id,
|
| 237 | u32 thresh)
|
| 238 | {
|
| 239 | host->intr_op->set_syncpt_threshold(host, id, thresh);
|
| 240 | }
|
| 241 |
|
| 242 | static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
|
| 243 | unsigned int id)
|
| 244 | {
|
| 245 | host->intr_op->enable_syncpt_intr(host, id);
|
| 246 | }
|
| 247 |
|
| 248 | static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
|
| 249 | unsigned int id)
|
| 250 | {
|
| 251 | host->intr_op->disable_syncpt_intr(host, id);
|
| 252 | }
|
| 253 |
|
| 254 | static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
|
| 255 | {
|
| 256 | host->intr_op->disable_all_syncpt_intrs(host);
|
| 257 | }
|
| 258 |
|
| 259 | static inline int host1x_hw_intr_free_syncpt_irq(struct host1x *host)
|
| 260 | {
|
| 261 | return host->intr_op->free_syncpt_irq(host);
|
| 262 | }
|
| 263 |
|
| 264 | static inline int host1x_hw_channel_init(struct host1x *host,
|
| 265 | struct host1x_channel *channel,
|
| 266 | unsigned int id)
|
| 267 | {
|
| 268 | return host->channel_op->init(channel, host, id);
|
| 269 | }
|
| 270 |
|
| 271 | static inline int host1x_hw_channel_submit(struct host1x *host,
|
| 272 | struct host1x_job *job)
|
| 273 | {
|
| 274 | return host->channel_op->submit(job);
|
| 275 | }
|
| 276 |
|
| 277 | static inline void host1x_hw_cdma_start(struct host1x *host,
|
| 278 | struct host1x_cdma *cdma)
|
| 279 | {
|
| 280 | host->cdma_op->start(cdma);
|
| 281 | }
|
| 282 |
|
| 283 | static inline void host1x_hw_cdma_stop(struct host1x *host,
|
| 284 | struct host1x_cdma *cdma)
|
| 285 | {
|
| 286 | host->cdma_op->stop(cdma);
|
| 287 | }
|
| 288 |
|
| 289 | static inline void host1x_hw_cdma_flush(struct host1x *host,
|
| 290 | struct host1x_cdma *cdma)
|
| 291 | {
|
| 292 | host->cdma_op->flush(cdma);
|
| 293 | }
|
| 294 |
|
| 295 | static inline int host1x_hw_cdma_timeout_init(struct host1x *host,
|
| 296 | struct host1x_cdma *cdma)
|
| 297 | {
|
| 298 | return host->cdma_op->timeout_init(cdma);
|
| 299 | }
|
| 300 |
|
| 301 | static inline void host1x_hw_cdma_timeout_destroy(struct host1x *host,
|
| 302 | struct host1x_cdma *cdma)
|
| 303 | {
|
| 304 | host->cdma_op->timeout_destroy(cdma);
|
| 305 | }
|
| 306 |
|
| 307 | static inline void host1x_hw_cdma_freeze(struct host1x *host,
|
| 308 | struct host1x_cdma *cdma)
|
| 309 | {
|
| 310 | host->cdma_op->freeze(cdma);
|
| 311 | }
|
| 312 |
|
| 313 | static inline void host1x_hw_cdma_resume(struct host1x *host,
|
| 314 | struct host1x_cdma *cdma, u32 getptr)
|
| 315 | {
|
| 316 | host->cdma_op->resume(cdma, getptr);
|
| 317 | }
|
| 318 |
|
| 319 | static inline void host1x_hw_cdma_timeout_cpu_incr(struct host1x *host,
|
| 320 | struct host1x_cdma *cdma,
|
| 321 | u32 getptr,
|
| 322 | u32 syncpt_incrs,
|
| 323 | u32 syncval, u32 nr_slots)
|
| 324 | {
|
| 325 | host->cdma_op->timeout_cpu_incr(cdma, getptr, syncpt_incrs, syncval,
|
| 326 | nr_slots);
|
| 327 | }
|
| 328 |
|
| 329 | static inline void host1x_hw_pushbuffer_init(struct host1x *host,
|
| 330 | struct push_buffer *pb)
|
| 331 | {
|
| 332 | host->cdma_pb_op->init(pb);
|
| 333 | }
|
| 334 |
|
| 335 | static inline void host1x_hw_debug_init(struct host1x *host, struct dentry *de)
|
| 336 | {
|
| 337 | if (host->debug_op && host->debug_op->debug_init)
|
| 338 | host->debug_op->debug_init(de);
|
| 339 | }
|
| 340 |
|
| 341 | static inline void host1x_hw_show_channel_cdma(struct host1x *host,
|
| 342 | struct host1x_channel *channel,
|
| 343 | struct output *o)
|
| 344 | {
|
| 345 | host->debug_op->show_channel_cdma(host, channel, o);
|
| 346 | }
|
| 347 |
|
| 348 | static inline void host1x_hw_show_channel_fifo(struct host1x *host,
|
| 349 | struct host1x_channel *channel,
|
| 350 | struct output *o)
|
| 351 | {
|
| 352 | host->debug_op->show_channel_fifo(host, channel, o);
|
| 353 | }
|
| 354 |
|
| 355 | static inline void host1x_hw_show_mlocks(struct host1x *host, struct output *o)
|
| 356 | {
|
| 357 | host->debug_op->show_mlocks(host, o);
|
| 358 | }
|
| 359 |
|
| 360 | extern struct platform_driver tegra_mipi_driver;
|
| 361 |
|
| 362 | #endif
|