lut.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright 2018 Red Hat Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #include "lut.h"
  23. #include "disp.h"
  24. #include <drm/drm_color_mgmt.h>
  25. #include <drm/drm_mode.h>
  26. #include <drm/drm_property.h>
  27. #include <nvif/class.h>
  28. u32
  29. nv50_lut_load(struct nv50_lut *lut, bool legacy, int buffer,
  30. struct drm_property_blob *blob)
  31. {
  32. struct drm_color_lut *in = (struct drm_color_lut *)blob->data;
  33. void __iomem *mem = lut->mem[buffer].object.map.ptr;
  34. const int size = blob->length / sizeof(*in);
  35. int bits, shift, i;
  36. u16 zero, r, g, b;
  37. u32 addr = lut->mem[buffer].addr;
  38. /* This can't happen.. But it shuts the compiler up. */
  39. if (WARN_ON(size != 256))
  40. return 0;
  41. if (legacy) {
  42. bits = 11;
  43. shift = 3;
  44. zero = 0x0000;
  45. } else {
  46. bits = 14;
  47. shift = 0;
  48. zero = 0x6000;
  49. }
  50. for (i = 0; i < size; i++) {
  51. r = (drm_color_lut_extract(in[i]. red, bits) + zero) << shift;
  52. g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift;
  53. b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift;
  54. writew(r, mem + (i * 0x08) + 0);
  55. writew(g, mem + (i * 0x08) + 2);
  56. writew(b, mem + (i * 0x08) + 4);
  57. }
  58. /* INTERPOLATE modes require a "next" entry to interpolate with,
  59. * so we replicate the last entry to deal with this for now.
  60. */
  61. writew(r, mem + (i * 0x08) + 0);
  62. writew(g, mem + (i * 0x08) + 2);
  63. writew(b, mem + (i * 0x08) + 4);
  64. return addr;
  65. }
  66. void
  67. nv50_lut_fini(struct nv50_lut *lut)
  68. {
  69. int i;
  70. for (i = 0; i < ARRAY_SIZE(lut->mem); i++)
  71. nvif_mem_fini(&lut->mem[i]);
  72. }
  73. int
  74. nv50_lut_init(struct nv50_disp *disp, struct nvif_mmu *mmu,
  75. struct nv50_lut *lut)
  76. {
  77. const u32 size = disp->disp->object.oclass < GF110_DISP ? 257 : 1025;
  78. int i;
  79. for (i = 0; i < ARRAY_SIZE(lut->mem); i++) {
  80. int ret = nvif_mem_init_map(mmu, NVIF_MEM_VRAM, size * 8,
  81. &lut->mem[i]);
  82. if (ret)
  83. return ret;
  84. }
  85. return 0;
  86. }