piornv50.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright 2012 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. * Authors: Ben Skeggs
  23. */
  24. #include "outpdp.h"
  25. #include "nv50.h"
  26. #include <core/client.h>
  27. #include <subdev/i2c.h>
  28. #include <subdev/timer.h>
  29. #include <nvif/cl5070.h>
  30. #include <nvif/unpack.h>
  31. int
  32. nv50_pior_power(NV50_DISP_MTHD_V1)
  33. {
  34. struct nvkm_device *device = disp->base.engine.subdev.device;
  35. const u32 soff = outp->or * 0x800;
  36. union {
  37. struct nv50_disp_pior_pwr_v0 v0;
  38. } *args = data;
  39. u32 ctrl, type;
  40. int ret = -ENOSYS;
  41. nvif_ioctl(object, "disp pior pwr size %d\n", size);
  42. if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
  43. nvif_ioctl(object, "disp pior pwr vers %d state %d type %x\n",
  44. args->v0.version, args->v0.state, args->v0.type);
  45. if (args->v0.type > 0x0f)
  46. return -EINVAL;
  47. ctrl = !!args->v0.state;
  48. type = args->v0.type;
  49. } else
  50. return ret;
  51. nvkm_msec(device, 2000,
  52. if (!(nvkm_rd32(device, 0x61e004 + soff) & 0x80000000))
  53. break;
  54. );
  55. nvkm_mask(device, 0x61e004 + soff, 0x80000101, 0x80000000 | ctrl);
  56. nvkm_msec(device, 2000,
  57. if (!(nvkm_rd32(device, 0x61e004 + soff) & 0x80000000))
  58. break;
  59. );
  60. disp->pior.type[outp->or] = type;
  61. return 0;
  62. }
  63. /******************************************************************************
  64. * TMDS
  65. *****************************************************************************/
  66. static const struct nvkm_output_func
  67. nv50_pior_output_func = {
  68. };
  69. int
  70. nv50_pior_output_new(struct nvkm_disp *disp, int index,
  71. struct dcb_output *dcbE, struct nvkm_output **poutp)
  72. {
  73. return nvkm_output_new_(&nv50_pior_output_func, disp,
  74. index, dcbE, poutp);
  75. }
  76. /******************************************************************************
  77. * DisplayPort
  78. *****************************************************************************/
  79. static int
  80. nv50_pior_output_dp_pattern(struct nvkm_output_dp *outp, int pattern)
  81. {
  82. return 0;
  83. }
  84. static int
  85. nv50_pior_output_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
  86. {
  87. return 0;
  88. }
  89. static int
  90. nv50_pior_output_dp_lnk_ctl(struct nvkm_output_dp *outp,
  91. int nr, int bw, bool ef)
  92. {
  93. int ret = nvkm_i2c_aux_lnk_ctl(outp->aux, nr, bw, ef);
  94. if (ret)
  95. return ret;
  96. return 1;
  97. }
  98. static const struct nvkm_output_dp_func
  99. nv50_pior_output_dp_func = {
  100. .pattern = nv50_pior_output_dp_pattern,
  101. .lnk_pwr = nv50_pior_output_dp_lnk_pwr,
  102. .lnk_ctl = nv50_pior_output_dp_lnk_ctl,
  103. };
  104. int
  105. nv50_pior_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE,
  106. struct nvkm_output **poutp)
  107. {
  108. struct nvkm_i2c *i2c = disp->engine.subdev.device->i2c;
  109. struct nvkm_i2c_aux *aux =
  110. nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbE->extdev));
  111. struct nvkm_output_dp *outp;
  112. if (!(outp = kzalloc(sizeof(*outp), GFP_KERNEL)))
  113. return -ENOMEM;
  114. *poutp = &outp->base;
  115. return nvkm_output_dp_ctor(&nv50_pior_output_dp_func, disp,
  116. index, dcbE, aux, outp);
  117. }