Lines Matching full:dc

32 #include "dc.h"
50 static u32 tegra_dc_readl_active(struct tegra_dc *dc, unsigned long offset) in tegra_dc_readl_active() argument
54 tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); in tegra_dc_readl_active()
55 value = tegra_dc_readl(dc, offset); in tegra_dc_readl_active()
56 tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); in tegra_dc_readl_active()
79 dev_WARN(plane->dc->dev, "invalid offset: %x\n", offset); in tegra_plane_offset()
87 return tegra_dc_readl(plane->dc, tegra_plane_offset(plane, offset)); in tegra_plane_readl()
93 tegra_dc_writel(plane->dc, value, tegra_plane_offset(plane, offset)); in tegra_plane_writel()
96 bool tegra_dc_has_output(struct tegra_dc *dc, struct device *dev) in tegra_dc_has_output() argument
98 struct device_node *np = dc->dev->of_node; in tegra_dc_has_output()
121 void tegra_dc_commit(struct tegra_dc *dc) in tegra_dc_commit() argument
123 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); in tegra_dc_commit()
124 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); in tegra_dc_commit()
317 struct tegra_dc *dc = plane->dc; in tegra_plane_use_horizontal_filtering() local
322 if (plane->index == 0 && dc->soc->has_win_a_without_filters) in tegra_plane_use_horizontal_filtering()
332 struct tegra_dc *dc = plane->dc; in tegra_plane_use_vertical_filtering() local
337 if (plane->index == 0 && dc->soc->has_win_a_without_filters) in tegra_plane_use_vertical_filtering()
340 if (plane->index == 2 && dc->soc->has_win_c_without_vert_filter) in tegra_plane_use_vertical_filtering()
350 struct tegra_dc *dc = plane->dc; in tegra_dc_setup_window() local
427 if (dc->soc->supports_block_linear) { in tegra_dc_setup_window()
533 if (dc->soc->has_legacy_blending) in tegra_dc_setup_window()
629 struct tegra_dc *dc = to_tegra_dc(new_plane_state->crtc); in tegra_plane_atomic_check() local
653 if (dc->soc->has_legacy_blending) { in tegra_plane_atomic_check()
664 !dc->soc->supports_block_linear) { in tegra_plane_atomic_check()
804 struct tegra_dc *dc) in tegra_primary_plane_create() argument
821 plane->dc = dc; in tegra_primary_plane_create()
823 num_formats = dc->soc->num_primary_formats; in tegra_primary_plane_create()
824 formats = dc->soc->primary_formats; in tegra_primary_plane_create()
825 modifiers = dc->soc->modifiers; in tegra_primary_plane_create()
851 dev_err(dc->dev, "failed to create rotation property: %d\n", in tegra_primary_plane_create()
907 struct tegra_dc *dc = to_tegra_dc(new_state->crtc); in __tegra_cursor_atomic_update() local
910 u64 dma_mask = *dc->dev->dma_mask; in __tegra_cursor_atomic_update()
923 if (!dc->soc->has_nvdisplay) in __tegra_cursor_atomic_update()
950 tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR); in __tegra_cursor_atomic_update()
954 tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR_HI); in __tegra_cursor_atomic_update()
958 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); in __tegra_cursor_atomic_update()
960 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); in __tegra_cursor_atomic_update()
962 value = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL); in __tegra_cursor_atomic_update()
966 if (dc->soc->has_nvdisplay) in __tegra_cursor_atomic_update()
974 tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL); in __tegra_cursor_atomic_update()
977 if (dc->soc->has_nvdisplay) { in __tegra_cursor_atomic_update()
986 tegra_dc_writel(dc, value, DC_DISP_PCALC_HEAD_SET_CROPPED_POINT_IN_CURSOR); in __tegra_cursor_atomic_update()
990 tegra_dc_writel(dc, value, DC_DISP_PCALC_HEAD_SET_CROPPED_SIZE_IN_CURSOR); in __tegra_cursor_atomic_update()
998 tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION); in __tegra_cursor_atomic_update()
1014 struct tegra_dc *dc; in tegra_cursor_atomic_disable() local
1021 dc = to_tegra_dc(old_state->crtc); in tegra_cursor_atomic_disable()
1023 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); in tegra_cursor_atomic_disable()
1025 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); in tegra_cursor_atomic_disable()
1069 struct tegra_dc *dc = to_tegra_dc(new_state->crtc); in tegra_cursor_atomic_async_update() local
1083 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); in tegra_cursor_atomic_async_update()
1084 (void)tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); in tegra_cursor_atomic_async_update()
1087 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); in tegra_cursor_atomic_async_update()
1088 (void)tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); in tegra_cursor_atomic_async_update()
1108 struct tegra_dc *dc) in tegra_dc_cursor_plane_create() argument
1128 plane->dc = dc; in tegra_dc_cursor_plane_create()
1130 if (!dc->soc->has_nvdisplay) { in tegra_dc_cursor_plane_create()
1253 struct tegra_dc *dc, in tegra_dc_overlay_plane_create() argument
1270 plane->dc = dc; in tegra_dc_overlay_plane_create()
1272 num_formats = dc->soc->num_overlay_formats; in tegra_dc_overlay_plane_create()
1273 formats = dc->soc->overlay_formats; in tegra_dc_overlay_plane_create()
1305 dev_err(dc->dev, "failed to create rotation property: %d\n", in tegra_dc_overlay_plane_create()
1312 struct tegra_dc *dc) in tegra_dc_add_shared_planes() argument
1317 for (i = 0; i < dc->soc->num_wgrps; i++) { in tegra_dc_add_shared_planes()
1318 const struct tegra_windowgroup_soc *wgrp = &dc->soc->wgrps[i]; in tegra_dc_add_shared_planes()
1320 if (wgrp->dc == dc->pipe) { in tegra_dc_add_shared_planes()
1324 plane = tegra_shared_plane_create(drm, dc, in tegra_dc_add_shared_planes()
1346 struct tegra_dc *dc) in tegra_dc_add_planes() argument
1353 primary = tegra_primary_plane_create(drm, dc); in tegra_dc_add_planes()
1357 if (dc->soc->supports_cursor) in tegra_dc_add_planes()
1363 planes[i] = tegra_dc_overlay_plane_create(drm, dc, 1 + i, in tegra_dc_add_planes()
1640 struct tegra_dc *dc = node->info_ent->data; in tegra_dc_show_regs() local
1644 drm_modeset_lock(&dc->base.mutex, NULL); in tegra_dc_show_regs()
1646 if (!dc->base.state->active) { in tegra_dc_show_regs()
1655 offset, tegra_dc_readl(dc, offset)); in tegra_dc_show_regs()
1659 drm_modeset_unlock(&dc->base.mutex); in tegra_dc_show_regs()
1666 struct tegra_dc *dc = node->info_ent->data; in tegra_dc_show_crc() local
1670 drm_modeset_lock(&dc->base.mutex, NULL); in tegra_dc_show_crc()
1672 if (!dc->base.state->active) { in tegra_dc_show_crc()
1678 tegra_dc_writel(dc, value, DC_COM_CRC_CONTROL); in tegra_dc_show_crc()
1679 tegra_dc_commit(dc); in tegra_dc_show_crc()
1681 drm_crtc_wait_one_vblank(&dc->base); in tegra_dc_show_crc()
1682 drm_crtc_wait_one_vblank(&dc->base); in tegra_dc_show_crc()
1684 value = tegra_dc_readl(dc, DC_COM_CRC_CHECKSUM); in tegra_dc_show_crc()
1687 tegra_dc_writel(dc, 0, DC_COM_CRC_CONTROL); in tegra_dc_show_crc()
1690 drm_modeset_unlock(&dc->base.mutex); in tegra_dc_show_crc()
1697 struct tegra_dc *dc = node->info_ent->data; in tegra_dc_show_stats() local
1699 seq_printf(s, "frames: %lu\n", dc->stats.frames); in tegra_dc_show_stats()
1700 seq_printf(s, "vblank: %lu\n", dc->stats.vblank); in tegra_dc_show_stats()
1701 seq_printf(s, "underflow: %lu\n", dc->stats.underflow); in tegra_dc_show_stats()
1702 seq_printf(s, "overflow: %lu\n", dc->stats.overflow); in tegra_dc_show_stats()
1704 seq_printf(s, "frames total: %lu\n", dc->stats.frames_total); in tegra_dc_show_stats()
1705 seq_printf(s, "vblank total: %lu\n", dc->stats.vblank_total); in tegra_dc_show_stats()
1706 seq_printf(s, "underflow total: %lu\n", dc->stats.underflow_total); in tegra_dc_show_stats()
1707 seq_printf(s, "overflow total: %lu\n", dc->stats.overflow_total); in tegra_dc_show_stats()
1723 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_dc_late_register() local
1731 dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files), in tegra_dc_late_register()
1733 if (!dc->debugfs_files) in tegra_dc_late_register()
1737 dc->debugfs_files[i].data = dc; in tegra_dc_late_register()
1739 drm_debugfs_create_files(dc->debugfs_files, count, root, minor); in tegra_dc_late_register()
1748 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_dc_early_unregister() local
1750 drm_debugfs_remove_files(dc->debugfs_files, count, minor); in tegra_dc_early_unregister()
1751 kfree(dc->debugfs_files); in tegra_dc_early_unregister()
1752 dc->debugfs_files = NULL; in tegra_dc_early_unregister()
1757 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_dc_get_vblank_counter() local
1760 if (dc->syncpt && !dc->soc->has_nvdisplay) in tegra_dc_get_vblank_counter()
1761 return host1x_syncpt_read(dc->syncpt); in tegra_dc_get_vblank_counter()
1764 return (u32)drm_crtc_vblank_count(&dc->base); in tegra_dc_get_vblank_counter()
1769 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_dc_enable_vblank() local
1772 value = tegra_dc_readl(dc, DC_CMD_INT_MASK); in tegra_dc_enable_vblank()
1774 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); in tegra_dc_enable_vblank()
1781 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_dc_disable_vblank() local
1784 value = tegra_dc_readl(dc, DC_CMD_INT_MASK); in tegra_dc_disable_vblank()
1786 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); in tegra_dc_disable_vblank()
1803 static int tegra_dc_set_timings(struct tegra_dc *dc, in tegra_dc_set_timings() argument
1810 if (!dc->soc->has_nvdisplay) { in tegra_dc_set_timings()
1811 tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS); in tegra_dc_set_timings()
1814 tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC); in tegra_dc_set_timings()
1819 tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH); in tegra_dc_set_timings()
1823 tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH); in tegra_dc_set_timings()
1827 tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH); in tegra_dc_set_timings()
1830 tegra_dc_writel(dc, value, DC_DISP_ACTIVE); in tegra_dc_set_timings()
1838 * @dc: display controller
1847 int tegra_dc_state_setup_clock(struct tegra_dc *dc, in tegra_dc_state_setup_clock() argument
1854 if (!clk_has_parent(dc->clk, clk)) in tegra_dc_state_setup_clock()
1864 static void tegra_dc_update_voltage_state(struct tegra_dc *dc, in tegra_dc_update_voltage_state() argument
1871 if (!dc->has_opp_table) in tegra_dc_update_voltage_state()
1875 rate = DIV_ROUND_UP(clk_get_rate(dc->clk) * 2, state->div + 2); in tegra_dc_update_voltage_state()
1878 opp = dev_pm_opp_find_freq_ceil(dc->dev, &rate); in tegra_dc_update_voltage_state()
1886 opp = dev_pm_opp_find_freq_floor(dc->dev, &rate); in tegra_dc_update_voltage_state()
1889 dev_err(dc->dev, "failed to find OPP for %luHz: %pe\n", in tegra_dc_update_voltage_state()
1904 err = dev_pm_genpd_set_performance_state(dc->dev, pstate); in tegra_dc_update_voltage_state()
1906 dev_err(dc->dev, "failed to set power domain state to %lu: %d\n", in tegra_dc_update_voltage_state()
1910 static void tegra_dc_set_clock_rate(struct tegra_dc *dc, in tegra_dc_set_clock_rate() argument
1915 err = clk_set_parent(dc->clk, state->clk); in tegra_dc_set_clock_rate()
1917 dev_err(dc->dev, "failed to set parent clock: %d\n", err); in tegra_dc_set_clock_rate()
1930 dev_err(dc->dev, in tegra_dc_set_clock_rate()
1934 err = clk_set_rate(dc->clk, state->pclk); in tegra_dc_set_clock_rate()
1936 dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", in tegra_dc_set_clock_rate()
1937 dc->clk, state->pclk, err); in tegra_dc_set_clock_rate()
1940 DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), in tegra_dc_set_clock_rate()
1944 tegra_dc_update_voltage_state(dc, state); in tegra_dc_set_clock_rate()
1947 static void tegra_dc_stop(struct tegra_dc *dc) in tegra_dc_stop() argument
1952 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND); in tegra_dc_stop()
1954 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND); in tegra_dc_stop()
1956 tegra_dc_commit(dc); in tegra_dc_stop()
1959 static bool tegra_dc_idle(struct tegra_dc *dc) in tegra_dc_idle() argument
1963 value = tegra_dc_readl_active(dc, DC_CMD_DISPLAY_COMMAND); in tegra_dc_idle()
1968 static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout) in tegra_dc_wait_idle() argument
1973 if (tegra_dc_idle(dc)) in tegra_dc_wait_idle()
1979 dev_dbg(dc->dev, "timeout waiting for DC to become idle\n"); in tegra_dc_wait_idle()
1993 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_crtc_update_memory_bandwidth() local
1997 if (dc->soc->has_nvdisplay) in tegra_crtc_update_memory_bandwidth()
2032 if (tegra->dc != dc) in tegra_crtc_update_memory_bandwidth()
2058 * freq should go high before the DC changes are committed in tegra_crtc_update_memory_bandwidth()
2083 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_crtc_atomic_disable() local
2087 if (!tegra_dc_idle(dc)) { in tegra_crtc_atomic_disable()
2088 tegra_dc_stop(dc); in tegra_crtc_atomic_disable()
2094 tegra_dc_wait_idle(dc, 100); in tegra_crtc_atomic_disable()
2113 if (dc->rgb) { in tegra_crtc_atomic_disable()
2114 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL); in tegra_crtc_atomic_disable()
2117 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); in tegra_crtc_atomic_disable()
2120 tegra_dc_stats_reset(&dc->stats); in tegra_crtc_atomic_disable()
2132 err = host1x_client_suspend(&dc->client); in tegra_crtc_atomic_disable()
2134 dev_err(dc->dev, "failed to suspend: %d\n", err); in tegra_crtc_atomic_disable()
2136 if (dc->has_opp_table) { in tegra_crtc_atomic_disable()
2137 err = dev_pm_genpd_set_performance_state(dc->dev, 0); in tegra_crtc_atomic_disable()
2139 dev_err(dc->dev, in tegra_crtc_atomic_disable()
2149 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_crtc_atomic_enable() local
2154 tegra_dc_set_clock_rate(dc, crtc_state); in tegra_crtc_atomic_enable()
2156 err = host1x_client_resume(&dc->client); in tegra_crtc_atomic_enable()
2158 dev_err(dc->dev, "failed to resume: %d\n", err); in tegra_crtc_atomic_enable()
2163 if (dc->syncpt) { in tegra_crtc_atomic_enable()
2164 u32 syncpt = host1x_syncpt_id(dc->syncpt), enable; in tegra_crtc_atomic_enable()
2166 if (dc->soc->has_nvdisplay) in tegra_crtc_atomic_enable()
2172 tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); in tegra_crtc_atomic_enable()
2175 tegra_dc_writel(dc, value, DC_CMD_CONT_SYNCPT_VSYNC); in tegra_crtc_atomic_enable()
2178 if (dc->soc->has_nvdisplay) { in tegra_crtc_atomic_enable()
2181 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE); in tegra_crtc_atomic_enable()
2188 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY); in tegra_crtc_atomic_enable()
2192 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE); in tegra_crtc_atomic_enable()
2195 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); in tegra_crtc_atomic_enable()
2197 tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); in tegra_crtc_atomic_enable()
2201 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE); in tegra_crtc_atomic_enable()
2205 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY); in tegra_crtc_atomic_enable()
2210 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY); in tegra_crtc_atomic_enable()
2214 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); in tegra_crtc_atomic_enable()
2218 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE); in tegra_crtc_atomic_enable()
2222 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); in tegra_crtc_atomic_enable()
2225 if (dc->soc->supports_background_color) in tegra_crtc_atomic_enable()
2226 tegra_dc_writel(dc, 0, DC_DISP_BLEND_BACKGROUND_COLOR); in tegra_crtc_atomic_enable()
2228 tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR); in tegra_crtc_atomic_enable()
2231 if (!dc->soc->has_nvdisplay) { in tegra_crtc_atomic_enable()
2233 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); in tegra_crtc_atomic_enable()
2237 tegra_dc_set_timings(dc, mode); in tegra_crtc_atomic_enable()
2240 if (dc->soc->supports_interlacing) { in tegra_crtc_atomic_enable()
2241 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL); in tegra_crtc_atomic_enable()
2243 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL); in tegra_crtc_atomic_enable()
2246 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND); in tegra_crtc_atomic_enable()
2249 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND); in tegra_crtc_atomic_enable()
2251 if (!dc->soc->has_nvdisplay) { in tegra_crtc_atomic_enable()
2252 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL); in tegra_crtc_atomic_enable()
2255 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); in tegra_crtc_atomic_enable()
2259 if (dc->soc->has_nvdisplay) { in tegra_crtc_atomic_enable()
2261 tegra_dc_writel(dc, value, DC_COM_RG_UNDERFLOW); in tegra_crtc_atomic_enable()
2264 if (dc->rgb) { in tegra_crtc_atomic_enable()
2267 tegra_dc_writel(dc, value, DC_DISP_SHIFT_CLOCK_OPTIONS); in tegra_crtc_atomic_enable()
2270 tegra_dc_commit(dc); in tegra_crtc_atomic_enable()
2302 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_crtc_atomic_flush() local
2306 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); in tegra_crtc_atomic_flush()
2307 value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); in tegra_crtc_atomic_flush()
2310 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); in tegra_crtc_atomic_flush()
2311 value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); in tegra_crtc_atomic_flush()
2384 struct tegra_dc *dc = to_tegra_dc(crtc); in tegra_crtc_calculate_memory_bandwidth() local
2395 if (dc->soc->has_nvdisplay) in tegra_crtc_calculate_memory_bandwidth()
2429 * overlapping planes, where "simultaneously" means areas where DC in tegra_crtc_calculate_memory_bandwidth()
2521 struct tegra_dc *dc = data; in tegra_dc_irq() local
2524 status = tegra_dc_readl(dc, DC_CMD_INT_STATUS); in tegra_dc_irq()
2525 tegra_dc_writel(dc, status, DC_CMD_INT_STATUS); in tegra_dc_irq()
2529 dev_dbg(dc->dev, "%s(): frame end\n", __func__); in tegra_dc_irq()
2531 dc->stats.frames_total++; in tegra_dc_irq()
2532 dc->stats.frames++; in tegra_dc_irq()
2537 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); in tegra_dc_irq()
2539 drm_crtc_handle_vblank(&dc->base); in tegra_dc_irq()
2540 dc->stats.vblank_total++; in tegra_dc_irq()
2541 dc->stats.vblank++; in tegra_dc_irq()
2546 dev_dbg(dc->dev, "%s(): underflow\n", __func__); in tegra_dc_irq()
2548 dc->stats.underflow_total++; in tegra_dc_irq()
2549 dc->stats.underflow++; in tegra_dc_irq()
2554 dev_dbg(dc->dev, "%s(): overflow\n", __func__); in tegra_dc_irq()
2556 dc->stats.overflow_total++; in tegra_dc_irq()
2557 dc->stats.overflow++; in tegra_dc_irq()
2561 dev_dbg_ratelimited(dc->dev, "%s(): head underflow\n", __func__); in tegra_dc_irq()
2562 dc->stats.underflow_total++; in tegra_dc_irq()
2563 dc->stats.underflow++; in tegra_dc_irq()
2569 static bool tegra_dc_has_window_groups(struct tegra_dc *dc) in tegra_dc_has_window_groups() argument
2573 if (!dc->soc->wgrps) in tegra_dc_has_window_groups()
2576 for (i = 0; i < dc->soc->num_wgrps; i++) { in tegra_dc_has_window_groups()
2577 const struct tegra_windowgroup_soc *wgrp = &dc->soc->wgrps[i]; in tegra_dc_has_window_groups()
2579 if (wgrp->dc == dc->pipe && wgrp->num_windows > 0) in tegra_dc_has_window_groups()
2600 struct tegra_dc *dc = host1x_client_to_dc(client); in tegra_dc_init() local
2607 * DC has been reset by now, so VBLANK syncpoint can be released in tegra_dc_init()
2610 host1x_syncpt_release_vblank_reservation(client, 26 + dc->pipe); in tegra_dc_init()
2617 if (!tegra_dc_has_window_groups(dc)) in tegra_dc_init()
2626 if (dc->soc->has_nvdisplay) in tegra_dc_init()
2629 dc->syncpt = host1x_syncpt_request(client, flags); in tegra_dc_init()
2630 if (!dc->syncpt) in tegra_dc_init()
2631 dev_warn(dc->dev, "failed to allocate syncpoint\n"); in tegra_dc_init()
2639 if (dc->soc->wgrps) in tegra_dc_init()
2640 primary = tegra_dc_add_shared_planes(drm, dc); in tegra_dc_init()
2642 primary = tegra_dc_add_planes(drm, dc); in tegra_dc_init()
2649 if (dc->soc->supports_cursor) { in tegra_dc_init()
2650 cursor = tegra_dc_cursor_plane_create(drm, dc); in tegra_dc_init()
2657 cursor = tegra_dc_overlay_plane_create(drm, dc, 2, true); in tegra_dc_init()
2664 err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor, in tegra_dc_init()
2669 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); in tegra_dc_init()
2675 if (dc->soc->pitch_align > tegra->pitch_align) in tegra_dc_init()
2676 tegra->pitch_align = dc->soc->pitch_align; in tegra_dc_init()
2679 if (dc->soc->has_nvdisplay) in tegra_dc_init()
2684 err = tegra_dc_rgb_init(drm, dc); in tegra_dc_init()
2686 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err); in tegra_dc_init()
2690 err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0, in tegra_dc_init()
2691 dev_name(dc->dev), dc); in tegra_dc_init()
2693 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq, in tegra_dc_init()
2714 host1x_syncpt_put(dc->syncpt); in tegra_dc_init()
2721 struct tegra_dc *dc = host1x_client_to_dc(client); in tegra_dc_exit() local
2724 if (!tegra_dc_has_window_groups(dc)) in tegra_dc_exit()
2730 devm_free_irq(dc->dev, dc->irq, dc); in tegra_dc_exit()
2732 err = tegra_dc_rgb_exit(dc); in tegra_dc_exit()
2734 dev_err(dc->dev, "failed to shutdown RGB output: %d\n", err); in tegra_dc_exit()
2739 host1x_syncpt_put(dc->syncpt); in tegra_dc_exit()
2756 struct tegra_dc *dc = host1x_client_to_dc(client); in tegra_dc_runtime_suspend() local
2760 err = reset_control_assert(dc->rst); in tegra_dc_runtime_suspend()
2766 if (dc->soc->has_powergate) in tegra_dc_runtime_suspend()
2767 tegra_powergate_power_off(dc->powergate); in tegra_dc_runtime_suspend()
2769 clk_disable_unprepare(dc->clk); in tegra_dc_runtime_suspend()
2777 struct tegra_dc *dc = host1x_client_to_dc(client); in tegra_dc_runtime_resume() local
2787 if (dc->soc->has_powergate) { in tegra_dc_runtime_resume()
2788 err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, in tegra_dc_runtime_resume()
2789 dc->rst); in tegra_dc_runtime_resume()
2795 err = clk_prepare_enable(dc->clk); in tegra_dc_runtime_resume()
2801 err = reset_control_deassert(dc->rst); in tegra_dc_runtime_resume()
2811 clk_disable_unprepare(dc->clk); in tegra_dc_runtime_resume()
2944 .dc = 0,
2949 .dc = 1,
2954 .dc = 1,
2959 .dc = 2,
2964 .dc = 2,
2969 .dc = 2,
2995 .dc = 0,
3000 .dc = 1,
3005 .dc = 1,
3010 .dc = 2,
3015 .dc = 2,
3020 .dc = 2,
3045 .compatible = "nvidia,tegra194-dc",
3048 .compatible = "nvidia,tegra186-dc",
3051 .compatible = "nvidia,tegra210-dc",
3054 .compatible = "nvidia,tegra124-dc",
3057 .compatible = "nvidia,tegra114-dc",
3060 .compatible = "nvidia,tegra30-dc",
3063 .compatible = "nvidia,tegra20-dc",
3071 static int tegra_dc_parse_dt(struct tegra_dc *dc) in tegra_dc_parse_dt() argument
3077 err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value); in tegra_dc_parse_dt()
3079 dev_err(dc->dev, "missing \"nvidia,head\" property\n"); in tegra_dc_parse_dt()
3094 if (np == dc->dev->of_node) { in tegra_dc_parse_dt()
3103 dc->pipe = value; in tegra_dc_parse_dt()
3110 struct tegra_dc *dc = dev_get_drvdata(dev); in tegra_dc_match_by_pipe() local
3113 return dc->pipe == pipe; in tegra_dc_match_by_pipe()
3116 static int tegra_dc_couple(struct tegra_dc *dc) in tegra_dc_couple() argument
3123 if (dc->soc->coupled_pm && dc->pipe == 1) { in tegra_dc_couple()
3127 companion = driver_find_device(dc->dev->driver, NULL, (const void *)0, in tegra_dc_couple()
3133 dc->client.parent = &parent->client; in tegra_dc_couple()
3135 dev_dbg(dc->dev, "coupled to %s\n", dev_name(companion)); in tegra_dc_couple()
3141 static int tegra_dc_init_opp_table(struct tegra_dc *dc) in tegra_dc_init_opp_table() argument
3146 err = devm_tegra_core_dev_init_opp_table(dc->dev, &opp_params); in tegra_dc_init_opp_table()
3151 dc->has_opp_table = false; in tegra_dc_init_opp_table()
3153 dc->has_opp_table = true; in tegra_dc_init_opp_table()
3161 struct tegra_dc *dc; in tegra_dc_probe() local
3170 dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL); in tegra_dc_probe()
3171 if (!dc) in tegra_dc_probe()
3174 dc->soc = of_device_get_match_data(&pdev->dev); in tegra_dc_probe()
3176 INIT_LIST_HEAD(&dc->list); in tegra_dc_probe()
3177 dc->dev = &pdev->dev; in tegra_dc_probe()
3179 err = tegra_dc_parse_dt(dc); in tegra_dc_probe()
3183 err = tegra_dc_couple(dc); in tegra_dc_probe()
3187 dc->clk = devm_clk_get(&pdev->dev, NULL); in tegra_dc_probe()
3188 if (IS_ERR(dc->clk)) { in tegra_dc_probe()
3190 return PTR_ERR(dc->clk); in tegra_dc_probe()
3193 dc->rst = devm_reset_control_get(&pdev->dev, "dc"); in tegra_dc_probe()
3194 if (IS_ERR(dc->rst)) { in tegra_dc_probe()
3196 return PTR_ERR(dc->rst); in tegra_dc_probe()
3200 err = clk_prepare_enable(dc->clk); in tegra_dc_probe()
3206 err = reset_control_assert(dc->rst); in tegra_dc_probe()
3208 clk_disable_unprepare(dc->clk); in tegra_dc_probe()
3214 clk_disable_unprepare(dc->clk); in tegra_dc_probe()
3216 if (dc->soc->has_powergate) { in tegra_dc_probe()
3217 if (dc->pipe == 0) in tegra_dc_probe()
3218 dc->powergate = TEGRA_POWERGATE_DIS; in tegra_dc_probe()
3220 dc->powergate = TEGRA_POWERGATE_DISB; in tegra_dc_probe()
3222 tegra_powergate_power_off(dc->powergate); in tegra_dc_probe()
3225 err = tegra_dc_init_opp_table(dc); in tegra_dc_probe()
3229 dc->regs = devm_platform_ioremap_resource(pdev, 0); in tegra_dc_probe()
3230 if (IS_ERR(dc->regs)) in tegra_dc_probe()
3231 return PTR_ERR(dc->regs); in tegra_dc_probe()
3233 dc->irq = platform_get_irq(pdev, 0); in tegra_dc_probe()
3234 if (dc->irq < 0) in tegra_dc_probe()
3237 err = tegra_dc_rgb_probe(dc); in tegra_dc_probe()
3242 platform_set_drvdata(pdev, dc); in tegra_dc_probe()
3245 INIT_LIST_HEAD(&dc->client.list); in tegra_dc_probe()
3246 dc->client.ops = &dc_client_ops; in tegra_dc_probe()
3247 dc->client.dev = &pdev->dev; in tegra_dc_probe()
3249 err = host1x_client_register(&dc->client); in tegra_dc_probe()
3260 tegra_dc_rgb_remove(dc); in tegra_dc_probe()
3267 struct tegra_dc *dc = platform_get_drvdata(pdev); in tegra_dc_remove() local
3269 host1x_client_unregister(&dc->client); in tegra_dc_remove()
3271 tegra_dc_rgb_remove(dc); in tegra_dc_remove()
3278 .name = "tegra-dc",