diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss')
21 files changed, 574 insertions, 450 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig index d1fa730c7d54..f53adb944a0d 100644 --- a/drivers/gpu/drm/omapdrm/dss/Kconfig +++ b/drivers/gpu/drm/omapdrm/dss/Kconfig @@ -1,8 +1,12 @@ config OMAP2_DSS_INIT bool +config OMAP_DSS_BASE + tristate + menuconfig OMAP2_DSS tristate "OMAP2+ Display Subsystem support" + select OMAP_DSS_BASE select VIDEOMODE_HELPERS select OMAP2_DSS_INIT select HDMI diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile index b651ec9751e6..75ec30f231c7 100644 --- a/drivers/gpu/drm/omapdrm/dss/Makefile +++ b/drivers/gpu/drm/omapdrm/dss/Makefile @@ -1,8 +1,12 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o + +obj-$(CONFIG_OMAP_DSS_BASE) += omapdss-base.o +omapdss-base-y := base.o display.o dss-of.o output.o + obj-$(CONFIG_OMAP2_DSS) += omapdss.o # Core DSS files -omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ - output.o dss-of.o pll.o video-pll.o +omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o \ + pll.o video-pll.o omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c new file mode 100644 index 000000000000..13e91faaf7a6 --- /dev/null +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -0,0 +1,140 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/list.h> +#include "omapdss.h" + +static bool dss_initialized; +static const struct dispc_ops *ops; + +static struct list_head omapdss_comp_list; + +struct omapdss_comp_node { + struct list_head list; + struct device_node *node; + bool dss_core_component; +}; + +void omapdss_set_is_initialized(bool set) +{ + dss_initialized = set; +} +EXPORT_SYMBOL(omapdss_set_is_initialized); + +bool omapdss_is_initialized(void) +{ + return dss_initialized; +} +EXPORT_SYMBOL(omapdss_is_initialized); + +void dispc_set_ops(const struct dispc_ops *o) +{ + ops = o; +} +EXPORT_SYMBOL(dispc_set_ops); + +const struct dispc_ops *dispc_get_ops(void) +{ + return ops; +} +EXPORT_SYMBOL(dispc_get_ops); + +static bool omapdss_list_contains(const struct device_node *node) +{ + struct omapdss_comp_node *comp; + + list_for_each_entry(comp, &omapdss_comp_list, list) { + if (comp->node == node) + return true; + } + + return false; +} + +static void omapdss_walk_device(struct device *dev, struct device_node *node, + bool dss_core) +{ + struct device_node *n; + struct omapdss_comp_node *comp = devm_kzalloc(dev, sizeof(*comp), + GFP_KERNEL); + + if (comp) { + comp->node = node; + comp->dss_core_component = dss_core; + list_add(&comp->list, &omapdss_comp_list); + } + + /* + * of_graph_get_remote_port_parent() prints an error if there is no + * port/ports node. To avoid that, check first that there's the node. + */ + n = of_get_child_by_name(node, "ports"); + if (!n) + n = of_get_child_by_name(node, "port"); + if (!n) + return; + + of_node_put(n); + + n = NULL; + while ((n = of_graph_get_next_endpoint(node, n)) != NULL) { + struct device_node *pn = of_graph_get_remote_port_parent(n); + + if (!pn) + continue; + + if (!of_device_is_available(pn) || omapdss_list_contains(pn)) { + of_node_put(pn); + continue; + } + + omapdss_walk_device(dev, pn, false); + } +} + +void omapdss_gather_components(struct device *dev) +{ + struct device_node *child; + + INIT_LIST_HEAD(&omapdss_comp_list); + + omapdss_walk_device(dev, dev->of_node, true); + + for_each_available_child_of_node(dev->of_node, child) { + if (!of_find_property(child, "compatible", NULL)) + continue; + + omapdss_walk_device(dev, child, true); + } +} +EXPORT_SYMBOL(omapdss_gather_components); + +static bool omapdss_component_is_loaded(struct omapdss_comp_node *comp) +{ + if (comp->dss_core_component) + return true; + if (omapdss_component_is_display(comp->node)) + return true; + if (omapdss_component_is_output(comp->node)) + return true; + + return false; +} + +bool omapdss_stack_is_ready(void) +{ + struct omapdss_comp_node *comp; + + list_for_each_entry(comp, &omapdss_comp_list, list) { + if (!omapdss_component_is_loaded(comp)) + return false; + } + + return true; +} +EXPORT_SYMBOL(omapdss_stack_is_ready); + +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); +MODULE_DESCRIPTION("OMAP Display Subsystem Base"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index d956e6266368..5ac0145fbae6 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -303,8 +303,12 @@ static unsigned long dispc_core_clk_rate(void); static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); -static unsigned long dispc_plane_pclk_rate(enum omap_plane plane); -static unsigned long dispc_plane_lclk_rate(enum omap_plane plane); +static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane); +static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane); + +static void dispc_clear_irqstatus(u32 mask); +static bool dispc_mgr_is_enabled(enum omap_channel channel); +static void dispc_clear_irqstatus(u32 mask); static inline void dispc_write_reg(const u16 idx, u32 val) { @@ -581,7 +585,6 @@ int dispc_runtime_get(void) WARN_ON(r < 0); return r < 0 ? r : 0; } -EXPORT_SYMBOL(dispc_runtime_get); void dispc_runtime_put(void) { @@ -592,54 +595,48 @@ void dispc_runtime_put(void) r = pm_runtime_put_sync(&dispc.pdev->dev); WARN_ON(r < 0 && r != -ENOSYS); } -EXPORT_SYMBOL(dispc_runtime_put); -u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) +static u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) { return mgr_desc[channel].vsync_irq; } -EXPORT_SYMBOL(dispc_mgr_get_vsync_irq); -u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) +static u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) { if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv) return 0; return mgr_desc[channel].framedone_irq; } -EXPORT_SYMBOL(dispc_mgr_get_framedone_irq); -u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel) +static u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel) { return mgr_desc[channel].sync_lost_irq; } -EXPORT_SYMBOL(dispc_mgr_get_sync_lost_irq); u32 dispc_wb_get_framedone_irq(void) { return DISPC_IRQ_FRAMEDONEWB; } -void dispc_mgr_enable(enum omap_channel channel, bool enable) +static void dispc_mgr_enable(enum omap_channel channel, bool enable) { mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); /* flush posted write */ mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); } -EXPORT_SYMBOL(dispc_mgr_enable); static bool dispc_mgr_is_enabled(enum omap_channel channel) { return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); } -bool dispc_mgr_go_busy(enum omap_channel channel) +static bool dispc_mgr_go_busy(enum omap_channel channel) { return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; } -EXPORT_SYMBOL(dispc_mgr_go_busy); -void dispc_mgr_go(enum omap_channel channel) +static void dispc_mgr_go(enum omap_channel channel) { WARN_ON(!dispc_mgr_is_enabled(channel)); WARN_ON(dispc_mgr_go_busy(channel)); @@ -648,7 +645,6 @@ void dispc_mgr_go(enum omap_channel channel) mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); } -EXPORT_SYMBOL(dispc_mgr_go); bool dispc_wb_go_busy(void) { @@ -657,7 +653,7 @@ bool dispc_wb_go_busy(void) void dispc_wb_go(void) { - enum omap_plane plane = OMAP_DSS_WB; + enum omap_plane_id plane = OMAP_DSS_WB; bool enable, go; enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1; @@ -674,29 +670,33 @@ void dispc_wb_go(void) REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6); } -static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) +static void dispc_ovl_write_firh_reg(enum omap_plane_id plane, int reg, + u32 value) { dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); } -static void dispc_ovl_write_firhv_reg(enum omap_plane plane, int reg, u32 value) +static void dispc_ovl_write_firhv_reg(enum omap_plane_id plane, int reg, + u32 value) { dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value); } -static void dispc_ovl_write_firv_reg(enum omap_plane plane, int reg, u32 value) +static void dispc_ovl_write_firv_reg(enum omap_plane_id plane, int reg, + u32 value) { dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value); } -static void dispc_ovl_write_firh2_reg(enum omap_plane plane, int reg, u32 value) +static void dispc_ovl_write_firh2_reg(enum omap_plane_id plane, int reg, + u32 value) { BUG_ON(plane == OMAP_DSS_GFX); dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value); } -static void dispc_ovl_write_firhv2_reg(enum omap_plane plane, int reg, +static void dispc_ovl_write_firhv2_reg(enum omap_plane_id plane, int reg, u32 value) { BUG_ON(plane == OMAP_DSS_GFX); @@ -704,14 +704,15 @@ static void dispc_ovl_write_firhv2_reg(enum omap_plane plane, int reg, dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value); } -static void dispc_ovl_write_firv2_reg(enum omap_plane plane, int reg, u32 value) +static void dispc_ovl_write_firv2_reg(enum omap_plane_id plane, int reg, + u32 value) { BUG_ON(plane == OMAP_DSS_GFX); dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value); } -static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc, +static void dispc_ovl_set_scale_coef(enum omap_plane_id plane, int fir_hinc, int fir_vinc, int five_taps, enum omap_color_component color_comp) { @@ -757,7 +758,7 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc, } -static void dispc_ovl_write_color_conv_coef(enum omap_plane plane, +static void dispc_ovl_write_color_conv_coef(enum omap_plane_id plane, const struct color_conv_coef *ct) { #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) @@ -793,27 +794,27 @@ static void dispc_setup_color_conv_coef(void) dispc_ovl_write_color_conv_coef(OMAP_DSS_WB, &ctbl_bt601_5_wb); } -static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr) +static void dispc_ovl_set_ba0(enum omap_plane_id plane, u32 paddr) { dispc_write_reg(DISPC_OVL_BA0(plane), paddr); } -static void dispc_ovl_set_ba1(enum omap_plane plane, u32 paddr) +static void dispc_ovl_set_ba1(enum omap_plane_id plane, u32 paddr) { dispc_write_reg(DISPC_OVL_BA1(plane), paddr); } -static void dispc_ovl_set_ba0_uv(enum omap_plane plane, u32 paddr) +static void dispc_ovl_set_ba0_uv(enum omap_plane_id plane, u32 paddr) { dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr); } -static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr) +static void dispc_ovl_set_ba1_uv(enum omap_plane_id plane, u32 paddr) { dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); } -static void dispc_ovl_set_pos(enum omap_plane plane, +static void dispc_ovl_set_pos(enum omap_plane_id plane, enum omap_overlay_caps caps, int x, int y) { u32 val; @@ -826,7 +827,7 @@ static void dispc_ovl_set_pos(enum omap_plane plane, dispc_write_reg(DISPC_OVL_POSITION(plane), val); } -static void dispc_ovl_set_input_size(enum omap_plane plane, int width, +static void dispc_ovl_set_input_size(enum omap_plane_id plane, int width, int height) { u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); @@ -837,7 +838,7 @@ static void dispc_ovl_set_input_size(enum omap_plane plane, int width, dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); } -static void dispc_ovl_set_output_size(enum omap_plane plane, int width, +static void dispc_ovl_set_output_size(enum omap_plane_id plane, int width, int height) { u32 val; @@ -852,7 +853,7 @@ static void dispc_ovl_set_output_size(enum omap_plane plane, int width, dispc_write_reg(DISPC_OVL_SIZE(plane), val); } -static void dispc_ovl_set_zorder(enum omap_plane plane, +static void dispc_ovl_set_zorder(enum omap_plane_id plane, enum omap_overlay_caps caps, u8 zorder) { if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) @@ -872,7 +873,7 @@ static void dispc_ovl_enable_zorder_planes(void) REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); } -static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, +static void dispc_ovl_set_pre_mult_alpha(enum omap_plane_id plane, enum omap_overlay_caps caps, bool enable) { if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) @@ -881,7 +882,7 @@ static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); } -static void dispc_ovl_setup_global_alpha(enum omap_plane plane, +static void dispc_ovl_setup_global_alpha(enum omap_plane_id plane, enum omap_overlay_caps caps, u8 global_alpha) { static const unsigned shifts[] = { 0, 8, 16, 24, }; @@ -894,17 +895,17 @@ static void dispc_ovl_setup_global_alpha(enum omap_plane plane, REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, shift + 7, shift); } -static void dispc_ovl_set_pix_inc(enum omap_plane plane, s32 inc) +static void dispc_ovl_set_pix_inc(enum omap_plane_id plane, s32 inc) { dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc); } -static void dispc_ovl_set_row_inc(enum omap_plane plane, s32 inc) +static void dispc_ovl_set_row_inc(enum omap_plane_id plane, s32 inc) { dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc); } -static void dispc_ovl_set_color_mode(enum omap_plane plane, +static void dispc_ovl_set_color_mode(enum omap_plane_id plane, enum omap_color_mode color_mode) { u32 m = 0; @@ -985,7 +986,7 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane, REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); } -static void dispc_ovl_configure_burst_type(enum omap_plane plane, +static void dispc_ovl_configure_burst_type(enum omap_plane_id plane, enum omap_dss_rotation_type rotation_type) { if (dss_has_feature(FEAT_BURST_2D) == 0) @@ -997,7 +998,8 @@ static void dispc_ovl_configure_burst_type(enum omap_plane plane, REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0, 29, 29); } -void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) +static void dispc_ovl_set_channel_out(enum omap_plane_id plane, + enum omap_channel channel) { int shift; u32 val; @@ -1057,9 +1059,8 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) } dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); } -EXPORT_SYMBOL(dispc_ovl_set_channel_out); -static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) +static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane_id plane) { int shift; u32 val; @@ -1101,12 +1102,12 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) void dispc_wb_set_channel_in(enum dss_writeback_channel channel) { - enum omap_plane plane = OMAP_DSS_WB; + enum omap_plane_id plane = OMAP_DSS_WB; REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16); } -static void dispc_ovl_set_burst_size(enum omap_plane plane, +static void dispc_ovl_set_burst_size(enum omap_plane_id plane, enum omap_burst_size burst_size) { static const unsigned shifts[] = { 6, 14, 14, 14, 14, }; @@ -1128,13 +1129,23 @@ static void dispc_configure_burst_sizes(void) dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size); } -static u32 dispc_ovl_get_burst_size(enum omap_plane plane) +static u32 dispc_ovl_get_burst_size(enum omap_plane_id plane) { unsigned unit = dss_feat_get_burst_size_unit(); /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ return unit * 8; } +static enum omap_color_mode dispc_ovl_get_color_modes(enum omap_plane_id plane) +{ + return dss_feat_get_supported_color_modes(plane); +} + +static int dispc_get_num_ovls(void) +{ + return dss_feat_get_num_ovls(); +} + static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) { if (channel == OMAP_DSS_CHANNEL_DIGIT) @@ -1163,7 +1174,8 @@ static void dispc_mgr_set_cpr_coef(enum omap_channel channel, dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b); } -static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) +static void dispc_ovl_set_vid_color_conv(enum omap_plane_id plane, + bool enable) { u32 val; @@ -1174,7 +1186,7 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); } -static void dispc_ovl_enable_replication(enum omap_plane plane, +static void dispc_ovl_enable_replication(enum omap_plane_id plane, enum omap_overlay_caps caps, bool enable) { static const unsigned shifts[] = { 5, 10, 10, 10 }; @@ -1271,7 +1283,7 @@ static void dispc_init_fifos(void) } } -static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) +static u32 dispc_ovl_get_fifo_size(enum omap_plane_id plane) { int fifo; u32 size = 0; @@ -1284,7 +1296,8 @@ static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) return size; } -void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) +void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low, + u32 high) { u8 hi_start, hi_end, lo_start, lo_end; u32 unit; @@ -1333,7 +1346,7 @@ void dispc_enable_fifomerge(bool enable) REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } -void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, +void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane, u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, bool manual_update) { @@ -1380,7 +1393,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, } } -static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable) +static void dispc_ovl_set_mflag(enum omap_plane_id plane, bool enable) { int bit; @@ -1392,7 +1405,7 @@ static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable) REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit); } -static void dispc_ovl_set_mflag_threshold(enum omap_plane plane, +static void dispc_ovl_set_mflag_threshold(enum omap_plane_id plane, int low, int high) { dispc_write_reg(DISPC_OVL_MFLAG_THRESHOLD(plane), @@ -1456,7 +1469,7 @@ static void dispc_init_mflag(void) } } -static void dispc_ovl_set_fir(enum omap_plane plane, +static void dispc_ovl_set_fir(enum omap_plane_id plane, int hinc, int vinc, enum omap_color_component color_comp) { @@ -1479,7 +1492,8 @@ static void dispc_ovl_set_fir(enum omap_plane plane, } } -static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) +static void dispc_ovl_set_vid_accu0(enum omap_plane_id plane, int haccu, + int vaccu) { u32 val; u8 hor_start, hor_end, vert_start, vert_end; @@ -1493,7 +1507,8 @@ static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) dispc_write_reg(DISPC_OVL_ACCU0(plane), val); } -static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) +static void dispc_ovl_set_vid_accu1(enum omap_plane_id plane, int haccu, + int vaccu) { u32 val; u8 hor_start, hor_end, vert_start, vert_end; @@ -1507,7 +1522,7 @@ static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) dispc_write_reg(DISPC_OVL_ACCU1(plane), val); } -static void dispc_ovl_set_vid_accu2_0(enum omap_plane plane, int haccu, +static void dispc_ovl_set_vid_accu2_0(enum omap_plane_id plane, int haccu, int vaccu) { u32 val; @@ -1516,7 +1531,7 @@ static void dispc_ovl_set_vid_accu2_0(enum omap_plane plane, int haccu, dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val); } -static void dispc_ovl_set_vid_accu2_1(enum omap_plane plane, int haccu, +static void dispc_ovl_set_vid_accu2_1(enum omap_plane_id plane, int haccu, int vaccu) { u32 val; @@ -1525,7 +1540,7 @@ static void dispc_ovl_set_vid_accu2_1(enum omap_plane plane, int haccu, dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val); } -static void dispc_ovl_set_scale_param(enum omap_plane plane, +static void dispc_ovl_set_scale_param(enum omap_plane_id plane, u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, bool five_taps, u8 rotation, @@ -1541,7 +1556,7 @@ static void dispc_ovl_set_scale_param(enum omap_plane plane, dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp); } -static void dispc_ovl_set_accu_uv(enum omap_plane plane, +static void dispc_ovl_set_accu_uv(enum omap_plane_id plane, u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, bool ilace, enum omap_color_mode color_mode, u8 rotation) { @@ -1629,7 +1644,7 @@ static void dispc_ovl_set_accu_uv(enum omap_plane plane, dispc_ovl_set_vid_accu2_1(plane, h_accu2_1, v_accu2_1); } -static void dispc_ovl_set_scaling_common(enum omap_plane plane, +static void dispc_ovl_set_scaling_common(enum omap_plane_id plane, u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, bool ilace, bool five_taps, @@ -1683,7 +1698,7 @@ static void dispc_ovl_set_scaling_common(enum omap_plane plane, dispc_ovl_set_vid_accu1(plane, 0, accu1); } -static void dispc_ovl_set_scaling_uv(enum omap_plane plane, +static void dispc_ovl_set_scaling_uv(enum omap_plane_id plane, u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, bool ilace, bool five_taps, @@ -1763,7 +1778,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6); } -static void dispc_ovl_set_scaling(enum omap_plane plane, +static void dispc_ovl_set_scaling(enum omap_plane_id plane, u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, bool ilace, bool five_taps, @@ -1787,7 +1802,7 @@ static void dispc_ovl_set_scaling(enum omap_plane plane, rotation); } -static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation, +static void dispc_ovl_set_rotation_attrs(enum omap_plane_id plane, u8 rotation, enum omap_dss_rotation_type rotation_type, bool mirroring, enum omap_color_mode color_mode) { @@ -2619,7 +2634,7 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk, return 0; } -static int dispc_ovl_setup_common(enum omap_plane plane, +static int dispc_ovl_setup_common(enum omap_plane_id plane, enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr, u16 screen_width, int pos_x, int pos_y, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, @@ -2817,13 +2832,14 @@ static int dispc_ovl_setup_common(enum omap_plane plane, return 0; } -int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, - bool replication, const struct videomode *vm, - bool mem_to_mem) +static int dispc_ovl_setup(enum omap_plane_id plane, + const struct omap_overlay_info *oi, + const struct videomode *vm, bool mem_to_mem) { int r; enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane); enum omap_channel channel; + const bool replication = true; channel = dispc_ovl_get_channel_out(plane); @@ -2841,17 +2857,16 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, return r; } -EXPORT_SYMBOL(dispc_ovl_setup); int dispc_wb_setup(const struct omap_dss_writeback_info *wi, bool mem_to_mem, const struct videomode *vm) { int r; u32 l; - enum omap_plane plane = OMAP_DSS_WB; + enum omap_plane_id plane = OMAP_DSS_WB; const int pos_x = 0, pos_y = 0; const u8 zorder = 0, global_alpha = 0; - const bool replication = false; + const bool replication = true; bool truncation; int in_width = vm->hactive; int in_height = vm->vactive; @@ -2911,7 +2926,7 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi, return r; } -int dispc_ovl_enable(enum omap_plane plane, bool enable) +static int dispc_ovl_enable(enum omap_plane_id plane, bool enable) { DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); @@ -2919,29 +2934,16 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable) return 0; } -EXPORT_SYMBOL(dispc_ovl_enable); -bool dispc_ovl_enabled(enum omap_plane plane) +static bool dispc_ovl_enabled(enum omap_plane_id plane) { return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); } -EXPORT_SYMBOL(dispc_ovl_enabled); -enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel) +static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel) { return dss_feat_get_supported_outputs(channel); } -EXPORT_SYMBOL(dispc_mgr_get_supported_outputs); - -void dispc_wb_enable(bool enable) -{ - dispc_ovl_enable(OMAP_DSS_WB, enable); -} - -bool dispc_wb_is_enabled(void) -{ - return dispc_ovl_enabled(OMAP_DSS_WB); -} static void dispc_lcd_enable_signal_polarity(bool act_high) { @@ -2967,6 +2969,11 @@ void dispc_pck_free_enable(bool enable) REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); } +static int dispc_get_num_mgrs(void) +{ + return dss_feat_get_num_mgrs(); +} + static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) { mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable); @@ -3015,7 +3022,7 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); } -void dispc_mgr_setup(enum omap_channel channel, +static void dispc_mgr_setup(enum omap_channel channel, const struct omap_overlay_manager_info *info) { dispc_mgr_set_default_color(channel, info->default_color); @@ -3028,7 +3035,6 @@ void dispc_mgr_setup(enum omap_channel channel, dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs); } } -EXPORT_SYMBOL(dispc_mgr_setup); static void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines) { @@ -3089,7 +3095,7 @@ static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable); } -void dispc_mgr_set_lcd_config(enum omap_channel channel, +static void dispc_mgr_set_lcd_config(enum omap_channel channel, const struct dss_lcd_mgr_config *config) { dispc_mgr_set_io_pad_mode(config->io_pad_mode); @@ -3105,7 +3111,6 @@ void dispc_mgr_set_lcd_config(enum omap_channel channel, dispc_mgr_set_lcd_type_tft(channel); } -EXPORT_SYMBOL(dispc_mgr_set_lcd_config); static bool _dispc_mgr_size_ok(u16 width, u16 height) { @@ -3235,8 +3240,18 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, } } +static int vm_flag_to_int(enum display_flags flags, enum display_flags high, + enum display_flags low) +{ + if (flags & high) + return 1; + if (flags & low) + return -1; + return 0; +} + /* change name to mode? */ -void dispc_mgr_set_timings(enum omap_channel channel, +static void dispc_mgr_set_timings(enum omap_channel channel, const struct videomode *vm) { unsigned xtot, ytot; @@ -3264,11 +3279,11 @@ void dispc_mgr_set_timings(enum omap_channel channel, t.hsync_len, t.hfront_porch, t.hback_porch, t.vsync_len, t.vfront_porch, t.vback_porch); DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n", - !!(t.flags & DISPLAY_FLAGS_VSYNC_HIGH), - !!(t.flags & DISPLAY_FLAGS_HSYNC_HIGH), - !!(t.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE), - !!(t.flags & DISPLAY_FLAGS_DE_HIGH), - !!(t.flags & DISPLAY_FLAGS_SYNC_POSEDGE)); + vm_flag_to_int(t.flags, DISPLAY_FLAGS_VSYNC_HIGH, DISPLAY_FLAGS_VSYNC_LOW), + vm_flag_to_int(t.flags, DISPLAY_FLAGS_HSYNC_HIGH, DISPLAY_FLAGS_HSYNC_LOW), + vm_flag_to_int(t.flags, DISPLAY_FLAGS_PIXDATA_POSEDGE, DISPLAY_FLAGS_PIXDATA_NEGEDGE), + vm_flag_to_int(t.flags, DISPLAY_FLAGS_DE_HIGH, DISPLAY_FLAGS_DE_LOW), + vm_flag_to_int(t.flags, DISPLAY_FLAGS_SYNC_POSEDGE, DISPLAY_FLAGS_SYNC_NEGEDGE)); DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); } else { @@ -3283,7 +3298,6 @@ void dispc_mgr_set_timings(enum omap_channel channel, dispc_mgr_set_size(channel, t.hactive, t.vactive); } -EXPORT_SYMBOL(dispc_mgr_set_timings); static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, u16 pck_div) @@ -3389,7 +3403,7 @@ static unsigned long dispc_core_clk_rate(void) return dispc.core_clk_rate; } -static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) +static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane) { enum omap_channel channel; @@ -3401,7 +3415,7 @@ static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) return dispc_mgr_pclk_rate(channel); } -static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) +static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane) { enum omap_channel channel; @@ -3763,25 +3777,22 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, return 0; } -u32 dispc_read_irqstatus(void) +static u32 dispc_read_irqstatus(void) { return dispc_read_reg(DISPC_IRQSTATUS); } -EXPORT_SYMBOL(dispc_read_irqstatus); -void dispc_clear_irqstatus(u32 mask) +static void dispc_clear_irqstatus(u32 mask) { dispc_write_reg(DISPC_IRQSTATUS, mask); } -EXPORT_SYMBOL(dispc_clear_irqstatus); -u32 dispc_read_irqenable(void) +static u32 dispc_read_irqenable(void) { return dispc_read_reg(DISPC_IRQENABLE); } -EXPORT_SYMBOL(dispc_read_irqenable); -void dispc_write_irqenable(u32 mask) +static void dispc_write_irqenable(u32 mask) { u32 old_mask = dispc_read_reg(DISPC_IRQENABLE); @@ -3790,7 +3801,6 @@ void dispc_write_irqenable(u32 mask) dispc_write_reg(DISPC_IRQENABLE, mask); } -EXPORT_SYMBOL(dispc_write_irqenable); void dispc_enable_sidle(void) { @@ -3802,7 +3812,7 @@ void dispc_disable_sidle(void) REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */ } -u32 dispc_mgr_gamma_size(enum omap_channel channel) +static u32 dispc_mgr_gamma_size(enum omap_channel channel) { const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; @@ -3811,7 +3821,6 @@ u32 dispc_mgr_gamma_size(enum omap_channel channel) return gdesc->len; } -EXPORT_SYMBOL(dispc_mgr_gamma_size); static void dispc_mgr_write_gamma_table(enum omap_channel channel) { @@ -3856,7 +3865,7 @@ static const struct drm_color_lut dispc_mgr_gamma_default_lut[] = { { .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, }, }; -void dispc_mgr_set_gamma(enum omap_channel channel, +static void dispc_mgr_set_gamma(enum omap_channel channel, const struct drm_color_lut *lut, unsigned int length) { @@ -3902,7 +3911,6 @@ void dispc_mgr_set_gamma(enum omap_channel channel, if (dispc.is_enabled) dispc_mgr_write_gamma_table(channel); } -EXPORT_SYMBOL(dispc_mgr_set_gamma); static int dispc_init_gamma_tables(void) { @@ -4149,7 +4157,7 @@ static irqreturn_t dispc_irq_handler(int irq, void *arg) return dispc.user_handler(irq, dispc.user_data); } -int dispc_request_irq(irq_handler_t handler, void *dev_id) +static int dispc_request_irq(irq_handler_t handler, void *dev_id) { int r; @@ -4171,16 +4179,14 @@ int dispc_request_irq(irq_handler_t handler, void *dev_id) return r; } -EXPORT_SYMBOL(dispc_request_irq); -void dispc_free_irq(void *dev_id) +static void dispc_free_irq(void *dev_id) { devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc); dispc.user_handler = NULL; dispc.user_data = NULL; } -EXPORT_SYMBOL(dispc_free_irq); /* * Workaround for errata i734 in DSS dispc @@ -4304,7 +4310,7 @@ static void dispc_errata_i734_wa(void) /* Setup and enable GFX plane */ dispc_ovl_set_channel_out(OMAP_DSS_GFX, OMAP_DSS_CHANNEL_LCD); - dispc_ovl_setup(OMAP_DSS_GFX, &ovli, false, &i734.vm, false); + dispc_ovl_setup(OMAP_DSS_GFX, &ovli, &i734.vm, false); dispc_ovl_enable(OMAP_DSS_GFX, true); /* Set up and enable display manager for LCD1 */ @@ -4341,6 +4347,42 @@ static void dispc_errata_i734_wa(void) REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4); } +static const struct dispc_ops dispc_ops = { + .read_irqstatus = dispc_read_irqstatus, + .clear_irqstatus = dispc_clear_irqstatus, + .read_irqenable = dispc_read_irqenable, + .write_irqenable = dispc_write_irqenable, + + .request_irq = dispc_request_irq, + .free_irq = dispc_free_irq, + + .runtime_get = dispc_runtime_get, + .runtime_put = dispc_runtime_put, + + .get_num_ovls = dispc_get_num_ovls, + .get_num_mgrs = dispc_get_num_mgrs, + + .mgr_enable = dispc_mgr_enable, + .mgr_is_enabled = dispc_mgr_is_enabled, + .mgr_get_vsync_irq = dispc_mgr_get_vsync_irq, + .mgr_get_framedone_irq = dispc_mgr_get_framedone_irq, + .mgr_get_sync_lost_irq = dispc_mgr_get_sync_lost_irq, + .mgr_go_busy = dispc_mgr_go_busy, + .mgr_go = dispc_mgr_go, + .mgr_set_lcd_config = dispc_mgr_set_lcd_config, + .mgr_set_timings = dispc_mgr_set_timings, + .mgr_setup = dispc_mgr_setup, + .mgr_get_supported_outputs = dispc_mgr_get_supported_outputs, + .mgr_gamma_size = dispc_mgr_gamma_size, + .mgr_set_gamma = dispc_mgr_set_gamma, + + .ovl_enable = dispc_ovl_enable, + .ovl_enabled = dispc_ovl_enabled, + .ovl_set_channel_out = dispc_ovl_set_channel_out, + .ovl_setup = dispc_ovl_setup, + .ovl_get_color_modes = dispc_ovl_get_color_modes, +}; + /* DISPC HW IP initialisation */ static int dispc_bind(struct device *dev, struct device *master, void *data) { @@ -4413,6 +4455,8 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) dispc_runtime_put(); + dispc_set_ops(&dispc_ops); + dss_debugfs_create_file("dispc", dispc_dump_regs); return 0; @@ -4425,6 +4469,8 @@ err_runtime_get: static void dispc_unbind(struct device *dev, struct device *master, void *data) { + dispc_set_ops(NULL); + pm_runtime_disable(dev); dispc_errata_i734_wa_fini(); diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.h b/drivers/gpu/drm/omapdrm/dss/dispc.h index bc1d8126ee87..003adce532f4 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.h +++ b/drivers/gpu/drm/omapdrm/dss/dispc.h @@ -353,7 +353,7 @@ static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel) } /* DISPC overlay register base addresses */ -static inline u16 DISPC_OVL_BASE(enum omap_plane plane) +static inline u16 DISPC_OVL_BASE(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -373,7 +373,7 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane) } /* DISPC overlay register offsets */ -static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) +static inline u16 DISPC_BA0_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -389,7 +389,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) +static inline u16 DISPC_BA1_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -405,7 +405,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) +static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -425,7 +425,7 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) +static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -445,7 +445,7 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_POS_OFFSET(enum omap_plane plane) +static inline u16 DISPC_POS_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -460,7 +460,7 @@ static inline u16 DISPC_POS_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) +static inline u16 DISPC_SIZE_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -476,7 +476,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) +static inline u16 DISPC_ATTR_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -493,7 +493,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) +static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -513,7 +513,7 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) +static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -530,7 +530,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane) +static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -547,7 +547,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) +static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -564,7 +564,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) +static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -581,7 +581,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane) +static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -597,7 +597,7 @@ static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane) +static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -613,7 +613,7 @@ static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) +static inline u16 DISPC_FIR_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -631,7 +631,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) +static inline u16 DISPC_FIR2_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -651,7 +651,7 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) +static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -670,7 +670,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) } -static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) +static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -688,7 +688,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) +static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -708,7 +708,7 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) +static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -726,7 +726,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) +static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -747,7 +747,7 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) } /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ -static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) +static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane_id plane, u16 i) { switch (plane) { case OMAP_DSS_GFX: @@ -766,7 +766,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) } /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ -static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) +static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane_id plane, u16 i) { switch (plane) { case OMAP_DSS_GFX: @@ -787,7 +787,7 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) } /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ -static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) +static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane_id plane, u16 i) { switch (plane) { case OMAP_DSS_GFX: @@ -806,7 +806,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) } /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ -static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) +static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane_id plane, u16 i) { switch (plane) { case OMAP_DSS_GFX: @@ -827,7 +827,7 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) } /* coef index i = {0, 1, 2, 3, 4,} */ -static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i) +static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane_id plane, u16 i) { switch (plane) { case OMAP_DSS_GFX: @@ -845,7 +845,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i) } /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ -static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) +static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane_id plane, u16 i) { switch (plane) { case OMAP_DSS_GFX: @@ -865,7 +865,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) } /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ -static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) +static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane_id plane, u16 i) { switch (plane) { case OMAP_DSS_GFX: @@ -885,7 +885,7 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) } } -static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane) +static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: @@ -902,7 +902,7 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane) } } -static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane plane) +static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane_id plane) { switch (plane) { case OMAP_DSS_GFX: diff --git a/drivers/gpu/drm/omapdrm/dss/display.c b/drivers/gpu/drm/omapdrm/dss/display.c index 425a5a8dff8b..26cb59be045e 100644 --- a/drivers/gpu/drm/omapdrm/dss/display.c +++ b/drivers/gpu/drm/omapdrm/dss/display.c @@ -29,8 +29,6 @@ #include <linux/of.h> #include "omapdss.h" -#include "dss.h" -#include "dss_features.h" void omapdss_default_get_resolution(struct omap_dss_device *dssdev, u16 *xres, u16 *yres) @@ -55,10 +53,10 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) else return 16; case OMAP_DISPLAY_TYPE_DSI: - if (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) > 16) - return 24; - else + if (dssdev->panel.dsi_pix_fmt == OMAP_DSS_DSI_FMT_RGB565) return 16; + else + return 24; case OMAP_DISPLAY_TYPE_VENC: case OMAP_DISPLAY_TYPE_SDI: case OMAP_DISPLAY_TYPE_HDMI: @@ -85,6 +83,7 @@ static int disp_num_counter; int omapdss_register_display(struct omap_dss_device *dssdev) { struct omap_dss_driver *drv = dssdev->driver; + struct list_head *cur; int id; /* @@ -120,7 +119,14 @@ int omapdss_register_display(struct omap_dss_device *dssdev) drv->get_timings = omapdss_default_get_timings; mutex_lock(&panel_list_mutex); - list_add_tail(&dssdev->panel_list, &panel_list); + list_for_each(cur, &panel_list) { + struct omap_dss_device *ldev = list_entry(cur, + struct omap_dss_device, + panel_list); + if (strcmp(ldev->alias, dssdev->alias) > 0) + break; + } + list_add_tail(&dssdev->panel_list, cur); mutex_unlock(&panel_list_mutex); return 0; } @@ -134,6 +140,24 @@ void omapdss_unregister_display(struct omap_dss_device *dssdev) } EXPORT_SYMBOL(omapdss_unregister_display); +bool omapdss_component_is_display(struct device_node *node) +{ + struct omap_dss_device *dssdev; + bool found = false; + + mutex_lock(&panel_list_mutex); + list_for_each_entry(dssdev, &panel_list, panel_list) { + if (dssdev->dev->of_node == node) { + found = true; + goto out; + } + } +out: + mutex_unlock(&panel_list_mutex); + return found; +} +EXPORT_SYMBOL(omapdss_component_is_display); + struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev) { if (!try_module_get(dssdev->owner)) diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index e75162d26ac0..8a730a7afe76 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -67,6 +67,45 @@ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev) return dev_get_drvdata(&pdev->dev); } +static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel) +{ + /* + * Possible clock sources: + * LCD1: FCK/PLL1_1/HDMI_PLL + * LCD2: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_3) + * LCD3: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_1) + */ + + switch (channel) { + case OMAP_DSS_CHANNEL_LCD: + { + if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_1)) + return DSS_CLK_SRC_PLL1_1; + break; + } + case OMAP_DSS_CHANNEL_LCD2: + { + if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3)) + return DSS_CLK_SRC_PLL1_3; + if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_3)) + return DSS_CLK_SRC_PLL2_3; + break; + } + case OMAP_DSS_CHANNEL_LCD3: + { + if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_1)) + return DSS_CLK_SRC_PLL2_1; + if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3)) + return DSS_CLK_SRC_PLL1_3; + break; + } + default: + break; + } + + return DSS_CLK_SRC_FCK; +} + static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel) { /* @@ -107,16 +146,7 @@ static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel) } case OMAPDSS_VER_DRA7xx: - switch (channel) { - case OMAP_DSS_CHANNEL_LCD: - return DSS_CLK_SRC_PLL1_1; - case OMAP_DSS_CHANNEL_LCD2: - return DSS_CLK_SRC_PLL1_3; - case OMAP_DSS_CHANNEL_LCD3: - return DSS_CLK_SRC_PLL2_1; - default: - return DSS_CLK_SRC_FCK; - } + return dpi_get_clk_src_dra7xx(channel); default: return DSS_CLK_SRC_FCK; @@ -170,14 +200,6 @@ static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc, { struct dpi_clk_calc_ctx *ctx = data; - /* - * Odd dividers give us uneven duty cycle, causing problem when level - * shifted. So skip all odd dividers when the pixel clock is on the - * higher side. - */ - if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000) - return false; - ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc; ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc; @@ -855,7 +877,7 @@ int dpi_init_port(struct platform_device *pdev, struct device_node *port) if (!dpi) return -ENOMEM; - ep = omapdss_of_get_next_endpoint(port, NULL); + ep = of_get_next_child(port, NULL); if (!ep) return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index f74615d005a8..910754bf8cf9 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -39,6 +39,7 @@ #include <linux/debugfs.h> #include <linux/pm_runtime.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <linux/of_platform.h> #include <linux/component.h> @@ -527,7 +528,7 @@ static inline int wait_for_bit_change(struct platform_device *dsidev, return !value; } -u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) +static u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) { switch (fmt) { case OMAP_DSS_DSI_FMT_RGB888: @@ -582,15 +583,14 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name) total_bytes = dsi->update_bytes; - printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " - "%u bytes, %u kbytes/sec\n", - name, - setup_us, - trans_us, - total_us, - 1000*1000 / total_us, - total_bytes, - total_bytes * 1000 / total_us); + pr_info("DSI(%s): %u us + %u us = %u us (%uHz), %u bytes, %u kbytes/sec\n", + name, + setup_us, + trans_us, + total_us, + 1000 * 1000 / total_us, + total_bytes, + total_bytes * 1000 / total_us); } #else static inline void dsi_perf_mark_setup(struct platform_device *dsidev) @@ -5091,7 +5091,7 @@ static int dsi_probe_of(struct platform_device *pdev) struct device_node *ep; struct omap_dsi_pin_config pin_cfg; - ep = omapdss_of_get_first_endpoint(node); + ep = of_graph_get_endpoint_by_regs(node, 0, 0); if (!ep) return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/dss-of.c b/drivers/gpu/drm/omapdrm/dss/dss-of.c index dfd4e9621e3b..c6b86f348a5c 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss-of.c +++ b/drivers/gpu/drm/omapdrm/dss/dss-of.c @@ -16,76 +16,10 @@ #include <linux/err.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <linux/seq_file.h> #include "omapdss.h" -#include "dss.h" - -struct device_node * -omapdss_of_get_next_port(const struct device_node *parent, - struct device_node *prev) -{ - struct device_node *port = NULL; - - if (!parent) - return NULL; - - if (!prev) { - struct device_node *ports; - /* - * It's the first call, we have to find a port subnode - * within this node or within an optional 'ports' node. - */ - ports = of_get_child_by_name(parent, "ports"); - if (ports) - parent = ports; - - port = of_get_child_by_name(parent, "port"); - - /* release the 'ports' node */ - of_node_put(ports); - } else { - struct device_node *ports; - - ports = of_get_parent(prev); - if (!ports) - return NULL; - - do { - port = of_get_next_child(ports, prev); - if (!port) { - of_node_put(ports); - return NULL; - } - prev = port; - } while (of_node_cmp(port->name, "port") != 0); - - of_node_put(ports); - } - - return port; -} -EXPORT_SYMBOL_GPL(omapdss_of_get_next_port); - -struct device_node * -omapdss_of_get_next_endpoint(const struct device_node *parent, - struct device_node *prev) -{ - struct device_node *ep = NULL; - - if (!parent) - return NULL; - - do { - ep = of_get_next_child(parent, prev); - if (!ep) - return NULL; - prev = ep; - } while (of_node_cmp(ep->name, "endpoint") != 0); - - return ep; -} -EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint); struct device_node *dss_of_port_get_parent_device(struct device_node *port) { @@ -110,6 +44,7 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port) return NULL; } +EXPORT_SYMBOL_GPL(dss_of_port_get_parent_device); u32 dss_of_port_get_port_number(struct device_node *port) { @@ -122,37 +57,7 @@ u32 dss_of_port_get_port_number(struct device_node *port) return reg; } - -static struct device_node *omapdss_of_get_remote_port(const struct device_node *node) -{ - struct device_node *np; - - np = of_parse_phandle(node, "remote-endpoint", 0); - if (!np) - return NULL; - - np = of_get_next_parent(np); - - return np; -} - -struct device_node * -omapdss_of_get_first_endpoint(const struct device_node *parent) -{ - struct device_node *port, *ep; - - port = omapdss_of_get_next_port(parent, NULL); - - if (!port) - return NULL; - - ep = omapdss_of_get_next_endpoint(port, NULL); - - of_node_put(port); - - return ep; -} -EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint); +EXPORT_SYMBOL_GPL(dss_of_port_get_port_number); struct omap_dss_device * omapdss_of_find_source_for_first_ep(struct device_node *node) @@ -161,11 +66,11 @@ omapdss_of_find_source_for_first_ep(struct device_node *node) struct device_node *src_port; struct omap_dss_device *src; - ep = omapdss_of_get_first_endpoint(node); + ep = of_graph_get_endpoint_by_regs(node, 0, 0); if (!ep) return ERR_PTR(-EINVAL); - src_port = omapdss_of_get_remote_port(ep); + src_port = of_graph_get_remote_port(ep); if (!src_port) { of_node_put(ep); return ERR_PTR(-EINVAL); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 14887d5b02e5..fa99ec72d832 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -38,6 +38,7 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <linux/regulator/consumer.h> #include <linux/suspend.h> #include <linux/component.h> @@ -117,14 +118,6 @@ static const char * const dss_generic_clk_source_names[] = { [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL", }; -static bool dss_initialized; - -bool omapdss_is_initialized(void) -{ - return dss_initialized; -} -EXPORT_SYMBOL(omapdss_is_initialized); - static inline void dss_write_reg(const struct dss_reg idx, u32 val) { __raw_writel(val, dss.base + idx.idx); @@ -1043,32 +1036,14 @@ static int dss_init_ports(struct platform_device *pdev) { struct device_node *parent = pdev->dev.of_node; struct device_node *port; - int r; - - if (parent == NULL) - return 0; - - port = omapdss_of_get_next_port(parent, NULL); - if (!port) - return 0; - - if (dss.feat->num_ports == 0) - return 0; - - do { - enum omap_display_type port_type; - u32 reg; - - r = of_property_read_u32(port, "reg", ®); - if (r) - reg = 0; + int i; - if (reg >= dss.feat->num_ports) + for (i = 0; i < dss.feat->num_ports; i++) { + port = of_graph_get_port_by_id(parent, i); + if (!port) continue; - port_type = dss.feat->ports[reg]; - - switch (port_type) { + switch (dss.feat->ports[i]) { case OMAP_DISPLAY_TYPE_DPI: dpi_init_port(pdev, port); break; @@ -1078,7 +1053,7 @@ static int dss_init_ports(struct platform_device *pdev) default: break; } - } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); + } return 0; } @@ -1087,32 +1062,14 @@ static void dss_uninit_ports(struct platform_device *pdev) { struct device_node *parent = pdev->dev.of_node; struct device_node *port; + int i; - if (parent == NULL) - return; - - port = omapdss_of_get_next_port(parent, NULL); - if (!port) - return; - - if (dss.feat->num_ports == 0) - return; - - do { - enum omap_display_type port_type; - u32 reg; - int r; - - r = of_property_read_u32(port, "reg", ®); - if (r) - reg = 0; - - if (reg >= dss.feat->num_ports) + for (i = 0; i < dss.feat->num_ports; i++) { + port = of_graph_get_port_by_id(parent, i); + if (!port) continue; - port_type = dss.feat->ports[reg]; - - switch (port_type) { + switch (dss.feat->ports[i]) { case OMAP_DISPLAY_TYPE_DPI: dpi_uninit_port(port); break; @@ -1122,7 +1079,7 @@ static void dss_uninit_ports(struct platform_device *pdev) default: break; } - } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); + } } static int dss_video_pll_probe(struct platform_device *pdev) @@ -1254,8 +1211,7 @@ static int dss_bind(struct device *dev) dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK; 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)); + pr_info("OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); dss_runtime_put(); @@ -1267,7 +1223,8 @@ static int dss_bind(struct device *dev) pm_set_vt_switch(0); - dss_initialized = true; + omapdss_gather_components(dev); + omapdss_set_is_initialized(true); return 0; @@ -1291,7 +1248,7 @@ static void dss_unbind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - dss_initialized = false; + omapdss_set_is_initialized(false); component_unbind_all(&pdev->dev, NULL); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 56493b290731..5dd29c98143a 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -42,29 +42,26 @@ #ifdef DSS_SUBSYS_NAME #define DSSERR(format, ...) \ - printk(KERN_ERR "omapdss " DSS_SUBSYS_NAME " error: " format, \ - ## __VA_ARGS__) + pr_err("omapdss " DSS_SUBSYS_NAME " error: " format, ##__VA_ARGS__) #else #define DSSERR(format, ...) \ - printk(KERN_ERR "omapdss error: " format, ## __VA_ARGS__) + pr_err("omapdss error: " format, ##__VA_ARGS__) #endif #ifdef DSS_SUBSYS_NAME #define DSSINFO(format, ...) \ - printk(KERN_INFO "omapdss " DSS_SUBSYS_NAME ": " format, \ - ## __VA_ARGS__) + pr_info("omapdss " DSS_SUBSYS_NAME ": " format, ##__VA_ARGS__) #else #define DSSINFO(format, ...) \ - printk(KERN_INFO "omapdss: " format, ## __VA_ARGS__) + pr_info("omapdss: " format, ## __VA_ARGS__) #endif #ifdef DSS_SUBSYS_NAME #define DSSWARN(format, ...) \ - printk(KERN_WARNING "omapdss " DSS_SUBSYS_NAME ": " format, \ - ## __VA_ARGS__) + pr_warn("omapdss " DSS_SUBSYS_NAME ": " format, ##__VA_ARGS__) #else #define DSSWARN(format, ...) \ - printk(KERN_WARNING "omapdss: " format, ## __VA_ARGS__) + pr_warn("omapdss: " format, ##__VA_ARGS__) #endif /* OMAP TRM gives bitfields as start:end, where start is the higher bit @@ -256,10 +253,6 @@ struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id, struct regulator *regulator); void dss_video_pll_uninit(struct dss_pll *pll); -/* dss-of */ -struct device_node *dss_of_port_get_parent_device(struct device_node *port); -u32 dss_of_port_get_port_number(struct device_node *port); - #if defined(CONFIG_OMAP2_DSS_DEBUGFS) void dss_debug_dump_clocks(struct seq_file *s); #endif @@ -318,15 +311,7 @@ void dsi_uninit_platform_driver(void); void dsi_dump_clocks(struct seq_file *s); void dsi_irq_handler(void); -u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); -#else -static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) -{ - WARN(1, "%s: DSI not compiled in, returning pixel_size as 0\n", - __func__); - return 0; -} #endif /* DPI */ @@ -352,6 +337,9 @@ int dispc_init_platform_driver(void) __init; void dispc_uninit_platform_driver(void); void dispc_dump_clocks(struct seq_file *s); +int dispc_runtime_get(void); +void dispc_runtime_put(void); + void dispc_enable_sidle(void); void dispc_disable_sidle(void); @@ -371,8 +359,9 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, struct dispc_clock_info *cinfo); -void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); -void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, +void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low, + u32 high); +void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane, u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, bool manual_update); @@ -385,8 +374,6 @@ void dispc_set_tv_pclk(unsigned long pclk); u32 dispc_wb_get_framedone_irq(void); bool dispc_wb_go_busy(void); void dispc_wb_go(void); -void dispc_wb_enable(bool enable); -bool dispc_wb_is_enabled(void); void dispc_wb_set_channel_in(enum dss_writeback_channel channel); int dispc_wb_setup(const struct omap_dss_writeback_info *wi, bool mem_to_mem, const struct videomode *vm); diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.c b/drivers/gpu/drm/omapdrm/dss/dss_features.c index ee5b93ce2763..80c6440a0e08 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss_features.c +++ b/drivers/gpu/drm/omapdrm/dss/dss_features.c @@ -774,13 +774,11 @@ int dss_feat_get_num_mgrs(void) { return omap_current_dss_features->num_mgrs; } -EXPORT_SYMBOL(dss_feat_get_num_mgrs); int dss_feat_get_num_ovls(void) { return omap_current_dss_features->num_ovls; } -EXPORT_SYMBOL(dss_feat_get_num_ovls); unsigned long dss_feat_get_param_min(enum dss_range_param param) { @@ -802,18 +800,17 @@ enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel return omap_current_dss_features->supported_outputs[channel]; } -enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) +enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane_id plane) { return omap_current_dss_features->supported_color_modes[plane]; } -EXPORT_SYMBOL(dss_feat_get_supported_color_modes); -enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane) +enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane) { return omap_current_dss_features->overlay_caps[plane]; } -bool dss_feat_color_mode_supported(enum omap_plane plane, +bool dss_feat_color_mode_supported(enum omap_plane_id plane, enum omap_color_mode color_mode) { return omap_current_dss_features->supported_color_modes[plane] & diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.h b/drivers/gpu/drm/omapdrm/dss/dss_features.h index bb4b7f0e642b..27fbe64935e8 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss_features.h +++ b/drivers/gpu/drm/omapdrm/dss/dss_features.h @@ -88,8 +88,8 @@ enum dss_range_param { /* DSS Feature Functions */ unsigned long dss_feat_get_param_min(enum dss_range_param param); unsigned long dss_feat_get_param_max(enum dss_range_param param); -enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); -bool dss_feat_color_mode_supported(enum omap_plane plane, +enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane); +bool dss_feat_color_mode_supported(enum omap_plane_id plane, enum omap_color_mode color_mode); u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ @@ -104,4 +104,8 @@ void dss_features_init(enum omapdss_version version); enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel); +int dss_feat_get_num_mgrs(void); +int dss_feat_get_num_ovls(void); +enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane_id plane); + #endif diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index e7162c16de2e..87c53034c634 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -34,6 +34,7 @@ #include <linux/regulator/consumer.h> #include <linux/component.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <sound/omap-hdmi-audio.h> #include "omapdss.h" @@ -546,7 +547,7 @@ static int hdmi_probe_of(struct platform_device *pdev) struct device_node *ep; int r; - ep = omapdss_of_get_first_endpoint(node); + ep = of_graph_get_endpoint_by_regs(node, 0, 0); if (!ep) return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 678dfb02764a..d13dce7e8079 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -39,6 +39,7 @@ #include <linux/regulator/consumer.h> #include <linux/component.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <sound/omap-hdmi-audio.h> #include "omapdss.h" @@ -572,7 +573,7 @@ static int hdmi_probe_of(struct platform_device *pdev) struct device_node *ep; int r; - ep = omapdss_of_get_first_endpoint(node); + ep = of_graph_get_endpoint_by_regs(node, 0, 0); if (!ep) return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c index b783d5a0750e..597ec9d87d1d 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c @@ -147,15 +147,17 @@ void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp, struct videomode *vm) { u32 r; - bool vsync_pol, hsync_pol; + bool vsync_inv, hsync_inv; DSSDBG("Enter hdmi_wp_video_config_interface\n"); - vsync_pol = !!(vm->flags & DISPLAY_FLAGS_VSYNC_HIGH); - hsync_pol = !!(vm->flags & DISPLAY_FLAGS_HSYNC_HIGH); + vsync_inv = !!(vm->flags & DISPLAY_FLAGS_VSYNC_LOW); + hsync_inv = !!(vm->flags & DISPLAY_FLAGS_HSYNC_LOW); r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG); - r = FLD_MOD(r, vsync_pol, 7, 7); - r = FLD_MOD(r, hsync_pol, 6, 6); + r = FLD_MOD(r, 1, 7, 7); /* VSYNC_POL to dispc active high */ + r = FLD_MOD(r, 1, 6, 6); /* HSYNC_POL to dispc active high */ + r = FLD_MOD(r, vsync_inv, 5, 5); /* CORE_VSYNC_INV */ + r = FLD_MOD(r, hsync_inv, 4, 4); /* CORE_HSYNC_INV */ r = FLD_MOD(r, !!(vm->flags & DISPLAY_FLAGS_INTERLACED), 3, 3); r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r); diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 5b3b961127bd..b19dae1fd6c5 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -76,7 +76,7 @@ enum omap_display_type { OMAP_DISPLAY_TYPE_DVI = 1 << 6, }; -enum omap_plane { +enum omap_plane_id { OMAP_DSS_GFX = 0, OMAP_DSS_VIDEO1 = 1, OMAP_DSS_VIDEO2 = 2, @@ -338,7 +338,7 @@ struct omap_overlay { /* static fields */ const char *name; - enum omap_plane id; + enum omap_plane_id id; enum omap_color_mode supported_modes; enum omap_overlay_caps caps; @@ -785,7 +785,7 @@ const char *omapdss_get_default_display_name(void); int dss_feat_get_num_mgrs(void); int dss_feat_get_num_ovls(void); -enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); +enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane_id plane); @@ -830,56 +830,13 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev) return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE; } -struct device_node * -omapdss_of_get_next_port(const struct device_node *parent, - struct device_node *prev); - -struct device_node * -omapdss_of_get_next_endpoint(const struct device_node *parent, - struct device_node *prev); - -struct device_node * -omapdss_of_get_first_endpoint(const struct device_node *parent); - struct omap_dss_device * omapdss_of_find_source_for_first_ep(struct device_node *node); -u32 dispc_read_irqstatus(void); -void dispc_clear_irqstatus(u32 mask); -u32 dispc_read_irqenable(void); -void dispc_write_irqenable(u32 mask); +void omapdss_set_is_initialized(bool set); -int dispc_request_irq(irq_handler_t handler, void *dev_id); -void dispc_free_irq(void *dev_id); - -int dispc_runtime_get(void); -void dispc_runtime_put(void); - -void dispc_mgr_enable(enum omap_channel channel, bool enable); -u32 dispc_mgr_get_vsync_irq(enum omap_channel channel); -u32 dispc_mgr_get_framedone_irq(enum omap_channel channel); -u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel); -bool dispc_mgr_go_busy(enum omap_channel channel); -void dispc_mgr_go(enum omap_channel channel); -void dispc_mgr_set_lcd_config(enum omap_channel channel, - const struct dss_lcd_mgr_config *config); -void dispc_mgr_set_timings(enum omap_channel channel, - const struct videomode *vm); -void dispc_mgr_setup(enum omap_channel channel, - const struct omap_overlay_manager_info *info); -u32 dispc_mgr_gamma_size(enum omap_channel channel); -void dispc_mgr_set_gamma(enum omap_channel channel, - const struct drm_color_lut *lut, - unsigned int length); - -int dispc_ovl_enable(enum omap_plane plane, bool enable); -bool dispc_ovl_enabled(enum omap_plane plane); -void dispc_ovl_set_channel_out(enum omap_plane plane, - enum omap_channel channel); -int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, - bool replication, const struct videomode *vm, bool mem_to_mem); - -enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel); +struct device_node *dss_of_port_get_parent_device(struct device_node *port); +u32 dss_of_port_get_port_number(struct device_node *port); struct dss_mgr_ops { int (*connect)(enum omap_channel channel, @@ -919,4 +876,60 @@ int dss_mgr_register_framedone_handler(enum omap_channel channel, void dss_mgr_unregister_framedone_handler(enum omap_channel channel, void (*handler)(void *), void *data); +/* dispc ops */ + +struct dispc_ops { + u32 (*read_irqstatus)(void); + void (*clear_irqstatus)(u32 mask); + u32 (*read_irqenable)(void); + void (*write_irqenable)(u32 mask); + + int (*request_irq)(irq_handler_t handler, void *dev_id); + void (*free_irq)(void *dev_id); + + int (*runtime_get)(void); + void (*runtime_put)(void); + + int (*get_num_ovls)(void); + int (*get_num_mgrs)(void); + + void (*mgr_enable)(enum omap_channel channel, bool enable); + bool (*mgr_is_enabled)(enum omap_channel channel); + u32 (*mgr_get_vsync_irq)(enum omap_channel channel); + u32 (*mgr_get_framedone_irq)(enum omap_channel channel); + u32 (*mgr_get_sync_lost_irq)(enum omap_channel channel); + bool (*mgr_go_busy)(enum omap_channel channel); + void (*mgr_go)(enum omap_channel channel); + void (*mgr_set_lcd_config)(enum omap_channel channel, + const struct dss_lcd_mgr_config *config); + void (*mgr_set_timings)(enum omap_channel channel, + const struct videomode *vm); + void (*mgr_setup)(enum omap_channel channel, + const struct omap_overlay_manager_info *info); + enum omap_dss_output_id (*mgr_get_supported_outputs)(enum omap_channel channel); + u32 (*mgr_gamma_size)(enum omap_channel channel); + void (*mgr_set_gamma)(enum omap_channel channel, + const struct drm_color_lut *lut, + unsigned int length); + + int (*ovl_enable)(enum omap_plane_id plane, bool enable); + bool (*ovl_enabled)(enum omap_plane_id plane); + void (*ovl_set_channel_out)(enum omap_plane_id plane, + enum omap_channel channel); + int (*ovl_setup)(enum omap_plane_id plane, + const struct omap_overlay_info *oi, + const struct videomode *vm, bool mem_to_mem); + + enum omap_color_mode (*ovl_get_color_modes)(enum omap_plane_id plane); +}; + +void dispc_set_ops(const struct dispc_ops *o); +const struct dispc_ops *dispc_get_ops(void); + +bool omapdss_component_is_display(struct device_node *node); +bool omapdss_component_is_output(struct device_node *node); + +bool omapdss_stack_is_ready(void); +void omapdss_gather_components(struct device *dev); + #endif /* __OMAP_DRM_DSS_H */ diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c index a901af5a9bc3..655c5d73eac9 100644 --- a/drivers/gpu/drm/omapdrm/dss/output.c +++ b/drivers/gpu/drm/omapdrm/dss/output.c @@ -22,7 +22,6 @@ #include <linux/of.h> #include "omapdss.h" -#include "dss.h" static LIST_HEAD(output_list); static DEFINE_MUTEX(output_lock); @@ -35,14 +34,15 @@ int omapdss_output_set_device(struct omap_dss_device *out, mutex_lock(&output_lock); if (out->dst) { - DSSERR("output already has device %s connected to it\n", + dev_err(out->dev, + "output already has device %s connected to it\n", out->dst->name); r = -EINVAL; goto err; } if (out->output_type != dssdev->type) { - DSSERR("output type and display type don't match\n"); + dev_err(out->dev, "output type and display type don't match\n"); r = -EINVAL; goto err; } @@ -67,14 +67,16 @@ int omapdss_output_unset_device(struct omap_dss_device *out) mutex_lock(&output_lock); if (!out->dst) { - DSSERR("output doesn't have a device connected to it\n"); + dev_err(out->dev, + "output doesn't have a device connected to it\n"); r = -EINVAL; goto err; } if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) { - DSSERR("device %s is not disabled, cannot unset device\n", - out->dst->name); + dev_err(out->dev, + "device %s is not disabled, cannot unset device\n", + out->dst->name); r = -EINVAL; goto err; } @@ -105,6 +107,19 @@ void omapdss_unregister_output(struct omap_dss_device *out) } EXPORT_SYMBOL(omapdss_unregister_output); +bool omapdss_component_is_output(struct device_node *node) +{ + struct omap_dss_device *out; + + list_for_each_entry(out, &output_list, list) { + if (out->dev->of_node == node) + return true; + } + + return false; +} +EXPORT_SYMBOL(omapdss_component_is_output); + struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id) { struct omap_dss_device *out; diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c index 0a76c89cdc2e..5e221302768b 100644 --- a/drivers/gpu/drm/omapdrm/dss/pll.c +++ b/drivers/gpu/drm/omapdrm/dss/pll.c @@ -215,8 +215,8 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin, dss_pll_calc_func func, void *data) { const struct dss_pll_hw *hw = pll->hw; - int n, n_start, n_stop; - int m, m_start, m_stop; + int n, n_min, n_max; + int m, m_min, m_max; unsigned long fint, clkdco; unsigned long pll_hw_max; unsigned long fint_hw_min, fint_hw_max; @@ -226,21 +226,22 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin, fint_hw_min = hw->fint_min; fint_hw_max = hw->fint_max; - n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); - n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max); + n_min = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); + n_max = min((unsigned)(clkin / fint_hw_min), hw->n_max); pll_max = pll_max ? pll_max : ULONG_MAX; - for (n = n_start; n <= n_stop; ++n) { + /* Try to find high N & M to avoid jitter (DRA7 errata i886) */ + for (n = n_max; n >= n_min; --n) { fint = clkin / n; - m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2), + m_min = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2), 1ul); - m_stop = min3((unsigned)(pll_max / fint / 2), + m_max = min3((unsigned)(pll_max / fint / 2), (unsigned)(pll_hw_max / fint / 2), hw->m_max); - for (m = m_start; m <= m_stop; ++m) { + for (m = m_max; m >= m_min; --m) { clkdco = 2 * m * fint; if (func(n, m, fint, clkdco, data)) diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c index b3bda2d3c08d..0620b9f8c231 100644 --- a/drivers/gpu/drm/omapdrm/dss/sdi.c +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c @@ -414,7 +414,7 @@ int sdi_init_port(struct platform_device *pdev, struct device_node *port) u32 datapairs; int r; - ep = omapdss_of_get_next_endpoint(port, NULL); + ep = of_get_next_child(port, NULL); if (!ep) return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index d74f7fcc2e46..19d14957f566 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -35,6 +35,7 @@ #include <linux/regulator/consumer.h> #include <linux/pm_runtime.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <linux/component.h> #include "omapdss.h" @@ -818,7 +819,7 @@ static int venc_probe_of(struct platform_device *pdev) u32 channels; int r; - ep = omapdss_of_get_first_endpoint(node); + ep = of_graph_get_endpoint_by_regs(node, 0, 0); if (!ep) return 0; |