sde_hw_ds.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include "sde_hw_ds.h"
  6. #include "sde_formats.h"
  7. #include "sde_dbg.h"
  8. #include "sde_kms.h"
  9. /* Destination scaler TOP registers */
  10. #define DEST_SCALER_OP_MODE 0x00
  11. #define DEST_SCALER_HW_VERSION 0x10
  12. static void sde_hw_ds_setup_opmode(struct sde_hw_ds *hw_ds,
  13. u32 op_mode)
  14. {
  15. struct sde_hw_blk_reg_map *hw = &hw_ds->hw;
  16. SDE_REG_WRITE(hw, DEST_SCALER_OP_MODE, op_mode);
  17. }
  18. static void sde_hw_ds_setup_scaler3(struct sde_hw_ds *hw_ds,
  19. void *scaler_cfg, void *scaler_lut_cfg)
  20. {
  21. struct sde_hw_scaler3_cfg *scl3_cfg = scaler_cfg;
  22. struct sde_hw_scaler3_lut_cfg *scl3_lut_cfg = scaler_lut_cfg;
  23. if (!hw_ds || !hw_ds->scl || !scl3_cfg || !scl3_lut_cfg)
  24. return;
  25. /*
  26. * copy LUT values to scaler structure
  27. */
  28. if (scl3_lut_cfg->is_configured) {
  29. scl3_cfg->dir_lut = scl3_lut_cfg->dir_lut;
  30. scl3_cfg->dir_len = scl3_lut_cfg->dir_len;
  31. scl3_cfg->cir_lut = scl3_lut_cfg->cir_lut;
  32. scl3_cfg->cir_len = scl3_lut_cfg->cir_len;
  33. scl3_cfg->sep_lut = scl3_lut_cfg->sep_lut;
  34. scl3_cfg->sep_len = scl3_lut_cfg->sep_len;
  35. }
  36. sde_hw_setup_scaler3(&hw_ds->hw, scl3_cfg, hw_ds->scl->version,
  37. hw_ds->scl->base,
  38. sde_get_sde_format(DRM_FORMAT_XBGR2101010));
  39. }
  40. static void _setup_ds_ops(struct sde_hw_ds_ops *ops, unsigned long features)
  41. {
  42. ops->setup_opmode = sde_hw_ds_setup_opmode;
  43. if (test_bit(SDE_SSPP_SCALER_QSEED3, &features) ||
  44. test_bit(SDE_SSPP_SCALER_QSEED3LITE, &features))
  45. ops->setup_scaler = sde_hw_ds_setup_scaler3;
  46. }
  47. static struct sde_ds_cfg *_ds_offset(enum sde_ds ds,
  48. struct sde_mdss_cfg *m,
  49. void __iomem *addr,
  50. struct sde_hw_blk_reg_map *b)
  51. {
  52. int i;
  53. if (!m || !addr || !b)
  54. return ERR_PTR(-EINVAL);
  55. for (i = 0; i < m->ds_count; i++) {
  56. if ((ds == m->ds[i].id) &&
  57. (m->ds[i].top)) {
  58. b->base_off = addr;
  59. b->blk_off = m->ds[i].top->base;
  60. b->length = m->ds[i].top->len;
  61. b->hwversion = m->hwversion;
  62. b->log_mask = SDE_DBG_MASK_DS;
  63. return &m->ds[i];
  64. }
  65. }
  66. return ERR_PTR(-EINVAL);
  67. }
  68. static struct sde_hw_blk_ops sde_hw_ops = {
  69. .start = NULL,
  70. .stop = NULL,
  71. };
  72. struct sde_hw_ds *sde_hw_ds_init(enum sde_ds idx,
  73. void __iomem *addr,
  74. struct sde_mdss_cfg *m)
  75. {
  76. struct sde_hw_ds *hw_ds;
  77. struct sde_ds_cfg *cfg;
  78. int rc;
  79. if (!addr || !m)
  80. return ERR_PTR(-EINVAL);
  81. hw_ds = kzalloc(sizeof(*hw_ds), GFP_KERNEL);
  82. if (!hw_ds)
  83. return ERR_PTR(-ENOMEM);
  84. cfg = _ds_offset(idx, m, addr, &hw_ds->hw);
  85. if (IS_ERR_OR_NULL(cfg)) {
  86. SDE_ERROR("failed to get ds cfg\n");
  87. kfree(hw_ds);
  88. return ERR_PTR(-EINVAL);
  89. }
  90. /* Assign ops */
  91. hw_ds->idx = idx;
  92. hw_ds->scl = cfg;
  93. _setup_ds_ops(&hw_ds->ops, hw_ds->scl->features);
  94. if (m->qseed_hw_version)
  95. hw_ds->scl->version = m->qseed_hw_version;
  96. rc = sde_hw_blk_init(&hw_ds->base, SDE_HW_BLK_DS, idx, &sde_hw_ops);
  97. if (rc) {
  98. SDE_ERROR("failed to init hw blk %d\n", rc);
  99. goto blk_init_error;
  100. }
  101. if (cfg->len) {
  102. sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name,
  103. hw_ds->hw.blk_off + cfg->base,
  104. hw_ds->hw.blk_off + cfg->base + cfg->len,
  105. hw_ds->hw.xin_id);
  106. }
  107. return hw_ds;
  108. blk_init_error:
  109. kfree(hw_ds);
  110. return ERR_PTR(rc);
  111. }
  112. void sde_hw_ds_destroy(struct sde_hw_ds *hw_ds)
  113. {
  114. if (hw_ds)
  115. sde_hw_blk_destroy(&hw_ds->base);
  116. kfree(hw_ds);
  117. }