18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (C) 2009 Francisco Jerez.
38c2ecf20Sopenharmony_ci * All Rights Reserved.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining
68c2ecf20Sopenharmony_ci * a copy of this software and associated documentation files (the
78c2ecf20Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
88c2ecf20Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
98c2ecf20Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to
108c2ecf20Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
118c2ecf20Sopenharmony_ci * the following conditions:
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the
148c2ecf20Sopenharmony_ci * next paragraph) shall be included in all copies or substantial
158c2ecf20Sopenharmony_ci * portions of the Software.
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
188c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
198c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
208c2ecf20Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
218c2ecf20Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
228c2ecf20Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
238c2ecf20Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#ifndef __NV17_TV_H__
288c2ecf20Sopenharmony_ci#define __NV17_TV_H__
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistruct nv17_tv_state {
318c2ecf20Sopenharmony_ci	uint8_t tv_enc[0x40];
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	uint32_t hfilter[4][7];
348c2ecf20Sopenharmony_ci	uint32_t hfilter2[4][7];
358c2ecf20Sopenharmony_ci	uint32_t vfilter[4][7];
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	uint32_t ptv_200;
388c2ecf20Sopenharmony_ci	uint32_t ptv_204;
398c2ecf20Sopenharmony_ci	uint32_t ptv_208;
408c2ecf20Sopenharmony_ci	uint32_t ptv_20c;
418c2ecf20Sopenharmony_ci	uint32_t ptv_304;
428c2ecf20Sopenharmony_ci	uint32_t ptv_500;
438c2ecf20Sopenharmony_ci	uint32_t ptv_504;
448c2ecf20Sopenharmony_ci	uint32_t ptv_508;
458c2ecf20Sopenharmony_ci	uint32_t ptv_600;
468c2ecf20Sopenharmony_ci	uint32_t ptv_604;
478c2ecf20Sopenharmony_ci	uint32_t ptv_608;
488c2ecf20Sopenharmony_ci	uint32_t ptv_60c;
498c2ecf20Sopenharmony_ci	uint32_t ptv_610;
508c2ecf20Sopenharmony_ci	uint32_t ptv_614;
518c2ecf20Sopenharmony_ci};
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cienum nv17_tv_norm{
548c2ecf20Sopenharmony_ci	TV_NORM_PAL,
558c2ecf20Sopenharmony_ci	TV_NORM_PAL_M,
568c2ecf20Sopenharmony_ci	TV_NORM_PAL_N,
578c2ecf20Sopenharmony_ci	TV_NORM_PAL_NC,
588c2ecf20Sopenharmony_ci	TV_NORM_NTSC_M,
598c2ecf20Sopenharmony_ci	TV_NORM_NTSC_J,
608c2ecf20Sopenharmony_ci	NUM_LD_TV_NORMS,
618c2ecf20Sopenharmony_ci	TV_NORM_HD480I = NUM_LD_TV_NORMS,
628c2ecf20Sopenharmony_ci	TV_NORM_HD480P,
638c2ecf20Sopenharmony_ci	TV_NORM_HD576I,
648c2ecf20Sopenharmony_ci	TV_NORM_HD576P,
658c2ecf20Sopenharmony_ci	TV_NORM_HD720P,
668c2ecf20Sopenharmony_ci	TV_NORM_HD1080I,
678c2ecf20Sopenharmony_ci	NUM_TV_NORMS
688c2ecf20Sopenharmony_ci};
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cistruct nv17_tv_encoder {
718c2ecf20Sopenharmony_ci	struct nouveau_encoder base;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	struct nv17_tv_state state;
748c2ecf20Sopenharmony_ci	struct nv17_tv_state saved_state;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	int overscan;
778c2ecf20Sopenharmony_ci	int flicker;
788c2ecf20Sopenharmony_ci	int saturation;
798c2ecf20Sopenharmony_ci	int hue;
808c2ecf20Sopenharmony_ci	enum nv17_tv_norm tv_norm;
818c2ecf20Sopenharmony_ci	int subconnector;
828c2ecf20Sopenharmony_ci	int select_subconnector;
838c2ecf20Sopenharmony_ci	uint32_t pin_mask;
848c2ecf20Sopenharmony_ci};
858c2ecf20Sopenharmony_ci#define to_tv_enc(x) container_of(nouveau_encoder(x),		\
868c2ecf20Sopenharmony_ci				  struct nv17_tv_encoder, base)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ciextern const char * const nv17_tv_norm_names[NUM_TV_NORMS];
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ciextern struct nv17_tv_norm_params {
918c2ecf20Sopenharmony_ci	enum {
928c2ecf20Sopenharmony_ci		TV_ENC_MODE,
938c2ecf20Sopenharmony_ci		CTV_ENC_MODE,
948c2ecf20Sopenharmony_ci	} kind;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	union {
978c2ecf20Sopenharmony_ci		struct {
988c2ecf20Sopenharmony_ci			int hdisplay;
998c2ecf20Sopenharmony_ci			int vdisplay;
1008c2ecf20Sopenharmony_ci			int vrefresh; /* mHz */
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci			uint8_t tv_enc[0x40];
1038c2ecf20Sopenharmony_ci		} tv_enc_mode;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci		struct {
1068c2ecf20Sopenharmony_ci			struct drm_display_mode mode;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci			uint32_t ctv_regs[38];
1098c2ecf20Sopenharmony_ci		} ctv_enc_mode;
1108c2ecf20Sopenharmony_ci	};
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci} nv17_tv_norms[NUM_TV_NORMS];
1138c2ecf20Sopenharmony_ci#define get_tv_norm(enc) (&nv17_tv_norms[to_tv_enc(enc)->tv_norm])
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ciextern const struct drm_display_mode nv17_tv_modes[];
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_cistatic inline int interpolate(int y0, int y1, int y2, int x)
1188c2ecf20Sopenharmony_ci{
1198c2ecf20Sopenharmony_ci	return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50;
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_civoid nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state);
1238c2ecf20Sopenharmony_civoid nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state);
1248c2ecf20Sopenharmony_civoid nv17_tv_update_properties(struct drm_encoder *encoder);
1258c2ecf20Sopenharmony_civoid nv17_tv_update_rescaler(struct drm_encoder *encoder);
1268c2ecf20Sopenharmony_civoid nv17_ctv_update_rescaler(struct drm_encoder *encoder);
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci/* TV hardware access functions */
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic inline void nv_write_ptv(struct drm_device *dev, uint32_t reg,
1318c2ecf20Sopenharmony_ci				uint32_t val)
1328c2ecf20Sopenharmony_ci{
1338c2ecf20Sopenharmony_ci	struct nvif_device *device = &nouveau_drm(dev)->client.device;
1348c2ecf20Sopenharmony_ci	nvif_wr32(&device->object, reg, val);
1358c2ecf20Sopenharmony_ci}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_cistatic inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg)
1388c2ecf20Sopenharmony_ci{
1398c2ecf20Sopenharmony_ci	struct nvif_device *device = &nouveau_drm(dev)->client.device;
1408c2ecf20Sopenharmony_ci	return nvif_rd32(&device->object, reg);
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistatic inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg,
1448c2ecf20Sopenharmony_ci				   uint8_t val)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	nv_write_ptv(dev, NV_PTV_TV_INDEX, reg);
1478c2ecf20Sopenharmony_ci	nv_write_ptv(dev, NV_PTV_TV_DATA, val);
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistatic inline uint8_t nv_read_tv_enc(struct drm_device *dev, uint8_t reg)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	nv_write_ptv(dev, NV_PTV_TV_INDEX, reg);
1538c2ecf20Sopenharmony_ci	return nv_read_ptv(dev, NV_PTV_TV_DATA);
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci#define nv_load_ptv(dev, state, reg) \
1578c2ecf20Sopenharmony_ci	nv_write_ptv(dev, NV_PTV_OFFSET + 0x##reg, state->ptv_##reg)
1588c2ecf20Sopenharmony_ci#define nv_save_ptv(dev, state, reg) \
1598c2ecf20Sopenharmony_ci	state->ptv_##reg = nv_read_ptv(dev, NV_PTV_OFFSET + 0x##reg)
1608c2ecf20Sopenharmony_ci#define nv_load_tv_enc(dev, state, reg) \
1618c2ecf20Sopenharmony_ci	nv_write_tv_enc(dev, 0x##reg, state->tv_enc[0x##reg])
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci#endif
164