1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <drm/drmP.h>
26#include <drm/drm_crtc_helper.h>
27
28#include "nouveau_drv.h"
29#include "nouveau_reg.h"
30#include "hw.h"
31#include "nouveau_encoder.h"
32#include "nouveau_connector.h"
33
34int
35nv04_display_create(struct drm_device *dev)
36{
37 struct nouveau_drm *drm = nouveau_drm(dev);
38 struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
39 struct dcb_table *dcb = &drm->vbios.dcb;
40 struct drm_connector *connector, *ct;
41 struct drm_encoder *encoder;
42 struct nouveau_encoder *nv_encoder;
43 struct nouveau_crtc *crtc;
44 struct nv04_display *disp;
45 int i, ret;
46
47 disp = kzalloc(sizeof(*disp), GFP_KERNEL);
48 if (!disp)
49 return -ENOMEM;
50
51 nvif_object_map(&drm->device.object);
52
53 nouveau_display(dev)->priv = disp;
54 nouveau_display(dev)->dtor = nv04_display_destroy;
55 nouveau_display(dev)->init = nv04_display_init;
56 nouveau_display(dev)->fini = nv04_display_fini;
57
58 nouveau_hw_save_vga_fonts(dev, 1);
59
60 nv04_crtc_create(dev, 0);
61 if (nv_two_heads(dev))
62 nv04_crtc_create(dev, 1);
63
64 for (i = 0; i < dcb->entries; i++) {
65 struct dcb_output *dcbent = &dcb->entry[i];
66
67 connector = nouveau_connector_create(dev, dcbent->connector);
68 if (IS_ERR(connector))
69 continue;
70
71 switch (dcbent->type) {
72 case DCB_OUTPUT_ANALOG:
73 ret = nv04_dac_create(connector, dcbent);
74 break;
75 case DCB_OUTPUT_LVDS:
76 case DCB_OUTPUT_TMDS:
77 ret = nv04_dfp_create(connector, dcbent);
78 break;
79 case DCB_OUTPUT_TV:
80 if (dcbent->location == DCB_LOC_ON_CHIP)
81 ret = nv17_tv_create(connector, dcbent);
82 else
83 ret = nv04_tv_create(connector, dcbent);
84 break;
85 default:
86 NV_WARN(drm, "DCB type %d not known\n", dcbent->type);
87 continue;
88 }
89
90 if (ret)
91 continue;
92 }
93
94 list_for_each_entry_safe(connector, ct,
95 &dev->mode_config.connector_list, head) {
96 if (!connector->encoder_ids[0]) {
97 NV_WARN(drm, "%s has no encoders, removing\n",
98 connector->name);
99 connector->funcs->destroy(connector);
100 }
101 }
102
103 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
104 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
105 struct nvkm_i2c_bus *bus =
106 nvkm_i2c_bus_find(i2c, nv_encoder->dcb->i2c_index);
107 nv_encoder->i2c = bus ? &bus->i2c : NULL;
108 }
109
110
111 list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
112 crtc->save(&crtc->base);
113
114 list_for_each_entry(nv_encoder, &dev->mode_config.encoder_list, base.base.head)
115 nv_encoder->enc_save(&nv_encoder->base.base);
116
117 nouveau_overlay_init(dev);
118
119 return 0;
120}
121
122void
123nv04_display_destroy(struct drm_device *dev)
124{
125 struct nv04_display *disp = nv04_display(dev);
126 struct nouveau_drm *drm = nouveau_drm(dev);
127 struct nouveau_encoder *encoder;
128 struct nouveau_crtc *nv_crtc;
129
130
131 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
132 encoder->enc_restore(&encoder->base.base);
133
134 list_for_each_entry(nv_crtc, &dev->mode_config.crtc_list, base.head)
135 nv_crtc->restore(&nv_crtc->base);
136
137 nouveau_hw_save_vga_fonts(dev, 0);
138
139 nouveau_display(dev)->priv = NULL;
140 kfree(disp);
141
142 nvif_object_unmap(&drm->device.object);
143}
144
145int
146nv04_display_init(struct drm_device *dev)
147{
148 struct nouveau_encoder *encoder;
149 struct nouveau_crtc *crtc;
150
151
152
153
154
155
156
157
158
159 list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
160 crtc->save(&crtc->base);
161
162 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
163 encoder->enc_save(&encoder->base.base);
164
165 return 0;
166}
167
168void
169nv04_display_fini(struct drm_device *dev)
170{
171
172 NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
173 if (nv_two_heads(dev))
174 NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
175}
176