static void s3c_mfc_cmd_reset(void) { WRITEL(1, S3C_FIMV_SW_RESET); mdelay(10); WRITEL(0, S3C_FIMV_SW_RESET); WRITEL(0, S3C_FIMV_LAST_DEC); }
static MFC_ERROR_CODE s3c_mfc_set_dec_frame_buffer(s3c_mfc_inst_ctx *MfcCtx, int buf_addr, unsigned int buf_size) { unsigned int Width, Height, FrameSize, dec_dpb_addr; mfc_debug("buf_addr : 0x%08x buf_size : %d\n", buf_addr, buf_size); Width = (MfcCtx->img_width + 15)/16*16; Height = (MfcCtx->img_height + 31)/32*32; FrameSize = (Width*Height*3)>>1; mfc_debug("width : %d height : %d framesize : %d buf_size : %d MfcCtx->DPBCnt :%d\n", \ Width, Height, FrameSize, buf_size, MfcCtx->DPBCnt); if(buf_size < FrameSize*MfcCtx->totalDPBCnt){ mfc_err("MFCINST_ERR_FRM_BUF_SIZE\n"); return MFCINST_ERR_FRM_BUF_SIZE; } WRITEL(Align(buf_addr, BUF_ALIGN_UNIT), S3C_FIMV_DEC_DPB_ADR); dec_dpb_addr = READL(S3C_FIMV_DEC_DPB_ADR); WRITEL(Align(dec_dpb_addr + FrameSize*MfcCtx->DPBCnt, BUF_ALIGN_UNIT), S3C_FIMV_DPB_COMV_ADR); if((MfcCtx->MfcCodecType == MPEG4_DEC) ||(MfcCtx->MfcCodecType == MPEG2_DEC) ||(MfcCtx->MfcCodecType == XVID_DEC) ||(MfcCtx->MfcCodecType == DIVX_DEC) ) { dec_dpb_addr = READL(S3C_FIMV_DEC_DPB_ADR); WRITEL(Align(dec_dpb_addr + ((3*FrameSize*MfcCtx->DPBCnt)>>1), BUF_ALIGN_UNIT), S3C_FIMV_POST_ADR); }
static int small_writes(void) { ne_socket *sock; DECL(str, "This\nIs\nSome\nText.\n"); CALL(begin(&sock, serve_expect, &str)); WRITEL("This\n"); WRITEL("Is\n"); WRITEL("Some\n"); WRITEL("Text.\n"); return finish(sock, 1); }
int update_display_mode(struct display_controller *disp_ctrl, struct soc_nvidia_tegra132_config *config) { print_mode(config); printk(BIOS_ERR, "config: xres:yres: %d x %d\n ", config->xres, config->yres); printk(BIOS_ERR, " href_sync:vref_sync: %d x %d\n ", config->href_to_sync, config->vref_to_sync); printk(BIOS_ERR, " hsyn_width:vsyn_width: %d x %d\n ", config->hsync_width, config->vsync_width); printk(BIOS_ERR, " hfnt_porch:vfnt_porch: %d x %d\n ", config->hfront_porch, config->vfront_porch); printk(BIOS_ERR, " hbk_porch:vbk_porch: %d x %d\n ", config->hback_porch, config->vback_porch); WRITEL(0x0, &disp_ctrl->disp.disp_timing_opt); WRITEL(0x0, &disp_ctrl->disp.disp_color_ctrl); /* select win opt */ WRITEL(config->win_opt, &disp_ctrl->disp.disp_win_opt); WRITEL(config->vref_to_sync << 16 | config->href_to_sync, &disp_ctrl->disp.ref_to_sync); WRITEL(config->vsync_width << 16 | config->hsync_width, &disp_ctrl->disp.sync_width); WRITEL((config->vback_porch << 16) | config->hback_porch, &disp_ctrl->disp.back_porch); WRITEL((config->vfront_porch << 16) | config->hfront_porch, &disp_ctrl->disp.front_porch); WRITEL(config->xres | (config->yres << 16), &disp_ctrl->disp.disp_active); /** * We want to use PLLD_out0, which is PLLD / 2: * PixelClock = (PLLD / 2) / ShiftClockDiv / PixelClockDiv. * * Currently most panels work inside clock range 50MHz~100MHz, and PLLD * has some requirements to have VCO in range 500MHz~1000MHz (see * clock.c for more detail). To simplify calculation, we set * PixelClockDiv to 1 and ShiftClockDiv to 1. In future these values * may be calculated by clock_configure_plld(), to allow wider * frequency range. * * Note ShiftClockDiv is a 7.1 format value. */ const u32 shift_clock_div = 1; WRITEL((PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT) | ((shift_clock_div - 1) * 2 + 1) << SHIFT_CLK_DIVIDER_SHIFT, &disp_ctrl->disp.disp_clk_ctrl); printk(BIOS_DEBUG, "%s: PixelClock=%u, ShiftClockDiv=%u\n", __func__, config->pixel_clock, shift_clock_div); return 0; }
static int mfc_resume(struct platform_device *pdev) { int ret = 0; unsigned int mc_status; #if ENABLE_MONITORING_MFC_DD mfc_info("mfc_resume......#1\n"); #endif mutex_lock(&mfc_mutex); if (!mfc_is_running()) { #if ENABLE_MONITORING_MFC_DD mfc_info("mfc_resume......#2-0\n"); #endif mutex_unlock(&mfc_mutex); return 0; } #if ENABLE_MONITORING_MFC_DD mfc_info("mfc_resume......#2-1\n"); #endif #if Frame_Base_Power_CTR_ON clk_enable(mfc_clk); #endif /* * 1. MFC reset */ do { mc_status = READL(MFC_MC_STATUS); } while(mc_status != 0); mfc_cmd_reset(); WRITEL(mfc_port0_base_paddr, MFC_MC_DRAMBASE_ADDR_A); WRITEL(mfc_port1_base_paddr, MFC_MC_DRAMBASE_ADDR_B); WRITEL(1, MFC_NUM_MASTER); ret = mfc_set_wakeup(); if(ret != MFCINST_RET_OK){ mutex_unlock(&mfc_mutex); return ret; } #if Frame_Base_Power_CTR_ON clk_disable(mfc_clk); #endif mutex_unlock(&mfc_mutex); return 0; }
static MFC_ERROR_CODE s3c_mfc_set_dec_stream_buffer(int buf_addr, unsigned int buf_size) { mfc_debug("buf_addr : 0x%08x buf_size : %d\n", buf_addr, buf_size); WRITEL(buf_addr & 0xfffffff8, S3C_FIMV_EXT_BUF_START_ADDR); WRITEL(buf_addr + buf_size + 0x200, S3C_FIMV_EXT_BUF_END_ADDR); WRITEL(buf_addr + buf_size + 0x200, S3C_FIMV_HOST_PTR); WRITEL(8 - (buf_addr & 0x7), S3C_FIMV_START_BYTE_NUM); WRITEL(buf_size, S3C_FIMV_DEC_UNIT_SIZE); return MFCINST_RET_OK; }
static void tegra_dc_sor_enable_dc(struct tegra_dc_sor_data *sor) { struct tegra_dc *dc = sor->dc; struct display_controller *disp_ctrl = (void *)dc->base; u32 reg_val = READL(&disp_ctrl->cmd.state_access); WRITEL(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access); WRITEL(VSYNC_H_POSITION(1), &disp_ctrl->disp.disp_timing_opt); /* Enable DC now - otherwise pure text console may not show. */ WRITEL(DISP_CTRL_MODE_C_DISPLAY, &disp_ctrl->cmd.disp_cmd); WRITEL(reg_val, &disp_ctrl->cmd.state_access); }
static int blocking(void) { ne_socket *sock; int ret; CALL(begin(&sock, echo_server, NULL)); CALL(expect_block_timeout(sock, 1, "with non-zero timeout")); WRITEL("Hello, world.\n"); /* poll for data */ do { ret = ne_sock_block(sock, 1); } while (ret == NE_SOCK_TIMEOUT); ONV(ret != 0, ("ne_sock_block never got data: %d", ret)); PEEK("Hello,"); ret = ne_sock_block(sock, 1); ONV(ret != 0, ("ne_sock_block failed after peek: %d", ret)); LINE("Hello, world.\n"); return finish(sock, 0); }
void set_gpio_output(u32 gpio_num, u8 set_value) { u32 gpio_base_id = gpio_num / 32; u32 gpio_offset = gpio_num % 32; u32 write_address = gpio_base_addresses[gpio_base_id]; // error validation if (!is_valid_gpio_number(gpio_num)) { return; } // get basic gpio info gpio_base_id = gpio_num / 32; gpio_offset = gpio_num % 32; // get appropriate write address to set/clear data out write_address = gpio_base_addresses[gpio_base_id]; if (set_value == 0x00) { write_address += OMAP4_GPIO_CLEARDATAOUT; } else { write_address += OMAP4_GPIO_SETDATAOUT; } // send command WRITEL((u32)(1 << gpio_offset), write_address); }
irqreturn_t mfc_irq(int irq, void *dev_id) { unsigned int int_reason; unsigned int err_status; int_reason = READL(MFC_RISC2HOST_COMMAND) & 0x1FFFF; err_status = READL(MFC_RISC2HOST_ARG2); mfc_disp_err_status = err_status >> 16; mfc_dec_err_status = err_status & 0xFFFF; mfc_debug_L0("mfc_irq() : Interrupt !! : %d\n", int_reason); if( ((int_reason & R2H_CMD_EMPTY) == R2H_CMD_EMPTY) || ((int_reason & R2H_CMD_OPEN_INSTANCE_RET) == R2H_CMD_OPEN_INSTANCE_RET) || ((int_reason & R2H_CMD_CLOSE_INSTANCE_RET) == R2H_CMD_CLOSE_INSTANCE_RET) || ((int_reason & R2H_CMD_ERROR_RET) == R2H_CMD_ERROR_RET) || ((int_reason & R2H_CMD_SEQ_DONE_RET) == R2H_CMD_SEQ_DONE_RET) || ((int_reason & R2H_CMD_FRAME_DONE_RET) == R2H_CMD_FRAME_DONE_RET) || ((int_reason & R2H_CMD_SLICE_DONE_RET) == R2H_CMD_SLICE_DONE_RET) || ((int_reason & R2H_CMD_ENC_COMPLETE_RET) == R2H_CMD_ENC_COMPLETE_RET) || ((int_reason & R2H_CMD_SYS_INIT_RET) == R2H_CMD_SYS_INIT_RET) || ((int_reason & R2H_CMD_FW_STATUS_RET) == R2H_CMD_FW_STATUS_RET) || ((int_reason & R2H_CMD_SLEEP_RET) == R2H_CMD_SLEEP_RET) || ((int_reason & R2H_CMD_WAKEUP_RET) == R2H_CMD_WAKEUP_RET) || ((int_reason & R2H_CMD_FLUSH_COMMAND_RET) == R2H_CMD_FLUSH_COMMAND_RET) || ((int_reason & R2H_CMD_CMD_ABORT_RET) == R2H_CMD_CMD_ABORT_RET) || ((int_reason & R2H_CMD_CMD_BATCH_ENC_RET) == R2H_CMD_CMD_BATCH_ENC_RET) || ((int_reason & R2H_CMD_INIT_BUFFERS_RET) == R2H_CMD_INIT_BUFFERS_RET) || ((int_reason & R2H_CMD_EDFU_INT_RET) == R2H_CMD_EDFU_INT_RET) || ((int_reason & R2H_CMD_DECODE_ERR_RET) == R2H_CMD_DECODE_ERR_RET)) { mfc_int_type = int_reason; wake_up_interruptible(&mfc_wait_queue); } else mfc_info("Strange Interrupt !! : %d\n", int_reason); WRITEL(0, MFC_RISC_HOST_INT); WRITEL(0, MFC_RISC2HOST_COMMAND); WRITEL(0xffff, MFC_SI_RTN_CHID); return IRQ_HANDLED; }
static int mfc_resume(struct platform_device *pdev) { int ret = 0; unsigned int mc_status; mutex_lock(&mfc_mutex); if (!mfc_is_running()) { mutex_unlock(&mfc_mutex); return 0; } clk_enable(mfc_sclk); /* * 1. MFC reset */ do { mc_status = READL(MFC_MC_STATUS); } while (mc_status != 0); if (mfc_cmd_reset() == false) { clk_disable(mfc_sclk); mutex_unlock(&mfc_mutex); mfc_err("MFCINST_ERR_INIT_FAIL\n"); return MFCINST_ERR_INIT_FAIL; } WRITEL(mfc_port0_base_paddr, MFC_MC_DRAMBASE_ADDR_A); WRITEL(mfc_port1_base_paddr, MFC_MC_DRAMBASE_ADDR_B); WRITEL(1, MFC_NUM_MASTER); ret = mfc_set_wakeup(); if (ret != MFCINST_RET_OK) { clk_disable(mfc_sclk); mutex_unlock(&mfc_mutex); return ret; } clk_disable(mfc_sclk); mutex_unlock(&mfc_mutex); return 0; }
void update_display_shift_clock_divider(struct display_controller *disp_ctrl, u32 shift_clock_div) { WRITEL((PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT) | (shift_clock_div & 0xff) << SHIFT_CLK_DIVIDER_SHIFT, &disp_ctrl->disp.disp_clk_ctrl); printk(BIOS_DEBUG, "%s: ShiftClockDiv=%u\n", __func__, shift_clock_div); }
static void tegra_dc_sor_io_set_dpd(struct tegra_dc_sor_data *sor, int up) { u32 reg_val; void *pmc_base = sor->pmc_base; if (up) { WRITEL(APBDEV_PMC_DPD_SAMPLE_ON_ENABLE, pmc_base + APBDEV_PMC_DPD_SAMPLE); WRITEL(10, pmc_base + APBDEV_PMC_SEL_DPD_TIM); } reg_val = READL(pmc_base + APBDEV_PMC_IO_DPD2_REQ); reg_val &= ~(APBDEV_PMC_IO_DPD2_REQ_LVDS_ON || APBDEV_PMC_IO_DPD2_REQ_CODE_DEFAULT_MASK); reg_val = up ? APBDEV_PMC_IO_DPD2_REQ_LVDS_ON | APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_OFF : APBDEV_PMC_IO_DPD2_REQ_LVDS_OFF | APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_ON; WRITEL(reg_val, pmc_base + APBDEV_PMC_IO_DPD2_REQ); /* Polling */ u32 temp = 10*1000; do { udelay(20); reg_val = READL(pmc_base + APBDEV_PMC_IO_DPD2_STATUS); if (temp > 20) temp -= 20; else break; } while ((reg_val & APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON) != 0); if ((reg_val & APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON) != 0) printk(BIOS_ERR, "PMC_IO_DPD2 polling failed (0x%x)\n", reg_val); if (up) WRITEL(APBDEV_PMC_DPD_SAMPLE_ON_DISABLE, pmc_base + APBDEV_PMC_DPD_SAMPLE); }
u32 get_gpio_value(u32 gpio_num) { u32 gpio_base_id = gpio_num / 32; u32 gpio_offset = gpio_num % 32; u32 read_address = gpio_base_addresses[gpio_base_id]; u32 value = 0; // error validation if (!is_valid_gpio_number(gpio_num)) { printf("Error, invalid gpio number\n"); return 0; } read_address += OMAP4_GPIO_DATAIN; value = READL(read_address); value = value >> gpio_offset; value &= 1; #if 0 printf("GPIO_DATAIN 0x%x\n", READL(0x4a310138)); printf("GPIO_IRQSTATUS 0x%x\n", READL(0x4a310020)); printf("GPIO_IRQSTATUS 0x%x\n", READL(0x4a31002c)); printf("GPIO_CONTROL 0x%x\n", READL(0x4a310010)); if (once){ volatile u8 reg = READL(0x4a310010); //enable wakeup pin reg |= (1 << 2); WRITEL(reg, 0x4a310010); reg = READL(0x4a310044); //enable wakeup pin reg |= (1 << 2); WRITEL(reg, 0x4a310044); once = 0; } #endif return value; }
/* Set display buffer through shared memory at INIT_BUFFER */ int hevc_set_dec_stride_buffer(struct hevc_ctx *ctx, struct list_head *buf_queue) { struct hevc_dev *dev = ctx->dev; int i; for (i = 0; i < ctx->raw_buf.num_planes; i++) { WRITEL(ctx->raw_buf.stride[i], HEVC_D_FIRST_PLANE_DPB_STRIDE_SIZE + (i * 4)); hevc_debug(2, "# plane%d.size = %d, stride = %d\n", i, ctx->raw_buf.plane_size[i], ctx->raw_buf.stride[i]); } return 0; }
int update_display_mode(struct display_controller *disp_ctrl, struct soc_nvidia_tegra132_config *config) { print_mode(config); printk(BIOS_ERR, "config: xres:yres: %d x %d\n ", config->xres, config->yres); printk(BIOS_ERR, " href_sync:vref_sync: %d x %d\n ", config->href_to_sync, config->vref_to_sync); printk(BIOS_ERR, " hsyn_width:vsyn_width: %d x %d\n ", config->hsync_width, config->vsync_width); printk(BIOS_ERR, " hfnt_porch:vfnt_porch: %d x %d\n ", config->hfront_porch, config->vfront_porch); printk(BIOS_ERR, " hbk_porch:vbk_porch: %d x %d\n ", config->hback_porch, config->vback_porch); WRITEL(0x0, &disp_ctrl->disp.disp_timing_opt); WRITEL(0x0, &disp_ctrl->disp.disp_color_ctrl); /* select win opt */ WRITEL(config->win_opt, &disp_ctrl->disp.disp_win_opt); WRITEL(config->vref_to_sync << 16 | config->href_to_sync, &disp_ctrl->disp.ref_to_sync); WRITEL(config->vsync_width << 16 | config->hsync_width, &disp_ctrl->disp.sync_width); WRITEL((config->vback_porch << 16) | config->hback_porch, &disp_ctrl->disp.back_porch); WRITEL((config->vfront_porch << 16) | config->hfront_porch, &disp_ctrl->disp.front_porch); WRITEL(config->xres | (config->yres << 16), &disp_ctrl->disp.disp_active); /* * PixelClock = (PLLD / 2) / ShiftClockDiv / PixelClockDiv. * * default: Set both shift_clk_div and pixel_clock_div to 1 */ update_display_shift_clock_divider(disp_ctrl, SHIFT_CLK_DIVIDER(1)); return 0; }
/* Set registers for decoding stream buffer */ int hevc_set_dec_stream_buffer(struct hevc_ctx *ctx, dma_addr_t buf_addr, unsigned int start_num_byte, unsigned int strm_size) { struct hevc_dev *dev; struct hevc_dec *dec; size_t cpb_buf_size; hevc_debug_enter(); if (!ctx) { hevc_err("no hevc context to run\n"); return -EINVAL; } dev = ctx->dev; if (!dev) { hevc_err("no hevc device to run\n"); return -EINVAL; } dec = ctx->dec_priv; if (!dec) { hevc_err("no mfc decoder to run\n"); return -EINVAL; } cpb_buf_size = ALIGN(dec->src_buf_size, HEVC_NV12M_HALIGN); hevc_debug(2, "inst_no: %d, buf_addr: 0x%x\n", ctx->inst_no, buf_addr); hevc_debug(2, "strm_size: 0x%08x cpb_buf_size: 0x%x\n", strm_size, cpb_buf_size); WRITEL(strm_size, HEVC_D_STREAM_DATA_SIZE); WRITEL(buf_addr, HEVC_D_CPB_BUFFER_ADDR); WRITEL(cpb_buf_size, HEVC_D_CPB_BUFFER_SIZE); WRITEL(start_num_byte, HEVC_D_CPB_BUFFER_OFFSET); hevc_debug_leave(); return 0; }
static int hevc_set_dynamic_dpb(struct hevc_ctx *ctx, struct hevc_buf *dst_vb) { struct hevc_dev *dev = ctx->dev; struct hevc_dec *dec = ctx->dec_priv; struct hevc_raw_info *raw = &ctx->raw_buf; int dst_index; int i; dst_index = dst_vb->vb.v4l2_buf.index; dec->dynamic_set = 1 << dst_index; dst_vb->used = 1; set_bit(dst_index, &dec->dpb_status); hevc_debug(2, "ADDING Flag after: %lx\n", dec->dpb_status); hevc_debug(2, "Dst addr [%d] = 0x%x\n", dst_index, dst_vb->planes.raw[0]); for (i = 0; i < raw->num_planes; i++) { WRITEL(raw->plane_size[i], HEVC_D_FIRST_PLANE_DPB_SIZE + i*4); WRITEL(dst_vb->planes.raw[i], HEVC_D_FIRST_PLANE_DPB0 + (i*0x100 + dst_index*4)); } return 0; }
/* Decode a single frame */ int hevc_decode_one_frame(struct hevc_ctx *ctx, int last_frame) { struct hevc_dev *dev; struct hevc_dec *dec; if (!ctx) { hevc_err("no hevc context to run\n"); return -EINVAL; } dev = ctx->dev; if (!dev) { hevc_err("no hevc device to run\n"); return -EINVAL; } dec = ctx->dec_priv; if (!dec) { hevc_err("no hevc decoder to run\n"); return -EINVAL; } hevc_debug(2, "Setting flags to %08lx (free:%d WTF:%d)\n", dec->dpb_status, ctx->dst_queue_cnt, dec->dpb_queue_cnt); if (dec->is_dynamic_dpb) { hevc_debug(2, "Dynamic:0x%08x, Available:0x%08lx\n", dec->dynamic_set, dec->dpb_status); WRITEL(dec->dynamic_set, HEVC_D_DYNAMIC_DPB_FLAG_LOWER); WRITEL(0x0, HEVC_D_DYNAMIC_DPB_FLAG_UPPER); } WRITEL(dec->dpb_status, HEVC_D_AVAILABLE_DPB_FLAG_LOWER); WRITEL(0x0, HEVC_D_AVAILABLE_DPB_FLAG_UPPER); WRITEL(dec->slice_enable, HEVC_D_SLICE_IF_ENABLE); hevc_debug(2, "dec->slice_enable : %d\n", dec->slice_enable); hevc_debug(2, "inst_no : %d last_frame : %d\n", ctx->inst_no, last_frame); WRITEL(ctx->inst_no, HEVC_INSTANCE_ID); /* Issue different commands to instance basing on whether it * is the last frame or not. */ switch (last_frame) { case 0: hevc_cmd_host2risc(HEVC_CH_FRAME_START, NULL); break; case 1: hevc_cmd_host2risc(HEVC_CH_LAST_FRAME, NULL); break; } hevc_debug(2, "Decoding a usual frame.\n"); return 0; }
void configure_gpio_output(u32 gpio_num) { u32 gpio_base_id = 0; u32 gpio_offset = 0; u32 gpio_oe_address = 0; u32 oe_val = 0; // error validation if (!is_valid_gpio_number(gpio_num)) { return; } // get basic gpio info gpio_base_id = gpio_num / 32; gpio_offset = gpio_num % 32; gpio_oe_address = gpio_base_addresses[gpio_base_id] + OMAP4_GPIO_OE; // read current value , mask in our single bit, then write oe_val = READL(gpio_oe_address); oe_val &= ~(1 << gpio_offset); WRITEL(oe_val, gpio_oe_address); }
static void s3c_mfc_cmd_frame_start(void) { WRITEL(1, S3C_FIMV_FRAME_START); }
/* this is really aimed at the lcd panel. That said, there are two display * devices on this part and we may someday want to extend it for other boards. */ void display_startup(device_t dev) { struct soc_nvidia_tegra124_config *config = dev->chip_info; struct display_controller *disp_ctrl = (void *)config->display_controller; struct pwm_controller *pwm = (void *)TEGRA_PWM_BASE; struct tegra_dc *dc = &dc_data; u32 plld_rate; /* init dc */ dc->base = (void *)TEGRA_ARM_DISPLAYA; dc->config = config; config->dc_data = dc; /* Note dp_init may read EDID and change some config values. */ dp_init(config); /* should probably just make it all MiB ... in future */ u32 framebuffer_size_mb = config->framebuffer_size / MiB; u32 framebuffer_base_mb= config->framebuffer_base / MiB; /* light it all up */ /* This one may have been done in romstage but that's ok for now. */ if (config->panel_vdd_gpio){ gpio_output(config->panel_vdd_gpio, 1); printk(BIOS_SPEW,"%s: panel_vdd setting gpio %08x to %d\n", __func__, config->panel_vdd_gpio, 1); } udelay(config->vdd_delay_ms * 1000); if (config->backlight_vdd_gpio){ gpio_output(config->backlight_vdd_gpio, 1); printk(BIOS_SPEW,"%s: backlight vdd setting gpio %08x to %d\n", __func__, config->backlight_vdd_gpio, 1); } if (config->lvds_shutdown_gpio){ gpio_output(config->lvds_shutdown_gpio, 0); printk(BIOS_SPEW,"%s: lvds shutdown setting gpio %08x to %d\n", __func__, config->lvds_shutdown_gpio, 0); } if (framebuffer_size_mb == 0){ framebuffer_size_mb = ALIGN_UP(config->xres * config->yres * (config->framebuffer_bits_per_pixel / 8), MiB)/MiB; } if (! framebuffer_base_mb) framebuffer_base_mb = fb_base_mb(); config->framebuffer_size = framebuffer_size_mb * MiB; config->framebuffer_base = framebuffer_base_mb * MiB; mmu_config_range(framebuffer_base_mb, framebuffer_size_mb, config->cache_policy); printk(BIOS_SPEW, "LCD frame buffer at %dMiB to %dMiB\n", framebuffer_base_mb, framebuffer_base_mb + framebuffer_size_mb); /* GPIO magic here if needed to start powering up things. You * really only want to enable vdd, wait a bit, and then enable * the panel. However ... the timings in the tegra20 dts make * no sense to me. I'm pretty sure they're wrong. * The panel_vdd is done in the romstage, so we need only * light things up here once we're sure it's all working. */ /* The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the * update_display_mode() for detail. */ plld_rate = clock_display(config->pixel_clock * 2); if (plld_rate == 0) { printk(BIOS_ERR, "dc: clock init failed\n"); return; } else if (plld_rate != config->pixel_clock * 2) { printk(BIOS_WARNING, "dc: plld rounded to %u\n", plld_rate); config->pixel_clock = plld_rate / 2; } /* Init dc */ if (tegra_dc_init(disp_ctrl)) { printk(BIOS_ERR, "dc: init failed\n"); return; } /* Configure dc mode */ if (update_display_mode(disp_ctrl, config)) { printk(BIOS_ERR, "dc: failed to configure display mode.\n"); return; } /* Enable dp */ dp_enable(dc->out); /* Init frame buffer */ memset((void *)(framebuffer_base_mb*MiB), 0x00, framebuffer_size_mb*MiB); update_window(disp_ctrl, config); /* Set up Tegra PWM n (where n is specified in config->pwm) to drive the * panel backlight. */ printk(BIOS_SPEW, "%s: enable panel backlight pwm\n", __func__); WRITEL(((1 << NV_PWM_CSR_ENABLE_SHIFT) | (220 << NV_PWM_CSR_PULSE_WIDTH_SHIFT) | /* 220/256 */ 0x02e), /* frequency divider */ &pwm->pwm[config->pwm].csr); udelay(config->pwm_to_bl_delay_ms * 1000); if (config->backlight_en_gpio){ gpio_output(config->backlight_en_gpio, 1); printk(BIOS_SPEW,"%s: backlight enable setting gpio %08x to %d\n", __func__, config->backlight_en_gpio, 1); } printk(BIOS_INFO, "%s: display init done.\n", __func__); /* tell depthcharge ... */ struct edid edid; edid.bytes_per_line = ((config->xres * config->framebuffer_bits_per_pixel / 8 + 31) / 32 * 32); edid.x_resolution = edid.bytes_per_line / (config->framebuffer_bits_per_pixel / 8); edid.y_resolution = config->yres; edid.framebuffer_bits_per_pixel = config->framebuffer_bits_per_pixel; set_vbe_mode_info_valid(&edid, (uintptr_t)(framebuffer_base_mb*MiB)); }
static int tegra_dc_init(struct display_controller *disp_ctrl) { /* do not accept interrupts during initialization */ WRITEL(0x00000000, &disp_ctrl->cmd.int_mask); WRITEL(WRITE_MUX_ASSEMBLY | READ_MUX_ASSEMBLY, &disp_ctrl->cmd.state_access); WRITEL(WINDOW_A_SELECT, &disp_ctrl->cmd.disp_win_header); WRITEL(0x00000000, &disp_ctrl->win.win_opt); WRITEL(0x00000000, &disp_ctrl->win.byte_swap); WRITEL(0x00000000, &disp_ctrl->win.buffer_ctrl); WRITEL(0x00000000, &disp_ctrl->win.pos); WRITEL(0x00000000, &disp_ctrl->win.h_initial_dda); WRITEL(0x00000000, &disp_ctrl->win.v_initial_dda); WRITEL(0x00000000, &disp_ctrl->win.dda_increment); WRITEL(0x00000000, &disp_ctrl->win.dv_ctrl); WRITEL(0x01000000, &disp_ctrl->win.blend_layer_ctrl); WRITEL(0x00000000, &disp_ctrl->win.blend_match_select); WRITEL(0x00000000, &disp_ctrl->win.blend_nomatch_select); WRITEL(0x00000000, &disp_ctrl->win.blend_alpha_1bit); WRITEL(0x00000000, &disp_ctrl->winbuf.start_addr_hi); WRITEL(0x00000000, &disp_ctrl->winbuf.addr_h_offset); WRITEL(0x00000000, &disp_ctrl->winbuf.addr_v_offset); WRITEL(0x00000000, &disp_ctrl->com.crc_checksum); WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[0]); WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[1]); WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[2]); WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[3]); WRITEL(0x00000000, &disp_ctrl->disp.disp_signal_opt0); return 0; }
static void update_window(struct display_controller *disp_ctrl, struct soc_nvidia_tegra124_config *config) { u32 val; WRITEL(WINDOW_A_SELECT, &disp_ctrl->cmd.disp_win_header); WRITEL(((config->yres << 16) | config->xres), &disp_ctrl->win.size); WRITEL(((config->yres << 16) | (config->xres * config->framebuffer_bits_per_pixel / 8)), &disp_ctrl->win.prescaled_size); WRITEL(((config->xres * config->framebuffer_bits_per_pixel / 8 + 31) / 32 * 32), &disp_ctrl->win.line_stride); WRITEL(config->color_depth, &disp_ctrl->win.color_depth); WRITEL(config->framebuffer_base, &disp_ctrl->winbuf.start_addr); WRITEL((V_DDA_INC(0x1000) | H_DDA_INC(0x1000)), &disp_ctrl->win.dda_increment); WRITEL(COLOR_WHITE, &disp_ctrl->disp.blend_background_color); WRITEL(DISP_CTRL_MODE_C_DISPLAY, &disp_ctrl->cmd.disp_cmd); WRITEL(WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access); val = GENERAL_ACT_REQ | WIN_A_ACT_REQ; val |= GENERAL_UPDATE | WIN_A_UPDATE; WRITEL(val, &disp_ctrl->cmd.state_ctrl); // Enable win_a val = READL(&disp_ctrl->win.win_opt); WRITEL(val | WIN_ENABLE, &disp_ctrl->win.win_opt); }
/* Initialize decoding */ int hevc_init_decode(struct hevc_ctx *ctx) { struct hevc_dev *dev; struct hevc_dec *dec; unsigned int reg = 0, pix_val; int fmo_aso_ctrl = 0; hevc_debug_enter(); if (!ctx) { hevc_err("no hevc context to run\n"); return -EINVAL; } dev = ctx->dev; if (!dev) { hevc_err("no hevc device to run\n"); return -EINVAL; } dec = ctx->dec_priv; if (!dec) { hevc_err("no hevc decoder to run\n"); return -EINVAL; } hevc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, HEVC_CH_SEQ_HEADER); hevc_debug(2, "BUFs: %08x %08x %08x\n", READL(HEVC_D_CPB_BUFFER_ADDR), READL(HEVC_D_CPB_BUFFER_ADDR), READL(HEVC_D_CPB_BUFFER_ADDR)); reg |= (dec->idr_decoding << HEVC_D_OPT_IDR_DECODING_SHFT); /* FMO_ASO_CTRL - 0: Enable, 1: Disable */ reg |= (fmo_aso_ctrl << HEVC_D_OPT_FMO_ASO_CTRL_MASK); /* When user sets desplay_delay to 0, * It works as "display_delay enable" and delay set to 0. * If user wants display_delay disable, It should be * set to negative value. */ if (dec->display_delay >= 0) { reg |= (0x1 << HEVC_D_OPT_DDELAY_EN_SHIFT); WRITEL(dec->display_delay, HEVC_D_DISPLAY_DELAY); } if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) reg |= (0x1 << HEVC_D_OPT_TILE_MODE_SHIFT); hevc_debug(2, "HEVC_D_DEC_OPTIONS : 0x%x\n", reg); WRITEL(0x20, HEVC_D_DEC_OPTIONS); switch (ctx->dst_fmt->fourcc) { case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV12MT_16X16: pix_val = 0; break; case V4L2_PIX_FMT_NV21M: pix_val = 1; break; case V4L2_PIX_FMT_YVU420M: pix_val = 2; break; case V4L2_PIX_FMT_YUV420M: pix_val = 3; break; default: pix_val = 0; break; } hevc_debug(2, "pixel format: %d\n", pix_val); WRITEL(pix_val, HEVC_PIXEL_FORMAT); /* sei parse */ reg = dec->sei_parse; hevc_debug(2, "sei parse: %d\n", dec->sei_parse); /* Enable realloc interface if SEI is enabled */ if (dec->sei_parse) reg |= (0x1 << HEVC_D_SEI_NEED_INIT_BUFFER_SHIFT); WRITEL(reg, HEVC_D_SEI_ENABLE); WRITEL(ctx->inst_no, HEVC_INSTANCE_ID); WRITEL(0xffffffff, HEVC_D_AVAILABLE_DPB_FLAG_UPPER); WRITEL(0xffffffff, HEVC_D_AVAILABLE_DPB_FLAG_LOWER); hevc_cmd_host2risc(HEVC_CH_SEQ_HEADER, NULL); hevc_debug_leave(); return 0; }
/* Set decoding frame buffer */ int hevc_set_dec_frame_buffer(struct hevc_ctx *ctx) { struct hevc_dev *dev; struct hevc_dec *dec; unsigned int i, frame_size_mv; size_t buf_addr1; int buf_size1; int align_gap; struct hevc_buf *buf; struct hevc_raw_info *raw; struct list_head *buf_queue; unsigned char *dpb_vir; int j; if (!ctx) { hevc_err("no hevc context to run\n"); return -EINVAL; } dev = ctx->dev; if (!dev) { hevc_err("no hevc device to run\n"); return -EINVAL; } dec = ctx->dec_priv; if (!dec) { hevc_err("no hevc decoder to run\n"); return -EINVAL; } raw = &ctx->raw_buf; buf_addr1 = ctx->port_a_phys; buf_size1 = ctx->port_a_size; hevc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); hevc_info("Total DPB COUNT: %d\n", dec->total_dpb_count); hevc_debug(2, "Setting display delay to %d\n", dec->display_delay); hevc_debug(2, "ctx->scratch_buf_size %d\n", ctx->scratch_buf_size); WRITEL(dec->total_dpb_count, HEVC_D_NUM_DPB); hevc_debug(2, "raw->num_planes %d\n", raw->num_planes); for (i = 0; i < raw->num_planes; i++) { hevc_debug(2, "raw->plane_size[%d]= %d\n", i, raw->plane_size[i]); WRITEL(raw->plane_size[i], HEVC_D_FIRST_PLANE_DPB_SIZE + i*4); } if (dec->is_dynamic_dpb) WRITEL((0x1 << HEVC_D_OPT_DYNAMIC_DPB_SET_SHIFT), HEVC_D_INIT_BUFFER_OPTIONS); WRITEL(buf_addr1, HEVC_D_SCRATCH_BUFFER_ADDR); WRITEL(ctx->scratch_buf_size, HEVC_D_SCRATCH_BUFFER_SIZE); buf_addr1 += ctx->scratch_buf_size; buf_size1 -= ctx->scratch_buf_size; WRITEL(ctx->mv_size, HEVC_D_MV_BUFFER_SIZE); frame_size_mv = ctx->mv_size; hevc_debug(2, "Frame size: %d, %d, %d, mv: %d\n", raw->plane_size[0], raw->plane_size[1], raw->plane_size[2], frame_size_mv); if (dec->dst_memtype == V4L2_MEMORY_USERPTR || dec->dst_memtype == V4L2_MEMORY_DMABUF) buf_queue = &ctx->dst_queue; else buf_queue = &dec->dpb_queue; i = 0; list_for_each_entry(buf, buf_queue, list) { /* Do not setting DPB */ if (dec->is_dynamic_dpb) break; for (j = 0; j < raw->num_planes; j++) { hevc_debug(2, "buf->planes.raw[%d] = 0x%x\n", j, buf->planes.raw[j]); WRITEL(buf->planes.raw[j], HEVC_D_FIRST_PLANE_DPB0 + (j*0x100 + i*4)); } if ((i == 0) && (!ctx->is_drm)) { int j, color[3] = { 0x0, 0x80, 0x80 }; for (j = 0; j < raw->num_planes; j++) { dpb_vir = vb2_plane_vaddr(&buf->vb, j); if (dpb_vir) memset(dpb_vir, color[j], raw->plane_size[j]); } hevc_mem_clean_vb(&buf->vb, j); } i++; } hevc_set_dec_stride_buffer(ctx, buf_queue); WRITEL(dec->mv_count, HEVC_D_NUM_MV); for (i = 0; i < dec->mv_count; i++) { /* To test alignment */ align_gap = buf_addr1; buf_addr1 = ALIGN(buf_addr1, 16); align_gap = buf_addr1 - align_gap; buf_size1 -= align_gap; hevc_debug(2, "\tBuf1: %x, size: %d\n", buf_addr1, buf_size1); WRITEL(buf_addr1, HEVC_D_MV_BUFFER0 + i * 4); buf_addr1 += frame_size_mv; buf_size1 -= frame_size_mv; } hevc_debug(2, "Buf1: %u, buf_size1: %d (frames %d)\n", buf_addr1, buf_size1, dec->total_dpb_count); if (buf_size1 < 0) { hevc_debug(2, "Not enough memory has been allocated.\n"); return -ENOMEM; } WRITEL(ctx->inst_no, HEVC_INSTANCE_ID); hevc_cmd_host2risc(HEVC_CH_INIT_BUFS, NULL); hevc_debug(2, "After setting buffers.\n"); return 0; }
static void s3c_mfc_cmd_seq_start(void) { WRITEL(1, S3C_FIMV_SEQ_START); }
static void s3c_mfc_cmd_sleep() { WRITEL(-1, S3C_FIMV_CH_ID); WRITEL(MFC_SLEEP, S3C_FIMV_COMMAND_TYPE); }
int mfc_wait_for_done(mfc_wait_done_type command) { unsigned int nwait_time = 100; unsigned int ret_val = 1; if((command == R2H_CMD_CLOSE_INSTANCE_RET) || (command == R2H_CMD_OPEN_INSTANCE_RET) || (command == R2H_CMD_FW_STATUS_RET)) nwait_time = MFC_WAIT_4_TIME; else nwait_time = MFC_WAIT_2_TIME; #if defined(MFC_REQUEST_TIME) long sec, msec; #endif #if defined(MFC_POLLING) unsigned long timeo = jiffies; timeo += 20; /* waiting for 100ms */ #endif //set_user_nice(current, -20); #if defined(MFC_REQUEST_TIME) do_gettimeofday(&mfc_wakeup_before); if (mfc_wakeup_before.tv_usec - mfc_wakeup_after.tv_usec < 0) { msec = 1000000 + mfc_wakeup_before.tv_usec - mfc_wakeup_after.tv_usec; sec = mfc_wakeup_before.tv_sec - mfc_wakeup_after.tv_sec - 1; } else { msec = mfc_wakeup_before.tv_usec - mfc_wakeup_after.tv_usec; sec = mfc_wakeup_before.tv_sec - mfc_wakeup_after.tv_sec; } #endif #if defined(MFC_POLLING) while (time_before(jiffies, timeo)) { ret_val = READL(MFC_RISC2HOST_COMMAND) & 0x1ffff; if (ret_val != 0) { WRITEL(0, MFC_RISC_HOST_INT); WRITEL(0, MFC_RISC2HOST_COMMAND); WRITEL(0xffff, MFC_SI_RTN_CHID); mfc_int_type = ret_val; break; } msleep_interruptible(2); } if (ret_val == 0) printk("MFC timeouted!\n"); #else if (interruptible_sleep_on_timeout(&mfc_wait_queue, nwait_time) == 0) { ret_val = R2H_CMD_TIMEOUT; mfc_err("Interrupt Time Out(Cmd: %d) (Ver: 0x%08x) (0x64: 0x%08x) (0xF4: 0x%08x) (0x80: 0x%08x)\n", command, READL(0x58), READL(0x64), READL(0xF4),READL(0x80)); #if ENABLE_MFC_INTERRUPT_DEBUG // For MFC Interrupt Debugging. mfc_interrupt_debug(10); #endif mfc_int_type = ret_val; return ret_val; } else if (mfc_int_type == R2H_CMD_DECODE_ERR_RET) { mfc_err("MFC Error Returned Disp Error Status(%d), Dec Error Status(%d)\n", mfc_disp_err_status, mfc_dec_err_status ); } else if (command != mfc_int_type) { mfc_err("Interrupt Error Returned (%d) waiting for (%d)\n", mfc_int_type, command); } #endif #if defined(MFC_REQUEST_TIME) do_gettimeofday(&mfc_wakeup_after); if (mfc_wakeup_after.tv_usec - mfc_wakeup_before.tv_usec < 0) { msec = 1000000 + mfc_wakeup_after.tv_usec - mfc_wakeup_before.tv_usec; sec = mfc_wakeup_after.tv_sec - mfc_wakeup_before.tv_sec - 1; } else { msec = mfc_wakeup_after.tv_usec - mfc_wakeup_before.tv_usec; sec = mfc_wakeup_after.tv_sec - mfc_wakeup_before.tv_sec; } mfc_info("mfc_wait_for_done: mfc request interval time is %ld(sec), %ld(msec)\n", sec, msec); #endif ret_val = mfc_int_type; mfc_int_type = 0; return ret_val; }
static void s3c_mfc_cmd_wakeup() { WRITEL(-1, S3C_FIMV_CH_ID); WRITEL(MFC_WAKEUP, S3C_FIMV_COMMAND_TYPE); mdelay(100); }