📄 theatre200.c
字号:
/************************************************************************************* * $Id$ * * Copyright (C) 2005 Bogdan D. bogdand@users.sourceforge.net * * 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 AUTHOR 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. * * Except as contained in this notice, the name of the author shall not be used in advertising or * otherwise to promote the sale, use or other dealings in this Software without prior written * authorization from the author. * * $Log$ * Revision 1.6 2006/03/22 22:30:14 krh * 2006-03-22 Kristian Høgsberg <krh@redhat.com> * * * src/theatre200.c: Convert use of xf86fopen() and other xf86 * wrapped libc symbols to use libc symbols directly. The xf86* * versions aren't supposed to be used directly. * * * src/ *.c: Drop libc wrapper; don't include xf86_ansic.h and add * includes now missing. * * Revision 1.4 2005/08/28 18:00:23 bogdand * Modified the licens type from GPL to a X/MIT one * * Revision 1.3 2005/07/11 02:29:45 ajax * Prep for modular builds by adding guarded #include "config.h" everywhere. * * Revision 1.2 2005/07/01 22:43:11 daniels * Change all misc.h and os.h references to <X11/foo.h>. * * ************************************************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <string.h>#include "xf86.h"#include "generic_bus.h"#include "radeon_reg.h"#include "radeon.h"#include "theatre_reg.h"#include "theatre200.h"#include "radeon_macros.h"#undef read#undef write#undef ioctlvoid DumpRageTheatreRegsByName(TheatrePtr t);static int DownloadMicrocode(TheatrePtr t);static int microc_load (char* micro_path, char* micro_type, struct rt200_microc_data* microc_datap, int screen);static void microc_clean(struct rt200_microc_data* microc_datap, int screen);static int dsp_init(TheatrePtr t, struct rt200_microc_data* microc_datap);static int dsp_load(TheatrePtr t, struct rt200_microc_data* microc_datap);static CARD32 dsp_send_command(TheatrePtr t, CARD32 fb_scratch1, CARD32 fb_scratch0);static CARD32 dsp_set_video_input_connector(TheatrePtr t, CARD32 connector);//static CARD32 dsp_reset(TheatrePtr t);static CARD32 dsp_set_lowpowerstate(TheatrePtr t, CARD32 pstate);static CARD32 dsp_set_video_standard(TheatrePtr t, CARD32 standard);static CARD32 dsp_set_videostreamformat(TheatrePtr t, CARD32 format);static CARD32 dsp_video_standard_detection(TheatrePtr t);//static CARD32 dsp_get_signallockstatus(TheatrePtr t);//static CARD32 dsp_get_signallinenumber(TheatrePtr t);static CARD32 dsp_set_brightness(TheatrePtr t, CARD8 brightness);static CARD32 dsp_set_contrast(TheatrePtr t, CARD8 contrast);//static CARD32 dsp_set_sharpness(TheatrePtr t, int sharpness);static CARD32 dsp_set_tint(TheatrePtr t, CARD8 tint);static CARD32 dsp_set_saturation(TheatrePtr t, CARD8 saturation);static CARD32 dsp_set_video_scaler_horizontal(TheatrePtr t, CARD16 output_width, CARD16 horz_start, CARD16 horz_end);static CARD32 dsp_set_video_scaler_vertical(TheatrePtr t, CARD16 output_height, CARD16 vert_start, CARD16 vert_end);static CARD32 dsp_audio_mute(TheatrePtr t, CARD8 left, CARD8 right);static CARD32 dsp_set_audio_volume(TheatrePtr t, CARD8 left, CARD8 right, CARD8 auto_mute);//static CARD32 dsp_audio_detection(TheatrePtr t, CARD8 option);static CARD32 dsp_configure_i2s_port(TheatrePtr t, CARD8 tx_mode, CARD8 rx_mode, CARD8 clk_mode);static CARD32 dsp_configure_spdif_port(TheatrePtr t, CARD8 state);static Bool theatre_read(TheatrePtr t,CARD32 reg, CARD32 *data){ if(t->theatre_num<0)return FALSE; return t->VIP->read(t->VIP, ((t->theatre_num & 0x3)<<14) | reg,4, (CARD8 *) data);}static Bool theatre_write(TheatrePtr t,CARD32 reg, CARD32 data){ if(t->theatre_num<0)return FALSE; return t->VIP->write(t->VIP,((t->theatre_num & 0x03)<<14) | reg,4, (CARD8 *) &data);}static Bool theatre_fifo_read(TheatrePtr t,CARD32 fifo, CARD8 *data){ if(t->theatre_num<0)return FALSE; return t->VIP->fifo_read(t->VIP, ((t->theatre_num & 0x3)<<14) | fifo,1, (CARD8 *) data);}static Bool theatre_fifo_write(TheatrePtr t,CARD32 fifo, CARD32 count, CARD8* buffer){ if(t->theatre_num<0)return FALSE; return t->VIP->fifo_write(t->VIP,((t->theatre_num & 0x03)<<14) | fifo,count, (CARD8 *)buffer);}#define RT_regr(reg,data) theatre_read(t,(reg),(data))#define RT_regw(reg,data) theatre_write(t,(reg),(data))#define RT_fifor(fifo,data) theatre_fifo_read(t,(fifo),(data))#define RT_fifow(fifo,count,data) theatre_fifo_write(t,(fifo),(count),(data))#define VIP_TYPE "ATI VIP BUS"static int microc_load (char* micro_path, char* micro_type, struct rt200_microc_data* microc_datap, int screen){ FILE* file; struct rt200_microc_head* microc_headp = µc_datap->microc_head; struct rt200_microc_seg* seg_list = NULL; struct rt200_microc_seg* curr_seg = NULL; struct rt200_microc_seg* prev_seg = NULL; int i; if (micro_path == NULL) return -1; if (micro_type == NULL) return -1; file = fopen(micro_path, "r"); if (file == NULL) { ERROR_0("Cannot open microcode file\n"); return -1; } if (!strcmp(micro_type, "BINARY")) { if (fread(microc_headp, sizeof(struct rt200_microc_head), 1, file) != 1) { ERROR("Cannot read header from file: %s\n", micro_path); goto fail_exit; } DEBUG("Microcode: num_seg: %x\n", microc_headp->num_seg); if (microc_headp->num_seg == 0) goto fail_exit; for (i = 0; i < microc_headp->num_seg; i++) { int ret; curr_seg = (struct rt200_microc_seg*)Xalloc(sizeof(struct rt200_microc_seg)); if (curr_seg == NULL) { ERROR_0("Cannot allocate memory\n"); goto fail_exit; } ret = fread(&curr_seg->num_bytes, 4, 1, file); ret += fread(&curr_seg->download_dst, 4, 1, file); ret += fread(&curr_seg->crc_val, 4, 1, file); if (ret != 3) { ERROR("Cannot read segment from microcode file: %s\n", micro_path); goto fail_exit; } curr_seg->data = (unsigned char*)Xalloc(curr_seg->num_bytes); if (curr_seg->data == NULL) { ERROR_0("cannot allocate memory\n"); goto fail_exit; } DEBUG("Microcode: segment number: %x\n", i); DEBUG("Microcode: curr_seg->num_bytes: %x\n", curr_seg->num_bytes); DEBUG("Microcode: curr_seg->download_dst: %x\n", curr_seg->download_dst); DEBUG("Microcode: curr_seg->crc_val: %x\n", curr_seg->crc_val); if (seg_list) { prev_seg->next = curr_seg; curr_seg->next = NULL; prev_seg = curr_seg; } else seg_list = prev_seg = curr_seg; } curr_seg = seg_list; while (curr_seg) { if (fread(curr_seg->data, curr_seg->num_bytes, 1, file) != 1) { ERROR_0("Cannot read segment data\n"); goto fail_exit; } curr_seg = curr_seg->next; } } else if (!strcmp(micro_type, "ASCII")) { char tmp1[12], tmp2[12], tmp3[12], tmp4[12]; unsigned int ltmp; if ((fgets(tmp1, 12, file) != NULL) && (fgets(tmp2, 12, file) != NULL) && (fgets(tmp3, 12, file) != NULL) && fgets(tmp4, 12, file) != NULL) { microc_headp->device_id = strtoul(tmp1, NULL, 16); microc_headp->vendor_id = strtoul(tmp2, NULL, 16); microc_headp->revision_id = strtoul(tmp3, NULL, 16); microc_headp->num_seg = strtoul(tmp4, NULL, 16); } else { ERROR("Cannot read header from file: %s\n", micro_path); goto fail_exit; } DEBUG("Microcode: num_seg: %x\n", microc_headp->num_seg); if (microc_headp->num_seg == 0) goto fail_exit; for (i = 0; i < microc_headp->num_seg; i++) { curr_seg = (struct rt200_microc_seg*)Xalloc(sizeof(struct rt200_microc_seg)); if (curr_seg == NULL) { ERROR_0("Cannot allocate memory\n"); goto fail_exit; } if (fgets(tmp1, 12, file) != NULL && fgets(tmp2, 12, file) != NULL && fgets(tmp3, 12, file) != NULL) { curr_seg->num_bytes = strtoul(tmp1, NULL, 16); curr_seg->download_dst = strtoul(tmp2, NULL, 16); curr_seg->crc_val = strtoul(tmp3, NULL, 16); } else { ERROR("Cannot read segment from microcode file: %s\n", micro_path); goto fail_exit; } curr_seg->data = (unsigned char*)Xalloc(curr_seg->num_bytes); if (curr_seg->data == NULL) { ERROR_0("cannot allocate memory\n"); goto fail_exit; } DEBUG("Microcode: segment number: %x\n", i); DEBUG("Microcode: curr_seg->num_bytes: %x\n", curr_seg->num_bytes); DEBUG("Microcode: curr_seg->download_dst: %x\n", curr_seg->download_dst); DEBUG("Microcode: curr_seg->crc_val: %x\n", curr_seg->crc_val); if (seg_list) { curr_seg->next = NULL; prev_seg->next = curr_seg; prev_seg = curr_seg; } else seg_list = prev_seg = curr_seg; } curr_seg = seg_list; while (curr_seg) { for ( i = 0; i < curr_seg->num_bytes; i+=4) { if (fgets(tmp1, 12, file) == NULL) { ERROR_0("Cannot read from file\n"); goto fail_exit; } ltmp = strtoul(tmp1, NULL, 16); *(unsigned int*)(curr_seg->data + i) = ltmp; } curr_seg = curr_seg->next; } } else { ERROR("File type %s unknown\n", micro_type); } microc_datap->microc_seg_list = seg_list; fclose(file); return 0;fail_exit: curr_seg = seg_list; while(curr_seg) { Xfree(curr_seg->data); prev_seg = curr_seg; curr_seg = curr_seg->next; Xfree(prev_seg); } fclose(file); return -1;}static void microc_clean(struct rt200_microc_data* microc_datap, int screen){ struct rt200_microc_seg* seg_list = microc_datap->microc_seg_list; struct rt200_microc_seg* prev_seg; while(seg_list) { Xfree(seg_list->data); prev_seg = seg_list; seg_list = seg_list->next; Xfree(prev_seg); }}static int dsp_init(TheatrePtr t, struct rt200_microc_data* microc_datap){ CARD32 data; int i = 0; int screen = t->VIP->scrnIndex; /* Map FIFOD to DSP Port I/O port */ RT_regr(VIP_HOSTINTF_PORT_CNTL, &data); RT_regw(VIP_HOSTINTF_PORT_CNTL, data & (~VIP_HOSTINTF_PORT_CNTL__FIFO_RW_MODE)); /* The default endianess is LE. It matches the ost one for x86 */ RT_regr(VIP_HOSTINTF_PORT_CNTL, &data); RT_regw(VIP_HOSTINTF_PORT_CNTL, data & (~VIP_HOSTINTF_PORT_CNTL__FIFOD_ENDIAN_SWAP)); /* Wait until Shuttle bus channel 14 is available */ RT_regr(VIP_TC_STATUS, &data); while(((data & VIP_TC_STATUS__TC_CHAN_BUSY) & 0x00004000) && (i++ < 10000)) RT_regr(VIP_TC_STATUS, &data); DEBUG_0("Microcode: dsp_init: channel 14 available\n"); return 0;}static int dsp_load(TheatrePtr t, struct rt200_microc_data* microc_datap){ struct rt200_microc_seg* seg_list = microc_datap->microc_seg_list; CARD8 data8; CARD32 data, fb_scratch0, fb_scratch1; CARD32 i; CARD32 tries = 0; CARD32 result = 0; CARD32 seg_id = 0; int screen = t->VIP->scrnIndex; DEBUG("Microcode: before everything: %x\n", data8); if (RT_fifor(0x000, &data8)) DEBUG("Microcode: FIFO status0: %x\n", data8); else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -