return PTR_ERR(vdds_dsi);
}
- if (regulator_can_change_voltage(vdds_dsi)) {
- r = regulator_set_voltage(vdds_dsi, 1800000, 1800000);
- if (r) {
- devm_regulator_put(vdds_dsi);
- DSSERR("can't set the DSI regulator voltage\n");
- return r;
- }
- }
-
dsi->vdds_dsi_reg = vdds_dsi;
return 0;
unsigned long r;
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) {
+ if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) {
/* DSI FCLK source is DSS_CLK_FCK */
r = clk_get_rate(dsi->dss_clk);
} else {
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
- enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
+ enum dss_clk_source dispc_clk_src, dsi_clk_src;
int dsi_module = dsi->module_id;
struct dss_pll *pll = &dsi->pll;
cinfo->clkdco, cinfo->m);
seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n",
- dss_feat_get_clk_source_name(dsi_module == 0 ?
- OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
- OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
+ dss_get_clk_source_name(dsi_module == 0 ?
+ DSS_CLK_SRC_PLL1_1 :
+ DSS_CLK_SRC_PLL2_1),
cinfo->clkout[HSDIV_DISPC],
cinfo->mX[HSDIV_DISPC],
- dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
+ dispc_clk_src == DSS_CLK_SRC_FCK ?
"off" : "on");
seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n",
- dss_feat_get_clk_source_name(dsi_module == 0 ?
- OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
- OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
+ dss_get_clk_source_name(dsi_module == 0 ?
+ DSS_CLK_SRC_PLL1_2 :
+ DSS_CLK_SRC_PLL2_2),
cinfo->clkout[HSDIV_DSI],
cinfo->mX[HSDIV_DSI],
- dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
+ dsi_clk_src == DSS_CLK_SRC_FCK ?
"off" : "on");
seq_printf(s, "- DSI%d -\n", dsi_module + 1);
- seq_printf(s, "dsi fclk source = %s (%s)\n",
- dss_get_generic_clk_source_name(dsi_clk_src),
- dss_feat_get_clk_source_name(dsi_clk_src));
+ seq_printf(s, "dsi fclk source = %s\n",
+ dss_get_clk_source_name(dsi_clk_src));
seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
int r;
dss_select_lcd_clk_source(channel, dsi->module_id == 0 ?
- OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
- OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC);
+ DSS_CLK_SRC_PLL1_1 :
+ DSS_CLK_SRC_PLL2_1);
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
r = dss_mgr_register_framedone_handler(channel,
dss_mgr_unregister_framedone_handler(channel,
dsi_framedone_irq_callback, dsidev);
err:
- dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
return r;
}
dss_mgr_unregister_framedone_handler(channel,
dsi_framedone_irq_callback, dsidev);
- dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
}
static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
goto err1;
dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ?
- OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
- OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI);
+ DSS_CLK_SRC_PLL1_2 :
+ DSS_CLK_SRC_PLL2_2);
DSSDBG("PLL OK\n");
err3:
dsi_cio_uninit(dsidev);
err2:
- dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
err1:
dss_pll_disable(&dsi->pll);
err0:
dsi_vc_enable(dsidev, 2, 0);
dsi_vc_enable(dsidev, 3, 0);
- dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
dsi_cio_uninit(dsidev);
dsi_pll_uninit(dsidev, disconnect_lanes);
}
ctx->dsi_cinfo.fint = fint;
ctx->dsi_cinfo.clkdco = clkdco;
- return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
+ return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
dsi_cm_calc_hsdiv_cb, ctx);
}
pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
pll_max = cfg->hs_clk_max * 4;
- return dss_pll_calc(ctx->pll, clkin,
+ return dss_pll_calc_a(ctx->pll, clkin,
pll_min, pll_max,
dsi_cm_calc_pll_cb, ctx);
}
ctx->dsi_cinfo.fint = fint;
ctx->dsi_cinfo.clkdco = clkdco;
- return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
+ return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
dsi_vm_calc_hsdiv_cb, ctx);
}
pll_max = byteclk_max * 4 * 4;
}
- return dss_pll_calc(ctx->pll, clkin,
+ return dss_pll_calc_a(ctx->pll, clkin,
pll_min, pll_max,
dsi_vm_calc_pll_cb, ctx);
}
};
static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
+ .type = DSS_PLL_TYPE_A,
+
.n_max = (1 << 7) - 1,
.m_max = (1 << 11) - 1,
.mX_max = (1 << 4) - 1,
};
static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
+ .type = DSS_PLL_TYPE_A,
+
.n_max = (1 << 8) - 1,
.m_max = (1 << 12) - 1,
.mX_max = (1 << 5) - 1,
};
static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
+ .type = DSS_PLL_TYPE_A,
+
.n_max = (1 << 8) - 1,
.m_max = (1 << 12) - 1,
.mX_max = (1 << 5) - 1,
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/clk.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/gfp.h>
const enum omap_display_type *ports;
int num_ports;
int (*dpi_select_source)(int port, enum omap_channel channel);
+ int (*select_lcd_source)(enum omap_channel channel,
+ enum dss_clk_source clk_src);
};
static struct {
unsigned long cache_prate;
struct dispc_clock_info cache_dispc_cinfo;
- enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
- enum omap_dss_clk_source dispc_clk_source;
- enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
+ enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
+ enum dss_clk_source dispc_clk_source;
+ enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
bool ctx_valid;
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
} dss;
static const char * const dss_generic_clk_source_names[] = {
- [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
- [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
- [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
- [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC",
- [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI",
+ [DSS_CLK_SRC_FCK] = "FCK",
+ [DSS_CLK_SRC_PLL1_1] = "PLL1:1",
+ [DSS_CLK_SRC_PLL1_2] = "PLL1:2",
+ [DSS_CLK_SRC_PLL1_3] = "PLL1:3",
+ [DSS_CLK_SRC_PLL2_1] = "PLL2:1",
+ [DSS_CLK_SRC_PLL2_2] = "PLL2:2",
+ [DSS_CLK_SRC_PLL2_3] = "PLL2:3",
+ [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL",
};
static bool dss_initialized;
1 << shift, val << shift);
}
- void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
+ static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
enum omap_channel channel)
{
unsigned shift, val;
if (!dss.syscon_pll_ctrl)
- return;
+ return -EINVAL;
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
shift = 3;
- switch (pll_id) {
- case DSS_PLL_VIDEO1:
+ switch (clk_src) {
+ case DSS_CLK_SRC_PLL1_1:
val = 0; break;
- case DSS_PLL_HDMI:
+ case DSS_CLK_SRC_HDMI_PLL:
val = 1; break;
default:
DSSERR("error in PLL mux config for LCD\n");
- return;
+ return -EINVAL;
}
break;
case OMAP_DSS_CHANNEL_LCD2:
shift = 5;
- switch (pll_id) {
- case DSS_PLL_VIDEO1:
+ switch (clk_src) {
+ case DSS_CLK_SRC_PLL1_3:
val = 0; break;
- case DSS_PLL_VIDEO2:
+ case DSS_CLK_SRC_PLL2_3:
val = 1; break;
- case DSS_PLL_HDMI:
+ case DSS_CLK_SRC_HDMI_PLL:
val = 2; break;
default:
DSSERR("error in PLL mux config for LCD2\n");
- return;
+ return -EINVAL;
}
break;
case OMAP_DSS_CHANNEL_LCD3:
shift = 7;
- switch (pll_id) {
- case DSS_PLL_VIDEO1:
- val = 1; break;
- case DSS_PLL_VIDEO2:
+ switch (clk_src) {
+ case DSS_CLK_SRC_PLL2_1:
val = 0; break;
- case DSS_PLL_HDMI:
+ case DSS_CLK_SRC_PLL1_3:
+ val = 1; break;
+ case DSS_CLK_SRC_HDMI_PLL:
val = 2; break;
default:
DSSERR("error in PLL mux config for LCD3\n");
- return;
+ return -EINVAL;
}
break;
default:
DSSERR("error in PLL mux config\n");
- return;
+ return -EINVAL;
}
regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
0x3 << shift, val << shift);
+
+ return 0;
}
void dss_sdi_init(int datapairs)
REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
}
- const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
+ const char *dss_get_clk_source_name(enum dss_clk_source clk_src)
{
return dss_generic_clk_source_names[clk_src];
}
void dss_dump_clocks(struct seq_file *s)
{
- const char *fclk_name, *fclk_real_name;
+ const char *fclk_name;
unsigned long fclk_rate;
if (dss_runtime_get())
seq_printf(s, "- DSS -\n");
- fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
- fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
+ fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK);
fclk_rate = clk_get_rate(dss.dss_clk);
- seq_printf(s, "%s (%s) = %lu\n",
- fclk_name, fclk_real_name,
+ seq_printf(s, "%s = %lu\n",
+ fclk_name,
fclk_rate);
dss_runtime_put();
#undef DUMPREG
}
- static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
+ static int dss_get_channel_index(enum omap_channel channel)
+ {
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ return 0;
+ case OMAP_DSS_CHANNEL_LCD2:
+ return 1;
+ case OMAP_DSS_CHANNEL_LCD3:
+ return 2;
+ default:
+ WARN_ON(1);
+ return 0;
+ }
+ }
+
+ static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
{
int b;
u8 start, end;
+ /*
+ * We always use PRCM clock as the DISPC func clock, except on DSS3,
+ * where we don't have separate DISPC and LCD clock sources.
+ */
+ if (WARN_ON(dss_has_feature(FEAT_LCD_CLK_SRC) &&
+ clk_src != DSS_CLK_SRC_FCK))
+ return;
+
switch (clk_src) {
- case OMAP_DSS_CLK_SRC_FCK:
+ case DSS_CLK_SRC_FCK:
b = 0;
break;
- case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
+ case DSS_CLK_SRC_PLL1_1:
b = 1;
break;
- case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+ case DSS_CLK_SRC_PLL2_1:
b = 2;
break;
default:
}
void dss_select_dsi_clk_source(int dsi_module,
- enum omap_dss_clk_source clk_src)
+ enum dss_clk_source clk_src)
{
int b, pos;
switch (clk_src) {
- case OMAP_DSS_CLK_SRC_FCK:
+ case DSS_CLK_SRC_FCK:
b = 0;
break;
- case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
+ case DSS_CLK_SRC_PLL1_2:
BUG_ON(dsi_module != 0);
b = 1;
break;
- case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
+ case DSS_CLK_SRC_PLL2_2:
BUG_ON(dsi_module != 1);
b = 1;
break;
dss.dsi_clk_source[dsi_module] = clk_src;
}
+ static int dss_lcd_clk_mux_dra7(enum omap_channel channel,
+ enum dss_clk_source clk_src)
+ {
+ const u8 ctrl_bits[] = {
+ [OMAP_DSS_CHANNEL_LCD] = 0,
+ [OMAP_DSS_CHANNEL_LCD2] = 12,
+ [OMAP_DSS_CHANNEL_LCD3] = 19,
+ };
+
+ u8 ctrl_bit = ctrl_bits[channel];
+ int r;
+
+ if (clk_src == DSS_CLK_SRC_FCK) {
+ /* LCDx_CLK_SWITCH */
+ REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
+ return -EINVAL;
+ }
+
+ r = dss_ctrl_pll_set_control_mux(clk_src, channel);
+ if (r)
+ return r;
+
+ REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
+
+ return 0;
+ }
+
+ static int dss_lcd_clk_mux_omap5(enum omap_channel channel,
+ enum dss_clk_source clk_src)
+ {
+ const u8 ctrl_bits[] = {
+ [OMAP_DSS_CHANNEL_LCD] = 0,
+ [OMAP_DSS_CHANNEL_LCD2] = 12,
+ [OMAP_DSS_CHANNEL_LCD3] = 19,
+ };
+ const enum dss_clk_source allowed_plls[] = {
+ [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
+ [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_FCK,
+ [OMAP_DSS_CHANNEL_LCD3] = DSS_CLK_SRC_PLL2_1,
+ };
+
+ u8 ctrl_bit = ctrl_bits[channel];
+
+ if (clk_src == DSS_CLK_SRC_FCK) {
+ /* LCDx_CLK_SWITCH */
+ REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
+ return -EINVAL;
+ }
+
+ if (WARN_ON(allowed_plls[channel] != clk_src))
+ return -EINVAL;
+
+ REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
+
+ return 0;
+ }
+
+ static int dss_lcd_clk_mux_omap4(enum omap_channel channel,
+ enum dss_clk_source clk_src)
+ {
+ const u8 ctrl_bits[] = {
+ [OMAP_DSS_CHANNEL_LCD] = 0,
+ [OMAP_DSS_CHANNEL_LCD2] = 12,
+ };
+ const enum dss_clk_source allowed_plls[] = {
+ [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
+ [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_PLL2_1,
+ };
+
+ u8 ctrl_bit = ctrl_bits[channel];
+
+ if (clk_src == DSS_CLK_SRC_FCK) {
+ /* LCDx_CLK_SWITCH */
+ REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
+ return 0;
+ }
+
+ if (WARN_ON(allowed_plls[channel] != clk_src))
+ return -EINVAL;
+
+ REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
+
+ return 0;
+ }
+
void dss_select_lcd_clk_source(enum omap_channel channel,
- enum omap_dss_clk_source clk_src)
+ enum dss_clk_source clk_src)
{
- int b, ix, pos;
+ int idx = dss_get_channel_index(channel);
+ int r;
if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
dss_select_dispc_clk_source(clk_src);
+ dss.lcd_clk_source[idx] = clk_src;
return;
}
- switch (clk_src) {
- case OMAP_DSS_CLK_SRC_FCK:
- b = 0;
- break;
- case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
- BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
- b = 1;
- break;
- case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
- BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
- channel != OMAP_DSS_CHANNEL_LCD3);
- b = 1;
- break;
- default:
- BUG();
+ r = dss.feat->select_lcd_source(channel, clk_src);
+ if (r)
return;
- }
-
- pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
- (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
- REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
- ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
- (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
- dss.lcd_clk_source[ix] = clk_src;
+ dss.lcd_clk_source[idx] = clk_src;
}
- enum omap_dss_clk_source dss_get_dispc_clk_source(void)
+ enum dss_clk_source dss_get_dispc_clk_source(void)
{
return dss.dispc_clk_source;
}
- enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
+ enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
{
return dss.dsi_clk_source[dsi_module];
}
- enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
+ enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
{
if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
- int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
- (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
- return dss.lcd_clk_source[ix];
+ int idx = dss_get_channel_index(channel);
+ return dss.lcd_clk_source[idx];
} else {
/* LCD_CLK source is the same as DISPC_FCLK source for
* OMAP2 and OMAP3 */
.dpi_select_source = &dss_dpi_select_source_omap4,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .select_lcd_source = &dss_lcd_clk_mux_omap4,
};
static const struct dss_features omap54xx_dss_feats = {
.dpi_select_source = &dss_dpi_select_source_omap5,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .select_lcd_source = &dss_lcd_clk_mux_omap5,
};
static const struct dss_features am43xx_dss_feats = {
.dpi_select_source = &dss_dpi_select_source_dra7xx,
.ports = dra7xx_ports,
.num_ports = ARRAY_SIZE(dra7xx_ports),
+ .select_lcd_source = &dss_lcd_clk_mux_dra7,
};
static int dss_init_features(struct platform_device *pdev)
/* Select DPLL */
REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
- dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
+ dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
#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
- dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
- dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
- dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
- dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
- dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
+ dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK;
+ dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK;
+ dss.dispc_clk_source = DSS_CLK_SRC_FCK;
+ dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
+ dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
rev = dss_read_reg(DSS_REVISION);
printk(KERN_INFO "OMAP DSS rev %d.%d\n",
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/seq_file.h>
+ #include <linux/pm_runtime.h>
#include <video/omapdss.h>
DUMPPLL(PLLCTRL_CFG4);
}
- void hdmi_pll_compute(struct hdmi_pll_data *pll,
- unsigned long target_tmds, struct dss_pll_clock_info *pi)
- {
- unsigned long fint, clkdco, clkout;
- unsigned long target_bitclk, target_clkdco;
- unsigned long min_dco;
- unsigned n, m, mf, m2, sd;
- unsigned long clkin;
- const struct dss_pll_hw *hw = pll->pll.hw;
-
- clkin = clk_get_rate(pll->pll.clkin);
-
- DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds);
-
- target_bitclk = target_tmds * 10;
-
- /* Fint */
- n = DIV_ROUND_UP(clkin, hw->fint_max);
- fint = clkin / n;
-
- /* adjust m2 so that the clkdco will be high enough */
- min_dco = roundup(hw->clkdco_min, fint);
- m2 = DIV_ROUND_UP(min_dco, target_bitclk);
- if (m2 == 0)
- m2 = 1;
-
- target_clkdco = target_bitclk * m2;
- m = target_clkdco / fint;
-
- clkdco = fint * m;
-
- /* adjust clkdco with fractional mf */
- if (WARN_ON(target_clkdco - clkdco > fint))
- mf = 0;
- else
- mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
-
- if (mf > 0)
- clkdco += (u32)div_u64((u64)mf * fint, 262144);
-
- clkout = clkdco / m2;
-
- /* sigma-delta */
- sd = DIV_ROUND_UP(fint * m, 250000000);
-
- DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
- n, m, mf, m2, sd);
- DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
-
- pi->n = n;
- pi->m = m;
- pi->mf = mf;
- pi->mX[0] = m2;
- pi->sd = sd;
-
- pi->fint = fint;
- pi->clkdco = clkdco;
- pi->clkout[0] = clkout;
- }
-
static int hdmi_pll_enable(struct dss_pll *dsspll)
{
struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
struct hdmi_wp_data *wp = pll->wp;
- u16 r = 0;
+ int r;
+
+ r = pm_runtime_get_sync(&pll->pdev->dev);
+ WARN_ON(r < 0);
dss_ctrl_pll_enable(DSS_PLL_HDMI, true);
{
struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
struct hdmi_wp_data *wp = pll->wp;
+ int r;
hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
dss_ctrl_pll_enable(DSS_PLL_HDMI, false);
+
+ r = pm_runtime_put_sync(&pll->pdev->dev);
+ WARN_ON(r < 0 && r != -ENOSYS);
}
static const struct dss_pll_ops dsi_pll_ops = {
};
static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
+ .type = DSS_PLL_TYPE_B,
+
.n_max = 255,
.m_min = 20,
.m_max = 4095,
};
static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
+ .type = DSS_PLL_TYPE_B,
+
.n_max = 255,
.m_min = 20,
.m_max = 2045,
int r;
struct resource *res;
+ pll->pdev = pdev;
pll->wp = wp;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");