/* read the header of the message */ for (i = 0; i < 4; i++) {
ret = cdn_dp_mailbox_read(dp); if (ret < 0) return ret;
header[i] = ret;
}
mbox_size = (header[2] << 8) | header[3];
if (opcode != header[0] || module_id != header[1] ||
req_size != mbox_size) { /* * If the message in mailbox is not what we want, we need to * clear the mailbox by reading its contents.
*/ for (i = 0; i < mbox_size; i++) if (cdn_dp_mailbox_read(dp) < 0) break;
/* check the keep alive register to make sure fw working */
ret = readx_poll_timeout(readl, dp->regs + KEEP_ALIVE,
reg, reg, 2000, FW_ALIVE_TIMEOUT_US); if (ret < 0) {
DRM_DEV_ERROR(dp->dev, "failed to loaded the FW reg = %x\n",
reg); return -EINVAL;
}
int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
{
u8 msg; int ret;
msg = !!active;
ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO, sizeof(msg), &msg); if (ret)
DRM_DEV_ERROR(dp->dev, "set video status failed: %d\n", ret);
ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); if (ret) goto err_config_video;
ret = cdn_dp_reg_write(dp, HSYNC2VSYNC_POL_CTRL, 0); if (ret) goto err_config_video;
/* * get a best tu_size and valid symbol: * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set * TU += 2 and repeat 2nd step.
*/ do {
tu_size_reg += 2;
symbol = (u64)tu_size_reg * mode->clock * bit_per_pix;
do_div(symbol, dp->max_lanes * link_rate * 8);
rem = do_div(symbol, 1000); if (tu_size_reg > 64) {
ret = -EINVAL;
DRM_DEV_ERROR(dp->dev, "tu error, clk:%d, lanes:%d, rate:%d\n",
mode->clock, dp->max_lanes, link_rate); goto err_config_video;
}
} while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
(rem > 850) || (rem < 100));
val = symbol + (tu_size_reg << 8);
val |= TU_CNT_RST_EN;
ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val); if (ret) goto err_config_video;
/* set the FIFO Buffer size */
val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
val /= (dp->max_lanes * link_rate);
val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
val += 2;
ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
switch (video->color_depth) { case 6:
val = BCS_6; break; case 8:
val = BCS_8; break; case 10:
val = BCS_10; break; case 12:
val = BCS_12; break; case 16:
val = BCS_16; break;
}
val += video->color_fmt << 8;
ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val); if (ret) goto err_config_video;
val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val); if (ret) goto err_config_video;
val = (mode->hsync_start - mode->hdisplay) << 16;
val |= mode->htotal - mode->hsync_end;
ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val); if (ret) goto err_config_video;
val = mode->hdisplay * bit_per_pix / 8;
ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val); if (ret) goto err_config_video;
val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val); if (ret) goto err_config_video;
val = mode->hsync_end - mode->hsync_start;
val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15);
ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val); if (ret) goto err_config_video;
val = mode->vtotal;
val |= (mode->vtotal - mode->vsync_start) << 16;
ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val); if (ret) goto err_config_video;
val = mode->vsync_end - mode->vsync_start;
val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15);
ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val); if (ret) goto err_config_video;
val = cdn_dp_get_msa_misc(video, mode);
ret = cdn_dp_reg_write(dp, MSA_MISC, val); if (ret) goto err_config_video;
ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1); if (ret) goto err_config_video;
val = mode->hsync_end - mode->hsync_start;
val |= mode->hdisplay << 16;
ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val); if (ret) goto err_config_video;
val = mode->vdisplay;
val |= (mode->vtotal - mode->vsync_start) << 16;
ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val); if (ret) goto err_config_video;
val = mode->vtotal;
ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val); if (ret) goto err_config_video;
ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0);
err_config_video: if (ret)
DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret); return ret;
}
int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio)
{ int ret;
ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0); if (ret) {
DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret); return ret;
}
val = MAX_NUM_CH(audio->channels);
val |= NUM_OF_I2S_PORTS(audio->channels);
val |= AUDIO_TYPE_LPCM;
val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
writel(val, dp->regs + SMPL2PKT_CNFG);
if (audio->sample_width == 16)
val = 0; elseif (audio->sample_width == 24)
val = 1 << 9; else
val = 2 << 9;
val |= AUDIO_CH_NUM(audio->channels);
val |= I2S_DEC_PORT_EN(i2s_port_en_val);
val |= TRANS_SMPL_WIDTH_32;
writel(val, dp->regs + AUDIO_SRC_CNFG);
for (i = 0; i < (audio->channels + 1) / 2; i++) { if (audio->sample_width == 16)
val = (0x02 << 8) | (0x02 << 20); elseif (audio->sample_width == 24)
val = (0x0b << 8) | (0x0b << 20);
val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
writel(val, dp->regs + STTS_BIT_CH(i));
}
switch (audio->sample_rate) { case 32000:
val = SAMPLING_FREQ(3) |
ORIGINAL_SAMP_FREQ(0xc); break; case 44100:
val = SAMPLING_FREQ(0) |
ORIGINAL_SAMP_FREQ(0xf); break; case 48000:
val = SAMPLING_FREQ(2) |
ORIGINAL_SAMP_FREQ(0xd); break; case 88200:
val = SAMPLING_FREQ(8) |
ORIGINAL_SAMP_FREQ(0x7); break; case 96000:
val = SAMPLING_FREQ(0xa) |
ORIGINAL_SAMP_FREQ(5); break; case 176400:
val = SAMPLING_FREQ(0xc) |
ORIGINAL_SAMP_FREQ(3); break; case 192000:
val = SAMPLING_FREQ(0xe) |
ORIGINAL_SAMP_FREQ(1); break;
}
val |= 4;
writel(val, dp->regs + COM_CH_STTS_BITS);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.