Example #1
0
void ast_set_index_reg_mask(struct ast_private *ast,
			    uint32_t base, uint8_t index,
			    uint8_t mask, uint8_t val)
{
	u8 tmp;
	ast_io_write8(ast, base, index);
	tmp = (ast_io_read8(ast, base + 1) & mask) | val;
	ast_set_index_reg(ast, base, index, tmp);
}
Example #2
0
static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
                                    struct drm_display_mode *adjusted_mode,
                                    struct ast_vbios_mode_info *vbios_mode)
{
    struct ast_private *ast = crtc->dev->dev_private;
    u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate;
    u32 hborder, vborder;
    bool check_sync;
    struct ast_vbios_enhtable *best = NULL;

    switch (crtc->primary->fb->bits_per_pixel) {
    case 8:
        vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
        color_index = VGAModeIndex - 1;
        break;
    case 16:
        vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
        color_index = HiCModeIndex;
        break;
    case 24:
    case 32:
        vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
        color_index = TrueCModeIndex;
        break;
    default:
        return false;
    }

    switch (crtc->mode.crtc_hdisplay) {
    case 640:
        vbios_mode->enh_table = &res_640x480[refresh_rate_index];
        break;
    case 800:
        vbios_mode->enh_table = &res_800x600[refresh_rate_index];
        break;
    case 1024:
        vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
        break;
    case 1280:
        if (crtc->mode.crtc_vdisplay == 800)
            vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
        else
            vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
        break;
    case 1360:
        vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
        break;
    case 1440:
        vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
        break;
    case 1600:
        if (crtc->mode.crtc_vdisplay == 900)
            vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
        else
            vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
        break;
    case 1680:
        vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
        break;
    case 1920:
        if (crtc->mode.crtc_vdisplay == 1080)
            vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
        else
            vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
        break;
    default:
        return false;
    }

    refresh_rate = drm_mode_vrefresh(mode);
    check_sync = vbios_mode->enh_table->flags & WideScreenMode;
    do {
        struct ast_vbios_enhtable *loop = vbios_mode->enh_table;

        while (loop->refresh_rate != 0xff) {
            if ((check_sync) &&
                    (((mode->flags & DRM_MODE_FLAG_NVSYNC)  &&
                      (loop->flags & PVSync))  ||
                     ((mode->flags & DRM_MODE_FLAG_PVSYNC)  &&
                      (loop->flags & NVSync))  ||
                     ((mode->flags & DRM_MODE_FLAG_NHSYNC)  &&
                      (loop->flags & PHSync))  ||
                     ((mode->flags & DRM_MODE_FLAG_PHSYNC)  &&
                      (loop->flags & NHSync)))) {
                loop++;
                continue;
            }
            if (loop->refresh_rate <= refresh_rate
                    && (!best || loop->refresh_rate > best->refresh_rate))
                best = loop;
            loop++;
        }
        if (best || !check_sync)
            break;
        check_sync = 0;
    } while (1);
    if (best)
        vbios_mode->enh_table = best;

    hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
    vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;

    adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht;
    adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder;
    adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
    adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder +
                                      vbios_mode->enh_table->hfp;
    adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder +
                                     vbios_mode->enh_table->hfp +
                                     vbios_mode->enh_table->hsync);

    adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt;
    adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder;
    adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
    adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder +
                                      vbios_mode->enh_table->vfp;
    adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder +
                                     vbios_mode->enh_table->vfp +
                                     vbios_mode->enh_table->vsync);

    refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
    mode_id = vbios_mode->enh_table->mode_id;

    if (ast->chip == AST1180) {
        /* TODO 1180 */
    } else {
        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0xf) << 4));
        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);

        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
        if (vbios_mode->enh_table->flags & NewModeInfo) {
            ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
            ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->primary->fb->bits_per_pixel);
            ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
            ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
            ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);

            ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
            ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
        }
    }
Example #3
0
bool ast_launch_m68k(struct drm_device *dev)
{
	struct ast_private *ast = dev->dev_private;
	u32 i, data, len = 0;
	u32 boot_address;
	u8 *fw_addr = NULL;
	u8 jreg;

	data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
	if (!data) {

		if (ast->dp501_fw_addr) {
			fw_addr = ast->dp501_fw_addr;
			len = 32*1024;
		} else if (ast->dp501_fw) {
			fw_addr = (u8 *)ast->dp501_fw->data;
			len = ast->dp501_fw->size;
		}
		/* Get BootAddress */
		ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
		data = ast_mindwm(ast, 0x1e6e0004);
		switch (data & 0x03) {
		case 0:
			boot_address = 0x44000000;
			break;
		default:
		case 1:
			boot_address = 0x48000000;
			break;
		case 2:
			boot_address = 0x50000000;
			break;
		case 3:
			boot_address = 0x60000000;
			break;
		}
		boot_address -= 0x200000; /* -2MB */

		/* copy image to buffer */
		for (i = 0; i < len; i += 4) {
			data = *(u32 *)(fw_addr + i);
			ast_moutdwm(ast, boot_address + i, data);
		}

		/* Init SCU */
		ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);

		/* Launch FW */
		ast_moutdwm(ast, 0x1e6e2104, 0x80000000 + boot_address);
		ast_moutdwm(ast, 0x1e6e2100, 1);

		/* Update Scratch */
		data = ast_mindwm(ast, 0x1e6e2040) & 0xfffff1ff;		/* D[11:9] = 100b: UEFI handling */
		data |= 0x800;
		ast_moutdwm(ast, 0x1e6e2040, data);

		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */
		jreg |= 0x02;
		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg);
	}
	return true;
}