Merge branches '3.14/fbdev', '3.14/dss-misc' and '3.14/dss-fclk' into for-next
Merge fbdev topic branches
This commit is contained in:
Коммит
cb1fbad7ec
|
@ -346,28 +346,22 @@ static int acx565akm_get_actual_brightness(struct panel_drv_data *ddata)
|
|||
static int acx565akm_bl_update_status(struct backlight_device *dev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
|
||||
int r;
|
||||
int level;
|
||||
|
||||
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
|
||||
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
|
||||
dev->props.power == FB_BLANK_UNBLANK)
|
||||
level = dev->props.brightness;
|
||||
else
|
||||
level = 0;
|
||||
|
||||
r = 0;
|
||||
if (ddata->has_bc)
|
||||
acx565akm_set_brightness(ddata, level);
|
||||
else
|
||||
r = -ENODEV;
|
||||
return -ENODEV;
|
||||
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acx565akm_bl_get_intensity(struct backlight_device *dev)
|
||||
|
@ -390,9 +384,33 @@ static int acx565akm_bl_get_intensity(struct backlight_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acx565akm_bl_update_status_locked(struct backlight_device *dev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
r = acx565akm_bl_update_status(dev);
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int acx565akm_bl_get_intensity_locked(struct backlight_device *dev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
r = acx565akm_bl_get_intensity(dev);
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct backlight_ops acx565akm_bl_ops = {
|
||||
.get_brightness = acx565akm_bl_get_intensity,
|
||||
.update_status = acx565akm_bl_update_status,
|
||||
.get_brightness = acx565akm_bl_get_intensity_locked,
|
||||
.update_status = acx565akm_bl_update_status_locked,
|
||||
};
|
||||
|
||||
/*--------------------Auto Brightness control via Sysfs---------------------*/
|
||||
|
@ -526,8 +544,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
|
|||
struct omap_dss_device *in = ddata->in;
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
|
||||
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
|
||||
|
||||
in->ops.sdi->set_timings(in, &ddata->videomode);
|
||||
|
@ -568,8 +584,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
|
|||
set_display_state(ddata, 1);
|
||||
set_cabc_mode(ddata, ddata->cabc_mode);
|
||||
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return acx565akm_bl_update_status(ddata->bl_dev);
|
||||
}
|
||||
|
||||
|
@ -616,7 +630,9 @@ static int acx565akm_enable(struct omap_dss_device *dssdev)
|
|||
if (omapdss_device_is_enabled(dssdev))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
r = acx565akm_panel_power_on(dssdev);
|
||||
mutex_unlock(&ddata->mutex);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -149,6 +149,9 @@ static void apply_init_priv(void)
|
|||
|
||||
op = &dss_data.ovl_priv_data_array[i];
|
||||
|
||||
op->info.color_mode = OMAP_DSS_COLOR_RGB16;
|
||||
op->info.rotation_type = OMAP_DSS_ROT_DMA;
|
||||
|
||||
op->info.global_alpha = 255;
|
||||
|
||||
switch (i) {
|
||||
|
@ -629,7 +632,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
|
|||
struct mgr_priv_data *mp;
|
||||
int r;
|
||||
|
||||
DSSDBG("writing ovl %d regs", ovl->id);
|
||||
DSSDBG("writing ovl %d regs\n", ovl->id);
|
||||
|
||||
if (!op->enabled || !op->info_dirty)
|
||||
return;
|
||||
|
@ -664,7 +667,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
|
|||
struct ovl_priv_data *op = get_ovl_priv(ovl);
|
||||
struct mgr_priv_data *mp;
|
||||
|
||||
DSSDBG("writing ovl %d regs extra", ovl->id);
|
||||
DSSDBG("writing ovl %d regs extra\n", ovl->id);
|
||||
|
||||
if (!op->extra_info_dirty)
|
||||
return;
|
||||
|
@ -687,7 +690,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
|
|||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
struct omap_overlay *ovl;
|
||||
|
||||
DSSDBG("writing mgr %d regs", mgr->id);
|
||||
DSSDBG("writing mgr %d regs\n", mgr->id);
|
||||
|
||||
if (!mp->enabled)
|
||||
return;
|
||||
|
@ -713,7 +716,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
|
|||
{
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
|
||||
DSSDBG("writing mgr %d regs extra", mgr->id);
|
||||
DSSDBG("writing mgr %d regs extra\n", mgr->id);
|
||||
|
||||
if (!mp->extra_info_dirty)
|
||||
return;
|
||||
|
|
|
@ -90,6 +90,8 @@ struct dispc_features {
|
|||
|
||||
/* revert to the OMAP4 mechanism of DISPC Smart Standby operation */
|
||||
bool mstandby_workaround:1;
|
||||
|
||||
bool set_max_preload:1;
|
||||
};
|
||||
|
||||
#define DISPC_MAX_NR_FIFOS 5
|
||||
|
@ -1200,7 +1202,17 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
|
|||
dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
|
||||
FLD_VAL(high, hi_start, hi_end) |
|
||||
FLD_VAL(low, lo_start, lo_end));
|
||||
|
||||
/*
|
||||
* configure the preload to the pipeline's high threhold, if HT it's too
|
||||
* large for the preload field, set the threshold to the maximum value
|
||||
* that can be held by the preload register
|
||||
*/
|
||||
if (dss_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
|
||||
plane != OMAP_DSS_WB)
|
||||
dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));
|
||||
}
|
||||
EXPORT_SYMBOL(dispc_ovl_set_fifo_threshold);
|
||||
|
||||
void dispc_enable_fifomerge(bool enable)
|
||||
{
|
||||
|
@ -1259,6 +1271,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
|
|||
*fifo_high = total_fifo_size - buf_unit;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);
|
||||
|
||||
static void dispc_ovl_set_fir(enum omap_plane plane,
|
||||
int hinc, int vinc,
|
||||
|
@ -1988,7 +2001,8 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
|
|||
*/
|
||||
static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
|
||||
const struct omap_video_timings *t, u16 pos_x,
|
||||
u16 width, u16 height, u16 out_width, u16 out_height)
|
||||
u16 width, u16 height, u16 out_width, u16 out_height,
|
||||
bool five_taps)
|
||||
{
|
||||
const int ds = DIV_ROUND_UP(height, out_height);
|
||||
unsigned long nonactive;
|
||||
|
@ -2008,6 +2022,10 @@ static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
|
|||
if (blank <= limits[i])
|
||||
return -EINVAL;
|
||||
|
||||
/* FIXME add checks for 3-tap filter once the limitations are known */
|
||||
if (!five_taps)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Pixel data should be prepared before visible display point starts.
|
||||
* So, atleast DS-2 lines must have already been fetched by DISPC
|
||||
|
@ -2183,22 +2201,30 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
|
|||
do {
|
||||
in_height = DIV_ROUND_UP(height, *decim_y);
|
||||
in_width = DIV_ROUND_UP(width, *decim_x);
|
||||
*core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
|
||||
in_width, in_height, out_width, out_height, color_mode);
|
||||
|
||||
error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
|
||||
pos_x, in_width, in_height, out_width,
|
||||
out_height);
|
||||
*five_taps = in_height > out_height;
|
||||
|
||||
if (in_width > maxsinglelinewidth)
|
||||
if (in_height > out_height &&
|
||||
in_height < out_height * 2)
|
||||
*five_taps = false;
|
||||
if (!*five_taps)
|
||||
again:
|
||||
if (*five_taps)
|
||||
*core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
|
||||
in_width, in_height, out_width,
|
||||
out_height, color_mode);
|
||||
else
|
||||
*core_clk = dispc.feat->calc_core_clk(pclk, in_width,
|
||||
in_height, out_width, out_height,
|
||||
mem_to_mem);
|
||||
|
||||
error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
|
||||
pos_x, in_width, in_height, out_width,
|
||||
out_height, *five_taps);
|
||||
if (error && *five_taps) {
|
||||
*five_taps = false;
|
||||
goto again;
|
||||
}
|
||||
|
||||
error = (error || in_width > maxsinglelinewidth * 2 ||
|
||||
(in_width > maxsinglelinewidth && *five_taps) ||
|
||||
!*core_clk || *core_clk > dispc_core_clk_rate());
|
||||
|
@ -2215,7 +2241,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
|
|||
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
|
||||
|
||||
if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width,
|
||||
height, out_width, out_height)){
|
||||
height, out_width, out_height, *five_taps)) {
|
||||
DSSERR("horizontal timing too tight\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -3211,6 +3237,8 @@ static void dispc_dump_regs(struct seq_file *s)
|
|||
DUMPREG(DISPC_CONTROL3);
|
||||
DUMPREG(DISPC_CONFIG3);
|
||||
}
|
||||
if (dss_has_feature(FEAT_MFLAG))
|
||||
DUMPREG(DISPC_GLOBAL_MFLAG_ATTRIBUTE);
|
||||
|
||||
#undef DUMPREG
|
||||
|
||||
|
@ -3285,6 +3313,8 @@ static void dispc_dump_regs(struct seq_file *s)
|
|||
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
|
||||
if (dss_has_feature(FEAT_PRELOAD))
|
||||
DUMPREG(i, DISPC_OVL_PRELOAD);
|
||||
if (dss_has_feature(FEAT_MFLAG))
|
||||
DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
|
||||
}
|
||||
|
||||
#undef DISPC_REG
|
||||
|
@ -3520,6 +3550,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_24xx,
|
||||
.num_fifos = 3,
|
||||
.no_framedone_tv = true,
|
||||
.set_max_preload = false,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
|
||||
|
@ -3539,6 +3570,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_34xx,
|
||||
.num_fifos = 3,
|
||||
.no_framedone_tv = true,
|
||||
.set_max_preload = false,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
|
||||
|
@ -3558,6 +3590,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_34xx,
|
||||
.num_fifos = 3,
|
||||
.no_framedone_tv = true,
|
||||
.set_max_preload = false,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap44xx_dispc_feats __initconst = {
|
||||
|
@ -3577,6 +3610,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_44xx,
|
||||
.num_fifos = 5,
|
||||
.gfx_fifo_workaround = true,
|
||||
.set_max_preload = true,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap54xx_dispc_feats __initconst = {
|
||||
|
@ -3597,6 +3631,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
|
|||
.num_fifos = 5,
|
||||
.gfx_fifo_workaround = true,
|
||||
.mstandby_workaround = true,
|
||||
.set_max_preload = true,
|
||||
};
|
||||
|
||||
static int __init dispc_init_features(struct platform_device *pdev)
|
||||
|
@ -3734,6 +3769,8 @@ static int dispc_runtime_suspend(struct device *dev)
|
|||
|
||||
static int dispc_runtime_resume(struct device *dev)
|
||||
{
|
||||
_omap_dispc_initial_config();
|
||||
|
||||
dispc_restore_context();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define DISPC_CONTROL3 0x0848
|
||||
#define DISPC_CONFIG3 0x084C
|
||||
#define DISPC_MSTANDBY_CTRL 0x0858
|
||||
#define DISPC_GLOBAL_MFLAG_ATTRIBUTE 0x085C
|
||||
|
||||
/* DISPC overlay registers */
|
||||
#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
|
||||
|
@ -100,6 +101,8 @@
|
|||
DISPC_FIR_COEF_V2_OFFSET(n, i))
|
||||
#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_PRELOAD_OFFSET(n))
|
||||
#define DISPC_OVL_MFLAG_THRESHOLD(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_MFLAG_THRESHOLD_OFFSET(n))
|
||||
|
||||
/* DISPC up/downsampling FIR filter coefficient structure */
|
||||
struct dispc_coef {
|
||||
|
@ -894,4 +897,21 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0860;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0864;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0868;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x086c;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -277,7 +277,7 @@ static ssize_t display_wss_store(struct device *dev,
|
|||
return size;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL);
|
||||
static DEVICE_ATTR(display_name, S_IRUGO, display_name_show, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
|
||||
display_enabled_show, display_enabled_store);
|
||||
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
|
||||
|
@ -292,7 +292,7 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
|
|||
display_wss_show, display_wss_store);
|
||||
|
||||
static const struct attribute *display_sysfs_attrs[] = {
|
||||
&dev_attr_name.attr,
|
||||
&dev_attr_display_name.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_tear_elim.attr,
|
||||
&dev_attr_timings.attr,
|
||||
|
|
|
@ -117,7 +117,7 @@ struct dpi_clk_calc_ctx {
|
|||
/* outputs */
|
||||
|
||||
struct dsi_clock_info dsi_cinfo;
|
||||
struct dss_clock_info dss_cinfo;
|
||||
unsigned long long fck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
};
|
||||
|
||||
|
@ -184,12 +184,11 @@ static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint,
|
|||
dpi_calc_hsdiv_cb, ctx);
|
||||
}
|
||||
|
||||
static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data)
|
||||
static bool dpi_calc_dss_cb(unsigned long fck, void *data)
|
||||
{
|
||||
struct dpi_clk_calc_ctx *ctx = data;
|
||||
|
||||
ctx->dss_cinfo.fck = fck;
|
||||
ctx->dss_cinfo.fck_div = fckd;
|
||||
ctx->fck = fck;
|
||||
|
||||
return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
|
||||
dpi_calc_dispc_cb, ctx);
|
||||
|
@ -237,7 +236,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
|
|||
ctx->pck_min = 0;
|
||||
ctx->pck_max = pck + 1000 * i * i * i;
|
||||
|
||||
ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx);
|
||||
ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx);
|
||||
if (ok)
|
||||
return ok;
|
||||
}
|
||||
|
@ -286,13 +285,13 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
|
|||
if (!ok)
|
||||
return -EINVAL;
|
||||
|
||||
r = dss_set_clock_div(&ctx.dss_cinfo);
|
||||
r = dss_set_fck_rate(ctx.fck);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dpi.mgr_config.clock_info = ctx.dispc_cinfo;
|
||||
|
||||
*fck = ctx.dss_cinfo.fck;
|
||||
*fck = ctx.fck;
|
||||
*lck_div = ctx.dispc_cinfo.lck_div;
|
||||
*pck_div = ctx.dispc_cinfo.pck_div;
|
||||
|
||||
|
@ -495,7 +494,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
|
|||
if (!ok)
|
||||
return -EINVAL;
|
||||
|
||||
fck = ctx.dss_cinfo.fck;
|
||||
fck = ctx.fck;
|
||||
}
|
||||
|
||||
lck_div = ctx.dispc_cinfo.lck_div;
|
||||
|
@ -551,7 +550,8 @@ static int dpi_init_regulator(void)
|
|||
|
||||
vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi");
|
||||
if (IS_ERR(vdds_dsi)) {
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
return PTR_ERR(vdds_dsi);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,63 +47,73 @@
|
|||
|
||||
#define DSI_CATCH_MISSING_TE
|
||||
|
||||
struct dsi_reg { u16 idx; };
|
||||
struct dsi_reg { u16 module; u16 idx; };
|
||||
|
||||
#define DSI_REG(idx) ((const struct dsi_reg) { idx })
|
||||
#define DSI_REG(mod, idx) ((const struct dsi_reg) { mod, idx })
|
||||
|
||||
#define DSI_SZ_REGS SZ_1K
|
||||
/* DSI Protocol Engine */
|
||||
|
||||
#define DSI_REVISION DSI_REG(0x0000)
|
||||
#define DSI_SYSCONFIG DSI_REG(0x0010)
|
||||
#define DSI_SYSSTATUS DSI_REG(0x0014)
|
||||
#define DSI_IRQSTATUS DSI_REG(0x0018)
|
||||
#define DSI_IRQENABLE DSI_REG(0x001C)
|
||||
#define DSI_CTRL DSI_REG(0x0040)
|
||||
#define DSI_GNQ DSI_REG(0x0044)
|
||||
#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048)
|
||||
#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C)
|
||||
#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050)
|
||||
#define DSI_CLK_CTRL DSI_REG(0x0054)
|
||||
#define DSI_TIMING1 DSI_REG(0x0058)
|
||||
#define DSI_TIMING2 DSI_REG(0x005C)
|
||||
#define DSI_VM_TIMING1 DSI_REG(0x0060)
|
||||
#define DSI_VM_TIMING2 DSI_REG(0x0064)
|
||||
#define DSI_VM_TIMING3 DSI_REG(0x0068)
|
||||
#define DSI_CLK_TIMING DSI_REG(0x006C)
|
||||
#define DSI_TX_FIFO_VC_SIZE DSI_REG(0x0070)
|
||||
#define DSI_RX_FIFO_VC_SIZE DSI_REG(0x0074)
|
||||
#define DSI_COMPLEXIO_CFG2 DSI_REG(0x0078)
|
||||
#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(0x007C)
|
||||
#define DSI_VM_TIMING4 DSI_REG(0x0080)
|
||||
#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(0x0084)
|
||||
#define DSI_VM_TIMING5 DSI_REG(0x0088)
|
||||
#define DSI_VM_TIMING6 DSI_REG(0x008C)
|
||||
#define DSI_VM_TIMING7 DSI_REG(0x0090)
|
||||
#define DSI_STOPCLK_TIMING DSI_REG(0x0094)
|
||||
#define DSI_VC_CTRL(n) DSI_REG(0x0100 + (n * 0x20))
|
||||
#define DSI_VC_TE(n) DSI_REG(0x0104 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(0x0108 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(0x010C + (n * 0x20))
|
||||
#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(0x0110 + (n * 0x20))
|
||||
#define DSI_VC_IRQSTATUS(n) DSI_REG(0x0118 + (n * 0x20))
|
||||
#define DSI_VC_IRQENABLE(n) DSI_REG(0x011C + (n * 0x20))
|
||||
#define DSI_PROTO 0
|
||||
#define DSI_PROTO_SZ 0x200
|
||||
|
||||
#define DSI_REVISION DSI_REG(DSI_PROTO, 0x0000)
|
||||
#define DSI_SYSCONFIG DSI_REG(DSI_PROTO, 0x0010)
|
||||
#define DSI_SYSSTATUS DSI_REG(DSI_PROTO, 0x0014)
|
||||
#define DSI_IRQSTATUS DSI_REG(DSI_PROTO, 0x0018)
|
||||
#define DSI_IRQENABLE DSI_REG(DSI_PROTO, 0x001C)
|
||||
#define DSI_CTRL DSI_REG(DSI_PROTO, 0x0040)
|
||||
#define DSI_GNQ DSI_REG(DSI_PROTO, 0x0044)
|
||||
#define DSI_COMPLEXIO_CFG1 DSI_REG(DSI_PROTO, 0x0048)
|
||||
#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(DSI_PROTO, 0x004C)
|
||||
#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(DSI_PROTO, 0x0050)
|
||||
#define DSI_CLK_CTRL DSI_REG(DSI_PROTO, 0x0054)
|
||||
#define DSI_TIMING1 DSI_REG(DSI_PROTO, 0x0058)
|
||||
#define DSI_TIMING2 DSI_REG(DSI_PROTO, 0x005C)
|
||||
#define DSI_VM_TIMING1 DSI_REG(DSI_PROTO, 0x0060)
|
||||
#define DSI_VM_TIMING2 DSI_REG(DSI_PROTO, 0x0064)
|
||||
#define DSI_VM_TIMING3 DSI_REG(DSI_PROTO, 0x0068)
|
||||
#define DSI_CLK_TIMING DSI_REG(DSI_PROTO, 0x006C)
|
||||
#define DSI_TX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0070)
|
||||
#define DSI_RX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0074)
|
||||
#define DSI_COMPLEXIO_CFG2 DSI_REG(DSI_PROTO, 0x0078)
|
||||
#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(DSI_PROTO, 0x007C)
|
||||
#define DSI_VM_TIMING4 DSI_REG(DSI_PROTO, 0x0080)
|
||||
#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(DSI_PROTO, 0x0084)
|
||||
#define DSI_VM_TIMING5 DSI_REG(DSI_PROTO, 0x0088)
|
||||
#define DSI_VM_TIMING6 DSI_REG(DSI_PROTO, 0x008C)
|
||||
#define DSI_VM_TIMING7 DSI_REG(DSI_PROTO, 0x0090)
|
||||
#define DSI_STOPCLK_TIMING DSI_REG(DSI_PROTO, 0x0094)
|
||||
#define DSI_VC_CTRL(n) DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
|
||||
#define DSI_VC_TE(n) DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
|
||||
#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
|
||||
#define DSI_VC_IRQSTATUS(n) DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
|
||||
#define DSI_VC_IRQENABLE(n) DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
|
||||
|
||||
/* DSIPHY_SCP */
|
||||
|
||||
#define DSI_DSIPHY_CFG0 DSI_REG(0x200 + 0x0000)
|
||||
#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004)
|
||||
#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008)
|
||||
#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014)
|
||||
#define DSI_DSIPHY_CFG10 DSI_REG(0x200 + 0x0028)
|
||||
#define DSI_PHY 1
|
||||
#define DSI_PHY_OFFSET 0x200
|
||||
#define DSI_PHY_SZ 0x40
|
||||
|
||||
#define DSI_DSIPHY_CFG0 DSI_REG(DSI_PHY, 0x0000)
|
||||
#define DSI_DSIPHY_CFG1 DSI_REG(DSI_PHY, 0x0004)
|
||||
#define DSI_DSIPHY_CFG2 DSI_REG(DSI_PHY, 0x0008)
|
||||
#define DSI_DSIPHY_CFG5 DSI_REG(DSI_PHY, 0x0014)
|
||||
#define DSI_DSIPHY_CFG10 DSI_REG(DSI_PHY, 0x0028)
|
||||
|
||||
/* DSI_PLL_CTRL_SCP */
|
||||
|
||||
#define DSI_PLL_CONTROL DSI_REG(0x300 + 0x0000)
|
||||
#define DSI_PLL_STATUS DSI_REG(0x300 + 0x0004)
|
||||
#define DSI_PLL_GO DSI_REG(0x300 + 0x0008)
|
||||
#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C)
|
||||
#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010)
|
||||
#define DSI_PLL 2
|
||||
#define DSI_PLL_OFFSET 0x300
|
||||
#define DSI_PLL_SZ 0x20
|
||||
|
||||
#define DSI_PLL_CONTROL DSI_REG(DSI_PLL, 0x0000)
|
||||
#define DSI_PLL_STATUS DSI_REG(DSI_PLL, 0x0004)
|
||||
#define DSI_PLL_GO DSI_REG(DSI_PLL, 0x0008)
|
||||
#define DSI_PLL_CONFIGURATION1 DSI_REG(DSI_PLL, 0x000C)
|
||||
#define DSI_PLL_CONFIGURATION2 DSI_REG(DSI_PLL, 0x0010)
|
||||
|
||||
#define REG_GET(dsidev, idx, start, end) \
|
||||
FLD_GET(dsi_read_reg(dsidev, idx), start, end)
|
||||
|
@ -277,7 +287,9 @@ struct dsi_clk_calc_ctx {
|
|||
|
||||
struct dsi_data {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
void __iomem *proto_base;
|
||||
void __iomem *phy_base;
|
||||
void __iomem *pll_base;
|
||||
|
||||
int module_id;
|
||||
|
||||
|
@ -297,7 +309,8 @@ struct dsi_data {
|
|||
struct {
|
||||
enum dsi_vc_source source;
|
||||
struct omap_dss_device *dssdev;
|
||||
enum fifo_size fifo_size;
|
||||
enum fifo_size tx_fifo_size;
|
||||
enum fifo_size rx_fifo_size;
|
||||
int vc_id;
|
||||
} vc[4];
|
||||
|
||||
|
@ -413,16 +426,32 @@ static inline void dsi_write_reg(struct platform_device *dsidev,
|
|||
const struct dsi_reg idx, u32 val)
|
||||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
void __iomem *base;
|
||||
|
||||
__raw_writel(val, dsi->base + idx.idx);
|
||||
switch(idx.module) {
|
||||
case DSI_PROTO: base = dsi->proto_base; break;
|
||||
case DSI_PHY: base = dsi->phy_base; break;
|
||||
case DSI_PLL: base = dsi->pll_base; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
__raw_writel(val, base + idx.idx);
|
||||
}
|
||||
|
||||
static inline u32 dsi_read_reg(struct platform_device *dsidev,
|
||||
const struct dsi_reg idx)
|
||||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
void __iomem *base;
|
||||
|
||||
return __raw_readl(dsi->base + idx.idx);
|
||||
switch(idx.module) {
|
||||
case DSI_PROTO: base = dsi->proto_base; break;
|
||||
case DSI_PHY: base = dsi->phy_base; break;
|
||||
case DSI_PLL: base = dsi->pll_base; break;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
return __raw_readl(base + idx.idx);
|
||||
}
|
||||
|
||||
static void dsi_bus_lock(struct omap_dss_device *dssdev)
|
||||
|
@ -1129,7 +1158,8 @@ static int dsi_regulator_init(struct platform_device *dsidev)
|
|||
vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO");
|
||||
|
||||
if (IS_ERR(vdds_dsi)) {
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
return PTR_ERR(vdds_dsi);
|
||||
}
|
||||
|
||||
|
@ -2427,14 +2457,14 @@ static void dsi_config_tx_fifo(struct platform_device *dsidev,
|
|||
int add = 0;
|
||||
int i;
|
||||
|
||||
dsi->vc[0].fifo_size = size1;
|
||||
dsi->vc[1].fifo_size = size2;
|
||||
dsi->vc[2].fifo_size = size3;
|
||||
dsi->vc[3].fifo_size = size4;
|
||||
dsi->vc[0].tx_fifo_size = size1;
|
||||
dsi->vc[1].tx_fifo_size = size2;
|
||||
dsi->vc[2].tx_fifo_size = size3;
|
||||
dsi->vc[3].tx_fifo_size = size4;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
u8 v;
|
||||
int size = dsi->vc[i].fifo_size;
|
||||
int size = dsi->vc[i].tx_fifo_size;
|
||||
|
||||
if (add + size > 4) {
|
||||
DSSERR("Illegal FIFO configuration\n");
|
||||
|
@ -2460,14 +2490,14 @@ static void dsi_config_rx_fifo(struct platform_device *dsidev,
|
|||
int add = 0;
|
||||
int i;
|
||||
|
||||
dsi->vc[0].fifo_size = size1;
|
||||
dsi->vc[1].fifo_size = size2;
|
||||
dsi->vc[2].fifo_size = size3;
|
||||
dsi->vc[3].fifo_size = size4;
|
||||
dsi->vc[0].rx_fifo_size = size1;
|
||||
dsi->vc[1].rx_fifo_size = size2;
|
||||
dsi->vc[2].rx_fifo_size = size3;
|
||||
dsi->vc[3].rx_fifo_size = size4;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
u8 v;
|
||||
int size = dsi->vc[i].fifo_size;
|
||||
int size = dsi->vc[i].rx_fifo_size;
|
||||
|
||||
if (add + size > 4) {
|
||||
DSSERR("Illegal FIFO configuration\n");
|
||||
|
@ -2920,7 +2950,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
|
|||
DSSDBG("dsi_vc_send_long, %d bytes\n", len);
|
||||
|
||||
/* len + header */
|
||||
if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) {
|
||||
if (dsi->vc[channel].tx_fifo_size * 32 * 4 < len + 4) {
|
||||
DSSERR("unable to send long packet: packet too long.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -5345,8 +5375,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
|
|||
{
|
||||
u32 rev;
|
||||
int r, i;
|
||||
struct resource *dsi_mem;
|
||||
struct dsi_data *dsi;
|
||||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
|
||||
if (!dsi)
|
||||
|
@ -5376,16 +5407,64 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
|
|||
dsi->te_timer.function = dsi_te_timeout;
|
||||
dsi->te_timer.data = 0;
|
||||
#endif
|
||||
dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
|
||||
if (!dsi_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto");
|
||||
if (!res) {
|
||||
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start;
|
||||
temp_res.end = temp_res.start + DSI_PROTO_SZ - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start,
|
||||
resource_size(dsi_mem));
|
||||
if (!dsi->base) {
|
||||
DSSERR("can't ioremap DSI\n");
|
||||
dsi->proto_base = devm_ioremap(&dsidev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!dsi->proto_base) {
|
||||
DSSERR("can't ioremap DSI protocol engine\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "phy");
|
||||
if (!res) {
|
||||
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start + DSI_PHY_OFFSET;
|
||||
temp_res.end = temp_res.start + DSI_PHY_SZ - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
dsi->phy_base = devm_ioremap(&dsidev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!dsi->proto_base) {
|
||||
DSSERR("can't ioremap DSI PHY\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "pll");
|
||||
if (!res) {
|
||||
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start + DSI_PLL_OFFSET;
|
||||
temp_res.end = temp_res.start + DSI_PLL_SZ - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
dsi->pll_base = devm_ioremap(&dsidev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!dsi->proto_base) {
|
||||
DSSERR("can't ioremap DSI PLL\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ static void dss_runtime_put(void);
|
|||
struct dss_features {
|
||||
u8 fck_div_max;
|
||||
u8 dss_fck_multiplier;
|
||||
const char *clk_name;
|
||||
const char *parent_clk_name;
|
||||
int (*dpi_select_source)(enum omap_channel channel);
|
||||
};
|
||||
|
||||
|
@ -75,13 +75,12 @@ static struct {
|
|||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
|
||||
struct clk *dpll4_m4_ck;
|
||||
struct clk *parent_clk;
|
||||
struct clk *dss_clk;
|
||||
unsigned long dss_clk_rate;
|
||||
|
||||
unsigned long cache_req_pck;
|
||||
unsigned long cache_prate;
|
||||
struct dss_clock_info cache_dss_cinfo;
|
||||
struct dispc_clock_info cache_dispc_cinfo;
|
||||
|
||||
enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
|
||||
|
@ -265,8 +264,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
|
|||
|
||||
void dss_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
unsigned long dpll4_ck_rate;
|
||||
unsigned long dpll4_m4_ck_rate;
|
||||
const char *fclk_name, *fclk_real_name;
|
||||
unsigned long fclk_rate;
|
||||
|
||||
|
@ -279,21 +276,9 @@ void dss_dump_clocks(struct seq_file *s)
|
|||
fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
|
||||
fclk_rate = clk_get_rate(dss.dss_clk);
|
||||
|
||||
if (dss.dpll4_m4_ck) {
|
||||
dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
|
||||
|
||||
seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
|
||||
|
||||
seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n",
|
||||
fclk_name, fclk_real_name, dpll4_ck_rate,
|
||||
dpll4_ck_rate / dpll4_m4_ck_rate,
|
||||
dss.feat->dss_fck_multiplier, fclk_rate);
|
||||
} else {
|
||||
seq_printf(s, "%s (%s) = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
fclk_rate);
|
||||
}
|
||||
seq_printf(s, "%s (%s) = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
fclk_rate);
|
||||
|
||||
dss_runtime_put();
|
||||
}
|
||||
|
@ -451,30 +436,8 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
|
|||
}
|
||||
}
|
||||
|
||||
/* calculate clock rates using dividers in cinfo */
|
||||
int dss_calc_clock_rates(struct dss_clock_info *cinfo)
|
||||
{
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
|
||||
if (cinfo->fck_div > dss.feat->fck_div_max ||
|
||||
cinfo->fck_div == 0)
|
||||
return -EINVAL;
|
||||
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
|
||||
cinfo->fck = prate / cinfo->fck_div *
|
||||
dss.feat->dss_fck_multiplier;
|
||||
} else {
|
||||
if (cinfo->fck_div != 0)
|
||||
return -EINVAL;
|
||||
cinfo->fck = clk_get_rate(dss.dss_clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
|
||||
bool dss_div_calc(unsigned long pck, unsigned long fck_min,
|
||||
dss_div_calc_func func, void *data)
|
||||
{
|
||||
int fckd, fckd_start, fckd_stop;
|
||||
unsigned long fck;
|
||||
|
@ -483,22 +446,24 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
|
|||
unsigned long prate;
|
||||
unsigned m;
|
||||
|
||||
if (dss.dpll4_m4_ck == NULL) {
|
||||
/*
|
||||
* TODO: dss1_fclk can be changed on OMAP2, but the available
|
||||
* dividers are not continuous. We just use the pre-set rate for
|
||||
* now.
|
||||
*/
|
||||
fck = clk_get_rate(dss.dss_clk);
|
||||
fckd = 1;
|
||||
return func(fckd, fck, data);
|
||||
fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
|
||||
if (dss.parent_clk == NULL) {
|
||||
unsigned pckd;
|
||||
|
||||
pckd = fck_hw_max / pck;
|
||||
|
||||
fck = pck * pckd;
|
||||
|
||||
fck = clk_round_rate(dss.dss_clk, fck);
|
||||
|
||||
return func(fck, data);
|
||||
}
|
||||
|
||||
fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
fckd_hw_max = dss.feat->fck_div_max;
|
||||
|
||||
m = dss.feat->dss_fck_multiplier;
|
||||
prate = dss_get_dpll4_rate();
|
||||
prate = clk_get_rate(dss.parent_clk);
|
||||
|
||||
fck_min = fck_min ? fck_min : 1;
|
||||
|
||||
|
@ -508,50 +473,32 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
|
|||
for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
|
||||
fck = prate / fckd * m;
|
||||
|
||||
if (func(fckd, fck, data))
|
||||
if (func(fck, data))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int dss_set_clock_div(struct dss_clock_info *cinfo)
|
||||
int dss_set_fck_rate(unsigned long rate)
|
||||
{
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
int r;
|
||||
int r;
|
||||
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
DSSDBG("dpll4_m4 = %ld\n", prate);
|
||||
DSSDBG("set fck to %lu\n", rate);
|
||||
|
||||
r = clk_set_rate(dss.dpll4_m4_ck,
|
||||
DIV_ROUND_UP(prate, cinfo->fck_div));
|
||||
if (r)
|
||||
return r;
|
||||
} else {
|
||||
if (cinfo->fck_div != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
r = clk_set_rate(dss.dss_clk, rate);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
|
||||
|
||||
WARN_ONCE(dss.dss_clk_rate != cinfo->fck,
|
||||
WARN_ONCE(dss.dss_clk_rate != rate,
|
||||
"clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
|
||||
cinfo->fck);
|
||||
|
||||
DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
|
||||
rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long dss_get_dpll4_rate(void)
|
||||
{
|
||||
if (dss.dpll4_m4_ck)
|
||||
return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long dss_get_dispc_clk_rate(void)
|
||||
{
|
||||
return dss.dss_clk_rate;
|
||||
|
@ -560,27 +507,23 @@ unsigned long dss_get_dispc_clk_rate(void)
|
|||
static int dss_setup_default_clock(void)
|
||||
{
|
||||
unsigned long max_dss_fck, prate;
|
||||
unsigned long fck;
|
||||
unsigned fck_div;
|
||||
struct dss_clock_info dss_cinfo = { 0 };
|
||||
int r;
|
||||
|
||||
if (dss.dpll4_m4_ck == NULL)
|
||||
return 0;
|
||||
|
||||
max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
|
||||
prate = dss_get_dpll4_rate();
|
||||
if (dss.parent_clk == NULL) {
|
||||
fck = clk_round_rate(dss.dss_clk, max_dss_fck);
|
||||
} else {
|
||||
prate = clk_get_rate(dss.parent_clk);
|
||||
|
||||
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
|
||||
max_dss_fck);
|
||||
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
|
||||
max_dss_fck);
|
||||
fck = prate / fck_div * dss.feat->dss_fck_multiplier;
|
||||
}
|
||||
|
||||
dss_cinfo.fck_div = fck_div;
|
||||
|
||||
r = dss_calc_clock_rates(&dss_cinfo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dss_set_clock_div(&dss_cinfo);
|
||||
r = dss_set_fck_rate(fck);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -706,25 +649,25 @@ static int dss_get_clocks(void)
|
|||
|
||||
dss.dss_clk = clk;
|
||||
|
||||
if (dss.feat->clk_name) {
|
||||
clk = clk_get(NULL, dss.feat->clk_name);
|
||||
if (dss.feat->parent_clk_name) {
|
||||
clk = clk_get(NULL, dss.feat->parent_clk_name);
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("Failed to get %s\n", dss.feat->clk_name);
|
||||
DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
} else {
|
||||
clk = NULL;
|
||||
}
|
||||
|
||||
dss.dpll4_m4_ck = clk;
|
||||
dss.parent_clk = clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dss_put_clocks(void)
|
||||
{
|
||||
if (dss.dpll4_m4_ck)
|
||||
clk_put(dss.dpll4_m4_ck);
|
||||
if (dss.parent_clk)
|
||||
clk_put(dss.parent_clk);
|
||||
}
|
||||
|
||||
static int dss_runtime_get(void)
|
||||
|
@ -761,37 +704,41 @@ void dss_debug_dump_clocks(struct seq_file *s)
|
|||
#endif
|
||||
|
||||
static const struct dss_features omap24xx_dss_feats __initconst = {
|
||||
.fck_div_max = 16,
|
||||
/*
|
||||
* fck div max is really 16, but the divider range has gaps. The range
|
||||
* from 1 to 6 has no gaps, so let's use that as a max.
|
||||
*/
|
||||
.fck_div_max = 6,
|
||||
.dss_fck_multiplier = 2,
|
||||
.clk_name = NULL,
|
||||
.parent_clk_name = "core_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap34xx_dss_feats __initconst = {
|
||||
.fck_div_max = 16,
|
||||
.dss_fck_multiplier = 2,
|
||||
.clk_name = "dpll4_m4_ck",
|
||||
.parent_clk_name = "dpll4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap3630_dss_feats __initconst = {
|
||||
.fck_div_max = 32,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll4_m4_ck",
|
||||
.parent_clk_name = "dpll4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap44xx_dss_feats __initconst = {
|
||||
.fck_div_max = 32,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll_per_m5x2_ck",
|
||||
.parent_clk_name = "dpll_per_x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap4,
|
||||
};
|
||||
|
||||
static const struct dss_features omap54xx_dss_feats __initconst = {
|
||||
.fck_div_max = 64,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll_per_h12x2_ck",
|
||||
.parent_clk_name = "dpll_per_x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap5,
|
||||
};
|
||||
|
||||
|
|
|
@ -100,14 +100,6 @@ enum dss_writeback_channel {
|
|||
DSS_WB_LCD3_MGR = 7,
|
||||
};
|
||||
|
||||
struct dss_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long fck;
|
||||
|
||||
/* dividers */
|
||||
u16 fck_div;
|
||||
};
|
||||
|
||||
struct dispc_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long lck;
|
||||
|
@ -250,12 +242,11 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
|
|||
void dss_set_venc_output(enum omap_dss_venc_type type);
|
||||
void dss_set_dac_pwrdn_bgz(bool enable);
|
||||
|
||||
unsigned long dss_get_dpll4_rate(void);
|
||||
int dss_calc_clock_rates(struct dss_clock_info *cinfo);
|
||||
int dss_set_clock_div(struct dss_clock_info *cinfo);
|
||||
int dss_set_fck_rate(unsigned long rate);
|
||||
|
||||
typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data);
|
||||
bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data);
|
||||
typedef bool (*dss_div_calc_func)(unsigned long fck, void *data);
|
||||
bool dss_div_calc(unsigned long pck, unsigned long fck_min,
|
||||
dss_div_calc_func func, void *data);
|
||||
|
||||
/* SDI */
|
||||
int sdi_init_platform_driver(void) __init;
|
||||
|
|
|
@ -613,6 +613,7 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
|
|||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
FEAT_MFLAG,
|
||||
};
|
||||
|
||||
/* OMAP2 DSS Features */
|
||||
|
|
|
@ -64,6 +64,7 @@ enum dss_feat_id {
|
|||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
FEAT_MFLAG,
|
||||
};
|
||||
|
||||
/* DSS register field id */
|
||||
|
|
|
@ -41,14 +41,14 @@
|
|||
#define HDMI_WP_VIDEO_SIZE 0x60
|
||||
#define HDMI_WP_VIDEO_TIMING_H 0x68
|
||||
#define HDMI_WP_VIDEO_TIMING_V 0x6C
|
||||
#define HDMI_WP_WP_CLK 0x70
|
||||
#define HDMI_WP_CLK 0x70
|
||||
#define HDMI_WP_AUDIO_CFG 0x80
|
||||
#define HDMI_WP_AUDIO_CFG2 0x84
|
||||
#define HDMI_WP_AUDIO_CTRL 0x88
|
||||
#define HDMI_WP_AUDIO_DATA 0x8C
|
||||
|
||||
/* HDMI WP IRQ flags */
|
||||
|
||||
#define HDMI_IRQ_CORE (1 << 0)
|
||||
#define HDMI_IRQ_OCP_TIMEOUT (1 << 4)
|
||||
#define HDMI_IRQ_AUDIO_FIFO_UNDERFLOW (1 << 8)
|
||||
#define HDMI_IRQ_AUDIO_FIFO_OVERFLOW (1 << 9)
|
||||
|
@ -378,15 +378,15 @@ static inline u32 hdmi_read_reg(void __iomem *base_addr, const u16 idx)
|
|||
FLD_GET(hdmi_read_reg(base, idx), start, end)
|
||||
|
||||
static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
|
||||
const u16 idx, int b2, int b1, u32 val)
|
||||
const u32 idx, int b2, int b1, u32 val)
|
||||
{
|
||||
u32 t = 0;
|
||||
while (val != REG_GET(base_addr, idx, b2, b1)) {
|
||||
udelay(1);
|
||||
u32 t = 0, v;
|
||||
while (val != (v = REG_GET(base_addr, idx, b2, b1))) {
|
||||
if (t++ > 10000)
|
||||
return !val;
|
||||
return v;
|
||||
udelay(1);
|
||||
}
|
||||
return val;
|
||||
return v;
|
||||
}
|
||||
|
||||
/* HDMI wrapper funcs */
|
||||
|
|
|
@ -95,7 +95,8 @@ static int hdmi_init_regulator(void)
|
|||
reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
|
||||
|
||||
if (IS_ERR(reg)) {
|
||||
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
|
||||
if (PTR_ERR(reg) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
|
||||
return PTR_ERR(reg);
|
||||
}
|
||||
|
||||
|
@ -148,8 +149,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
dss_mgr_disable(mgr);
|
||||
|
||||
p = &hdmi.cfg.timings;
|
||||
|
||||
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
|
||||
|
@ -158,8 +157,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
|
|||
|
||||
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
|
||||
|
||||
hdmi_wp_video_stop(&hdmi.wp);
|
||||
|
||||
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
|
||||
r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
|
||||
if (r) {
|
||||
|
@ -218,14 +215,12 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
|
|||
static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct hdmi_cm cm;
|
||||
struct omap_dss_device *out = &hdmi.output;
|
||||
|
||||
cm = hdmi_get_code(timings);
|
||||
if (cm.code == -1)
|
||||
if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
|
@ -244,8 +239,17 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
|||
hdmi.cfg = *t;
|
||||
|
||||
dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
|
||||
} else {
|
||||
hdmi.cfg.timings = *timings;
|
||||
hdmi.cfg.cm.code = 0;
|
||||
hdmi.cfg.cm.mode = HDMI_DVI;
|
||||
|
||||
dispc_set_tv_pclk(timings->pixel_clock * 1000);
|
||||
}
|
||||
|
||||
DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
|
||||
"DVI" : "HDMI", hdmi.cfg.cm.code);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMICORE"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -125,12 +127,12 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
|
|||
|
||||
/* HDMI_CORE_DDC_STATUS_BUS_LOW */
|
||||
if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
|
||||
pr_err("I2C Bus Low?\n");
|
||||
DSSERR("I2C Bus Low?\n");
|
||||
return -EIO;
|
||||
}
|
||||
/* HDMI_CORE_DDC_STATUS_NO_ACK */
|
||||
if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
|
||||
pr_err("I2C No Ack\n");
|
||||
DSSERR("I2C No Ack\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -161,7 +163,7 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
|
|||
checksum += pedid[i];
|
||||
|
||||
if (checksum != 0) {
|
||||
pr_err("E-EDID checksum failed!!\n");
|
||||
DSSERR("E-EDID checksum failed!!\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -199,7 +201,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
|
|||
struct hdmi_core_infoframe_avi *avi_cfg,
|
||||
struct hdmi_core_packet_enable_repeat *repeat_cfg)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_init\n");
|
||||
DSSDBG("Enter hdmi_core_init\n");
|
||||
|
||||
/* video core */
|
||||
video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
|
||||
|
@ -241,19 +243,19 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
|
|||
|
||||
static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_powerdown_disable\n");
|
||||
DSSDBG("Enter hdmi_core_powerdown_disable\n");
|
||||
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0);
|
||||
}
|
||||
|
||||
static void hdmi_core_swreset_release(struct hdmi_core_data *core)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_swreset_release\n");
|
||||
DSSDBG("Enter hdmi_core_swreset_release\n");
|
||||
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0);
|
||||
}
|
||||
|
||||
static void hdmi_core_swreset_assert(struct hdmi_core_data *core)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_swreset_assert\n");
|
||||
DSSDBG("Enter hdmi_core_swreset_assert\n");
|
||||
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1006,7 @@ int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_core");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
|
||||
if (!res) {
|
||||
DSSDBG("can't get CORE mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
* map it to corresponding CEA or VESA index.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMI"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <video/omapdss.h>
|
||||
|
|
|
@ -124,7 +124,7 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_txphy");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
|
||||
if (!res) {
|
||||
DSSDBG("can't get PHY mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMIPLL"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -127,24 +129,24 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
|
|||
/* wait for bit change */
|
||||
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO,
|
||||
0, 0, 1) != 1) {
|
||||
pr_err("PLL GO bit not set\n");
|
||||
DSSERR("PLL GO bit not set\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Wait till the lock bit is set in PLL status */
|
||||
if (hdmi_wait_for_bit_change(pll->base,
|
||||
PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
|
||||
pr_err("cannot lock PLL\n");
|
||||
pr_err("CFG1 0x%x\n",
|
||||
DSSERR("cannot lock PLL\n");
|
||||
DSSERR("CFG1 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG1));
|
||||
pr_err("CFG2 0x%x\n",
|
||||
DSSERR("CFG2 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG2));
|
||||
pr_err("CFG4 0x%x\n",
|
||||
DSSERR("CFG4 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG4));
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
pr_debug("PLL locked!\n");
|
||||
DSSDBG("PLL locked!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ static int hdmi_pll_reset(struct hdmi_pll_data *pll)
|
|||
/* READ 0x0 reset is in progress */
|
||||
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
|
||||
!= 1) {
|
||||
pr_err("Failed to sysreset PLL\n");
|
||||
DSSERR("Failed to sysreset PLL\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -200,7 +202,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_pllctrl");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
|
||||
if (!res) {
|
||||
DSSDBG("can't get PLL mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMIWP"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -34,7 +36,7 @@ void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s)
|
|||
DUMPREG(HDMI_WP_VIDEO_SIZE);
|
||||
DUMPREG(HDMI_WP_VIDEO_TIMING_H);
|
||||
DUMPREG(HDMI_WP_VIDEO_TIMING_V);
|
||||
DUMPREG(HDMI_WP_WP_CLK);
|
||||
DUMPREG(HDMI_WP_CLK);
|
||||
DUMPREG(HDMI_WP_AUDIO_CFG);
|
||||
DUMPREG(HDMI_WP_AUDIO_CFG2);
|
||||
DUMPREG(HDMI_WP_AUDIO_CTRL);
|
||||
|
@ -76,7 +78,7 @@ int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val)
|
|||
/* Status of the power control of HDMI PHY */
|
||||
if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val)
|
||||
!= val) {
|
||||
pr_err("Failed to set PHY power mode to %d\n", val);
|
||||
DSSERR("Failed to set PHY power mode to %d\n", val);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -92,7 +94,7 @@ int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val)
|
|||
/* wait till PHY_PWR_STATUS is set */
|
||||
if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val)
|
||||
!= val) {
|
||||
pr_err("Failed to set PLL_PWR_STATUS\n");
|
||||
DSSERR("Failed to set PLL_PWR_STATUS\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -129,7 +131,7 @@ void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
|
|||
{
|
||||
u32 r;
|
||||
bool vsync_pol, hsync_pol;
|
||||
pr_debug("Enter hdmi_wp_video_config_interface\n");
|
||||
DSSDBG("Enter hdmi_wp_video_config_interface\n");
|
||||
|
||||
vsync_pol = timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
hsync_pol = timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
|
@ -148,7 +150,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
|
|||
u32 timing_h = 0;
|
||||
u32 timing_v = 0;
|
||||
|
||||
pr_debug("Enter hdmi_wp_video_config_timing\n");
|
||||
DSSDBG("Enter hdmi_wp_video_config_timing\n");
|
||||
|
||||
timing_h |= FLD_VAL(timings->hbp, 31, 20);
|
||||
timing_h |= FLD_VAL(timings->hfp, 19, 8);
|
||||
|
@ -164,7 +166,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
|
|||
void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
|
||||
struct omap_video_timings *timings, struct hdmi_config *param)
|
||||
{
|
||||
pr_debug("Enter hdmi_wp_video_init_format\n");
|
||||
DSSDBG("Enter hdmi_wp_video_init_format\n");
|
||||
|
||||
video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
|
||||
video_fmt->y_res = param->timings.y_res;
|
||||
|
@ -241,7 +243,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_wp");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wp");
|
||||
if (!res) {
|
||||
DSSDBG("can't get WP mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -113,11 +113,6 @@ void dss_uninit_overlays(struct platform_device *pdev)
|
|||
int dss_ovl_simple_check(struct omap_overlay *ovl,
|
||||
const struct omap_overlay_info *info)
|
||||
{
|
||||
if (info->paddr == 0) {
|
||||
DSSERR("check_overlay: paddr cannot be 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
|
||||
if (info->out_width != 0 && info->width != info->out_width) {
|
||||
DSSERR("check_overlay: overlay %d doesn't support "
|
||||
|
|
|
@ -46,7 +46,7 @@ static struct {
|
|||
struct sdi_clk_calc_ctx {
|
||||
unsigned long pck_min, pck_max;
|
||||
|
||||
struct dss_clock_info dss_cinfo;
|
||||
unsigned long long fck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
};
|
||||
|
||||
|
@ -63,19 +63,18 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data)
|
||||
static bool dpi_calc_dss_cb(unsigned long fck, void *data)
|
||||
{
|
||||
struct sdi_clk_calc_ctx *ctx = data;
|
||||
|
||||
ctx->dss_cinfo.fck = fck;
|
||||
ctx->dss_cinfo.fck_div = fckd;
|
||||
ctx->fck = fck;
|
||||
|
||||
return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
|
||||
dpi_calc_dispc_cb, ctx);
|
||||
}
|
||||
|
||||
static int sdi_calc_clock_div(unsigned long pclk,
|
||||
struct dss_clock_info *dss_cinfo,
|
||||
unsigned long *fck,
|
||||
struct dispc_clock_info *dispc_cinfo)
|
||||
{
|
||||
int i;
|
||||
|
@ -98,9 +97,9 @@ static int sdi_calc_clock_div(unsigned long pclk,
|
|||
ctx.pck_min = 0;
|
||||
ctx.pck_max = pclk + 1000 * i * i * i;
|
||||
|
||||
ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx);
|
||||
ok = dss_div_calc(pclk, ctx.pck_min, dpi_calc_dss_cb, &ctx);
|
||||
if (ok) {
|
||||
*dss_cinfo = ctx.dss_cinfo;
|
||||
*fck = ctx.fck;
|
||||
*dispc_cinfo = ctx.dispc_cinfo;
|
||||
return 0;
|
||||
}
|
||||
|
@ -128,7 +127,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
{
|
||||
struct omap_dss_device *out = &sdi.output;
|
||||
struct omap_video_timings *t = &sdi.timings;
|
||||
struct dss_clock_info dss_cinfo;
|
||||
unsigned long fck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
unsigned long pck;
|
||||
int r;
|
||||
|
@ -150,13 +149,13 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
||||
t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
||||
|
||||
r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
|
||||
r = sdi_calc_clock_div(t->pixel_clock * 1000, &fck, &dispc_cinfo);
|
||||
if (r)
|
||||
goto err_calc_clock_div;
|
||||
|
||||
sdi.mgr_config.clock_info = dispc_cinfo;
|
||||
|
||||
pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
|
||||
pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
|
||||
|
||||
if (pck != t->pixel_clock) {
|
||||
DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
|
||||
|
@ -169,7 +168,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
|
||||
dss_mgr_set_timings(out->manager, t);
|
||||
|
||||
r = dss_set_clock_div(&dss_cinfo);
|
||||
r = dss_set_fck_rate(fck);
|
||||
if (r)
|
||||
goto err_set_dss_clock_div;
|
||||
|
||||
|
@ -265,7 +264,8 @@ static int sdi_init_regulator(void)
|
|||
|
||||
vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi");
|
||||
if (IS_ERR(vdds_sdi)) {
|
||||
DSSERR("can't get VDDS_SDI regulator\n");
|
||||
if (PTR_ERR(vdds_sdi) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDS_SDI regulator\n");
|
||||
return PTR_ERR(vdds_sdi);
|
||||
}
|
||||
|
||||
|
|
|
@ -639,7 +639,8 @@ static int venc_init_regulator(void)
|
|||
vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");
|
||||
|
||||
if (IS_ERR(vdda_dac)) {
|
||||
DSSERR("can't get VDDA_DAC regulator\n");
|
||||
if (PTR_ERR(vdda_dac) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDA_DAC regulator\n");
|
||||
return PTR_ERR(vdda_dac);
|
||||
}
|
||||
|
||||
|
|
|
@ -1833,6 +1833,16 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
|
|||
if (fbdev == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < fbdev->num_fbs; i++) {
|
||||
struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
|
||||
int j;
|
||||
|
||||
for (j = 0; j < ofbi->num_overlays; j++) {
|
||||
struct omap_overlay *ovl = ofbi->overlays[j];
|
||||
ovl->disable(ovl);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < fbdev->num_fbs; i++)
|
||||
unregister_framebuffer(fbdev->fbs[i]);
|
||||
|
||||
|
@ -2557,6 +2567,15 @@ static int omapfb_probe(struct platform_device *pdev)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (def_display) {
|
||||
u16 w, h;
|
||||
|
||||
def_display->driver->get_resolution(def_display, &w, &h);
|
||||
|
||||
dev_info(fbdev->dev, "using display '%s' mode %dx%d\n",
|
||||
def_display->name, w, h);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
|
|
Загрузка…
Ссылка в новой задаче