1111#include <linux/interconnect.h>
1212#include <linux/module.h>
1313#include <linux/of_device.h>
14+ #include <linux/pm_domain.h>
15+ #include <linux/pm_opp.h>
1416#include <linux/pm_runtime.h>
1517#include <linux/reset.h>
1618
19+ #include <soc/tegra/common.h>
1720#include <soc/tegra/pmc.h>
1821
1922#include <drm/drm_atomic.h>
@@ -890,11 +893,9 @@ static int tegra_cursor_atomic_check(struct drm_plane *plane,
890893 return 0 ;
891894}
892895
893- static void tegra_cursor_atomic_update (struct drm_plane * plane ,
894- struct drm_atomic_state * state )
896+ static void __tegra_cursor_atomic_update (struct drm_plane * plane ,
897+ struct drm_plane_state * new_state )
895898{
896- struct drm_plane_state * new_state = drm_atomic_get_new_plane_state (state ,
897- plane );
898899 struct tegra_plane_state * tegra_plane_state = to_tegra_plane_state (new_state );
899900 struct tegra_dc * dc = to_tegra_dc (new_state -> crtc );
900901 struct tegra_drm * tegra = plane -> dev -> dev_private ;
@@ -990,6 +991,14 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
990991 tegra_dc_writel (dc , value , DC_DISP_CURSOR_POSITION );
991992}
992993
994+ static void tegra_cursor_atomic_update (struct drm_plane * plane ,
995+ struct drm_atomic_state * state )
996+ {
997+ struct drm_plane_state * new_state = drm_atomic_get_new_plane_state (state , plane );
998+
999+ __tegra_cursor_atomic_update (plane , new_state );
1000+ }
1001+
9931002static void tegra_cursor_atomic_disable (struct drm_plane * plane ,
9941003 struct drm_atomic_state * state )
9951004{
@@ -1009,12 +1018,78 @@ static void tegra_cursor_atomic_disable(struct drm_plane *plane,
10091018 tegra_dc_writel (dc , value , DC_DISP_DISP_WIN_OPTIONS );
10101019}
10111020
1021+ static int tegra_cursor_atomic_async_check (struct drm_plane * plane , struct drm_atomic_state * state )
1022+ {
1023+ struct drm_plane_state * new_state = drm_atomic_get_new_plane_state (state , plane );
1024+ struct drm_crtc_state * crtc_state ;
1025+ int min_scale , max_scale ;
1026+ int err ;
1027+
1028+ crtc_state = drm_atomic_get_existing_crtc_state (state , new_state -> crtc );
1029+ if (WARN_ON (!crtc_state ))
1030+ return - EINVAL ;
1031+
1032+ if (!crtc_state -> active )
1033+ return - EINVAL ;
1034+
1035+ if (plane -> state -> crtc != new_state -> crtc ||
1036+ plane -> state -> src_w != new_state -> src_w ||
1037+ plane -> state -> src_h != new_state -> src_h ||
1038+ plane -> state -> crtc_w != new_state -> crtc_w ||
1039+ plane -> state -> crtc_h != new_state -> crtc_h ||
1040+ plane -> state -> fb != new_state -> fb ||
1041+ plane -> state -> fb == NULL )
1042+ return - EINVAL ;
1043+
1044+ min_scale = (1 << 16 ) / 8 ;
1045+ max_scale = (8 << 16 ) / 1 ;
1046+
1047+ err = drm_atomic_helper_check_plane_state (new_state , crtc_state , min_scale , max_scale ,
1048+ true, true);
1049+ if (err < 0 )
1050+ return err ;
1051+
1052+ if (new_state -> visible != plane -> state -> visible )
1053+ return - EINVAL ;
1054+
1055+ return 0 ;
1056+ }
1057+
1058+ static void tegra_cursor_atomic_async_update (struct drm_plane * plane ,
1059+ struct drm_atomic_state * state )
1060+ {
1061+ struct drm_plane_state * new_state = drm_atomic_get_new_plane_state (state , plane );
1062+ struct tegra_dc * dc = to_tegra_dc (new_state -> crtc );
1063+
1064+ plane -> state -> src_x = new_state -> src_x ;
1065+ plane -> state -> src_y = new_state -> src_y ;
1066+ plane -> state -> crtc_x = new_state -> crtc_x ;
1067+ plane -> state -> crtc_y = new_state -> crtc_y ;
1068+
1069+ if (new_state -> visible ) {
1070+ struct tegra_plane * p = to_tegra_plane (plane );
1071+ u32 value ;
1072+
1073+ __tegra_cursor_atomic_update (plane , new_state );
1074+
1075+ value = (WIN_A_ACT_REQ << p -> index ) << 8 | GENERAL_UPDATE ;
1076+ tegra_dc_writel (dc , value , DC_CMD_STATE_CONTROL );
1077+ (void )tegra_dc_readl (dc , DC_CMD_STATE_CONTROL );
1078+
1079+ value = (WIN_A_ACT_REQ << p -> index ) | GENERAL_ACT_REQ ;
1080+ tegra_dc_writel (dc , value , DC_CMD_STATE_CONTROL );
1081+ (void )tegra_dc_readl (dc , DC_CMD_STATE_CONTROL );
1082+ }
1083+ }
1084+
10121085static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs = {
10131086 .prepare_fb = tegra_plane_prepare_fb ,
10141087 .cleanup_fb = tegra_plane_cleanup_fb ,
10151088 .atomic_check = tegra_cursor_atomic_check ,
10161089 .atomic_update = tegra_cursor_atomic_update ,
10171090 .atomic_disable = tegra_cursor_atomic_disable ,
1091+ .atomic_async_check = tegra_cursor_atomic_async_check ,
1092+ .atomic_async_update = tegra_cursor_atomic_async_update ,
10181093};
10191094
10201095static const uint64_t linear_modifiers [] = {
@@ -1267,9 +1342,9 @@ static struct drm_plane *tegra_dc_add_planes(struct drm_device *drm,
12671342 err = PTR_ERR (planes [i ]);
12681343
12691344 while (i -- )
1270- tegra_plane_funcs . destroy (planes [i ]);
1345+ planes [ i ] -> funcs -> destroy (planes [i ]);
12711346
1272- tegra_plane_funcs . destroy (primary );
1347+ primary -> funcs -> destroy (primary );
12731348 return ERR_PTR (err );
12741349 }
12751350 }
@@ -1762,10 +1837,55 @@ int tegra_dc_state_setup_clock(struct tegra_dc *dc,
17621837 return 0 ;
17631838}
17641839
1765- static void tegra_dc_commit_state (struct tegra_dc * dc ,
1766- struct tegra_dc_state * state )
1840+ static void tegra_dc_update_voltage_state (struct tegra_dc * dc ,
1841+ struct tegra_dc_state * state )
1842+ {
1843+ unsigned long rate , pstate ;
1844+ struct dev_pm_opp * opp ;
1845+ int err ;
1846+
1847+ if (!dc -> has_opp_table )
1848+ return ;
1849+
1850+ /* calculate actual pixel clock rate which depends on internal divider */
1851+ rate = DIV_ROUND_UP (clk_get_rate (dc -> clk ) * 2 , state -> div + 2 );
1852+
1853+ /* find suitable OPP for the rate */
1854+ opp = dev_pm_opp_find_freq_ceil (dc -> dev , & rate );
1855+
1856+ /*
1857+ * Very high resolution modes may results in a clock rate that is
1858+ * above the characterized maximum. In this case it's okay to fall
1859+ * back to the characterized maximum.
1860+ */
1861+ if (opp == ERR_PTR (- ERANGE ))
1862+ opp = dev_pm_opp_find_freq_floor (dc -> dev , & rate );
1863+
1864+ if (IS_ERR (opp )) {
1865+ dev_err (dc -> dev , "failed to find OPP for %luHz: %pe\n" ,
1866+ rate , opp );
1867+ return ;
1868+ }
1869+
1870+ pstate = dev_pm_opp_get_required_pstate (opp , 0 );
1871+ dev_pm_opp_put (opp );
1872+
1873+ /*
1874+ * The minimum core voltage depends on the pixel clock rate (which
1875+ * depends on internal clock divider of the CRTC) and not on the
1876+ * rate of the display controller clock. This is why we're not using
1877+ * dev_pm_opp_set_rate() API and instead controlling the power domain
1878+ * directly.
1879+ */
1880+ err = dev_pm_genpd_set_performance_state (dc -> dev , pstate );
1881+ if (err )
1882+ dev_err (dc -> dev , "failed to set power domain state to %lu: %d\n" ,
1883+ pstate , err );
1884+ }
1885+
1886+ static void tegra_dc_set_clock_rate (struct tegra_dc * dc ,
1887+ struct tegra_dc_state * state )
17671888{
1768- u32 value ;
17691889 int err ;
17701890
17711891 err = clk_set_parent (dc -> clk , state -> clk );
@@ -1797,10 +1917,7 @@ static void tegra_dc_commit_state(struct tegra_dc *dc,
17971917 state -> div );
17981918 DRM_DEBUG_KMS ("pclk: %lu\n" , state -> pclk );
17991919
1800- if (!dc -> soc -> has_nvdisplay ) {
1801- value = SHIFT_CLK_DIVIDER (state -> div ) | PIXEL_CLK_DIVIDER_PCD1 ;
1802- tegra_dc_writel (dc , value , DC_DISP_DISP_CLOCK_CONTROL );
1803- }
1920+ tegra_dc_update_voltage_state (dc , state );
18041921}
18051922
18061923static void tegra_dc_stop (struct tegra_dc * dc )
@@ -1991,6 +2108,13 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
19912108 err = host1x_client_suspend (& dc -> client );
19922109 if (err < 0 )
19932110 dev_err (dc -> dev , "failed to suspend: %d\n" , err );
2111+
2112+ if (dc -> has_opp_table ) {
2113+ err = dev_pm_genpd_set_performance_state (dc -> dev , 0 );
2114+ if (err )
2115+ dev_err (dc -> dev ,
2116+ "failed to clear power domain state: %d\n" , err );
2117+ }
19942118}
19952119
19962120static void tegra_crtc_atomic_enable (struct drm_crtc * crtc ,
@@ -2002,6 +2126,9 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
20022126 u32 value ;
20032127 int err ;
20042128
2129+ /* apply PLL changes */
2130+ tegra_dc_set_clock_rate (dc , crtc_state );
2131+
20052132 err = host1x_client_resume (& dc -> client );
20062133 if (err < 0 ) {
20072134 dev_err (dc -> dev , "failed to resume: %d\n" , err );
@@ -2076,8 +2203,11 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
20762203 else
20772204 tegra_dc_writel (dc , 0 , DC_DISP_BORDER_COLOR );
20782205
2079- /* apply PLL and pixel clock changes */
2080- tegra_dc_commit_state (dc , crtc_state );
2206+ /* apply pixel clock changes */
2207+ if (!dc -> soc -> has_nvdisplay ) {
2208+ value = SHIFT_CLK_DIVIDER (crtc_state -> div ) | PIXEL_CLK_DIVIDER_PCD1 ;
2209+ tegra_dc_writel (dc , value , DC_DISP_DISP_CLOCK_CONTROL );
2210+ }
20812211
20822212 /* program display mode */
20832213 tegra_dc_set_timings (dc , mode );
@@ -2107,6 +2237,12 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
21072237 tegra_dc_writel (dc , value , DC_COM_RG_UNDERFLOW );
21082238 }
21092239
2240+ if (dc -> rgb ) {
2241+ /* XXX: parameterize? */
2242+ value = SC0_H_QUALIFIER_NONE | SC1_H_QUALIFIER_NONE ;
2243+ tegra_dc_writel (dc , value , DC_DISP_SHIFT_CLOCK_OPTIONS );
2244+ }
2245+
21102246 tegra_dc_commit (dc );
21112247
21122248 drm_crtc_vblank_on (crtc );
@@ -2685,6 +2821,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
26852821 .has_win_b_vfilter_mem_client = true,
26862822 .has_win_c_without_vert_filter = true,
26872823 .plane_tiled_memory_bandwidth_x2 = false,
2824+ .has_pll_d2_out0 = false,
26882825};
26892826
26902827static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
@@ -2707,6 +2844,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
27072844 .has_win_b_vfilter_mem_client = true,
27082845 .has_win_c_without_vert_filter = false,
27092846 .plane_tiled_memory_bandwidth_x2 = true,
2847+ .has_pll_d2_out0 = true,
27102848};
27112849
27122850static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
@@ -2729,6 +2867,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
27292867 .has_win_b_vfilter_mem_client = false,
27302868 .has_win_c_without_vert_filter = false,
27312869 .plane_tiled_memory_bandwidth_x2 = true,
2870+ .has_pll_d2_out0 = true,
27322871};
27332872
27342873static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
@@ -2751,6 +2890,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
27512890 .has_win_b_vfilter_mem_client = false,
27522891 .has_win_c_without_vert_filter = false,
27532892 .plane_tiled_memory_bandwidth_x2 = false,
2893+ .has_pll_d2_out0 = true,
27542894};
27552895
27562896static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -2773,6 +2913,7 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
27732913 .has_win_b_vfilter_mem_client = false,
27742914 .has_win_c_without_vert_filter = false,
27752915 .plane_tiled_memory_bandwidth_x2 = false,
2916+ .has_pll_d2_out0 = true,
27762917};
27772918
27782919static const struct tegra_windowgroup_soc tegra186_dc_wgrps [] = {
@@ -2823,6 +2964,7 @@ static const struct tegra_dc_soc_info tegra186_dc_soc_info = {
28232964 .wgrps = tegra186_dc_wgrps ,
28242965 .num_wgrps = ARRAY_SIZE (tegra186_dc_wgrps ),
28252966 .plane_tiled_memory_bandwidth_x2 = false,
2967+ .has_pll_d2_out0 = false,
28262968};
28272969
28282970static const struct tegra_windowgroup_soc tegra194_dc_wgrps [] = {
@@ -2873,6 +3015,7 @@ static const struct tegra_dc_soc_info tegra194_dc_soc_info = {
28733015 .wgrps = tegra194_dc_wgrps ,
28743016 .num_wgrps = ARRAY_SIZE (tegra194_dc_wgrps ),
28753017 .plane_tiled_memory_bandwidth_x2 = false,
3018+ .has_pll_d2_out0 = false,
28763019};
28773020
28783021static const struct of_device_id tegra_dc_of_match [] = {
@@ -2973,6 +3116,23 @@ static int tegra_dc_couple(struct tegra_dc *dc)
29733116 return 0 ;
29743117}
29753118
3119+ static int tegra_dc_init_opp_table (struct tegra_dc * dc )
3120+ {
3121+ struct tegra_core_opp_params opp_params = {};
3122+ int err ;
3123+
3124+ err = devm_tegra_core_dev_init_opp_table (dc -> dev , & opp_params );
3125+ if (err && err != - ENODEV )
3126+ return err ;
3127+
3128+ if (err )
3129+ dc -> has_opp_table = false;
3130+ else
3131+ dc -> has_opp_table = true;
3132+
3133+ return 0 ;
3134+ }
3135+
29763136static int tegra_dc_probe (struct platform_device * pdev )
29773137{
29783138 u64 dma_mask = dma_get_mask (pdev -> dev .parent );
@@ -3038,6 +3198,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
30383198 tegra_powergate_power_off (dc -> powergate );
30393199 }
30403200
3201+ err = tegra_dc_init_opp_table (dc );
3202+ if (err < 0 )
3203+ return err ;
3204+
30413205 dc -> regs = devm_platform_ioremap_resource (pdev , 0 );
30423206 if (IS_ERR (dc -> regs ))
30433207 return PTR_ERR (dc -> regs );
0 commit comments