drm/nvd0/disp: move HDA codec setup to core
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
		
					parent
					
						
							
								35b21d39a5
							
						
					
				
			
			
				commit
				
					
						0a9e2b959f
					
				
			
		
					 9 changed files with 70 additions and 18 deletions
				
			
		|  | @ -138,6 +138,7 @@ nouveau-y += core/engine/disp/nva3.o | ||||||
| nouveau-y += core/engine/disp/nvd0.o | nouveau-y += core/engine/disp/nvd0.o | ||||||
| nouveau-y += core/engine/disp/nve0.o | nouveau-y += core/engine/disp/nve0.o | ||||||
| nouveau-y += core/engine/disp/dacnv50.o | nouveau-y += core/engine/disp/dacnv50.o | ||||||
|  | nouveau-y += core/engine/disp/hdanvd0.o | ||||||
| nouveau-y += core/engine/disp/sornv50.o | nouveau-y += core/engine/disp/sornv50.o | ||||||
| nouveau-y += core/engine/disp/sornvd0.o | nouveau-y += core/engine/disp/sornvd0.o | ||||||
| nouveau-y += core/engine/disp/vga.o | nouveau-y += core/engine/disp/vga.o | ||||||
|  |  | ||||||
							
								
								
									
										53
									
								
								drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2012 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 <core/os.h> | ||||||
|  | #include <core/class.h> | ||||||
|  | 
 | ||||||
|  | #include <subdev/bios.h> | ||||||
|  | #include <subdev/bios/dcb.h> | ||||||
|  | #include <subdev/bios/dp.h> | ||||||
|  | #include <subdev/bios/init.h> | ||||||
|  | 
 | ||||||
