0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _FSL_MC_H_
0011 #define _FSL_MC_H_
0012
0013 #include <linux/device.h>
0014 #include <linux/mod_devicetable.h>
0015 #include <linux/interrupt.h>
0016 #include <uapi/linux/fsl_mc.h>
0017
0018 #define FSL_MC_VENDOR_FREESCALE 0x1957
0019
0020 struct irq_domain;
0021 struct msi_domain_info;
0022
0023 struct fsl_mc_device;
0024 struct fsl_mc_io;
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 struct fsl_mc_driver {
0048 struct device_driver driver;
0049 const struct fsl_mc_device_id *match_id_table;
0050 int (*probe)(struct fsl_mc_device *dev);
0051 int (*remove)(struct fsl_mc_device *dev);
0052 void (*shutdown)(struct fsl_mc_device *dev);
0053 int (*suspend)(struct fsl_mc_device *dev, pm_message_t state);
0054 int (*resume)(struct fsl_mc_device *dev);
0055 bool driver_managed_dma;
0056 };
0057
0058 #define to_fsl_mc_driver(_drv) \
0059 container_of(_drv, struct fsl_mc_driver, driver)
0060
0061
0062
0063
0064
0065
0066
0067 enum fsl_mc_pool_type {
0068 FSL_MC_POOL_DPMCP = 0x0,
0069 FSL_MC_POOL_DPBP,
0070 FSL_MC_POOL_DPCON,
0071 FSL_MC_POOL_IRQ,
0072
0073
0074
0075
0076 FSL_MC_NUM_POOL_TYPES
0077 };
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 struct fsl_mc_resource {
0093 enum fsl_mc_pool_type type;
0094 s32 id;
0095 void *data;
0096 struct fsl_mc_resource_pool *parent_pool;
0097 struct list_head node;
0098 };
0099
0100
0101
0102
0103
0104
0105
0106
0107 struct fsl_mc_device_irq {
0108 unsigned int virq;
0109 struct fsl_mc_device *mc_dev;
0110 u8 dev_irq_index;
0111 struct fsl_mc_resource resource;
0112 };
0113
0114 #define to_fsl_mc_irq(_mc_resource) \
0115 container_of(_mc_resource, struct fsl_mc_device_irq, resource)
0116
0117
0118 #define FSL_MC_OBJ_STATE_OPEN 0x00000001
0119
0120 #define FSL_MC_OBJ_STATE_PLUGGED 0x00000002
0121
0122
0123
0124
0125
0126
0127
0128 #define FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY 0x0001
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 struct fsl_mc_obj_desc {
0144 char type[16];
0145 int id;
0146 u16 vendor;
0147 u16 ver_major;
0148 u16 ver_minor;
0149 u8 irq_count;
0150 u8 region_count;
0151 u32 state;
0152 char label[16];
0153 u16 flags;
0154 };
0155
0156
0157
0158
0159 #define FSL_MC_IS_DPRC 0x0001
0160
0161
0162
0163 #define FSL_MC_REGION_CACHEABLE 0x00000001
0164
0165
0166 #define FSL_MC_REGION_SHAREABLE 0x00000002
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205 struct fsl_mc_device {
0206 struct device dev;
0207 u64 dma_mask;
0208 u16 flags;
0209 u32 icid;
0210 u16 mc_handle;
0211 struct fsl_mc_io *mc_io;
0212 struct fsl_mc_obj_desc obj_desc;
0213 struct resource *regions;
0214 struct fsl_mc_device_irq **irqs;
0215 struct fsl_mc_resource *resource;
0216 struct device_link *consumer_link;
0217 const char *driver_override;
0218 };
0219
0220 #define to_fsl_mc_device(_dev) \
0221 container_of(_dev, struct fsl_mc_device, dev)
0222
0223 struct mc_cmd_header {
0224 u8 src_id;
0225 u8 flags_hw;
0226 u8 status;
0227 u8 flags_sw;
0228 __le16 token;
0229 __le16 cmd_id;
0230 };
0231
0232 enum mc_cmd_status {
0233 MC_CMD_STATUS_OK = 0x0,
0234 MC_CMD_STATUS_READY = 0x1,
0235 MC_CMD_STATUS_AUTH_ERR = 0x3,
0236 MC_CMD_STATUS_NO_PRIVILEGE = 0x4,
0237 MC_CMD_STATUS_DMA_ERR = 0x5,
0238 MC_CMD_STATUS_CONFIG_ERR = 0x6,
0239 MC_CMD_STATUS_TIMEOUT = 0x7,
0240 MC_CMD_STATUS_NO_RESOURCE = 0x8,
0241 MC_CMD_STATUS_NO_MEMORY = 0x9,
0242 MC_CMD_STATUS_BUSY = 0xA,
0243 MC_CMD_STATUS_UNSUPPORTED_OP = 0xB,
0244 MC_CMD_STATUS_INVALID_STATE = 0xC
0245 };
0246
0247
0248
0249
0250
0251
0252 #define MC_CMD_FLAG_PRI 0x80
0253
0254 #define MC_CMD_FLAG_INTR_DIS 0x01
0255
0256 static inline __le64 mc_encode_cmd_header(u16 cmd_id,
0257 u32 cmd_flags,
0258 u16 token)
0259 {
0260 __le64 header = 0;
0261 struct mc_cmd_header *hdr = (struct mc_cmd_header *)&header;
0262
0263 hdr->cmd_id = cpu_to_le16(cmd_id);
0264 hdr->token = cpu_to_le16(token);
0265 hdr->status = MC_CMD_STATUS_READY;
0266 if (cmd_flags & MC_CMD_FLAG_PRI)
0267 hdr->flags_hw = MC_CMD_FLAG_PRI;
0268 if (cmd_flags & MC_CMD_FLAG_INTR_DIS)
0269 hdr->flags_sw = MC_CMD_FLAG_INTR_DIS;
0270
0271 return header;
0272 }
0273
0274 static inline u16 mc_cmd_hdr_read_token(struct fsl_mc_command *cmd)
0275 {
0276 struct mc_cmd_header *hdr = (struct mc_cmd_header *)&cmd->header;
0277 u16 token = le16_to_cpu(hdr->token);
0278
0279 return token;
0280 }
0281
0282 struct mc_rsp_create {
0283 __le32 object_id;
0284 };
0285
0286 struct mc_rsp_api_ver {
0287 __le16 major_ver;
0288 __le16 minor_ver;
0289 };
0290
0291 static inline u32 mc_cmd_read_object_id(struct fsl_mc_command *cmd)
0292 {
0293 struct mc_rsp_create *rsp_params;
0294
0295 rsp_params = (struct mc_rsp_create *)cmd->params;
0296 return le32_to_cpu(rsp_params->object_id);
0297 }
0298
0299 static inline void mc_cmd_read_api_version(struct fsl_mc_command *cmd,
0300 u16 *major_ver,
0301 u16 *minor_ver)
0302 {
0303 struct mc_rsp_api_ver *rsp_params;
0304
0305 rsp_params = (struct mc_rsp_api_ver *)cmd->params;
0306 *major_ver = le16_to_cpu(rsp_params->major_ver);
0307 *minor_ver = le16_to_cpu(rsp_params->minor_ver);
0308 }
0309
0310
0311
0312
0313 #define FSL_MC_IO_ATOMIC_CONTEXT_PORTAL 0x0001
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338 struct fsl_mc_io {
0339 struct device *dev;
0340 u16 flags;
0341 u32 portal_size;
0342 phys_addr_t portal_phys_addr;
0343 void __iomem *portal_virt_addr;
0344 struct fsl_mc_device *dpmcp_dev;
0345 union {
0346
0347
0348
0349
0350 struct mutex mutex;
0351
0352
0353
0354
0355
0356 raw_spinlock_t spinlock;
0357 };
0358 };
0359
0360 int mc_send_command(struct fsl_mc_io *mc_io, struct fsl_mc_command *cmd);
0361
0362 #ifdef CONFIG_FSL_MC_BUS
0363 #define dev_is_fsl_mc(_dev) ((_dev)->bus == &fsl_mc_bus_type)
0364 #else
0365
0366 #define dev_is_fsl_mc(_dev) (0)
0367 #endif
0368
0369
0370 #define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \
0371 FSL_MC_IS_DPRC)
0372
0373
0374 #define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \
0375 (_dev) : (_dev)->parent)
0376
0377
0378
0379
0380
0381
0382
0383 #define module_fsl_mc_driver(__fsl_mc_driver) \
0384 module_driver(__fsl_mc_driver, fsl_mc_driver_register, \
0385 fsl_mc_driver_unregister)
0386
0387
0388
0389
0390 #define fsl_mc_driver_register(drv) \
0391 __fsl_mc_driver_register(drv, THIS_MODULE)
0392
0393 int __must_check __fsl_mc_driver_register(struct fsl_mc_driver *fsl_mc_driver,
0394 struct module *owner);
0395
0396 void fsl_mc_driver_unregister(struct fsl_mc_driver *driver);
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 struct fsl_mc_version {
0407 u32 major;
0408 u32 minor;
0409 u32 revision;
0410 };
0411
0412 struct fsl_mc_version *fsl_mc_get_version(void);
0413
0414 int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
0415 u16 mc_io_flags,
0416 struct fsl_mc_io **new_mc_io);
0417
0418 void fsl_mc_portal_free(struct fsl_mc_io *mc_io);
0419
0420 int fsl_mc_portal_reset(struct fsl_mc_io *mc_io);
0421
0422 int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev,
0423 enum fsl_mc_pool_type pool_type,
0424 struct fsl_mc_device **new_mc_adev);
0425
0426 void fsl_mc_object_free(struct fsl_mc_device *mc_adev);
0427
0428 struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
0429 struct msi_domain_info *info,
0430 struct irq_domain *parent);
0431
0432 int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev);
0433
0434 void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev);
0435
0436 struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev,
0437 u16 if_id);
0438
0439 extern struct bus_type fsl_mc_bus_type;
0440
0441 extern struct device_type fsl_mc_bus_dprc_type;
0442 extern struct device_type fsl_mc_bus_dpni_type;
0443 extern struct device_type fsl_mc_bus_dpio_type;
0444 extern struct device_type fsl_mc_bus_dpsw_type;
0445 extern struct device_type fsl_mc_bus_dpbp_type;
0446 extern struct device_type fsl_mc_bus_dpcon_type;
0447 extern struct device_type fsl_mc_bus_dpmcp_type;
0448 extern struct device_type fsl_mc_bus_dpmac_type;
0449 extern struct device_type fsl_mc_bus_dprtc_type;
0450 extern struct device_type fsl_mc_bus_dpseci_type;
0451 extern struct device_type fsl_mc_bus_dpdmux_type;
0452 extern struct device_type fsl_mc_bus_dpdcei_type;
0453 extern struct device_type fsl_mc_bus_dpaiop_type;
0454 extern struct device_type fsl_mc_bus_dpci_type;
0455 extern struct device_type fsl_mc_bus_dpdmai_type;
0456
0457 static inline bool is_fsl_mc_bus_dprc(const struct fsl_mc_device *mc_dev)
0458 {
0459 return mc_dev->dev.type == &fsl_mc_bus_dprc_type;
0460 }
0461
0462 static inline bool is_fsl_mc_bus_dpni(const struct fsl_mc_device *mc_dev)
0463 {
0464 return mc_dev->dev.type == &fsl_mc_bus_dpni_type;
0465 }
0466
0467 static inline bool is_fsl_mc_bus_dpio(const struct fsl_mc_device *mc_dev)
0468 {
0469 return mc_dev->dev.type == &fsl_mc_bus_dpio_type;
0470 }
0471
0472 static inline bool is_fsl_mc_bus_dpsw(const struct fsl_mc_device *mc_dev)
0473 {
0474 return mc_dev->dev.type == &fsl_mc_bus_dpsw_type;
0475 }
0476
0477 static inline bool is_fsl_mc_bus_dpdmux(const struct fsl_mc_device *mc_dev)
0478 {
0479 return mc_dev->dev.type == &fsl_mc_bus_dpdmux_type;
0480 }
0481
0482 static inline bool is_fsl_mc_bus_dpbp(const struct fsl_mc_device *mc_dev)
0483 {
0484 return mc_dev->dev.type == &fsl_mc_bus_dpbp_type;
0485 }
0486
0487 static inline bool is_fsl_mc_bus_dpcon(const struct fsl_mc_device *mc_dev)
0488 {
0489 return mc_dev->dev.type == &fsl_mc_bus_dpcon_type;
0490 }
0491
0492 static inline bool is_fsl_mc_bus_dpmcp(const struct fsl_mc_device *mc_dev)
0493 {
0494 return mc_dev->dev.type == &fsl_mc_bus_dpmcp_type;
0495 }
0496
0497 static inline bool is_fsl_mc_bus_dpmac(const struct fsl_mc_device *mc_dev)
0498 {
0499 return mc_dev->dev.type == &fsl_mc_bus_dpmac_type;
0500 }
0501
0502 static inline bool is_fsl_mc_bus_dprtc(const struct fsl_mc_device *mc_dev)
0503 {
0504 return mc_dev->dev.type == &fsl_mc_bus_dprtc_type;
0505 }
0506
0507 static inline bool is_fsl_mc_bus_dpseci(const struct fsl_mc_device *mc_dev)
0508 {
0509 return mc_dev->dev.type == &fsl_mc_bus_dpseci_type;
0510 }
0511
0512 static inline bool is_fsl_mc_bus_dpdcei(const struct fsl_mc_device *mc_dev)
0513 {
0514 return mc_dev->dev.type == &fsl_mc_bus_dpdcei_type;
0515 }
0516
0517 static inline bool is_fsl_mc_bus_dpaiop(const struct fsl_mc_device *mc_dev)
0518 {
0519 return mc_dev->dev.type == &fsl_mc_bus_dpaiop_type;
0520 }
0521
0522 static inline bool is_fsl_mc_bus_dpci(const struct fsl_mc_device *mc_dev)
0523 {
0524 return mc_dev->dev.type == &fsl_mc_bus_dpci_type;
0525 }
0526
0527 static inline bool is_fsl_mc_bus_dpdmai(const struct fsl_mc_device *mc_dev)
0528 {
0529 return mc_dev->dev.type == &fsl_mc_bus_dpdmai_type;
0530 }
0531
0532 #define DPRC_RESET_OPTION_NON_RECURSIVE 0x00000001
0533 int dprc_reset_container(struct fsl_mc_io *mc_io,
0534 u32 cmd_flags,
0535 u16 token,
0536 int child_container_id,
0537 u32 options);
0538
0539 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
0540 bool alloc_interrupts);
0541
0542 void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev,
0543 struct fsl_mc_obj_desc *obj_desc_array,
0544 int num_child_objects_in_mc);
0545
0546 int dprc_cleanup(struct fsl_mc_device *mc_dev);
0547
0548 int dprc_setup(struct fsl_mc_device *mc_dev);
0549
0550
0551
0552
0553
0554 #define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS 256
0555
0556 int fsl_mc_populate_irq_pool(struct fsl_mc_device *mc_bus_dev,
0557 unsigned int irq_count);
0558
0559 void fsl_mc_cleanup_irq_pool(struct fsl_mc_device *mc_bus_dev);
0560
0561
0562
0563
0564
0565
0566 int dpbp_open(struct fsl_mc_io *mc_io,
0567 u32 cmd_flags,
0568 int dpbp_id,
0569 u16 *token);
0570
0571 int dpbp_close(struct fsl_mc_io *mc_io,
0572 u32 cmd_flags,
0573 u16 token);
0574
0575 int dpbp_enable(struct fsl_mc_io *mc_io,
0576 u32 cmd_flags,
0577 u16 token);
0578
0579 int dpbp_disable(struct fsl_mc_io *mc_io,
0580 u32 cmd_flags,
0581 u16 token);
0582
0583 int dpbp_reset(struct fsl_mc_io *mc_io,
0584 u32 cmd_flags,
0585 u16 token);
0586
0587
0588
0589
0590
0591
0592
0593 struct dpbp_attr {
0594 int id;
0595 u16 bpid;
0596 };
0597
0598 int dpbp_get_attributes(struct fsl_mc_io *mc_io,
0599 u32 cmd_flags,
0600 u16 token,
0601 struct dpbp_attr *attr);
0602
0603
0604
0605
0606
0607
0608
0609
0610 #define DPCON_INVALID_DPIO_ID (int)(-1)
0611
0612 int dpcon_open(struct fsl_mc_io *mc_io,
0613 u32 cmd_flags,
0614 int dpcon_id,
0615 u16 *token);
0616
0617 int dpcon_close(struct fsl_mc_io *mc_io,
0618 u32 cmd_flags,
0619 u16 token);
0620
0621 int dpcon_enable(struct fsl_mc_io *mc_io,
0622 u32 cmd_flags,
0623 u16 token);
0624
0625 int dpcon_disable(struct fsl_mc_io *mc_io,
0626 u32 cmd_flags,
0627 u16 token);
0628
0629 int dpcon_reset(struct fsl_mc_io *mc_io,
0630 u32 cmd_flags,
0631 u16 token);
0632
0633 int fsl_mc_obj_open(struct fsl_mc_io *mc_io,
0634 u32 cmd_flags,
0635 int obj_id,
0636 char *obj_type,
0637 u16 *token);
0638
0639 int fsl_mc_obj_close(struct fsl_mc_io *mc_io,
0640 u32 cmd_flags,
0641 u16 token);
0642
0643 int fsl_mc_obj_reset(struct fsl_mc_io *mc_io,
0644 u32 cmd_flags,
0645 u16 token);
0646
0647
0648
0649
0650
0651
0652
0653 struct dpcon_attr {
0654 int id;
0655 u16 qbman_ch_id;
0656 u8 num_priorities;
0657 };
0658
0659 int dpcon_get_attributes(struct fsl_mc_io *mc_io,
0660 u32 cmd_flags,
0661 u16 token,
0662 struct dpcon_attr *attr);
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672 struct dpcon_notification_cfg {
0673 int dpio_id;
0674 u8 priority;
0675 u64 user_ctx;
0676 };
0677
0678 int dpcon_set_notification(struct fsl_mc_io *mc_io,
0679 u32 cmd_flags,
0680 u16 token,
0681 struct dpcon_notification_cfg *cfg);
0682
0683 #endif