void dss_select_dispc_clk_source(enum omap_dsi_index ix, enum dss_clk_source clk_src) { int b; if (cpu_is_omap44xx()) { BUG_ON(clk_src != DSS_SRC_DSS1_ALWON_FCLK && clk_src != DSS_SRC_PLL1_CLK1 && clk_src != DSS_SRC_PLL2_CLK1 && clk_src != DSS_SRC_PLL3_CLK1); b = clk_src - 2; } else { BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && clk_src != DSS_SRC_DSS1_ALWON_FCLK); b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; } if (clk_src == DSS_SRC_DSI1_PLL_FCLK || clk_src == DSS_SRC_PLL1_CLK1 || clk_src == DSS_SRC_PLL2_CLK1) dsi_wait_pll_dispc_active(ix); if (!cpu_is_omap44xx()) REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ else REG_FLD_MOD(DSS_CONTROL, b, 9, 8); /* FCK_CLK_SWITCH */ dss.dispc_clk_source = clk_src; }
void dss_sdi_enable(void) { dispc_pck_free_enable(1); /* Reset SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */ udelay(1); /* wait 2x PCLK */ /* Lock SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */ /* Waiting for PLL lock request to complete */ while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) ; /* Clearing PLL_GO bit */ REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28); /* Waiting for PLL to lock */ while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) ; dispc_lcd_enable_signal(1); /* Waiting for SDI reset to complete */ while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) ; }
void dss_select_dsi_clk_source(enum omap_dsi_index ix, enum dss_clk_source clk_src) { int b; if (cpu_is_omap44xx()) { BUG_ON((clk_src != DSS_SRC_PLL1_CLK2 && ix == DSI1) && (clk_src != DSS_SRC_PLL2_CLK2 && ix == DSI2) && clk_src != DSS_SRC_DSS1_ALWON_FCLK); } else { BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && clk_src != DSS_SRC_DSS1_ALWON_FCLK); } b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; if (clk_src == DSS_SRC_DSI2_PLL_FCLK || clk_src == DSS_SRC_PLL1_CLK2 || clk_src == DSS_SRC_PLL2_CLK2) dsi_wait_pll_dsi_active(ix); if (ix == DSI1) { REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ dss.dsi1_clk_source = clk_src; } else { REG_FLD_MOD(DSS_CONTROL, b, 10, 10); /* DSI2_CLK_SWITCH */ dss.dsi2_clk_source = clk_src; } }
int dss_init(bool skip_init) { int r; u32 rev; dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); if (!dss.base) { DSSERR("can't ioremap DSS\n"); r = -ENOMEM; goto fail0; } if (!skip_init) { /* disable LCD and DIGIT output. This seems to fix the synclost * problem that we get, if the bootloader starts the DSS and * the kernel resets it */ omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); /* We need to wait here a bit, otherwise we sometimes start to * get synclost errors, and after that only power cycle will * restore DSS functionality. I have no idea why this happens. * And we have to wait _before_ resetting the DSS, but after * enabling clocks. */ msleep(50); _omap_dss_reset(); } /* autoidle */ REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); /* Select DPLL */ REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); r = request_irq(INT_24XX_DSS_IRQ, cpu_is_omap24xx() ? dss_irq_handler_omap2 : dss_irq_handler_omap3, 0, "OMAP DSS", NULL); if (r < 0) { DSSERR("omap2 dss: request_irq failed\n"); goto fail1; } dss_save_context(); rev = dss_read_reg(DSS_REVISION); printk(KERN_INFO "OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); return 0; fail1: iounmap(dss.base); fail0: return r; }
int dss_init(void) { int r; u32 rev; dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); if (!dss.base) { DSSERR("can't ioremap DSS\n"); r = -ENOMEM; goto fail0; } /* We need to wait here a bit, otherwise we sometimes start to get * synclost errors. I believe we could wait for one framedone or * perhaps vsync interrupt, but, because dispc is not initialized yet, * we don't have access to the irq register. */ msleep(400); _omap_dss_reset(); /* autoidle */ REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); /* Select DPLL */ REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); #ifdef CONFIG_OMAP2_DSS_VENC REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ #endif r = request_irq(INT_24XX_DSS_IRQ, cpu_is_omap24xx() ? dss_irq_handler_omap2 : dss_irq_handler_omap3, 0, "OMAP DSS", NULL); if (r < 0) { DSSERR("omap2 dss: request_irq failed\n"); goto fail1; } dss_save_context(); rev = dss_read_reg(DSS_REVISION); printk(KERN_INFO "OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); return 0; fail1: iounmap(dss.base); fail0: return r; }
int dss_sdi_enable(void) { unsigned long timeout; dispc_pck_free_enable(1); /* Reset SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */ udelay(1); /* wait 2x PCLK */ /* Lock SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */ /* Waiting for PLL lock request to complete */ timeout = jiffies + msecs_to_jiffies(500); while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) { if (time_after_eq(jiffies, timeout)) { DSSERR("PLL lock request timed out\n"); goto err1; } } /* Clearing PLL_GO bit */ REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28); /* Waiting for PLL to lock */ timeout = jiffies + msecs_to_jiffies(500); while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) { if (time_after_eq(jiffies, timeout)) { DSSERR("PLL lock timed out\n"); goto err1; } } dispc_lcd_enable_signal(1); /* Waiting for SDI reset to complete */ timeout = jiffies + msecs_to_jiffies(500); while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) { if (time_after_eq(jiffies, timeout)) { DSSERR("SDI reset timed out\n"); goto err2; } } return 0; err2: dispc_lcd_enable_signal(0); err1: /* Reset SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ dispc_pck_free_enable(0); return -ETIMEDOUT; }
static void dsi_set_pipe_plane_enable_state(struct drm_device *dev, int state, int pipe) { struct drm_psb_private *dev_priv = dev->dev_private; u32 pipeconf_reg = PIPEACONF; u32 dspcntr_reg = DSPACNTR; u32 dspcntr = dev_priv->dspcntr[pipe]; u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; if (pipe) { pipeconf_reg = PIPECCONF; dspcntr_reg = DSPCCNTR; } else mipi &= (~0x03); if (state) { /*Set up pipe */ REG_WRITE(pipeconf_reg, BIT(31)); if (REG_BIT_WAIT(pipeconf_reg, 1, 30)) dev_err(&dev->pdev->dev, "%s: Pipe enable timeout\n", __func__); /*Set up display plane */ REG_WRITE(dspcntr_reg, dspcntr); } else { u32 dspbase_reg = pipe ? MDFLD_DSPCBASE : MRST_DSPABASE; /* Put DSI lanes to ULPS to disable pipe */ REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 2, 2, 1); REG_READ(MIPI_DEVICE_READY_REG(pipe)); /* posted write? */ /* LP Hold */ REG_FLD_MOD(MIPI_PORT_CONTROL(pipe), 0, 16, 16); REG_READ(MIPI_PORT_CONTROL(pipe)); /* posted write? */ /* Disable display plane */ REG_FLD_MOD(dspcntr_reg, 0, 31, 31); /* Flush the plane changes ??? posted write? */ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); REG_READ(dspbase_reg); /* Disable PIPE */ REG_FLD_MOD(pipeconf_reg, 0, 31, 31); if (REG_BIT_WAIT(pipeconf_reg, 0, 30)) dev_err(&dev->pdev->dev, "%s: Pipe disable timeout\n", __func__); if (REG_BIT_WAIT(MIPI_GEN_FIFO_STAT_REG(pipe), 1, 28)) dev_err(&dev->pdev->dev, "%s: FIFO not empty\n", __func__); } }
static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy) { static const u16 pad_cfg_list[] = { 0x0123, 0x0132, 0x0312, 0x0321, 0x0231, 0x0213, 0x1023, 0x1032, 0x3012, 0x3021, 0x2031, 0x2013, 0x1203, 0x1302, 0x3102, 0x3201, 0x2301, 0x2103, 0x1230, 0x1320, 0x3120, 0x3210, 0x2310, 0x2130, }; u16 lane_cfg = 0; int i; unsigned int lane_cfg_val; u16 pol_val = 0; for (i = 0; i < 4; ++i) lane_cfg |= phy->lane_function[i] << ((3 - i) * 4); pol_val |= phy->lane_polarity[0] << 0; pol_val |= phy->lane_polarity[1] << 3; pol_val |= phy->lane_polarity[2] << 2; pol_val |= phy->lane_polarity[3] << 1; for (i = 0; i < ARRAY_SIZE(pad_cfg_list); ++i) if (pad_cfg_list[i] == lane_cfg) break; if (WARN_ON(i == ARRAY_SIZE(pad_cfg_list))) i = 0; lane_cfg_val = i; REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, lane_cfg_val, 26, 22); REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, pol_val, 30, 27); }
int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp, struct hdmi_config *cfg) { u16 r = 0; u32 irqstatus; hdmi_wp_clear_irqenable(wp, 0xffffffff); irqstatus = hdmi_wp_get_irqstatus(wp); hdmi_wp_set_irqstatus(wp, irqstatus); r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); if (r) return r; /* * Read address 0 in order to get the SCP reset done completed * Dummy access performed to make sure reset is done */ hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL); /* * Write to phy address 0 to configure the clock * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field */ REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); /* Setup max LDO voltage */ REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); /* Write to phy address 3 to change the polarity control */ REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); r = request_threaded_irq(phy->irq, NULL, hdmi_irq_handler, IRQF_ONESHOT, "OMAP HDMI", wp); if (r) { DSSERR("HDMI IRQ request failed\n"); hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); return r; } hdmi_wp_set_irqenable(wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); return 0; }
int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk, unsigned long lfbitclk) { u8 freqout; /* * Read address 0 in order to get the SCP reset done completed * Dummy access performed to make sure reset is done */ hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL); /* * In OMAP5+, the HFBITCLK must be divided by 2 before issuing the * HDMI_PHYPWRCMD_LDOON command. */ if (phy->features->bist_ctrl) REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11); /* * If the hfbitclk != lfbitclk, it means the lfbitclk was configured * to be used for TMDS. */ if (hfbitclk != lfbitclk) freqout = 0; else if (hfbitclk / 10 < phy->features->max_phy) freqout = 1; else freqout = 2; /* * Write to phy address 0 to configure the clock * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field */ REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, freqout, 31, 30); /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); /* Setup max LDO voltage */ if (phy->features->ldo_voltage) REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); hdmi_phy_configure_lanes(phy); return 0; }
void dss_sdi_disable(void) { dispc_lcd_enable_signal(0); dispc_pck_free_enable(0); /* Reset SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ }
static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, u16 height, void (*callback)(void *data), void *data) { u32 l; int r; struct omap_video_timings timings = { .hsw = 1, .hfp = 1, .hbp = 1, .vsw = 1, .vfp = 0, .vbp = 0, .x_res = width, .y_res = height, }; /*BUG_ON(callback == 0);*/ BUG_ON(rfbi.framedone_callback != NULL); DSSDBG("rfbi_transfer_area %dx%d\n", width, height); dss_mgr_set_timings(dssdev->manager, &timings); r = dss_mgr_enable(dssdev->manager); if (r) return r; rfbi.framedone_callback = callback; rfbi.framedone_callback_data = data; rfbi_write_reg(RFBI_PIXEL_CNT, width * height); l = rfbi_read_reg(RFBI_CONTROL); l = FLD_MOD(l, 1, 0, 0); /* enable */ if (!rfbi.te_enabled) l = FLD_MOD(l, 1, 4, 4); /* ITE */ rfbi_write_reg(RFBI_CONTROL, l); return 0; } static void framedone_callback(void *data, u32 mask) { void (*callback)(void *data); DSSDBG("FRAMEDONE\n"); REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); callback = rfbi.framedone_callback; rfbi.framedone_callback = NULL; if (callback != NULL) callback(rfbi.framedone_callback_data); }
/* HDMI_CORE_VIDEO_CONFIG */ static void hdmi_core_video_config(struct hdmi_core_data *core, struct hdmi_core_video_config *cfg) { u32 r = 0; void __iomem *core_sys_base = core->base; void __iomem *core_av_base = hdmi_av_base(core); /* sys_ctrl1 default configuration not tunable */ r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1); r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC, 5, 5); r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC, 4, 4); r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS, 2, 2); r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE, 1, 1); hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1, r); REG_FLD_MOD(core_sys_base, HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6); /* Vid_Mode */ r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE); /* dither truncation configuration */ if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) { r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6); r = FLD_MOD(r, 1, 5, 5); } else { r = FLD_MOD(r, cfg->op_dither_truc, 7, 6); r = FLD_MOD(r, 0, 5, 5); } hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r); /* HDMI_Ctrl */ r = hdmi_read_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL); r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6); r = FLD_MOD(r, cfg->pkt_mode, 5, 3); r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0); hdmi_write_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL, r); /* TMDS_CTRL */ REG_FLD_MOD(core_sys_base, HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); }
void dss_sdi_init(int datapairs) { u32 l; BUG_ON(datapairs > 3 || datapairs < 1); l = dss_read_reg(DSS_SDI_CONTROL); l = FLD_MOD(l, 0xf, 19, 15); /* SDI_PDIV */ l = FLD_MOD(l, datapairs-1, 3, 2); /* SDI_PRSEL */ l = FLD_MOD(l, 2, 1, 0); /* SDI_BWSEL */ dss_write_reg(DSS_SDI_CONTROL, l); l = dss_read_reg(DSS_PLL_CONTROL); l = FLD_MOD(l, 0x7, 25, 22); /* SDI_PLL_FREQSEL */ l = FLD_MOD(l, 0xb, 16, 11); /* SDI_PLL_REGN */ l = FLD_MOD(l, 0xb4, 10, 1); /* SDI_PLL_REGM */ dss_write_reg(DSS_PLL_CONTROL, l); /* Reset SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */ udelay(1); /* wait 2x PCLK */ /* Lock SDI PLL */ REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */ /* Waiting for PLL lock request to complete */ while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) ; /* Clearing PLL_GO bit */ REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28); /* Waiting for PLL to lock */ while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) ; dispc_lcd_enable_signal(1); /* Waiting for SDI reset to complete */ while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) ; }
static void hdmi_core_audio_config(struct hdmi_core_data *core, struct hdmi_core_audio_config *cfg) { u32 r; void __iomem *av_base = hdmi_av_base(core); /* * Parameters for generation of Audio Clock Recovery packets */ REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) { REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0); REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0); REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); } else {
static int hdmi_core_ddc_init(struct hdmi_core_data *core) { void __iomem *base = core->base; /* Turn on CLK for DDC */ REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0); /* IN_PROG */ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) { /* Abort transaction */ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0); /* IN_PROG */ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { DSSERR("Timeout aborting DDC transaction\n"); return -ETIMEDOUT; } } /* Clk SCL Devices */ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0); /* HDMI_CORE_DDC_STATUS_IN_PROG */ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { DSSERR("Timeout starting SCL clock\n"); return -ETIMEDOUT; } /* Clear FIFO */ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0); /* HDMI_CORE_DDC_STATUS_IN_PROG */ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { DSSERR("Timeout clearing DDC fifo\n"); return -ETIMEDOUT; } return 0; }
void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, struct hdmi_video_format *video_fmt) { u32 l = 0; REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8); l |= FLD_VAL(video_fmt->y_res, 31, 16); l |= FLD_VAL(video_fmt->x_res, 15, 0); hdmi_write_reg(wp->base, HDMI_WP_VIDEO_SIZE, l); }
void dss_select_dispc_clk_source(enum dss_clk_source clk_src) { int b; BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && clk_src != DSS_SRC_DSS1_ALWON_FCLK); b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ dss.dispc_clk_source = clk_src; }
void dss_select_dsi_clk_source(enum dss_clk_source clk_src) { int b; BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && clk_src != DSS_SRC_DSS1_ALWON_FCLK); b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ dss.dsi_clk_source = clk_src; }
void dss_select_lcd_clk_source(enum omap_dsi_index ix, enum dss_clk_source clk_src) { int b; if (!cpu_is_omap44xx()) BUG(); BUG_ON((clk_src != DSS_SRC_PLL1_CLK1 && ix == DSI1) && (clk_src != DSS_SRC_PLL2_CLK1 && ix == DSI2) && clk_src != DSS_SRC_DSS1_ALWON_FCLK); b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; if (ix == DSI1) { REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* LCD1_CLK_SWITCH */ dss.lcd1_clk_source = clk_src; } else { REG_FLD_MOD(DSS_CONTROL, b, 12, 12); /* LCD2_CLK_SWITCH */ dss.lcd2_clk_source = clk_src; } }
static void hdmi_audio_stop(struct device *dev) { struct omap_hdmi *hd = dev_get_drvdata(dev); WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); WARN_ON(!hd->display_enabled); hdmi_wp_audio_core_req_enable(&hd->wp, false); hdmi_wp_audio_enable(&hd->wp, false); /* Playback stopped, restore original idlemode */ REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2); }
static void framedone_callback(void *data) { void (*callback)(void *data); DSSDBG("FRAMEDONE\n"); REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); callback = rfbi.framedone_callback; rfbi.framedone_callback = NULL; if (callback != NULL) callback(rfbi.framedone_callback_data); }
static int read_edid(u8 *buf, int len) { int r; int idlemode; mutex_lock(&hdmi.lock); r = hdmi_runtime_get(); BUG_ON(r); idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); /* No-idle mode */ REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); r = hdmi5_read_edid(&hdmi.core, buf, len); REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2); hdmi_runtime_put(); mutex_unlock(&hdmi.lock); return r; }
void dss_set_venc_output(enum omap_dss_venc_type type) { int l = 0; if (type == OMAP_DSS_VENC_TYPE_COMPOSITE) l = 0; else if (type == OMAP_DSS_VENC_TYPE_SVIDEO) l = 1; else BUG(); /* venc out selection. 0 = comp, 1 = svideo */ REG_FLD_MOD(DSS_CONTROL, l, 6, 6); }
static int hdmi_pll_reset(struct hdmi_pll_data *pll) { /* SYSRESET controlled by power FSM */ REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3); /* READ 0x0 reset is in progress */ if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) { DSSERR("Failed to sysreset PLL\n"); return -ETIMEDOUT; } return 0; }
/* PLL_PWR_CMD */ int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val) { /* Command for power control of HDMI PLL */ REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 3, 2); /* wait till PHY_PWR_STATUS is set */ if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val) != val) { DSSERR("Failed to set PLL_PWR_STATUS\n"); return -ETIMEDOUT; } return 0; }
static int hdmi_audio_start(struct device *dev) { struct omap_hdmi *hd = dev_get_drvdata(dev); WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); WARN_ON(!hd->display_enabled); /* No-idle while playing audio, store the old value */ hd->wp_idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); hdmi_wp_audio_enable(&hd->wp, true); hdmi_wp_audio_core_req_enable(&hd->wp, true); return 0; }
static void framedone_callback(void *data, u32 mask) { void (*callback)(void *data); DSSDBG("FRAMEDONE\n"); REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); // dispc_enable_sidle(); callback = rfbi.framedone_callback; rfbi.framedone_callback = NULL; if (callback != NULL) callback(rfbi.framedone_callback_data); }
static irqreturn_t hdmi_irq_handler(int irq, void *data) { struct hdmi_wp_data *wp = data; u32 irqstatus; irqstatus = hdmi_wp_get_irqstatus(wp); hdmi_wp_set_irqstatus(wp, irqstatus); if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && irqstatus & HDMI_IRQ_LINK_DISCONNECT) { u32 v; /* * If we get both connect and disconnect interrupts at the same * time, turn off the PHY, clear interrupts, and restart, which * raises connect interrupt if a cable is connected, or nothing * if cable is not connected. */ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); /* * We always get bogus CONNECT & DISCONNECT interrupts when * setting the PHY to LDOON. To ignore those, we force the RXDET * line to 0 until the PHY power state has been changed. */ v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); } return IRQ_HANDLED; }
/* PHY_PWR_CMD */ int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val) { /* Return if already the state */ if (REG_GET(wp->base, HDMI_WP_PWR_CTRL, 5, 4) == val) return 0; /* Command for power control of HDMI PHY */ REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 7, 6); /* Status of the power control of HDMI PHY */ if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val) != val) { DSSERR("Failed to set PHY power mode to %d\n", val); return -ETIMEDOUT; } return 0; }