pvr_cccb.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
  2. /* Copyright (c) 2023 Imagination Technologies Ltd. */
  3. #ifndef PVR_CCCB_H
  4. #define PVR_CCCB_H
  5. #include "pvr_rogue_fwif.h"
  6. #include "pvr_rogue_fwif_shared.h"
  7. #include <linux/mutex.h>
  8. #include <linux/types.h>
  9. #define PADDING_COMMAND_SIZE sizeof(struct rogue_fwif_ccb_cmd_header)
  10. /* Forward declaration from pvr_device.h. */
  11. struct pvr_device;
  12. /* Forward declaration from pvr_gem.h. */
  13. struct pvr_fw_object;
  14. /* Forward declaration from pvr_hwrt.h. */
  15. struct pvr_hwrt_data;
  16. struct pvr_cccb {
  17. /** @ctrl_obj: FW object representing CCCB control structure. */
  18. struct pvr_fw_object *ctrl_obj;
  19. /** @ccb_obj: FW object representing CCCB. */
  20. struct pvr_fw_object *cccb_obj;
  21. /**
  22. * @ctrl: Kernel mapping of CCCB control structure. @lock must be held
  23. * when accessing.
  24. */
  25. struct rogue_fwif_cccb_ctl *ctrl;
  26. /** @cccb: Kernel mapping of CCCB. @lock must be held when accessing.*/
  27. u8 *cccb;
  28. /** @ctrl_fw_addr: FW virtual address of CCCB control structure. */
  29. u32 ctrl_fw_addr;
  30. /** @ccb_fw_addr: FW virtual address of CCCB. */
  31. u32 cccb_fw_addr;
  32. /** @size: Size of CCCB in bytes. */
  33. size_t size;
  34. /** @write_offset: CCCB write offset. */
  35. u32 write_offset;
  36. /** @wrap_mask: CCCB wrap mask. */
  37. u32 wrap_mask;
  38. };
  39. int pvr_cccb_init(struct pvr_device *pvr_dev, struct pvr_cccb *cccb,
  40. u32 size_log2, const char *name);
  41. void pvr_cccb_fini(struct pvr_cccb *cccb);
  42. void pvr_cccb_write_command_with_header(struct pvr_cccb *pvr_cccb,
  43. u32 cmd_type, u32 cmd_size, void *cmd_data,
  44. u32 ext_job_ref, u32 int_job_ref);
  45. void pvr_cccb_send_kccb_kick(struct pvr_device *pvr_dev,
  46. struct pvr_cccb *pvr_cccb, u32 cctx_fw_addr,
  47. struct pvr_hwrt_data *hwrt);
  48. void pvr_cccb_send_kccb_combined_kick(struct pvr_device *pvr_dev,
  49. struct pvr_cccb *geom_cccb,
  50. struct pvr_cccb *frag_cccb,
  51. u32 geom_ctx_fw_addr,
  52. u32 frag_ctx_fw_addr,
  53. struct pvr_hwrt_data *hwrt,
  54. bool frag_is_pr);
  55. bool pvr_cccb_cmdseq_fits(struct pvr_cccb *pvr_cccb, size_t size);
  56. /**
  57. * pvr_cccb_get_size_of_cmd_with_hdr() - Get the size of a command and its header.
  58. * @cmd_size: Command size.
  59. *
  60. * Returns the size of the command and its header.
  61. */
  62. static __always_inline u32
  63. pvr_cccb_get_size_of_cmd_with_hdr(u32 cmd_size)
  64. {
  65. WARN_ON(!IS_ALIGNED(cmd_size, 8));
  66. return sizeof(struct rogue_fwif_ccb_cmd_header) + ALIGN(cmd_size, 8);
  67. }
  68. /**
  69. * pvr_cccb_cmdseq_can_fit() - Check if a command sequence can fit in the CCCB.
  70. * @pvr_cccb: Target Client CCB.
  71. * @size: Command sequence size.
  72. *
  73. * Returns:
  74. * * true it the CCCB is big enough to contain a command sequence, or
  75. * * false otherwise.
  76. */
  77. static __always_inline bool
  78. pvr_cccb_cmdseq_can_fit(struct pvr_cccb *pvr_cccb, size_t size)
  79. {
  80. /* We divide the capacity by two to simplify our CCCB fencing logic:
  81. * we want to be sure that, no matter what we had queued before, we
  82. * are able to either queue our command sequence at the end or add a
  83. * padding command and queue the command sequence at the beginning
  84. * of the CCCB. If the command sequence size is bigger than half the
  85. * CCCB capacity, we'd have to queue the padding command and make sure
  86. * the FW is done processing it before queueing our command sequence.
  87. */
  88. return size + PADDING_COMMAND_SIZE <= pvr_cccb->size / 2;
  89. }
  90. #endif /* PVR_CCCB_H */