dc.c (6ea24cf79e055f0a62a64baa8587e2254a493c7b) | dc.c (33a8eb8d40ee7fc07f23a407607bdbaa46893b2d) |
---|---|
1/* 2 * Copyright (C) 2012 Avionic Design GmbH 3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10#include <linux/clk.h> 11#include <linux/debugfs.h> 12#include <linux/iommu.h> | 1/* 2 * Copyright (C) 2012 Avionic Design GmbH 3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10#include <linux/clk.h> 11#include <linux/debugfs.h> 12#include <linux/iommu.h> |
13#include <linux/pm_runtime.h> |
|
13#include <linux/reset.h> 14 15#include <soc/tegra/pmc.h> 16 17#include "dc.h" 18#include "drm.h" 19#include "gem.h" 20 --- 408 unchanged lines hidden (view full) --- 429 tegra_plane_destroy(plane); 430} 431 432static void tegra_plane_reset(struct drm_plane *plane) 433{ 434 struct tegra_plane_state *state; 435 436 if (plane->state) | 14#include <linux/reset.h> 15 16#include <soc/tegra/pmc.h> 17 18#include "dc.h" 19#include "drm.h" 20#include "gem.h" 21 --- 408 unchanged lines hidden (view full) --- 430 tegra_plane_destroy(plane); 431} 432 433static void tegra_plane_reset(struct drm_plane *plane) 434{ 435 struct tegra_plane_state *state; 436 437 if (plane->state) |
437 __drm_atomic_helper_plane_destroy_state(plane, plane->state); | 438 __drm_atomic_helper_plane_destroy_state(plane->state); |
438 439 kfree(plane->state); 440 plane->state = NULL; 441 442 state = kzalloc(sizeof(*state), GFP_KERNEL); 443 if (state) { 444 plane->state = &state->base; 445 plane->state->plane = plane; --- 15 unchanged lines hidden (view full) --- 461 copy->swap = state->swap; 462 463 return ©->base; 464} 465 466static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, 467 struct drm_plane_state *state) 468{ | 439 440 kfree(plane->state); 441 plane->state = NULL; 442 443 state = kzalloc(sizeof(*state), GFP_KERNEL); 444 if (state) { 445 plane->state = &state->base; 446 plane->state->plane = plane; --- 15 unchanged lines hidden (view full) --- 462 copy->swap = state->swap; 463 464 return ©->base; 465} 466 467static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, 468 struct drm_plane_state *state) 469{ |
469 __drm_atomic_helper_plane_destroy_state(plane, state); | 470 __drm_atomic_helper_plane_destroy_state(state); |
470 kfree(state); 471} 472 473static const struct drm_plane_funcs tegra_primary_plane_funcs = { 474 .update_plane = drm_atomic_helper_update_plane, 475 .disable_plane = drm_atomic_helper_disable_plane, 476 .destroy = tegra_primary_plane_destroy, 477 .reset = tegra_plane_reset, --- 515 unchanged lines hidden (view full) --- 993 drm_crtc_cleanup(crtc); 994} 995 996static void tegra_crtc_reset(struct drm_crtc *crtc) 997{ 998 struct tegra_dc_state *state; 999 1000 if (crtc->state) | 471 kfree(state); 472} 473 474static const struct drm_plane_funcs tegra_primary_plane_funcs = { 475 .update_plane = drm_atomic_helper_update_plane, 476 .disable_plane = drm_atomic_helper_disable_plane, 477 .destroy = tegra_primary_plane_destroy, 478 .reset = tegra_plane_reset, --- 515 unchanged lines hidden (view full) --- 994 drm_crtc_cleanup(crtc); 995} 996 997static void tegra_crtc_reset(struct drm_crtc *crtc) 998{ 999 struct tegra_dc_state *state; 1000 1001 if (crtc->state) |
1001 __drm_atomic_helper_crtc_destroy_state(crtc, crtc->state); | 1002 __drm_atomic_helper_crtc_destroy_state(crtc->state); |
1002 1003 kfree(crtc->state); 1004 crtc->state = NULL; 1005 1006 state = kzalloc(sizeof(*state), GFP_KERNEL); 1007 if (state) { 1008 crtc->state = &state->base; 1009 crtc->state->crtc = crtc; --- 19 unchanged lines hidden (view full) --- 1029 copy->planes = state->planes; 1030 1031 return ©->base; 1032} 1033 1034static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc, 1035 struct drm_crtc_state *state) 1036{ | 1003 1004 kfree(crtc->state); 1005 crtc->state = NULL; 1006 1007 state = kzalloc(sizeof(*state), GFP_KERNEL); 1008 if (state) { 1009 crtc->state = &state->base; 1010 crtc->state->crtc = crtc; --- 19 unchanged lines hidden (view full) --- 1030 copy->planes = state->planes; 1031 1032 return ©->base; 1033} 1034 1035static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc, 1036 struct drm_crtc_state *state) 1037{ |
1037 __drm_atomic_helper_crtc_destroy_state(crtc, state); | 1038 __drm_atomic_helper_crtc_destroy_state(state); |
1038 kfree(state); 1039} 1040 1041static const struct drm_crtc_funcs tegra_crtc_funcs = { 1042 .page_flip = drm_atomic_helper_page_flip, 1043 .set_config = drm_atomic_helper_set_config, 1044 .destroy = tegra_dc_destroy, 1045 .reset = tegra_crtc_reset, --- 165 unchanged lines hidden (view full) --- 1211 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL); 1212 value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | 1213 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); 1214 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); 1215 } 1216 1217 tegra_dc_stats_reset(&dc->stats); 1218 drm_crtc_vblank_off(crtc); | 1039 kfree(state); 1040} 1041 1042static const struct drm_crtc_funcs tegra_crtc_funcs = { 1043 .page_flip = drm_atomic_helper_page_flip, 1044 .set_config = drm_atomic_helper_set_config, 1045 .destroy = tegra_dc_destroy, 1046 .reset = tegra_crtc_reset, --- 165 unchanged lines hidden (view full) --- 1212 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL); 1213 value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | 1214 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); 1215 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); 1216 } 1217 1218 tegra_dc_stats_reset(&dc->stats); 1219 drm_crtc_vblank_off(crtc); |
1220 1221 pm_runtime_put_sync(dc->dev); |
|
1219} 1220 1221static void tegra_crtc_enable(struct drm_crtc *crtc) 1222{ 1223 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 1224 struct tegra_dc_state *state = to_dc_state(crtc->state); 1225 struct tegra_dc *dc = to_tegra_dc(crtc); 1226 u32 value; 1227 | 1222} 1223 1224static void tegra_crtc_enable(struct drm_crtc *crtc) 1225{ 1226 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 1227 struct tegra_dc_state *state = to_dc_state(crtc->state); 1228 struct tegra_dc *dc = to_tegra_dc(crtc); 1229 u32 value; 1230 |
1231 pm_runtime_get_sync(dc->dev); 1232 1233 /* initialize display controller */ 1234 if (dc->syncpt) { 1235 u32 syncpt = host1x_syncpt_id(dc->syncpt); 1236 1237 value = SYNCPT_CNTRL_NO_STALL; 1238 tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); 1239 1240 value = SYNCPT_VSYNC_ENABLE | syncpt; 1241 tegra_dc_writel(dc, value, DC_CMD_CONT_SYNCPT_VSYNC); 1242 } 1243 1244 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1245 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1246 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE); 1247 1248 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1249 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1250 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY); 1251 1252 /* initialize timer */ 1253 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) | 1254 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20); 1255 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY); 1256 1257 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) | 1258 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1); 1259 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); 1260 1261 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1262 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1263 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE); 1264 1265 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1266 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1267 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); 1268 1269 if (dc->soc->supports_border_color) 1270 tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR); 1271 1272 /* apply PLL and pixel clock changes */ |
|
1228 tegra_dc_commit_state(dc, state); 1229 1230 /* program display mode */ 1231 tegra_dc_set_timings(dc, mode); 1232 1233 /* interlacing isn't supported yet, so disable it */ 1234 if (dc->soc->supports_interlacing) { 1235 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL); --- 444 unchanged lines hidden (view full) --- 1680static int tegra_dc_init(struct host1x_client *client) 1681{ 1682 struct drm_device *drm = dev_get_drvdata(client->parent); 1683 unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED; 1684 struct tegra_dc *dc = host1x_client_to_dc(client); 1685 struct tegra_drm *tegra = drm->dev_private; 1686 struct drm_plane *primary = NULL; 1687 struct drm_plane *cursor = NULL; | 1273 tegra_dc_commit_state(dc, state); 1274 1275 /* program display mode */ 1276 tegra_dc_set_timings(dc, mode); 1277 1278 /* interlacing isn't supported yet, so disable it */ 1279 if (dc->soc->supports_interlacing) { 1280 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL); --- 444 unchanged lines hidden (view full) --- 1725static int tegra_dc_init(struct host1x_client *client) 1726{ 1727 struct drm_device *drm = dev_get_drvdata(client->parent); 1728 unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED; 1729 struct tegra_dc *dc = host1x_client_to_dc(client); 1730 struct tegra_drm *tegra = drm->dev_private; 1731 struct drm_plane *primary = NULL; 1732 struct drm_plane *cursor = NULL; |
1688 u32 value; | |
1689 int err; 1690 1691 dc->syncpt = host1x_syncpt_request(dc->dev, flags); 1692 if (!dc->syncpt) 1693 dev_warn(dc->dev, "failed to allocate syncpoint\n"); 1694 1695 if (tegra->domain) { 1696 err = iommu_attach_device(tegra->domain, dc->dev); --- 20 unchanged lines hidden (view full) --- 1717 } 1718 } 1719 1720 err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor, 1721 &tegra_crtc_funcs, NULL); 1722 if (err < 0) 1723 goto cleanup; 1724 | 1733 int err; 1734 1735 dc->syncpt = host1x_syncpt_request(dc->dev, flags); 1736 if (!dc->syncpt) 1737 dev_warn(dc->dev, "failed to allocate syncpoint\n"); 1738 1739 if (tegra->domain) { 1740 err = iommu_attach_device(tegra->domain, dc->dev); --- 20 unchanged lines hidden (view full) --- 1761 } 1762 } 1763 1764 err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor, 1765 &tegra_crtc_funcs, NULL); 1766 if (err < 0) 1767 goto cleanup; 1768 |
1725 drm_mode_crtc_set_gamma_size(&dc->base, 256); | |
1726 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); 1727 1728 /* 1729 * Keep track of the minimum pitch alignment across all display 1730 * controllers. 1731 */ 1732 if (dc->soc->pitch_align > tegra->pitch_align) 1733 tegra->pitch_align = dc->soc->pitch_align; --- 17 unchanged lines hidden (view full) --- 1751 err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0, 1752 dev_name(dc->dev), dc); 1753 if (err < 0) { 1754 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq, 1755 err); 1756 goto cleanup; 1757 } 1758 | 1769 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); 1770 1771 /* 1772 * Keep track of the minimum pitch alignment across all display 1773 * controllers. 1774 */ 1775 if (dc->soc->pitch_align > tegra->pitch_align) 1776 tegra->pitch_align = dc->soc->pitch_align; --- 17 unchanged lines hidden (view full) --- 1794 err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0, 1795 dev_name(dc->dev), dc); 1796 if (err < 0) { 1797 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq, 1798 err); 1799 goto cleanup; 1800 } 1801 |
1759 /* initialize display controller */ 1760 if (dc->syncpt) { 1761 u32 syncpt = host1x_syncpt_id(dc->syncpt); 1762 1763 value = SYNCPT_CNTRL_NO_STALL; 1764 tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); 1765 1766 value = SYNCPT_VSYNC_ENABLE | syncpt; 1767 tegra_dc_writel(dc, value, DC_CMD_CONT_SYNCPT_VSYNC); 1768 } 1769 1770 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1771 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1772 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE); 1773 1774 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1775 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1776 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY); 1777 1778 /* initialize timer */ 1779 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) | 1780 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20); 1781 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY); 1782 1783 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) | 1784 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1); 1785 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); 1786 1787 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1788 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1789 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE); 1790 1791 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 1792 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 1793 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); 1794 1795 if (dc->soc->supports_border_color) 1796 tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR); 1797 1798 tegra_dc_stats_reset(&dc->stats); 1799 | |
1800 return 0; 1801 1802cleanup: 1803 if (cursor) 1804 drm_plane_cleanup(cursor); 1805 1806 if (primary) 1807 drm_plane_cleanup(primary); --- 175 unchanged lines hidden (view full) --- 1983 } 1984 1985 dc->rst = devm_reset_control_get(&pdev->dev, "dc"); 1986 if (IS_ERR(dc->rst)) { 1987 dev_err(&pdev->dev, "failed to get reset\n"); 1988 return PTR_ERR(dc->rst); 1989 } 1990 | 1802 return 0; 1803 1804cleanup: 1805 if (cursor) 1806 drm_plane_cleanup(cursor); 1807 1808 if (primary) 1809 drm_plane_cleanup(primary); --- 175 unchanged lines hidden (view full) --- 1985 } 1986 1987 dc->rst = devm_reset_control_get(&pdev->dev, "dc"); 1988 if (IS_ERR(dc->rst)) { 1989 dev_err(&pdev->dev, "failed to get reset\n"); 1990 return PTR_ERR(dc->rst); 1991 } 1992 |
1993 reset_control_assert(dc->rst); 1994 |
|
1991 if (dc->soc->has_powergate) { 1992 if (dc->pipe == 0) 1993 dc->powergate = TEGRA_POWERGATE_DIS; 1994 else 1995 dc->powergate = TEGRA_POWERGATE_DISB; 1996 | 1995 if (dc->soc->has_powergate) { 1996 if (dc->pipe == 0) 1997 dc->powergate = TEGRA_POWERGATE_DIS; 1998 else 1999 dc->powergate = TEGRA_POWERGATE_DISB; 2000 |
1997 err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, 1998 dc->rst); 1999 if (err < 0) { 2000 dev_err(&pdev->dev, "failed to power partition: %d\n", 2001 err); 2002 return err; 2003 } 2004 } else { 2005 err = clk_prepare_enable(dc->clk); 2006 if (err < 0) { 2007 dev_err(&pdev->dev, "failed to enable clock: %d\n", 2008 err); 2009 return err; 2010 } 2011 2012 err = reset_control_deassert(dc->rst); 2013 if (err < 0) { 2014 dev_err(&pdev->dev, "failed to deassert reset: %d\n", 2015 err); 2016 return err; 2017 } | 2001 tegra_powergate_power_off(dc->powergate); |
2018 } 2019 2020 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2021 dc->regs = devm_ioremap_resource(&pdev->dev, regs); 2022 if (IS_ERR(dc->regs)) 2023 return PTR_ERR(dc->regs); 2024 2025 dc->irq = platform_get_irq(pdev, 0); 2026 if (dc->irq < 0) { 2027 dev_err(&pdev->dev, "failed to get IRQ\n"); 2028 return -ENXIO; 2029 } 2030 | 2002 } 2003 2004 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2005 dc->regs = devm_ioremap_resource(&pdev->dev, regs); 2006 if (IS_ERR(dc->regs)) 2007 return PTR_ERR(dc->regs); 2008 2009 dc->irq = platform_get_irq(pdev, 0); 2010 if (dc->irq < 0) { 2011 dev_err(&pdev->dev, "failed to get IRQ\n"); 2012 return -ENXIO; 2013 } 2014 |
2031 INIT_LIST_HEAD(&dc->client.list); 2032 dc->client.ops = &dc_client_ops; 2033 dc->client.dev = &pdev->dev; 2034 | |
2035 err = tegra_dc_rgb_probe(dc); 2036 if (err < 0 && err != -ENODEV) { 2037 dev_err(&pdev->dev, "failed to probe RGB output: %d\n", err); 2038 return err; 2039 } 2040 | 2015 err = tegra_dc_rgb_probe(dc); 2016 if (err < 0 && err != -ENODEV) { 2017 dev_err(&pdev->dev, "failed to probe RGB output: %d\n", err); 2018 return err; 2019 } 2020 |
2021 platform_set_drvdata(pdev, dc); 2022 pm_runtime_enable(&pdev->dev); 2023 2024 INIT_LIST_HEAD(&dc->client.list); 2025 dc->client.ops = &dc_client_ops; 2026 dc->client.dev = &pdev->dev; 2027 |
|
2041 err = host1x_client_register(&dc->client); 2042 if (err < 0) { 2043 dev_err(&pdev->dev, "failed to register host1x client: %d\n", 2044 err); 2045 return err; 2046 } 2047 | 2028 err = host1x_client_register(&dc->client); 2029 if (err < 0) { 2030 dev_err(&pdev->dev, "failed to register host1x client: %d\n", 2031 err); 2032 return err; 2033 } 2034 |
2048 platform_set_drvdata(pdev, dc); 2049 | |
2050 return 0; 2051} 2052 2053static int tegra_dc_remove(struct platform_device *pdev) 2054{ 2055 struct tegra_dc *dc = platform_get_drvdata(pdev); 2056 int err; 2057 --- 5 unchanged lines hidden (view full) --- 2063 } 2064 2065 err = tegra_dc_rgb_remove(dc); 2066 if (err < 0) { 2067 dev_err(&pdev->dev, "failed to remove RGB output: %d\n", err); 2068 return err; 2069 } 2070 | 2035 return 0; 2036} 2037 2038static int tegra_dc_remove(struct platform_device *pdev) 2039{ 2040 struct tegra_dc *dc = platform_get_drvdata(pdev); 2041 int err; 2042 --- 5 unchanged lines hidden (view full) --- 2048 } 2049 2050 err = tegra_dc_rgb_remove(dc); 2051 if (err < 0) { 2052 dev_err(&pdev->dev, "failed to remove RGB output: %d\n", err); 2053 return err; 2054 } 2055 |
2071 reset_control_assert(dc->rst); | 2056 pm_runtime_disable(&pdev->dev); |
2072 | 2057 |
2058 return 0; 2059} 2060 2061#ifdef CONFIG_PM 2062static int tegra_dc_suspend(struct device *dev) 2063{ 2064 struct tegra_dc *dc = dev_get_drvdata(dev); 2065 int err; 2066 2067 err = reset_control_assert(dc->rst); 2068 if (err < 0) { 2069 dev_err(dev, "failed to assert reset: %d\n", err); 2070 return err; 2071 } 2072 |
|
2073 if (dc->soc->has_powergate) 2074 tegra_powergate_power_off(dc->powergate); 2075 2076 clk_disable_unprepare(dc->clk); 2077 2078 return 0; 2079} 2080 | 2073 if (dc->soc->has_powergate) 2074 tegra_powergate_power_off(dc->powergate); 2075 2076 clk_disable_unprepare(dc->clk); 2077 2078 return 0; 2079} 2080 |
2081static int tegra_dc_resume(struct device *dev) 2082{ 2083 struct tegra_dc *dc = dev_get_drvdata(dev); 2084 int err; 2085 2086 if (dc->soc->has_powergate) { 2087 err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, 2088 dc->rst); 2089 if (err < 0) { 2090 dev_err(dev, "failed to power partition: %d\n", err); 2091 return err; 2092 } 2093 } else { 2094 err = clk_prepare_enable(dc->clk); 2095 if (err < 0) { 2096 dev_err(dev, "failed to enable clock: %d\n", err); 2097 return err; 2098 } 2099 2100 err = reset_control_deassert(dc->rst); 2101 if (err < 0) { 2102 dev_err(dev, "failed to deassert reset: %d\n", err); 2103 return err; 2104 } 2105 } 2106 2107 return 0; 2108} 2109#endif 2110 2111static const struct dev_pm_ops tegra_dc_pm_ops = { 2112 SET_RUNTIME_PM_OPS(tegra_dc_suspend, tegra_dc_resume, NULL) 2113}; 2114 |
|
2081struct platform_driver tegra_dc_driver = { 2082 .driver = { 2083 .name = "tegra-dc", 2084 .of_match_table = tegra_dc_of_match, | 2115struct platform_driver tegra_dc_driver = { 2116 .driver = { 2117 .name = "tegra-dc", 2118 .of_match_table = tegra_dc_of_match, |
2119 .pm = &tegra_dc_pm_ops, |
|
2085 }, 2086 .probe = tegra_dc_probe, 2087 .remove = tegra_dc_remove, 2088}; | 2120 }, 2121 .probe = tegra_dc_probe, 2122 .remove = tegra_dc_remove, 2123}; |