Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xenomai
ipipe-x86
Commits
4f6029da
Commit
4f6029da
authored
Nov 16, 2012
by
Ben Skeggs
Browse files
drm/nv50-nvc0: switch to common disp impl, removing previous version
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
f9887d09
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
drivers/gpu/drm/nouveau/Makefile
View file @
4f6029da
...
...
@@ -192,7 +192,7 @@ nouveau-y += nv04_fence.o nv10_fence.o nv50_fence.o nv84_fence.o nvc0_fence.o
# drm/kms
nouveau-y
+=
nouveau_bios.o nouveau_fbcon.o nouveau_display.o
nouveau-y
+=
nouveau_connector.o
nouveau_hdmi.o
nouveau_dp.o
nouveau-y
+=
nouveau_connector.o nouveau_dp.o
nouveau-y
+=
nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o
# drm/kms/nv04:nv50
...
...
@@ -201,9 +201,7 @@ nouveau-y += nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o
nouveau-y
+=
nv04_crtc.o nv04_display.o nv04_cursor.o
# drm/kms/nv50-
nouveau-y
+=
nv50_display.o nvd0_display.o
nouveau-y
+=
nv50_crtc.o nv50_dac.o nv50_sor.o nv50_cursor.o
nouveau-y
+=
nv50_evo.o
nouveau-y
+=
nvd0_display.o
# drm/pm
nouveau-y
+=
nouveau_pm.o nouveau_volt.o nouveau_perf.o
...
...
drivers/gpu/drm/nouveau/nouveau_connector.h
View file @
4f6029da
...
...
@@ -28,6 +28,7 @@
#define __NOUVEAU_CONNECTOR_H__
#include <drm/drm_edid.h>
#include "nouveau_crtc.h"
struct
nouveau_i2c_port
;
...
...
@@ -80,6 +81,21 @@ static inline struct nouveau_connector *nouveau_connector(
return
container_of
(
con
,
struct
nouveau_connector
,
base
);
}
static
inline
struct
nouveau_connector
*
nouveau_crtc_connector_get
(
struct
nouveau_crtc
*
nv_crtc
)
{
struct
drm_device
*
dev
=
nv_crtc
->
base
.
dev
;
struct
drm_connector
*
connector
;
struct
drm_crtc
*
crtc
=
to_drm_crtc
(
nv_crtc
);
list_for_each_entry
(
connector
,
&
dev
->
mode_config
.
connector_list
,
head
)
{
if
(
connector
->
encoder
&&
connector
->
encoder
->
crtc
==
crtc
)
return
nouveau_connector
(
connector
);
}
return
NULL
;
}
struct
drm_connector
*
nouveau_connector_create
(
struct
drm_device
*
,
int
index
);
...
...
drivers/gpu/drm/nouveau/nouveau_crtc.h
View file @
4f6029da
...
...
@@ -91,7 +91,4 @@ int nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y);
int
nv04_cursor_init
(
struct
nouveau_crtc
*
);
int
nv50_cursor_init
(
struct
nouveau_crtc
*
);
struct
nouveau_connector
*
nouveau_crtc_connector_get
(
struct
nouveau_crtc
*
crtc
);
#endif
/* __NOUVEAU_CRTC_H__ */
drivers/gpu/drm/nouveau/nouveau_display.c
View file @
4f6029da
...
...
@@ -98,12 +98,12 @@ nouveau_framebuffer_init(struct drm_device *dev,
nv_fb
->
r_dma
=
NvEvoVRAM_LP
;
switch
(
fb
->
depth
)
{
case
8
:
nv_fb
->
r_format
=
NV50_EVO_CRTC_FB_DEPTH_8
;
break
;
case
15
:
nv_fb
->
r_format
=
NV50_EVO_CRTC_FB_DEPTH_15
;
break
;
case
16
:
nv_fb
->
r_format
=
NV50_EVO_CRTC_FB_DEPTH_16
;
break
;
case
8
:
nv_fb
->
r_format
=
0x1e00
;
break
;
case
15
:
nv_fb
->
r_format
=
0xe900
;
break
;
case
16
:
nv_fb
->
r_format
=
0xe800
;
break
;
case
24
:
case
32
:
nv_fb
->
r_format
=
NV50_EVO_CRTC_FB_DEPTH_24
;
break
;
case
30
:
nv_fb
->
r_format
=
NV50_EVO_CRTC_FB_DEPTH_3
0
;
break
;
case
32
:
nv_fb
->
r_format
=
0xcf00
;
break
;
case
30
:
nv_fb
->
r_format
=
0xd10
0
;
break
;
default:
NV_ERROR
(
drm
,
"unknown depth %d
\n
"
,
fb
->
depth
);
return
-
EINVAL
;
...
...
@@ -365,9 +365,6 @@ nouveau_display_create(struct drm_device *dev)
(
nouveau_modeset
<
0
&&
pclass
==
PCI_CLASS_DISPLAY_VGA
))
{
if
(
nv_device
(
drm
->
device
)
->
card_type
<
NV_50
)
ret
=
nv04_display_create
(
dev
);
else
if
(
nv_device
(
drm
->
device
)
->
card_type
<
NV_D0
)
ret
=
nv50_display_create
(
dev
);
else
ret
=
nvd0_display_create
(
dev
);
if
(
ret
)
...
...
@@ -660,10 +657,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Emit a page flip */
if
(
nv_device
(
drm
->
device
)
->
card_type
>=
NV_50
)
{
if
(
nv_device
(
drm
->
device
)
->
card_type
>=
NV_D0
)
ret
=
nvd0_display_flip_next
(
crtc
,
fb
,
chan
,
0
);
else
ret
=
nv50_display_flip_next
(
crtc
,
fb
,
chan
);
ret
=
nvd0_display_flip_next
(
crtc
,
fb
,
chan
,
0
);
if
(
ret
)
{
mutex_unlock
(
&
chan
->
cli
->
mutex
);
goto
fail_unreserve
;
...
...
drivers/gpu/drm/nouveau/nouveau_hdmi.c
deleted
100644 → 0
View file @
f9887d09
/*
* Copyright 2011 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include <drm/drmP.h>
#include "nouveau_drm.h"
#include "nouveau_connector.h"
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
#include <core/class.h>
#include "nv50_display.h"
static
bool
hdmi_sor
(
struct
drm_encoder
*
encoder
)
{
struct
nouveau_drm
*
drm
=
nouveau_drm
(
encoder
->
dev
);
if
(
nv_device
(
drm
->
device
)
->
chipset
<
0xa3
||
nv_device
(
drm
->
device
)
->
chipset
==
0xaa
||
nv_device
(
drm
->
device
)
->
chipset
==
0xac
)
return
false
;
return
true
;
}
static
void
nouveau_audio_disconnect
(
struct
drm_encoder
*
encoder
)
{
struct
nv50_display
*
priv
=
nv50_display
(
encoder
->
dev
);
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
u32
or
=
nv_encoder
->
or
;
if
(
hdmi_sor
(
encoder
))
nv_exec
(
priv
->
core
,
NVA3_DISP_SOR_HDA_ELD
+
or
,
NULL
,
0
);
}
static
void
nouveau_audio_mode_set
(
struct
drm_encoder
*
encoder
,
struct
drm_display_mode
*
mode
)
{
struct
nv50_display
*
priv
=
nv50_display
(
encoder
->
dev
);
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
nouveau_connector
*
nv_connector
;
nv_connector
=
nouveau_encoder_connector_get
(
nv_encoder
);
if
(
!
drm_detect_monitor_audio
(
nv_connector
->
edid
))
{
nouveau_audio_disconnect
(
encoder
);
return
;
}
if
(
hdmi_sor
(
encoder
))
{
drm_edid_to_eld
(
&
nv_connector
->
base
,
nv_connector
->
edid
);
nv_exec
(
priv
->
core
,
NVA3_DISP_SOR_HDA_ELD
+
nv_encoder
->
or
,
nv_connector
->
base
.
eld
,
nv_connector
->
base
.
eld
[
2
]
*
4
);
}
}
static
void
nouveau_hdmi_disconnect
(
struct
drm_encoder
*
encoder
)
{
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
nouveau_crtc
*
nv_crtc
=
nouveau_crtc
(
nv_encoder
->
crtc
);
struct
nv50_display
*
priv
=
nv50_display
(
encoder
->
dev
);
const
u32
moff
=
(
nv_crtc
->
index
<<
3
)
|
nv_encoder
->
or
;
nouveau_audio_disconnect
(
encoder
);
nv_call
(
priv
->
core
,
NV84_DISP_SOR_HDMI_PWR
+
moff
,
0x00000000
);
}
void
nouveau_hdmi_mode_set
(
struct
drm_encoder
*
encoder
,
struct
drm_display_mode
*
mode
)
{
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
nouveau_crtc
*
nv_crtc
=
nouveau_crtc
(
nv_encoder
->
crtc
);
struct
nv50_display
*
priv
=
nv50_display
(
encoder
->
dev
);
const
u32
moff
=
(
nv_crtc
->
index
<<
3
)
|
nv_encoder
->
or
;
struct
nouveau_connector
*
nv_connector
;
u32
max_ac_packet
,
rekey
;
nv_connector
=
nouveau_encoder_connector_get
(
nv_encoder
);
if
(
!
mode
||
!
nv_connector
||
!
nv_connector
->
edid
||
!
drm_detect_hdmi_monitor
(
nv_connector
->
edid
))
{
nouveau_hdmi_disconnect
(
encoder
);
return
;
}
/* value matches nvidia binary driver, and tegra constant */
rekey
=
56
;
max_ac_packet
=
mode
->
htotal
-
mode
->
hdisplay
;
max_ac_packet
-=
rekey
;
max_ac_packet
-=
18
;
/* constant from tegra */
max_ac_packet
/=
32
;
nv_call
(
priv
->
core
,
NV84_DISP_SOR_HDMI_PWR
+
moff
,
NV84_DISP_SOR_HDMI_PWR_STATE_ON
|
(
max_ac_packet
<<
16
)
|
rekey
);
nouveau_audio_mode_set
(
encoder
,
mode
);
}
drivers/gpu/drm/nouveau/nv50_crtc.c
deleted
100644 → 0
View file @
f9887d09
This diff is collapsed.
Click to expand it.
drivers/gpu/drm/nouveau/nv50_cursor.c
deleted
100644 → 0
View file @
f9887d09
/*
* Copyright (C) 2008 Maarten Maathuis.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <drm/drmP.h>
#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_crtc.h"
#include "nv50_display.h"
static
void
nv50_cursor_show
(
struct
nouveau_crtc
*
nv_crtc
,
bool
update
)
{
struct
drm_device
*
dev
=
nv_crtc
->
base
.
dev
;
struct
nouveau_drm
*
drm
=
nouveau_drm
(
dev
);
struct
nouveau_channel
*
evo
=
nv50_display
(
dev
)
->
master
;
int
ret
;
if
(
update
&&
nv_crtc
->
cursor
.
visible
)
return
;
ret
=
RING_SPACE
(
evo
,
(
nv_device
(
drm
->
device
)
->
chipset
!=
0x50
?
5
:
3
)
+
update
*
2
);
if
(
ret
)
{
NV_ERROR
(
drm
,
"no space while unhiding cursor
\n
"
);
return
;
}
if
(
nv_device
(
drm
->
device
)
->
chipset
!=
0x50
)
{
BEGIN_NV04
(
evo
,
0
,
NV84_EVO_CRTC
(
nv_crtc
->
index
,
CURSOR_DMA
),
1
);
OUT_RING
(
evo
,
NvEvoVRAM
);
}
BEGIN_NV04
(
evo
,
0
,
NV50_EVO_CRTC
(
nv_crtc
->
index
,
CURSOR_CTRL
),
2
);
OUT_RING
(
evo
,
NV50_EVO_CRTC_CURSOR_CTRL_SHOW
);
OUT_RING
(
evo
,
nv_crtc
->
cursor
.
offset
>>
8
);
if
(
update
)
{
BEGIN_NV04
(
evo
,
0
,
NV50_EVO_UPDATE
,
1
);
OUT_RING
(
evo
,
0
);
FIRE_RING
(
evo
);
nv_crtc
->
cursor
.
visible
=
true
;
}
}
static
void
nv50_cursor_hide
(
struct
nouveau_crtc
*
nv_crtc
,
bool
update
)
{
struct
drm_device
*
dev
=
nv_crtc
->
base
.
dev
;
struct
nouveau_drm
*
drm
=
nouveau_drm
(
dev
);
struct
nouveau_channel
*
evo
=
nv50_display
(
dev
)
->
master
;
int
ret
;
if
(
update
&&
!
nv_crtc
->
cursor
.
visible
)
return
;
ret
=
RING_SPACE
(
evo
,
(
nv_device
(
drm
->
device
)
->
chipset
!=
0x50
?
5
:
3
)
+
update
*
2
);
if
(
ret
)
{
NV_ERROR
(
drm
,
"no space while hiding cursor
\n
"
);
return
;
}
BEGIN_NV04
(
evo
,
0
,
NV50_EVO_CRTC
(
nv_crtc
->
index
,
CURSOR_CTRL
),
2
);
OUT_RING
(
evo
,
NV50_EVO_CRTC_CURSOR_CTRL_HIDE
);
OUT_RING
(
evo
,
0
);
if
(
nv_device
(
drm
->
device
)
->
chipset
!=
0x50
)
{
BEGIN_NV04
(
evo
,
0
,
NV84_EVO_CRTC
(
nv_crtc
->
index
,
CURSOR_DMA
),
1
);
OUT_RING
(
evo
,
NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE
);
}
if
(
update
)
{
BEGIN_NV04
(
evo
,
0
,
NV50_EVO_UPDATE
,
1
);
OUT_RING
(
evo
,
0
);
FIRE_RING
(
evo
);
nv_crtc
->
cursor
.
visible
=
false
;
}
}
static
void
nv50_cursor_set_pos
(
struct
nouveau_crtc
*
nv_crtc
,
int
x
,
int
y
)
{
struct
nouveau_device
*
device
=
nouveau_dev
(
nv_crtc
->
base
.
dev
);
nv_crtc
->
cursor_saved_x
=
x
;
nv_crtc
->
cursor_saved_y
=
y
;
nv_wr32
(
device
,
NV50_PDISPLAY_CURSOR_USER_POS
(
nv_crtc
->
index
),
((
y
&
0xFFFF
)
<<
16
)
|
(
x
&
0xFFFF
));
/* Needed to make the cursor move. */
nv_wr32
(
device
,
NV50_PDISPLAY_CURSOR_USER_POS_CTRL
(
nv_crtc
->
index
),
0
);
}
static
void
nv50_cursor_set_offset
(
struct
nouveau_crtc
*
nv_crtc
,
uint32_t
offset
)
{
if
(
offset
==
nv_crtc
->
cursor
.
offset
)
return
;
nv_crtc
->
cursor
.
offset
=
offset
;
if
(
nv_crtc
->
cursor
.
visible
)
{
nv_crtc
->
cursor
.
visible
=
false
;
nv_crtc
->
cursor
.
show
(
nv_crtc
,
true
);
}
}
int
nv50_cursor_init
(
struct
nouveau_crtc
*
nv_crtc
)
{
nv_crtc
->
cursor
.
set_offset
=
nv50_cursor_set_offset
;
nv_crtc
->
cursor
.
set_pos
=
nv50_cursor_set_pos
;
nv_crtc
->
cursor
.
hide
=
nv50_cursor_hide
;
nv_crtc
->
cursor
.
show
=
nv50_cursor_show
;
return
0
;
}
drivers/gpu/drm/nouveau/nv50_dac.c
deleted
100644 → 0
View file @
f9887d09
/*
* Copyright (C) 2008 Maarten Maathuis.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
#include "nouveau_reg.h"
#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
#include "nv50_display.h"
#include <core/class.h>
#include <subdev/timer.h>
static
void
nv50_dac_disconnect
(
struct
drm_encoder
*
encoder
)
{
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
nouveau_drm
*
drm
=
nouveau_drm
(
dev
);
struct
nouveau_channel
*
evo
=
nv50_display
(
dev
)
->
master
;
int
ret
;
if
(
!
nv_encoder
->
crtc
)
return
;
nv50_crtc_blank
(
nouveau_crtc
(
nv_encoder
->
crtc
),
true
);
NV_DEBUG
(
drm
,
"Disconnecting DAC %d
\n
"
,
nv_encoder
->
or
);
ret
=
RING_SPACE
(
evo
,
4
);
if
(
ret
)
{
NV_ERROR
(
drm
,
"no space while disconnecting DAC
\n
"
);
return
;
}
BEGIN_NV04
(
evo
,
0
,
NV50_EVO_DAC
(
nv_encoder
->
or
,
MODE_CTRL
),
1
);
OUT_RING
(
evo
,
0
);
BEGIN_NV04
(
evo
,
0
,
NV50_EVO_UPDATE
,
1
);
OUT_RING
(
evo
,
0
);
nv_encoder
->
crtc
=
NULL
;
}
static
enum
drm_connector_status
nv50_dac_detect
(
struct
drm_encoder
*
encoder
,
struct
drm_connector
*
connector
)
{
struct
nv50_display
*
priv
=
nv50_display
(
encoder
->
dev
);
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
nouveau_drm
*
drm
=
nouveau_drm
(
encoder
->
dev
);
int
or
=
nv_encoder
->
or
,
ret
;
u32
load
;
if
(
drm
->
vbios
.
dactestval
)
load
=
drm
->
vbios
.
dactestval
;
else
load
=
340
;
ret
=
nv_exec
(
priv
->
core
,
NV50_DISP_DAC_LOAD
+
or
,
&
load
,
sizeof
(
load
));
if
(
ret
||
load
!=
7
)
return
connector_status_disconnected
;
return
connector_status_connected
;
}
static
void
nv50_dac_dpms
(
struct
drm_encoder
*
encoder
,
int
mode
)
{
struct
nv50_display
*
priv
=
nv50_display
(
encoder
->
dev
);
struct
nouveau_drm
*
drm
=
nouveau_drm
(
encoder
->
dev
);
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
uint32_t
val
;
int
or
=
nv_encoder
->
or
;
NV_DEBUG
(
drm
,
"or %d mode %d
\n
"
,
or
,
mode
);
if
(
mode
!=
DRM_MODE_DPMS_ON
)
val
=
NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED
;
else
val
=
0
;
switch
(
mode
)
{
case
DRM_MODE_DPMS_STANDBY
:
val
|=
NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF
;
break
;
case
DRM_MODE_DPMS_SUSPEND
:
val
|=
NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF
;
break
;
case
DRM_MODE_DPMS_OFF
:
val
|=
NV50_PDISPLAY_DAC_DPMS_CTRL_OFF
;
val
|=
NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF
;
val
|=
NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF
;
break
;
default:
break
;
}
nv_call
(
priv
->
core
,
NV50_DISP_DAC_PWR
+
or
,
val
);
}
static
void
nv50_dac_save
(
struct
drm_encoder
*
encoder
)
{
struct
nouveau_drm
*
drm
=
nouveau_drm
(
encoder
->
dev
);
NV_ERROR
(
drm
,
"!!
\n
"
);
}
static
void
nv50_dac_restore
(
struct
drm_encoder
*
encoder
)
{
struct
nouveau_drm
*
drm
=
nouveau_drm
(
encoder
->
dev
);
NV_ERROR
(
drm
,
"!!
\n
"
);
}
static
bool
nv50_dac_mode_fixup
(
struct
drm_encoder
*
encoder
,
const
struct
drm_display_mode
*
mode
,
struct
drm_display_mode
*
adjusted_mode
)
{
struct
nouveau_drm
*
drm
=
nouveau_drm
(
encoder
->
dev
);
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
nouveau_connector
*
connector
;
NV_DEBUG
(
drm
,
"or %d
\n
"
,
nv_encoder
->
or
);
connector
=
nouveau_encoder_connector_get
(
nv_encoder
);
if
(
!
connector
)
{
NV_ERROR
(
drm
,
"Encoder has no connector
\n
"
);
return
false
;
}
if
(
connector
->
scaling_mode
!=
DRM_MODE_SCALE_NONE
&&
connector
->
native_mode
)
drm_mode_copy
(
adjusted_mode
,
connector
->
native_mode
);
return
true
;
}
static
void
nv50_dac_commit
(
struct
drm_encoder
*
encoder
)
{
}
static
void
nv50_dac_mode_set
(
struct
drm_encoder
*
encoder
,
struct
drm_display_mode
*
mode
,
struct
drm_display_mode
*
adjusted_mode
)
{
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
nouveau_drm
*
drm
=
nouveau_drm
(
encoder
->
dev
);
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
nouveau_channel
*
evo
=
nv50_display
(
dev
)
->
master
;
struct
nouveau_crtc
*
crtc
=
nouveau_crtc
(
encoder
->
crtc
);
uint32_t
mode_ctl
=
0
,
mode_ctl2
=
0
;
int
ret
;
NV_DEBUG
(
drm
,
"or %d type %d crtc %d
\n
"
,
nv_encoder
->
or
,
nv_encoder
->
dcb
->
type
,
crtc
->
index
);
nv50_dac_dpms
(
encoder
,
DRM_MODE_DPMS_ON
);
if
(
crtc
->
index
==
1
)
mode_ctl
|=
NV50_EVO_DAC_MODE_CTRL_CRTC1
;
else
mode_ctl
|=
NV50_EVO_DAC_MODE_CTRL_CRTC0
;
/* Lacking a working tv-out, this is not a 100% sure. */
if
(
nv_encoder
->
dcb
->
type
==
DCB_OUTPUT_ANALOG
)
mode_ctl
|=
0x40
;
else
if
(
nv_encoder
->
dcb
->
type
==
DCB_OUTPUT_TV
)
mode_ctl
|=
0x100
;
if
(
adjusted_mode
->
flags
&
DRM_MODE_FLAG_NHSYNC
)
mode_ctl2
|=
NV50_EVO_DAC_MODE_CTRL2_NHSYNC
;
if
(
adjusted_mode
->
flags
&
DRM_MODE_FLAG_NVSYNC
)
mode_ctl2
|=
NV50_EVO_DAC_MODE_CTRL2_NVSYNC
;
ret
=
RING_SPACE
(
evo
,
3
);
if
(
ret
)
{
NV_ERROR
(
drm
,
"no space while connecting DAC
\n
"
);
return
;
}
BEGIN_NV04
(
evo
,
0
,
NV50_EVO_DAC
(
nv_encoder
->
or
,
MODE_CTRL
),
2
);
OUT_RING
(
evo
,
mode_ctl
);
OUT_RING
(
evo
,
mode_ctl2
);
nv_encoder
->
crtc
=
encoder
->
crtc
;
}
static
struct
drm_crtc
*
nv50_dac_crtc_get
(
struct
drm_encoder
*
encoder
)
{
return
nouveau_encoder
(
encoder
)
->
crtc
;
}
static
const
struct
drm_encoder_helper_funcs
nv50_dac_helper_funcs
=
{
.
dpms
=
nv50_dac_dpms
,
.
save
=
nv50_dac_save
,
.
restore
=
nv50_dac_restore
,
.
mode_fixup
=
nv50_dac_mode_fixup
,
.
prepare
=
nv50_dac_disconnect
,
.
commit
=
nv50_dac_commit
,
.
mode_set
=
nv50_dac_mode_set
,
.
get_crtc
=
nv50_dac_crtc_get
,
.
detect
=
nv50_dac_detect
,
.
disable
=
nv50_dac_disconnect
};
static
void
nv50_dac_destroy
(
struct
drm_encoder
*
encoder
)
{
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
if
(
!
encoder
)
return
;
drm_encoder_cleanup
(
encoder
);
kfree
(
nv_encoder
);
}
static
const
struct
drm_encoder_funcs
nv50_dac_encoder_funcs
=
{
.
destroy
=
nv50_dac_destroy
,
};
int