11099013bSjsg /*
21099013bSjsg * Copyright 2007-8 Advanced Micro Devices, Inc.
31099013bSjsg * Copyright 2008 Red Hat Inc.
41099013bSjsg *
51099013bSjsg * Permission is hereby granted, free of charge, to any person obtaining a
61099013bSjsg * copy of this software and associated documentation files (the "Software"),
71099013bSjsg * to deal in the Software without restriction, including without limitation
81099013bSjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
91099013bSjsg * and/or sell copies of the Software, and to permit persons to whom the
101099013bSjsg * Software is furnished to do so, subject to the following conditions:
111099013bSjsg *
121099013bSjsg * The above copyright notice and this permission notice shall be included in
131099013bSjsg * all copies or substantial portions of the Software.
141099013bSjsg *
151099013bSjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161099013bSjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171099013bSjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
181099013bSjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
191099013bSjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
201099013bSjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
211099013bSjsg * OTHER DEALINGS IN THE SOFTWARE.
221099013bSjsg *
231099013bSjsg * Authors: Dave Airlie
241099013bSjsg * Alex Deucher
251099013bSjsg */
26c349dbc7Sjsg
277f4dd379Sjsg #include <drm/drm_fixed.h>
28c349dbc7Sjsg #include <drm/drm_fourcc.h>
291bb76ff1Sjsg #include <drm/drm_framebuffer.h>
30*f005ef32Sjsg #include <drm/drm_modeset_helper_vtables.h>
31c349dbc7Sjsg #include <drm/drm_vblank.h>
32c349dbc7Sjsg #include <drm/radeon_drm.h>
33c349dbc7Sjsg
341099013bSjsg #include "atom.h"
35c349dbc7Sjsg #include "radeon.h"
361099013bSjsg
radeon_overscan_setup(struct drm_crtc * crtc,struct drm_display_mode * mode)371099013bSjsg static void radeon_overscan_setup(struct drm_crtc *crtc,
381099013bSjsg struct drm_display_mode *mode)
391099013bSjsg {
401099013bSjsg struct drm_device *dev = crtc->dev;
411099013bSjsg struct radeon_device *rdev = dev->dev_private;
421099013bSjsg struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
431099013bSjsg
441099013bSjsg WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0);
451099013bSjsg WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0);
461099013bSjsg WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0);
471099013bSjsg }
481099013bSjsg
radeon_legacy_rmx_mode_set(struct drm_crtc * crtc,struct drm_display_mode * mode)491099013bSjsg static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
501099013bSjsg struct drm_display_mode *mode)
511099013bSjsg {
521099013bSjsg struct drm_device *dev = crtc->dev;
531099013bSjsg struct radeon_device *rdev = dev->dev_private;
541099013bSjsg struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
551099013bSjsg int xres = mode->hdisplay;
561099013bSjsg int yres = mode->vdisplay;
571099013bSjsg bool hscale = true, vscale = true;
581099013bSjsg int hsync_wid;
591099013bSjsg int vsync_wid;
601099013bSjsg int hsync_start;
611099013bSjsg int blank_width;
621099013bSjsg u32 scale, inc, crtc_more_cntl;
631099013bSjsg u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active;
641099013bSjsg u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp;
651099013bSjsg u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp;
661099013bSjsg struct drm_display_mode *native_mode = &radeon_crtc->native_mode;
671099013bSjsg
681099013bSjsg fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) &
691099013bSjsg (RADEON_VERT_STRETCH_RESERVED |
701099013bSjsg RADEON_VERT_AUTO_RATIO_INC);
711099013bSjsg fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH) &
721099013bSjsg (RADEON_HORZ_FP_LOOP_STRETCH |
731099013bSjsg RADEON_HORZ_AUTO_RATIO_INC);
741099013bSjsg
751099013bSjsg crtc_more_cntl = 0;
761099013bSjsg if ((rdev->family == CHIP_RS100) ||
771099013bSjsg (rdev->family == CHIP_RS200)) {
781099013bSjsg /* This is to workaround the asic bug for RMX, some versions
791099013bSjsg of BIOS dosen't have this register initialized correctly. */
801099013bSjsg crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
811099013bSjsg }
821099013bSjsg
831099013bSjsg
841099013bSjsg fp_crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff)
851099013bSjsg | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
861099013bSjsg
871099013bSjsg hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
881099013bSjsg if (!hsync_wid)
891099013bSjsg hsync_wid = 1;
901099013bSjsg hsync_start = mode->crtc_hsync_start - 8;
911099013bSjsg
921099013bSjsg fp_h_sync_strt_wid = ((hsync_start & 0x1fff)
931099013bSjsg | ((hsync_wid & 0x3f) << 16)
941099013bSjsg | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
951099013bSjsg ? RADEON_CRTC_H_SYNC_POL
961099013bSjsg : 0));
971099013bSjsg
981099013bSjsg fp_crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff)
991099013bSjsg | ((mode->crtc_vdisplay - 1) << 16));
1001099013bSjsg
1011099013bSjsg vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
1021099013bSjsg if (!vsync_wid)
1031099013bSjsg vsync_wid = 1;
1041099013bSjsg
1051099013bSjsg fp_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff)
1061099013bSjsg | ((vsync_wid & 0x1f) << 16)
1071099013bSjsg | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
1081099013bSjsg ? RADEON_CRTC_V_SYNC_POL
1091099013bSjsg : 0));
1101099013bSjsg
1111099013bSjsg fp_horz_vert_active = 0;
1121099013bSjsg
1131099013bSjsg if (native_mode->hdisplay == 0 ||
1141099013bSjsg native_mode->vdisplay == 0) {
1151099013bSjsg hscale = false;
1161099013bSjsg vscale = false;
1171099013bSjsg } else {
1181099013bSjsg if (xres > native_mode->hdisplay)
1191099013bSjsg xres = native_mode->hdisplay;
1201099013bSjsg if (yres > native_mode->vdisplay)
1211099013bSjsg yres = native_mode->vdisplay;
1221099013bSjsg
1231099013bSjsg if (xres == native_mode->hdisplay)
1241099013bSjsg hscale = false;
1251099013bSjsg if (yres == native_mode->vdisplay)
1261099013bSjsg vscale = false;
1271099013bSjsg }
1281099013bSjsg
1291099013bSjsg switch (radeon_crtc->rmx_type) {
1301099013bSjsg case RMX_FULL:
1311099013bSjsg case RMX_ASPECT:
1321099013bSjsg if (!hscale)
1331099013bSjsg fp_horz_stretch |= ((xres/8-1) << 16);
1341099013bSjsg else {
1351099013bSjsg inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
1361099013bSjsg scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
1371099013bSjsg / native_mode->hdisplay + 1;
1381099013bSjsg fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
1391099013bSjsg RADEON_HORZ_STRETCH_BLEND |
1401099013bSjsg RADEON_HORZ_STRETCH_ENABLE |
1411099013bSjsg ((native_mode->hdisplay/8-1) << 16));
1421099013bSjsg }
1431099013bSjsg
1441099013bSjsg if (!vscale)
1451099013bSjsg fp_vert_stretch |= ((yres-1) << 12);
1461099013bSjsg else {
1471099013bSjsg inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
1481099013bSjsg scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
1491099013bSjsg / native_mode->vdisplay + 1;
1501099013bSjsg fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
1511099013bSjsg RADEON_VERT_STRETCH_ENABLE |
1521099013bSjsg RADEON_VERT_STRETCH_BLEND |
1531099013bSjsg ((native_mode->vdisplay-1) << 12));
1541099013bSjsg }
1551099013bSjsg break;
1561099013bSjsg case RMX_CENTER:
1571099013bSjsg fp_horz_stretch |= ((xres/8-1) << 16);
1581099013bSjsg fp_vert_stretch |= ((yres-1) << 12);
1591099013bSjsg
1601099013bSjsg crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN |
1611099013bSjsg RADEON_CRTC_AUTO_VERT_CENTER_EN);
1621099013bSjsg
1631099013bSjsg blank_width = (mode->crtc_hblank_end - mode->crtc_hblank_start) / 8;
1641099013bSjsg if (blank_width > 110)
1651099013bSjsg blank_width = 110;
1661099013bSjsg
1671099013bSjsg fp_crtc_h_total_disp = (((blank_width) & 0x3ff)
1681099013bSjsg | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
1691099013bSjsg
1701099013bSjsg hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
1711099013bSjsg if (!hsync_wid)
1721099013bSjsg hsync_wid = 1;
1731099013bSjsg
1741099013bSjsg fp_h_sync_strt_wid = ((((mode->crtc_hsync_start - mode->crtc_hblank_start) / 8) & 0x1fff)
1751099013bSjsg | ((hsync_wid & 0x3f) << 16)
1761099013bSjsg | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
1771099013bSjsg ? RADEON_CRTC_H_SYNC_POL
1781099013bSjsg : 0));
1791099013bSjsg
1801099013bSjsg fp_crtc_v_total_disp = (((mode->crtc_vblank_end - mode->crtc_vblank_start) & 0xffff)
1811099013bSjsg | ((mode->crtc_vdisplay - 1) << 16));
1821099013bSjsg
1831099013bSjsg vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
1841099013bSjsg if (!vsync_wid)
1851099013bSjsg vsync_wid = 1;
1861099013bSjsg
1871099013bSjsg fp_v_sync_strt_wid = ((((mode->crtc_vsync_start - mode->crtc_vblank_start) & 0xfff)
1881099013bSjsg | ((vsync_wid & 0x1f) << 16)
1891099013bSjsg | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
1901099013bSjsg ? RADEON_CRTC_V_SYNC_POL
1911099013bSjsg : 0)));
1921099013bSjsg
1931099013bSjsg fp_horz_vert_active = (((native_mode->vdisplay) & 0xfff) |
1941099013bSjsg (((native_mode->hdisplay / 8) & 0x1ff) << 16));
1951099013bSjsg break;
1961099013bSjsg case RMX_OFF:
1971099013bSjsg default:
1981099013bSjsg fp_horz_stretch |= ((xres/8-1) << 16);
1991099013bSjsg fp_vert_stretch |= ((yres-1) << 12);
2001099013bSjsg break;
2011099013bSjsg }
2021099013bSjsg
2031099013bSjsg WREG32(RADEON_FP_HORZ_STRETCH, fp_horz_stretch);
2041099013bSjsg WREG32(RADEON_FP_VERT_STRETCH, fp_vert_stretch);
2051099013bSjsg WREG32(RADEON_CRTC_MORE_CNTL, crtc_more_cntl);
2061099013bSjsg WREG32(RADEON_FP_HORZ_VERT_ACTIVE, fp_horz_vert_active);
2071099013bSjsg WREG32(RADEON_FP_H_SYNC_STRT_WID, fp_h_sync_strt_wid);
2081099013bSjsg WREG32(RADEON_FP_V_SYNC_STRT_WID, fp_v_sync_strt_wid);
2091099013bSjsg WREG32(RADEON_FP_CRTC_H_TOTAL_DISP, fp_crtc_h_total_disp);
2101099013bSjsg WREG32(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp);
2111099013bSjsg }
2121099013bSjsg
radeon_pll_wait_for_read_update_complete(struct drm_device * dev)2131099013bSjsg static void radeon_pll_wait_for_read_update_complete(struct drm_device *dev)
2141099013bSjsg {
2151099013bSjsg struct radeon_device *rdev = dev->dev_private;
2161099013bSjsg int i = 0;
2171099013bSjsg
2181099013bSjsg /* FIXME: Certain revisions of R300 can't recover here. Not sure of
2191099013bSjsg the cause yet, but this workaround will mask the problem for now.
2201099013bSjsg Other chips usually will pass at the very first test, so the
2211099013bSjsg workaround shouldn't have any effect on them. */
2221099013bSjsg for (i = 0;
2231099013bSjsg (i < 10000 &&
2241099013bSjsg RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
2251099013bSjsg i++);
2261099013bSjsg }
2271099013bSjsg
radeon_pll_write_update(struct drm_device * dev)2281099013bSjsg static void radeon_pll_write_update(struct drm_device *dev)
2291099013bSjsg {
2301099013bSjsg struct radeon_device *rdev = dev->dev_private;
2311099013bSjsg
2321099013bSjsg while (RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
2331099013bSjsg
2341099013bSjsg WREG32_PLL_P(RADEON_PPLL_REF_DIV,
2351099013bSjsg RADEON_PPLL_ATOMIC_UPDATE_W,
2361099013bSjsg ~(RADEON_PPLL_ATOMIC_UPDATE_W));
2371099013bSjsg }
2381099013bSjsg
radeon_pll2_wait_for_read_update_complete(struct drm_device * dev)2391099013bSjsg static void radeon_pll2_wait_for_read_update_complete(struct drm_device *dev)
2401099013bSjsg {
2411099013bSjsg struct radeon_device *rdev = dev->dev_private;
2421099013bSjsg int i = 0;
2431099013bSjsg
2441099013bSjsg
2451099013bSjsg /* FIXME: Certain revisions of R300 can't recover here. Not sure of
2461099013bSjsg the cause yet, but this workaround will mask the problem for now.
2471099013bSjsg Other chips usually will pass at the very first test, so the
2481099013bSjsg workaround shouldn't have any effect on them. */
2491099013bSjsg for (i = 0;
2501099013bSjsg (i < 10000 &&
2511099013bSjsg RREG32_PLL(RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
2521099013bSjsg i++);
2531099013bSjsg }
2541099013bSjsg
radeon_pll2_write_update(struct drm_device * dev)2551099013bSjsg static void radeon_pll2_write_update(struct drm_device *dev)
2561099013bSjsg {
2571099013bSjsg struct radeon_device *rdev = dev->dev_private;
2581099013bSjsg
2591099013bSjsg while (RREG32_PLL(RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
2601099013bSjsg
2611099013bSjsg WREG32_PLL_P(RADEON_P2PLL_REF_DIV,
2621099013bSjsg RADEON_P2PLL_ATOMIC_UPDATE_W,
2631099013bSjsg ~(RADEON_P2PLL_ATOMIC_UPDATE_W));
2641099013bSjsg }
2651099013bSjsg
radeon_compute_pll_gain(uint16_t ref_freq,uint16_t ref_div,uint16_t fb_div)2661099013bSjsg static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div,
2671099013bSjsg uint16_t fb_div)
2681099013bSjsg {
2691099013bSjsg unsigned int vcoFreq;
2701099013bSjsg
2711099013bSjsg if (!ref_div)
2721099013bSjsg return 1;
2731099013bSjsg
2741099013bSjsg vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div;
2751099013bSjsg
2761099013bSjsg /*
2771099013bSjsg * This is horribly crude: the VCO frequency range is divided into
2781099013bSjsg * 3 parts, each part having a fixed PLL gain value.
2791099013bSjsg */
2801099013bSjsg if (vcoFreq >= 30000)
2811099013bSjsg /*
2821099013bSjsg * [300..max] MHz : 7
2831099013bSjsg */
2841099013bSjsg return 7;
2851099013bSjsg else if (vcoFreq >= 18000)
2861099013bSjsg /*
2871099013bSjsg * [180..300) MHz : 4
2881099013bSjsg */
2891099013bSjsg return 4;
2901099013bSjsg else
2911099013bSjsg /*
2921099013bSjsg * [0..180) MHz : 1
2931099013bSjsg */
2941099013bSjsg return 1;
2951099013bSjsg }
2961099013bSjsg
radeon_crtc_dpms(struct drm_crtc * crtc,int mode)2971099013bSjsg static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
2981099013bSjsg {
2991099013bSjsg struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
3001099013bSjsg struct drm_device *dev = crtc->dev;
3011099013bSjsg struct radeon_device *rdev = dev->dev_private;
3021099013bSjsg uint32_t crtc_ext_cntl = 0;
3031099013bSjsg uint32_t mask;
3041099013bSjsg
3051099013bSjsg if (radeon_crtc->crtc_id)
3061099013bSjsg mask = (RADEON_CRTC2_DISP_DIS |
3071099013bSjsg RADEON_CRTC2_VSYNC_DIS |
3081099013bSjsg RADEON_CRTC2_HSYNC_DIS |
3091099013bSjsg RADEON_CRTC2_DISP_REQ_EN_B);
3101099013bSjsg else
3111099013bSjsg mask = (RADEON_CRTC_DISPLAY_DIS |
3121099013bSjsg RADEON_CRTC_VSYNC_DIS |
3131099013bSjsg RADEON_CRTC_HSYNC_DIS);
3141099013bSjsg
3151099013bSjsg /*
3161099013bSjsg * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC.
3171099013bSjsg * Therefore it is set in the DAC DMPS function.
3181099013bSjsg * This is different for GPU's with a single CRTC but a primary and a
3191099013bSjsg * TV DAC: here it controls the single CRTC no matter where it is
3201099013bSjsg * routed. Therefore we set it here.
3211099013bSjsg */
3221099013bSjsg if (rdev->flags & RADEON_SINGLE_CRTC)
3231099013bSjsg crtc_ext_cntl = RADEON_CRTC_CRT_ON;
3241099013bSjsg
3251099013bSjsg switch (mode) {
3261099013bSjsg case DRM_MODE_DPMS_ON:
3271099013bSjsg radeon_crtc->enabled = true;
3281099013bSjsg /* adjust pm to dpms changes BEFORE enabling crtcs */
3291099013bSjsg radeon_pm_compute_clocks(rdev);
3301099013bSjsg if (radeon_crtc->crtc_id)
3311099013bSjsg WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask));
3321099013bSjsg else {
3331099013bSjsg WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
3341099013bSjsg RADEON_CRTC_DISP_REQ_EN_B));
3351099013bSjsg WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
3361099013bSjsg }
3377f4dd379Sjsg if (dev->num_crtcs > radeon_crtc->crtc_id)
3387f4dd379Sjsg drm_crtc_vblank_on(crtc);
3391099013bSjsg radeon_crtc_load_lut(crtc);
3401099013bSjsg break;
3411099013bSjsg case DRM_MODE_DPMS_STANDBY:
3421099013bSjsg case DRM_MODE_DPMS_SUSPEND:
3431099013bSjsg case DRM_MODE_DPMS_OFF:
3447f4dd379Sjsg if (dev->num_crtcs > radeon_crtc->crtc_id)
3457f4dd379Sjsg drm_crtc_vblank_off(crtc);
3461099013bSjsg if (radeon_crtc->crtc_id)
3471099013bSjsg WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
3481099013bSjsg else {
3491099013bSjsg WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
3501099013bSjsg RADEON_CRTC_DISP_REQ_EN_B));
3511099013bSjsg WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl));
3521099013bSjsg }
3531099013bSjsg radeon_crtc->enabled = false;
3541099013bSjsg /* adjust pm to dpms changes AFTER disabling crtcs */
3551099013bSjsg radeon_pm_compute_clocks(rdev);
3561099013bSjsg break;
3571099013bSjsg }
3581099013bSjsg }
3591099013bSjsg
radeon_crtc_set_base(struct drm_crtc * crtc,int x,int y,struct drm_framebuffer * old_fb)3601099013bSjsg int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
3611099013bSjsg struct drm_framebuffer *old_fb)
3621099013bSjsg {
3631099013bSjsg return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
3641099013bSjsg }
3651099013bSjsg
radeon_crtc_set_base_atomic(struct drm_crtc * crtc,struct drm_framebuffer * fb,int x,int y,enum mode_set_atomic state)3661099013bSjsg int radeon_crtc_set_base_atomic(struct drm_crtc *crtc,
3671099013bSjsg struct drm_framebuffer *fb,
3681099013bSjsg int x, int y, enum mode_set_atomic state)
3691099013bSjsg {
3701099013bSjsg return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
3711099013bSjsg }
3721099013bSjsg
radeon_crtc_do_set_base(struct drm_crtc * crtc,struct drm_framebuffer * fb,int x,int y,int atomic)3731099013bSjsg int radeon_crtc_do_set_base(struct drm_crtc *crtc,
3741099013bSjsg struct drm_framebuffer *fb,
3751099013bSjsg int x, int y, int atomic)
3761099013bSjsg {
3771099013bSjsg struct drm_device *dev = crtc->dev;
3781099013bSjsg struct radeon_device *rdev = dev->dev_private;
3791099013bSjsg struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
3801099013bSjsg struct drm_framebuffer *target_fb;
3814a5d3272Skettenis struct drm_gem_object *obj;
3821099013bSjsg struct radeon_bo *rbo;
3831099013bSjsg uint64_t base;
3841099013bSjsg uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
3851099013bSjsg uint32_t crtc_pitch, pitch_pixels;
3861099013bSjsg uint32_t tiling_flags;
3871099013bSjsg int format;
3881099013bSjsg uint32_t gen_cntl_reg, gen_cntl_val;
3891099013bSjsg int r;
3901099013bSjsg
3911099013bSjsg DRM_DEBUG_KMS("\n");
3921099013bSjsg /* no fb bound */
3933253c27bSkettenis if (!atomic && !crtc->primary->fb) {
3941099013bSjsg DRM_DEBUG_KMS("No FB bound\n");
3951099013bSjsg return 0;
3961099013bSjsg }
3971099013bSjsg
3987f4dd379Sjsg if (atomic)
3991099013bSjsg target_fb = fb;
4007f4dd379Sjsg else
4013253c27bSkettenis target_fb = crtc->primary->fb;
4021099013bSjsg
4037f4dd379Sjsg switch (target_fb->format->cpp[0] * 8) {
4041099013bSjsg case 8:
4051099013bSjsg format = 2;
4061099013bSjsg break;
4071099013bSjsg case 15: /* 555 */
4081099013bSjsg format = 3;
4091099013bSjsg break;
4101099013bSjsg case 16: /* 565 */
4111099013bSjsg format = 4;
4121099013bSjsg break;
4131099013bSjsg case 24: /* RGB */
4141099013bSjsg format = 5;
4151099013bSjsg break;
4161099013bSjsg case 32: /* xRGB */
4171099013bSjsg format = 6;
4181099013bSjsg break;
4191099013bSjsg default:
4201099013bSjsg return false;
4211099013bSjsg }
4221099013bSjsg
4231099013bSjsg /* Pin framebuffer & get tilling informations */
4247f4dd379Sjsg obj = target_fb->obj[0];
4251099013bSjsg rbo = gem_to_radeon_bo(obj);
426c252e55eSjsg retry:
4271099013bSjsg r = radeon_bo_reserve(rbo, false);
4281099013bSjsg if (unlikely(r != 0))
4291099013bSjsg return r;
4301099013bSjsg /* Only 27 bit offset for legacy CRTC */
4311099013bSjsg r = radeon_bo_pin_restricted(rbo, RADEON_GEM_DOMAIN_VRAM, 1 << 27,
4321099013bSjsg &base);
4331099013bSjsg if (unlikely(r != 0)) {
4341099013bSjsg radeon_bo_unreserve(rbo);
435c252e55eSjsg
436c252e55eSjsg /* On old GPU like RN50 with little vram pining can fails because
437c252e55eSjsg * current fb is taking all space needed. So instead of unpining
438c252e55eSjsg * the old buffer after pining the new one, first unpin old one
439c252e55eSjsg * and then retry pining new one.
440c252e55eSjsg *
441c252e55eSjsg * As only master can set mode only master can pin and it is
442c252e55eSjsg * unlikely the master client will race with itself especialy
443c252e55eSjsg * on those old gpu with single crtc.
444c252e55eSjsg *
445c252e55eSjsg * We don't shutdown the display controller because new buffer
446c252e55eSjsg * will end up in same spot.
447c252e55eSjsg */
4483253c27bSkettenis if (!atomic && fb && fb != crtc->primary->fb) {
449c252e55eSjsg struct radeon_bo *old_rbo;
450c252e55eSjsg unsigned long nsize, osize;
451c252e55eSjsg
4527f4dd379Sjsg old_rbo = gem_to_radeon_bo(fb->obj[0]);
453c252e55eSjsg osize = radeon_bo_size(old_rbo);
454c252e55eSjsg nsize = radeon_bo_size(rbo);
455c252e55eSjsg if (nsize <= osize && !radeon_bo_reserve(old_rbo, false)) {
456c252e55eSjsg radeon_bo_unpin(old_rbo);
457c252e55eSjsg radeon_bo_unreserve(old_rbo);
458c252e55eSjsg fb = NULL;
459c252e55eSjsg goto retry;
460c252e55eSjsg }
461c252e55eSjsg }
4621099013bSjsg return -EINVAL;
4631099013bSjsg }
4641099013bSjsg radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
4651099013bSjsg radeon_bo_unreserve(rbo);
4661099013bSjsg if (tiling_flags & RADEON_TILING_MICRO)
4671099013bSjsg DRM_ERROR("trying to scanout microtiled buffer\n");
4681099013bSjsg
4691099013bSjsg /* if scanout was in GTT this really wouldn't work */
4701099013bSjsg /* crtc offset is from display base addr not FB location */
4711099013bSjsg radeon_crtc->legacy_display_base_addr = rdev->mc.vram_start;
4721099013bSjsg
4731099013bSjsg base -= radeon_crtc->legacy_display_base_addr;
4741099013bSjsg
4751099013bSjsg crtc_offset_cntl = 0;
4761099013bSjsg
4777f4dd379Sjsg pitch_pixels = target_fb->pitches[0] / target_fb->format->cpp[0];
4787f4dd379Sjsg crtc_pitch = DIV_ROUND_UP(pitch_pixels * target_fb->format->cpp[0] * 8,
4797f4dd379Sjsg target_fb->format->cpp[0] * 8 * 8);
4801099013bSjsg crtc_pitch |= crtc_pitch << 16;
4811099013bSjsg
4821099013bSjsg crtc_offset_cntl |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN;
4831099013bSjsg if (tiling_flags & RADEON_TILING_MACRO) {
4841099013bSjsg if (ASIC_IS_R300(rdev))
4851099013bSjsg crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
4861099013bSjsg R300_CRTC_MICRO_TILE_BUFFER_DIS |
4871099013bSjsg R300_CRTC_MACRO_TILE_EN);
4881099013bSjsg else
4891099013bSjsg crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
4901099013bSjsg } else {
4911099013bSjsg if (ASIC_IS_R300(rdev))
4921099013bSjsg crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
4931099013bSjsg R300_CRTC_MICRO_TILE_BUFFER_DIS |
4941099013bSjsg R300_CRTC_MACRO_TILE_EN);
4951099013bSjsg else
4961099013bSjsg crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
4971099013bSjsg }
4981099013bSjsg
4991099013bSjsg if (tiling_flags & RADEON_TILING_MACRO) {
5001099013bSjsg if (ASIC_IS_R300(rdev)) {
5011099013bSjsg crtc_tile_x0_y0 = x | (y << 16);
5021099013bSjsg base &= ~0x7ff;
5031099013bSjsg } else {
5047f4dd379Sjsg int byteshift = target_fb->format->cpp[0] * 8 >> 4;
5051099013bSjsg int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11;
5061099013bSjsg base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
5071099013bSjsg crtc_offset_cntl |= (y % 16);
5081099013bSjsg }
5091099013bSjsg } else {
5101099013bSjsg int offset = y * pitch_pixels + x;
5117f4dd379Sjsg switch (target_fb->format->cpp[0] * 8) {
5121099013bSjsg case 8:
5131099013bSjsg offset *= 1;
5141099013bSjsg break;
5151099013bSjsg case 15:
5161099013bSjsg case 16:
5171099013bSjsg offset *= 2;
5181099013bSjsg break;
5191099013bSjsg case 24:
5201099013bSjsg offset *= 3;
5211099013bSjsg break;
5221099013bSjsg case 32:
5231099013bSjsg offset *= 4;
5241099013bSjsg break;
5251099013bSjsg default:
5261099013bSjsg return false;
5271099013bSjsg }
5281099013bSjsg base += offset;
5291099013bSjsg }
5301099013bSjsg
5311099013bSjsg base &= ~7;
5321099013bSjsg
5331099013bSjsg if (radeon_crtc->crtc_id == 1)
5341099013bSjsg gen_cntl_reg = RADEON_CRTC2_GEN_CNTL;
5351099013bSjsg else
5361099013bSjsg gen_cntl_reg = RADEON_CRTC_GEN_CNTL;
5371099013bSjsg
5381099013bSjsg gen_cntl_val = RREG32(gen_cntl_reg);
5391099013bSjsg gen_cntl_val &= ~(0xf << 8);
5401099013bSjsg gen_cntl_val |= (format << 8);
5411099013bSjsg gen_cntl_val &= ~RADEON_CRTC_VSTAT_MODE_MASK;
5421099013bSjsg WREG32(gen_cntl_reg, gen_cntl_val);
5431099013bSjsg
5441099013bSjsg crtc_offset = (u32)base;
5451099013bSjsg
5461099013bSjsg WREG32(RADEON_DISPLAY_BASE_ADDR + radeon_crtc->crtc_offset, radeon_crtc->legacy_display_base_addr);
5471099013bSjsg
5481099013bSjsg if (ASIC_IS_R300(rdev)) {
5491099013bSjsg if (radeon_crtc->crtc_id)
5501099013bSjsg WREG32(R300_CRTC2_TILE_X0_Y0, crtc_tile_x0_y0);
5511099013bSjsg else
5521099013bSjsg WREG32(R300_CRTC_TILE_X0_Y0, crtc_tile_x0_y0);
5531099013bSjsg }
5541099013bSjsg WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, crtc_offset_cntl);
5551099013bSjsg WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset);
5561099013bSjsg WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
5571099013bSjsg
5583253c27bSkettenis if (!atomic && fb && fb != crtc->primary->fb) {
5597f4dd379Sjsg rbo = gem_to_radeon_bo(fb->obj[0]);
5601099013bSjsg r = radeon_bo_reserve(rbo, false);
5611099013bSjsg if (unlikely(r != 0))
5621099013bSjsg return r;
5631099013bSjsg radeon_bo_unpin(rbo);
5641099013bSjsg radeon_bo_unreserve(rbo);
5651099013bSjsg }
5661099013bSjsg
5671099013bSjsg /* Bytes per pixel may have changed */
5681099013bSjsg radeon_bandwidth_update(rdev);
5691099013bSjsg
5701099013bSjsg return 0;
5711099013bSjsg }
5721099013bSjsg
radeon_set_crtc_timing(struct drm_crtc * crtc,struct drm_display_mode * mode)5731099013bSjsg static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mode *mode)
5741099013bSjsg {
5751099013bSjsg struct drm_device *dev = crtc->dev;
5761099013bSjsg struct radeon_device *rdev = dev->dev_private;
5771099013bSjsg struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
5787f4dd379Sjsg const struct drm_framebuffer *fb = crtc->primary->fb;
5791099013bSjsg struct drm_encoder *encoder;
5801099013bSjsg int format;
5811099013bSjsg int hsync_start;
5821099013bSjsg int hsync_wid;
5831099013bSjsg int vsync_wid;
5841099013bSjsg uint32_t crtc_h_total_disp;
5851099013bSjsg uint32_t crtc_h_sync_strt_wid;
5861099013bSjsg uint32_t crtc_v_total_disp;
5871099013bSjsg uint32_t crtc_v_sync_strt_wid;
5881099013bSjsg bool is_tv = false;
5891099013bSjsg
5901099013bSjsg DRM_DEBUG_KMS("\n");
5911099013bSjsg list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
5921099013bSjsg if (encoder->crtc == crtc) {
5931099013bSjsg struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
5941099013bSjsg if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
5951099013bSjsg is_tv = true;
5961099013bSjsg DRM_INFO("crtc %d is connected to a TV\n", radeon_crtc->crtc_id);
5971099013bSjsg break;
5981099013bSjsg }
5991099013bSjsg }
6001099013bSjsg }
6011099013bSjsg
6027f4dd379Sjsg switch (fb->format->cpp[0] * 8) {
6031099013bSjsg case 8:
6041099013bSjsg format = 2;
6051099013bSjsg break;
6061099013bSjsg case 15: /* 555 */
6071099013bSjsg format = 3;
6081099013bSjsg break;
6091099013bSjsg case 16: /* 565 */
6101099013bSjsg format = 4;
6111099013bSjsg break;
6121099013bSjsg case 24: /* RGB */
6131099013bSjsg format = 5;
6141099013bSjsg break;
6151099013bSjsg case 32: /* xRGB */
6161099013bSjsg format = 6;
6171099013bSjsg break;
6181099013bSjsg default:
6191099013bSjsg return false;
6201099013bSjsg }
6211099013bSjsg
6221099013bSjsg crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff)
6231099013bSjsg | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
6241099013bSjsg
6251099013bSjsg hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
6261099013bSjsg if (!hsync_wid)
6271099013bSjsg hsync_wid = 1;
6281099013bSjsg hsync_start = mode->crtc_hsync_start - 8;
6291099013bSjsg
6301099013bSjsg crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
6311099013bSjsg | ((hsync_wid & 0x3f) << 16)
6321099013bSjsg | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
6331099013bSjsg ? RADEON_CRTC_H_SYNC_POL
6341099013bSjsg : 0));
6351099013bSjsg
6361099013bSjsg /* This works for double scan mode. */
6371099013bSjsg crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff)
6381099013bSjsg | ((mode->crtc_vdisplay - 1) << 16));
6391099013bSjsg
6401099013bSjsg vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
6411099013bSjsg if (!vsync_wid)
6421099013bSjsg vsync_wid = 1;
6431099013bSjsg
6441099013bSjsg crtc_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff)
6451099013bSjsg | ((vsync_wid & 0x1f) << 16)
6461099013bSjsg | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
6471099013bSjsg ? RADEON_CRTC_V_SYNC_POL
6481099013bSjsg : 0));
6491099013bSjsg
6501099013bSjsg if (radeon_crtc->crtc_id) {
6511099013bSjsg uint32_t crtc2_gen_cntl;
6521099013bSjsg uint32_t disp2_merge_cntl;
6531099013bSjsg
6541099013bSjsg /* if TV DAC is enabled for another crtc and keep it enabled */
6551099013bSjsg crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080;
6561099013bSjsg crtc2_gen_cntl |= ((format << 8)
6571099013bSjsg | RADEON_CRTC2_VSYNC_DIS
6581099013bSjsg | RADEON_CRTC2_HSYNC_DIS
6591099013bSjsg | RADEON_CRTC2_DISP_DIS
6601099013bSjsg | RADEON_CRTC2_DISP_REQ_EN_B
6611099013bSjsg | ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
6621099013bSjsg ? RADEON_CRTC2_DBL_SCAN_EN
6631099013bSjsg : 0)
6641099013bSjsg | ((mode->flags & DRM_MODE_FLAG_CSYNC)
6651099013bSjsg ? RADEON_CRTC2_CSYNC_EN
6661099013bSjsg : 0)
6671099013bSjsg | ((mode->flags & DRM_MODE_FLAG_INTERLACE)
6681099013bSjsg ? RADEON_CRTC2_INTERLACE_EN
6691099013bSjsg : 0));
6701099013bSjsg
6711099013bSjsg /* rs4xx chips seem to like to have the crtc enabled when the timing is set */
6721099013bSjsg if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
6731099013bSjsg crtc2_gen_cntl |= RADEON_CRTC2_EN;
6741099013bSjsg
6751099013bSjsg disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
6761099013bSjsg disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
6771099013bSjsg
6781099013bSjsg WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl);
6791099013bSjsg WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
6801099013bSjsg
6811099013bSjsg WREG32(RADEON_FP_H2_SYNC_STRT_WID, crtc_h_sync_strt_wid);
6821099013bSjsg WREG32(RADEON_FP_V2_SYNC_STRT_WID, crtc_v_sync_strt_wid);
6831099013bSjsg } else {
6841099013bSjsg uint32_t crtc_gen_cntl;
6851099013bSjsg uint32_t crtc_ext_cntl;
6861099013bSjsg uint32_t disp_merge_cntl;
6871099013bSjsg
6881099013bSjsg crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000;
6891099013bSjsg crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN
6901099013bSjsg | (format << 8)
6911099013bSjsg | RADEON_CRTC_DISP_REQ_EN_B
6921099013bSjsg | ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
6931099013bSjsg ? RADEON_CRTC_DBL_SCAN_EN
6941099013bSjsg : 0)
6951099013bSjsg | ((mode->flags & DRM_MODE_FLAG_CSYNC)
6961099013bSjsg ? RADEON_CRTC_CSYNC_EN
6971099013bSjsg : 0)
6981099013bSjsg | ((mode->flags & DRM_MODE_FLAG_INTERLACE)
6991099013bSjsg ? RADEON_CRTC_INTERLACE_EN
7001099013bSjsg : 0));
7011099013bSjsg
7021099013bSjsg /* rs4xx chips seem to like to have the crtc enabled when the timing is set */
7031099013bSjsg if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
7041099013bSjsg crtc_gen_cntl |= RADEON_CRTC_EN;
7051099013bSjsg
7061099013bSjsg crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
7071099013bSjsg crtc_ext_cntl |= (RADEON_XCRT_CNT_EN |
7081099013bSjsg RADEON_CRTC_VSYNC_DIS |
7091099013bSjsg RADEON_CRTC_HSYNC_DIS |
7101099013bSjsg RADEON_CRTC_DISPLAY_DIS);
7111099013bSjsg
7121099013bSjsg disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
7131099013bSjsg disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
7141099013bSjsg
7151099013bSjsg WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
7161099013bSjsg WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl);
7171099013bSjsg WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
7181099013bSjsg }
7191099013bSjsg
7201099013bSjsg if (is_tv)
7211099013bSjsg radeon_legacy_tv_adjust_crtc_reg(encoder, &crtc_h_total_disp,
7221099013bSjsg &crtc_h_sync_strt_wid, &crtc_v_total_disp,
7231099013bSjsg &crtc_v_sync_strt_wid);
7241099013bSjsg
7251099013bSjsg WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp);
7261099013bSjsg WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid);
7271099013bSjsg WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp);
7281099013bSjsg WREG32(RADEON_CRTC_V_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_v_sync_strt_wid);
7291099013bSjsg
7301099013bSjsg return true;
7311099013bSjsg }
7321099013bSjsg
radeon_set_pll(struct drm_crtc * crtc,struct drm_display_mode * mode)7331099013bSjsg static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
7341099013bSjsg {
7351099013bSjsg struct drm_device *dev = crtc->dev;
7361099013bSjsg struct radeon_device *rdev = dev->dev_private;
7371099013bSjsg struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
7381099013bSjsg struct drm_encoder *encoder;
7391099013bSjsg uint32_t feedback_div = 0;
7401099013bSjsg uint32_t frac_fb_div = 0;
7411099013bSjsg uint32_t reference_div = 0;
7421099013bSjsg uint32_t post_divider = 0;
7431099013bSjsg uint32_t freq = 0;
7441099013bSjsg uint8_t pll_gain;
7451099013bSjsg bool use_bios_divs = false;
7461099013bSjsg /* PLL registers */
7471099013bSjsg uint32_t pll_ref_div = 0;
7481099013bSjsg uint32_t pll_fb_post_div = 0;
7491099013bSjsg uint32_t htotal_cntl = 0;
7501099013bSjsg bool is_tv = false;
7511099013bSjsg struct radeon_pll *pll;
7521099013bSjsg
7531099013bSjsg struct {
7541099013bSjsg int divider;
7551099013bSjsg int bitvalue;
7561099013bSjsg } *post_div, post_divs[] = {
7571099013bSjsg /* From RAGE 128 VR/RAGE 128 GL Register
7581099013bSjsg * Reference Manual (Technical Reference
7591099013bSjsg * Manual P/N RRG-G04100-C Rev. 0.04), page
7601099013bSjsg * 3-17 (PLL_DIV_[3:0]).
7611099013bSjsg */
7621099013bSjsg { 1, 0 }, /* VCLK_SRC */
7631099013bSjsg { 2, 1 }, /* VCLK_SRC/2 */
7641099013bSjsg { 4, 2 }, /* VCLK_SRC/4 */
7651099013bSjsg { 8, 3 }, /* VCLK_SRC/8 */
7661099013bSjsg { 3, 4 }, /* VCLK_SRC/3 */
7671099013bSjsg { 16, 5 }, /* VCLK_SRC/16 */
7681099013bSjsg { 6, 6 }, /* VCLK_SRC/6 */
7691099013bSjsg { 12, 7 }, /* VCLK_SRC/12 */
7701099013bSjsg { 0, 0 }
7711099013bSjsg };
7721099013bSjsg
7731099013bSjsg if (radeon_crtc->crtc_id)
7741099013bSjsg pll = &rdev->clock.p2pll;
7751099013bSjsg else
7761099013bSjsg pll = &rdev->clock.p1pll;
7771099013bSjsg
7781099013bSjsg pll->flags = RADEON_PLL_LEGACY;
7791099013bSjsg
7801099013bSjsg if (mode->clock > 200000) /* range limits??? */
7811099013bSjsg pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
7821099013bSjsg else
7831099013bSjsg pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
7841099013bSjsg
7851099013bSjsg list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
7861099013bSjsg if (encoder->crtc == crtc) {
7871099013bSjsg struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
7881099013bSjsg
7891099013bSjsg if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
7901099013bSjsg is_tv = true;
7911099013bSjsg break;
7921099013bSjsg }
7931099013bSjsg
7941099013bSjsg if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
7951099013bSjsg pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
7961099013bSjsg if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
7971099013bSjsg if (!rdev->is_atom_bios) {
7981099013bSjsg struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
7991099013bSjsg struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
8001099013bSjsg if (lvds) {
8011099013bSjsg if (lvds->use_bios_dividers) {
8021099013bSjsg pll_ref_div = lvds->panel_ref_divider;
8031099013bSjsg pll_fb_post_div = (lvds->panel_fb_divider |
8041099013bSjsg (lvds->panel_post_divider << 16));
8051099013bSjsg htotal_cntl = 0;
8061099013bSjsg use_bios_divs = true;
8071099013bSjsg }
8081099013bSjsg }
8091099013bSjsg }
8101099013bSjsg pll->flags |= RADEON_PLL_USE_REF_DIV;
8111099013bSjsg }
8121099013bSjsg }
8131099013bSjsg }
8141099013bSjsg
8151099013bSjsg DRM_DEBUG_KMS("\n");
8161099013bSjsg
8171099013bSjsg if (!use_bios_divs) {
8181099013bSjsg radeon_compute_pll_legacy(pll, mode->clock,
8191099013bSjsg &freq, &feedback_div, &frac_fb_div,
8201099013bSjsg &reference_div, &post_divider);
8211099013bSjsg
8221099013bSjsg for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
8231099013bSjsg if (post_div->divider == post_divider)
8241099013bSjsg break;
8251099013bSjsg }
8261099013bSjsg
8271099013bSjsg if (!post_div->divider)
8281099013bSjsg post_div = &post_divs[0];
8291099013bSjsg
8301099013bSjsg DRM_DEBUG_KMS("dc=%u, fd=%d, rd=%d, pd=%d\n",
8311099013bSjsg (unsigned)freq,
8321099013bSjsg feedback_div,
8331099013bSjsg reference_div,
8341099013bSjsg post_divider);
8351099013bSjsg
8361099013bSjsg pll_ref_div = reference_div;
8371099013bSjsg #if defined(__powerpc__) && (0) /* TODO */
8381099013bSjsg /* apparently programming this otherwise causes a hang??? */
8391099013bSjsg if (info->MacModel == RADEON_MAC_IBOOK)
8401099013bSjsg pll_fb_post_div = 0x000600ad;
8411099013bSjsg else
8421099013bSjsg #endif
8431099013bSjsg pll_fb_post_div = (feedback_div | (post_div->bitvalue << 16));
8441099013bSjsg
8451099013bSjsg htotal_cntl = mode->htotal & 0x7;
8461099013bSjsg
8471099013bSjsg }
8481099013bSjsg
8491099013bSjsg pll_gain = radeon_compute_pll_gain(pll->reference_freq,
8501099013bSjsg pll_ref_div & 0x3ff,
8511099013bSjsg pll_fb_post_div & 0x7ff);
8521099013bSjsg
8531099013bSjsg if (radeon_crtc->crtc_id) {
8541099013bSjsg uint32_t pixclks_cntl = ((RREG32_PLL(RADEON_PIXCLKS_CNTL) &
8551099013bSjsg ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
8561099013bSjsg RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
8571099013bSjsg
8581099013bSjsg if (is_tv) {
8591099013bSjsg radeon_legacy_tv_adjust_pll2(encoder, &htotal_cntl,
8601099013bSjsg &pll_ref_div, &pll_fb_post_div,
8611099013bSjsg &pixclks_cntl);
8621099013bSjsg }
8631099013bSjsg
8641099013bSjsg WREG32_PLL_P(RADEON_PIXCLKS_CNTL,
8651099013bSjsg RADEON_PIX2CLK_SRC_SEL_CPUCLK,
8661099013bSjsg ~(RADEON_PIX2CLK_SRC_SEL_MASK));
8671099013bSjsg
8681099013bSjsg WREG32_PLL_P(RADEON_P2PLL_CNTL,
8691099013bSjsg RADEON_P2PLL_RESET
8701099013bSjsg | RADEON_P2PLL_ATOMIC_UPDATE_EN
8711099013bSjsg | ((uint32_t)pll_gain << RADEON_P2PLL_PVG_SHIFT),
8721099013bSjsg ~(RADEON_P2PLL_RESET
8731099013bSjsg | RADEON_P2PLL_ATOMIC_UPDATE_EN
8741099013bSjsg | RADEON_P2PLL_PVG_MASK));
8751099013bSjsg
8761099013bSjsg WREG32_PLL_P(RADEON_P2PLL_REF_DIV,
8771099013bSjsg pll_ref_div,
8781099013bSjsg ~RADEON_P2PLL_REF_DIV_MASK);
8791099013bSjsg
8801099013bSjsg WREG32_PLL_P(RADEON_P2PLL_DIV_0,
8811099013bSjsg pll_fb_post_div,
8821099013bSjsg ~RADEON_P2PLL_FB0_DIV_MASK);
8831099013bSjsg
8841099013bSjsg WREG32_PLL_P(RADEON_P2PLL_DIV_0,
8851099013bSjsg pll_fb_post_div,
8861099013bSjsg ~RADEON_P2PLL_POST0_DIV_MASK);
8871099013bSjsg
8881099013bSjsg radeon_pll2_write_update(dev);
8891099013bSjsg radeon_pll2_wait_for_read_update_complete(dev);
8901099013bSjsg
8911099013bSjsg WREG32_PLL(RADEON_HTOTAL2_CNTL, htotal_cntl);
8921099013bSjsg
8931099013bSjsg WREG32_PLL_P(RADEON_P2PLL_CNTL,
8941099013bSjsg 0,
8951099013bSjsg ~(RADEON_P2PLL_RESET
8961099013bSjsg | RADEON_P2PLL_SLEEP
8971099013bSjsg | RADEON_P2PLL_ATOMIC_UPDATE_EN));
8981099013bSjsg
8991099013bSjsg DRM_DEBUG_KMS("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
9001099013bSjsg (unsigned)pll_ref_div,
9011099013bSjsg (unsigned)pll_fb_post_div,
9021099013bSjsg (unsigned)htotal_cntl,
9031099013bSjsg RREG32_PLL(RADEON_P2PLL_CNTL));
9041099013bSjsg DRM_DEBUG_KMS("Wrote2: rd=%u, fd=%u, pd=%u\n",
9051099013bSjsg (unsigned)pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
9061099013bSjsg (unsigned)pll_fb_post_div & RADEON_P2PLL_FB0_DIV_MASK,
9071099013bSjsg (unsigned)((pll_fb_post_div &
9081099013bSjsg RADEON_P2PLL_POST0_DIV_MASK) >> 16));
9091099013bSjsg
9101099013bSjsg mdelay(50); /* Let the clock to lock */
9111099013bSjsg
9121099013bSjsg WREG32_PLL_P(RADEON_PIXCLKS_CNTL,
9131099013bSjsg RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
9141099013bSjsg ~(RADEON_PIX2CLK_SRC_SEL_MASK));
9151099013bSjsg
9161099013bSjsg WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
9171099013bSjsg } else {
9181099013bSjsg uint32_t pixclks_cntl;
9191099013bSjsg
9201099013bSjsg
9211099013bSjsg if (is_tv) {
9221099013bSjsg pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
9231099013bSjsg radeon_legacy_tv_adjust_pll1(encoder, &htotal_cntl, &pll_ref_div,
9241099013bSjsg &pll_fb_post_div, &pixclks_cntl);
9251099013bSjsg }
9261099013bSjsg
9271099013bSjsg if (rdev->flags & RADEON_IS_MOBILITY) {
9281099013bSjsg /* A temporal workaround for the occasional blanking on certain laptop panels.
9291099013bSjsg This appears to related to the PLL divider registers (fail to lock?).
9301099013bSjsg It occurs even when all dividers are the same with their old settings.
9311099013bSjsg In this case we really don't need to fiddle with PLL registers.
9321099013bSjsg By doing this we can avoid the blanking problem with some panels.
9331099013bSjsg */
9341099013bSjsg if ((pll_ref_div == (RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
9351099013bSjsg (pll_fb_post_div == (RREG32_PLL(RADEON_PPLL_DIV_3) &
9361099013bSjsg (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
9371099013bSjsg WREG32_P(RADEON_CLOCK_CNTL_INDEX,
9381099013bSjsg RADEON_PLL_DIV_SEL,
9391099013bSjsg ~(RADEON_PLL_DIV_SEL));
9401099013bSjsg r100_pll_errata_after_index(rdev);
9411099013bSjsg return;
9421099013bSjsg }
9431099013bSjsg }
9441099013bSjsg
9451099013bSjsg WREG32_PLL_P(RADEON_VCLK_ECP_CNTL,
9461099013bSjsg RADEON_VCLK_SRC_SEL_CPUCLK,
9471099013bSjsg ~(RADEON_VCLK_SRC_SEL_MASK));
9481099013bSjsg WREG32_PLL_P(RADEON_PPLL_CNTL,
9491099013bSjsg RADEON_PPLL_RESET
9501099013bSjsg | RADEON_PPLL_ATOMIC_UPDATE_EN
9511099013bSjsg | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
9521099013bSjsg | ((uint32_t)pll_gain << RADEON_PPLL_PVG_SHIFT),
9531099013bSjsg ~(RADEON_PPLL_RESET
9541099013bSjsg | RADEON_PPLL_ATOMIC_UPDATE_EN
9551099013bSjsg | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
9561099013bSjsg | RADEON_PPLL_PVG_MASK));
9571099013bSjsg
9581099013bSjsg WREG32_P(RADEON_CLOCK_CNTL_INDEX,
9591099013bSjsg RADEON_PLL_DIV_SEL,
9601099013bSjsg ~(RADEON_PLL_DIV_SEL));
9611099013bSjsg r100_pll_errata_after_index(rdev);
9621099013bSjsg
9631099013bSjsg if (ASIC_IS_R300(rdev) ||
9641099013bSjsg (rdev->family == CHIP_RS300) ||
9651099013bSjsg (rdev->family == CHIP_RS400) ||
9661099013bSjsg (rdev->family == CHIP_RS480)) {
9671099013bSjsg if (pll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
9681099013bSjsg /* When restoring console mode, use saved PPLL_REF_DIV
9691099013bSjsg * setting.
9701099013bSjsg */
9711099013bSjsg WREG32_PLL_P(RADEON_PPLL_REF_DIV,
9721099013bSjsg pll_ref_div,
9731099013bSjsg 0);
9741099013bSjsg } else {
9751099013bSjsg /* R300 uses ref_div_acc field as real ref divider */
9761099013bSjsg WREG32_PLL_P(RADEON_PPLL_REF_DIV,
9771099013bSjsg (pll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
9781099013bSjsg ~R300_PPLL_REF_DIV_ACC_MASK);
9791099013bSjsg }
9801099013bSjsg } else
9811099013bSjsg WREG32_PLL_P(RADEON_PPLL_REF_DIV,
9821099013bSjsg pll_ref_div,
9831099013bSjsg ~RADEON_PPLL_REF_DIV_MASK);
9841099013bSjsg
9851099013bSjsg WREG32_PLL_P(RADEON_PPLL_DIV_3,
9861099013bSjsg pll_fb_post_div,
9871099013bSjsg ~RADEON_PPLL_FB3_DIV_MASK);
9881099013bSjsg
9891099013bSjsg WREG32_PLL_P(RADEON_PPLL_DIV_3,
9901099013bSjsg pll_fb_post_div,
9911099013bSjsg ~RADEON_PPLL_POST3_DIV_MASK);
9921099013bSjsg
9931099013bSjsg radeon_pll_write_update(dev);
9941099013bSjsg radeon_pll_wait_for_read_update_complete(dev);
9951099013bSjsg
9961099013bSjsg WREG32_PLL(RADEON_HTOTAL_CNTL, htotal_cntl);
9971099013bSjsg
9981099013bSjsg WREG32_PLL_P(RADEON_PPLL_CNTL,
9991099013bSjsg 0,
10001099013bSjsg ~(RADEON_PPLL_RESET
10011099013bSjsg | RADEON_PPLL_SLEEP
10021099013bSjsg | RADEON_PPLL_ATOMIC_UPDATE_EN
10031099013bSjsg | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
10041099013bSjsg
10051099013bSjsg DRM_DEBUG_KMS("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
10061099013bSjsg pll_ref_div,
10071099013bSjsg pll_fb_post_div,
10081099013bSjsg (unsigned)htotal_cntl,
10091099013bSjsg RREG32_PLL(RADEON_PPLL_CNTL));
10101099013bSjsg DRM_DEBUG_KMS("Wrote: rd=%d, fd=%d, pd=%d\n",
10111099013bSjsg pll_ref_div & RADEON_PPLL_REF_DIV_MASK,
10121099013bSjsg pll_fb_post_div & RADEON_PPLL_FB3_DIV_MASK,
10131099013bSjsg (pll_fb_post_div & RADEON_PPLL_POST3_DIV_MASK) >> 16);
10141099013bSjsg
10151099013bSjsg mdelay(50); /* Let the clock to lock */
10161099013bSjsg
10171099013bSjsg WREG32_PLL_P(RADEON_VCLK_ECP_CNTL,
10181099013bSjsg RADEON_VCLK_SRC_SEL_PPLLCLK,
10191099013bSjsg ~(RADEON_VCLK_SRC_SEL_MASK));
10201099013bSjsg
10211099013bSjsg if (is_tv)
10221099013bSjsg WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
10231099013bSjsg }
10241099013bSjsg }
10251099013bSjsg
radeon_crtc_mode_fixup(struct drm_crtc * crtc,const struct drm_display_mode * mode,struct drm_display_mode * adjusted_mode)10261099013bSjsg static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,
10271099013bSjsg const struct drm_display_mode *mode,
10281099013bSjsg struct drm_display_mode *adjusted_mode)
10291099013bSjsg {
10301099013bSjsg if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
10311099013bSjsg return false;
10321099013bSjsg return true;
10331099013bSjsg }
10341099013bSjsg
radeon_crtc_mode_set(struct drm_crtc * crtc,struct drm_display_mode * mode,struct drm_display_mode * adjusted_mode,int x,int y,struct drm_framebuffer * old_fb)10351099013bSjsg static int radeon_crtc_mode_set(struct drm_crtc *crtc,
10361099013bSjsg struct drm_display_mode *mode,
10371099013bSjsg struct drm_display_mode *adjusted_mode,
10381099013bSjsg int x, int y, struct drm_framebuffer *old_fb)
10391099013bSjsg {
10401099013bSjsg struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
10411099013bSjsg
10421099013bSjsg /* TODO TV */
10431099013bSjsg radeon_crtc_set_base(crtc, x, y, old_fb);
10441099013bSjsg radeon_set_crtc_timing(crtc, adjusted_mode);
10451099013bSjsg radeon_set_pll(crtc, adjusted_mode);
10461099013bSjsg radeon_overscan_setup(crtc, adjusted_mode);
10471099013bSjsg if (radeon_crtc->crtc_id == 0) {
10481099013bSjsg radeon_legacy_rmx_mode_set(crtc, adjusted_mode);
10491099013bSjsg } else {
10501099013bSjsg if (radeon_crtc->rmx_type != RMX_OFF) {
10511099013bSjsg /* FIXME: only first crtc has rmx what should we
10521099013bSjsg * do ?
10531099013bSjsg */
10541099013bSjsg DRM_ERROR("Mode need scaling but only first crtc can do that.\n");
10551099013bSjsg }
10561099013bSjsg }
10577ccd5a2cSjsg radeon_cursor_reset(crtc);
10581099013bSjsg return 0;
10591099013bSjsg }
10601099013bSjsg
radeon_crtc_prepare(struct drm_crtc * crtc)10611099013bSjsg static void radeon_crtc_prepare(struct drm_crtc *crtc)
10621099013bSjsg {
10631099013bSjsg struct drm_device *dev = crtc->dev;
10641099013bSjsg struct drm_crtc *crtci;
10651099013bSjsg
10661099013bSjsg /*
10671099013bSjsg * The hardware wedges sometimes if you reconfigure one CRTC
10681099013bSjsg * whilst another is running (see fdo bug #24611).
10691099013bSjsg */
10701099013bSjsg list_for_each_entry(crtci, &dev->mode_config.crtc_list, head)
10711099013bSjsg radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF);
10721099013bSjsg }
10731099013bSjsg
radeon_crtc_commit(struct drm_crtc * crtc)10741099013bSjsg static void radeon_crtc_commit(struct drm_crtc *crtc)
10751099013bSjsg {
10761099013bSjsg struct drm_device *dev = crtc->dev;
10771099013bSjsg struct drm_crtc *crtci;
10781099013bSjsg
10791099013bSjsg /*
10801099013bSjsg * Reenable the CRTCs that should be running.
10811099013bSjsg */
10821099013bSjsg list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) {
10831099013bSjsg if (crtci->enabled)
10841099013bSjsg radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
10851099013bSjsg }
10867ccd5a2cSjsg }
10877ccd5a2cSjsg
radeon_crtc_disable(struct drm_crtc * crtc)10887ccd5a2cSjsg static void radeon_crtc_disable(struct drm_crtc *crtc)
10897ccd5a2cSjsg {
10907ccd5a2cSjsg radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
10917ccd5a2cSjsg if (crtc->primary->fb) {
10927ccd5a2cSjsg int r;
10937ccd5a2cSjsg struct radeon_bo *rbo;
10947ccd5a2cSjsg
10957f4dd379Sjsg rbo = gem_to_radeon_bo(crtc->primary->fb->obj[0]);
10967ccd5a2cSjsg r = radeon_bo_reserve(rbo, false);
10977ccd5a2cSjsg if (unlikely(r))
10987ccd5a2cSjsg DRM_ERROR("failed to reserve rbo before unpin\n");
10997ccd5a2cSjsg else {
11007ccd5a2cSjsg radeon_bo_unpin(rbo);
11017ccd5a2cSjsg radeon_bo_unreserve(rbo);
11027ccd5a2cSjsg }
11037ccd5a2cSjsg }
11041099013bSjsg }
11051099013bSjsg
11061099013bSjsg static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
11071099013bSjsg .dpms = radeon_crtc_dpms,
11081099013bSjsg .mode_fixup = radeon_crtc_mode_fixup,
11091099013bSjsg .mode_set = radeon_crtc_mode_set,
11101099013bSjsg .mode_set_base = radeon_crtc_set_base,
11111099013bSjsg .mode_set_base_atomic = radeon_crtc_set_base_atomic,
11121099013bSjsg .prepare = radeon_crtc_prepare,
11131099013bSjsg .commit = radeon_crtc_commit,
1114c349dbc7Sjsg .disable = radeon_crtc_disable,
1115c349dbc7Sjsg .get_scanout_position = radeon_get_crtc_scanout_position,
11161099013bSjsg };
11171099013bSjsg
11181099013bSjsg
radeon_legacy_init_crtc(struct drm_device * dev,struct radeon_crtc * radeon_crtc)11191099013bSjsg void radeon_legacy_init_crtc(struct drm_device *dev,
11201099013bSjsg struct radeon_crtc *radeon_crtc)
11211099013bSjsg {
11221099013bSjsg if (radeon_crtc->crtc_id == 1)
11231099013bSjsg radeon_crtc->crtc_offset = RADEON_CRTC2_H_TOTAL_DISP - RADEON_CRTC_H_TOTAL_DISP;
11241099013bSjsg drm_crtc_helper_add(&radeon_crtc->base, &legacy_helper_funcs);
11251099013bSjsg }
1126