|  | #include "nv50.h" | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) | ||||||
|  | { | ||||||
|  | 	const u32 soff = (or * 0x030); | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (data && data[0]) { | ||||||
|  | 		for (i = 0; i < size; i++) | ||||||
|  | 			nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]); | ||||||
|  | 		nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); | ||||||
|  | 	} else | ||||||
|  | 	if (data) { | ||||||
|  | 		nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000001); | ||||||
|  | 	} else { | ||||||
|  | 		nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000000); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | @ -24,6 +24,7 @@ struct nv50_disp_priv { | ||||||
| 	struct { | 	struct { | ||||||
| 		int nr; | 		int nr; | ||||||
| 		int (*power)(struct nv50_disp_priv *, int sor, u32 data); | 		int (*power)(struct nv50_disp_priv *, int sor, u32 data); | ||||||
|  | 		int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32); | ||||||
| 		int (*dp_train)(struct nv50_disp_priv *, int sor, int link, | 		int (*dp_train)(struct nv50_disp_priv *, int sor, int link, | ||||||
| 				u16 type, u16 mask, u32 data, | 				u16 type, u16 mask, u32 data, | ||||||
| 				struct dcb_output *); | 				struct dcb_output *); | ||||||
|  | @ -49,6 +50,8 @@ int nv50_dac_sense(struct nv50_disp_priv *, int); | ||||||
| int nv50_sor_mthd(struct nouveau_object *, u32, void *, u32); | int nv50_sor_mthd(struct nouveau_object *, u32, void *, u32); | ||||||
| int nv50_sor_power(struct nv50_disp_priv *, int, u32); | int nv50_sor_power(struct nv50_disp_priv *, int, u32); | ||||||
| 
 | 
 | ||||||
|  | int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); | ||||||
|  | 
 | ||||||
| int nvd0_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32, | int nvd0_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32, | ||||||
| 		      struct dcb_output *); | 		      struct dcb_output *); | ||||||
| int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, | int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ nva3_disp_sclass[] = { | ||||||
| struct nouveau_omthds | struct nouveau_omthds | ||||||
| nva3_disp_base_omthds[] = { | nva3_disp_base_omthds[] = { | ||||||
| 	{ SOR_MTHD(NV50_DISP_SOR_PWR)         , nv50_sor_mthd }, | 	{ SOR_MTHD(NV50_DISP_SOR_PWR)         , nv50_sor_mthd }, | ||||||
|  | 	{ SOR_MTHD(NVA3_DISP_SOR_HDA_ELD)     , nv50_sor_mthd }, | ||||||
| 	{ SOR_MTHD(NV94_DISP_SOR_DP_TRAIN)    , nv50_sor_mthd }, | 	{ SOR_MTHD(NV94_DISP_SOR_DP_TRAIN)    , nv50_sor_mthd }, | ||||||
| 	{ SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL)   , nv50_sor_mthd }, | 	{ SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL)   , nv50_sor_mthd }, | ||||||
| 	{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, | 	{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, | ||||||
|  |  | ||||||
|  | @ -899,6 +899,7 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||||||
| 	priv->dac.power = nv50_dac_power; | 	priv->dac.power = nv50_dac_power; | ||||||
| 	priv->dac.sense = nv50_dac_sense; | 	priv->dac.sense = nv50_dac_sense; | ||||||
| 	priv->sor.power = nv50_sor_power; | 	priv->sor.power = nv50_sor_power; | ||||||
|  | 	priv->sor.hda_eld = nvd0_hda_eld; | ||||||
| 	priv->sor.dp_train = nvd0_sor_dp_train; | 	priv->sor.dp_train = nvd0_sor_dp_train; | ||||||
| 	priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; | 	priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; | ||||||
| 	priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; | 	priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; | ||||||
|  |  | ||||||
|  | @ -69,6 +69,7 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||||||
| 	priv->dac.power = nv50_dac_power; | 	priv->dac.power = nv50_dac_power; | ||||||
| 	priv->dac.sense = nv50_dac_sense; | 	priv->dac.sense = nv50_dac_sense; | ||||||
| 	priv->sor.power = nv50_sor_power; | 	priv->sor.power = nv50_sor_power; | ||||||
|  | 	priv->sor.hda_eld = nvd0_hda_eld; | ||||||
| 	priv->sor.dp_train = nvd0_sor_dp_train; | 	priv->sor.dp_train = nvd0_sor_dp_train; | ||||||
| 	priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; | 	priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; | ||||||
| 	priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; | 	priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; | ||||||
|  |  | ||||||
|  | @ -88,6 +88,9 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | ||||||
| 	case NV50_DISP_SOR_PWR: | 	case NV50_DISP_SOR_PWR: | ||||||
| 		ret = priv->sor.power(priv, or, data); | 		ret = priv->sor.power(priv, or, data); | ||||||
| 		break; | 		break; | ||||||
|  | 	case NVA3_DISP_SOR_HDA_ELD: | ||||||
|  | 		ret = priv->sor.hda_eld(priv, or, args, size); | ||||||
|  | 		break; | ||||||
| 	case NV94_DISP_SOR_DP_TRAIN: | 	case NV94_DISP_SOR_DP_TRAIN: | ||||||
| 		ret = priv->sor.dp_train(priv, or, link, type, mask, data, &outp); | 		ret = priv->sor.dp_train(priv, or, link, type, mask, data, &outp); | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
|  | @ -181,6 +181,7 @@ struct nve0_channel_ind_class { | ||||||
| #define NV50_DISP_SOR_PWR_STATE                                      0x00000001 | #define NV50_DISP_SOR_PWR_STATE                                      0x00000001 | ||||||
| #define NV50_DISP_SOR_PWR_STATE_ON                                   0x00000001 | #define NV50_DISP_SOR_PWR_STATE_ON                                   0x00000001 | ||||||
| #define NV50_DISP_SOR_PWR_STATE_OFF                                  0x00000000 | #define NV50_DISP_SOR_PWR_STATE_OFF                                  0x00000000 | ||||||
|  | #define NVA3_DISP_SOR_HDA_ELD                                        0x00010100 | ||||||
| #define NV94_DISP_SOR_DP_TRAIN                                       0x00016000 | #define NV94_DISP_SOR_DP_TRAIN                                       0x00016000 | ||||||
| #define NV94_DISP_SOR_DP_TRAIN_PATTERN                               0x00000003 | #define NV94_DISP_SOR_DP_TRAIN_PATTERN                               0x00000003 | ||||||
| #define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED                      0x00000000 | #define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED                      0x00000000 | ||||||
|  |  | ||||||
|  | @ -1238,38 +1238,26 @@ nvd0_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | ||||||
| { | { | ||||||
| 	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||||||
| 	struct nouveau_connector *nv_connector; | 	struct nouveau_connector *nv_connector; | ||||||
| 	struct drm_device *dev = encoder->dev; | 	struct nvd0_disp *disp = nvd0_disp(encoder->dev); | ||||||
| 	struct nouveau_device *device = nouveau_dev(dev); |  | ||||||
| 	int i, or = nv_encoder->or * 0x30; |  | ||||||
| 
 | 
 | ||||||
| 	nv_connector = nouveau_encoder_connector_get(nv_encoder); | 	nv_connector = nouveau_encoder_connector_get(nv_encoder); | ||||||
| 	if (!drm_detect_monitor_audio(nv_connector->edid)) | 	if (!drm_detect_monitor_audio(nv_connector->edid)) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	nv_mask(device, 0x10ec10 + or, 0x80000003, 0x80000001); |  | ||||||
| 
 |  | ||||||
| 	drm_edid_to_eld(&nv_connector->base, nv_connector->edid); | 	drm_edid_to_eld(&nv_connector->base, nv_connector->edid); | ||||||
| 	if (nv_connector->base.eld[0]) { |  | ||||||
| 		u8 *eld = nv_connector->base.eld; |  | ||||||
| 
 | 
 | ||||||
| 		for (i = 0; i < eld[2] * 4; i++) | 	nv_exec(disp->core, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, | ||||||
| 			nv_wr32(device, 0x10ec00 + or, (i << 8) | eld[i]); | 			    nv_connector->base.eld, | ||||||
| 		for (i = eld[2] * 4; i < 0x60; i++) | 			    nv_connector->base.eld[2] * 4); | ||||||
| 			nv_wr32(device, 0x10ec00 + or, (i << 8) | 0x00); |  | ||||||
| 
 |  | ||||||
| 		nv_mask(device, 0x10ec10 + or, 0x80000002, 0x80000002); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| nvd0_audio_disconnect(struct drm_encoder *encoder) | nvd0_audio_disconnect(struct drm_encoder *encoder) | ||||||
| { | { | ||||||
| 	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||||||
| 	struct drm_device *dev = encoder->dev; | 	struct nvd0_disp *disp = nvd0_disp(encoder->dev); | ||||||
| 	struct nouveau_device *device = nouveau_dev(dev); |  | ||||||
| 	int or = nv_encoder->or * 0x30; |  | ||||||
| 
 | 
 | ||||||
| 	nv_mask(device, 0x10ec10 + or, 0x80000003, 0x80000000); | 	nv_exec(disp->core, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, NULL, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /******************************************************************************
 | /******************************************************************************
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ben Skeggs
				Ben Skeggs