1*b843c749SSergey Zigachev /* 2*b843c749SSergey Zigachev * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and 3*b843c749SSergey Zigachev * VA Linux Systems Inc., Fremont, California. 4*b843c749SSergey Zigachev * Copyright 2008 Red Hat Inc. 5*b843c749SSergey Zigachev * 6*b843c749SSergey Zigachev * Permission is hereby granted, free of charge, to any person obtaining a 7*b843c749SSergey Zigachev * copy of this software and associated documentation files (the "Software"), 8*b843c749SSergey Zigachev * to deal in the Software without restriction, including without limitation 9*b843c749SSergey Zigachev * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10*b843c749SSergey Zigachev * and/or sell copies of the Software, and to permit persons to whom the 11*b843c749SSergey Zigachev * Software is furnished to do so, subject to the following conditions: 12*b843c749SSergey Zigachev * 13*b843c749SSergey Zigachev * The above copyright notice and this permission notice shall be included in 14*b843c749SSergey Zigachev * all copies or substantial portions of the Software. 15*b843c749SSergey Zigachev * 16*b843c749SSergey Zigachev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*b843c749SSergey Zigachev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*b843c749SSergey Zigachev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*b843c749SSergey Zigachev * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20*b843c749SSergey Zigachev * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21*b843c749SSergey Zigachev * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22*b843c749SSergey Zigachev * OTHER DEALINGS IN THE SOFTWARE. 23*b843c749SSergey Zigachev * 24*b843c749SSergey Zigachev * Original Authors: 25*b843c749SSergey Zigachev * Kevin E. Martin, Rickard E. Faith, Alan Hourihane 26*b843c749SSergey Zigachev * 27*b843c749SSergey Zigachev * Kernel port Author: Dave Airlie 28*b843c749SSergey Zigachev */ 29*b843c749SSergey Zigachev 30*b843c749SSergey Zigachev #ifndef AMDGPU_MODE_H 31*b843c749SSergey Zigachev #define AMDGPU_MODE_H 32*b843c749SSergey Zigachev 33*b843c749SSergey Zigachev #include <drm/drm_crtc.h> 34*b843c749SSergey Zigachev #include <drm/drm_edid.h> 35*b843c749SSergey Zigachev #include <drm/drm_encoder.h> 36*b843c749SSergey Zigachev #include <drm/drm_dp_helper.h> 37*b843c749SSergey Zigachev #include <drm/drm_fixed.h> 38*b843c749SSergey Zigachev #include <drm/drm_crtc_helper.h> 39*b843c749SSergey Zigachev #include <drm/drm_fb_helper.h> 40*b843c749SSergey Zigachev #include <drm/drm_plane_helper.h> 41*b843c749SSergey Zigachev #include <drm/drm_fb_helper.h> 42*b843c749SSergey Zigachev #include <linux/i2c.h> 43*b843c749SSergey Zigachev #include <linux/i2c-algo-bit.h> 44*b843c749SSergey Zigachev #include <linux/hrtimer.h> 45*b843c749SSergey Zigachev #include "amdgpu_irq.h" 46*b843c749SSergey Zigachev 47*b843c749SSergey Zigachev #include <drm/drm_dp_mst_helper.h> 48*b843c749SSergey Zigachev #include "modules/inc/mod_freesync.h" 49*b843c749SSergey Zigachev 50*b843c749SSergey Zigachev struct amdgpu_bo; 51*b843c749SSergey Zigachev struct amdgpu_device; 52*b843c749SSergey Zigachev struct amdgpu_encoder; 53*b843c749SSergey Zigachev struct amdgpu_router; 54*b843c749SSergey Zigachev struct amdgpu_hpd; 55*b843c749SSergey Zigachev 56*b843c749SSergey Zigachev #define to_amdgpu_crtc(x) container_of(x, struct amdgpu_crtc, base) 57*b843c749SSergey Zigachev #define to_amdgpu_connector(x) container_of(x, struct amdgpu_connector, base) 58*b843c749SSergey Zigachev #define to_amdgpu_encoder(x) container_of(x, struct amdgpu_encoder, base) 59*b843c749SSergey Zigachev #define to_amdgpu_framebuffer(x) container_of(x, struct amdgpu_framebuffer, base) 60*b843c749SSergey Zigachev #define to_amdgpu_plane(x) container_of(x, struct amdgpu_plane, base) 61*b843c749SSergey Zigachev 62*b843c749SSergey Zigachev #define to_dm_plane_state(x) container_of(x, struct dm_plane_state, base); 63*b843c749SSergey Zigachev 64*b843c749SSergey Zigachev #define AMDGPU_MAX_HPD_PINS 6 65*b843c749SSergey Zigachev #define AMDGPU_MAX_CRTCS 6 66*b843c749SSergey Zigachev #define AMDGPU_MAX_PLANES 6 67*b843c749SSergey Zigachev #define AMDGPU_MAX_AFMT_BLOCKS 9 68*b843c749SSergey Zigachev 69*b843c749SSergey Zigachev enum amdgpu_rmx_type { 70*b843c749SSergey Zigachev RMX_OFF, 71*b843c749SSergey Zigachev RMX_FULL, 72*b843c749SSergey Zigachev RMX_CENTER, 73*b843c749SSergey Zigachev RMX_ASPECT 74*b843c749SSergey Zigachev }; 75*b843c749SSergey Zigachev 76*b843c749SSergey Zigachev enum amdgpu_underscan_type { 77*b843c749SSergey Zigachev UNDERSCAN_OFF, 78*b843c749SSergey Zigachev UNDERSCAN_ON, 79*b843c749SSergey Zigachev UNDERSCAN_AUTO, 80*b843c749SSergey Zigachev }; 81*b843c749SSergey Zigachev 82*b843c749SSergey Zigachev #define AMDGPU_HPD_CONNECT_INT_DELAY_IN_MS 50 83*b843c749SSergey Zigachev #define AMDGPU_HPD_DISCONNECT_INT_DELAY_IN_MS 10 84*b843c749SSergey Zigachev 85*b843c749SSergey Zigachev enum amdgpu_hpd_id { 86*b843c749SSergey Zigachev AMDGPU_HPD_1 = 0, 87*b843c749SSergey Zigachev AMDGPU_HPD_2, 88*b843c749SSergey Zigachev AMDGPU_HPD_3, 89*b843c749SSergey Zigachev AMDGPU_HPD_4, 90*b843c749SSergey Zigachev AMDGPU_HPD_5, 91*b843c749SSergey Zigachev AMDGPU_HPD_6, 92*b843c749SSergey Zigachev AMDGPU_HPD_NONE = 0xff, 93*b843c749SSergey Zigachev }; 94*b843c749SSergey Zigachev 95*b843c749SSergey Zigachev enum amdgpu_crtc_irq { 96*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VBLANK1 = 0, 97*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VBLANK2, 98*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VBLANK3, 99*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VBLANK4, 100*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VBLANK5, 101*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VBLANK6, 102*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VLINE1, 103*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VLINE2, 104*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VLINE3, 105*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VLINE4, 106*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VLINE5, 107*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_VLINE6, 108*b843c749SSergey Zigachev AMDGPU_CRTC_IRQ_NONE = 0xff 109*b843c749SSergey Zigachev }; 110*b843c749SSergey Zigachev 111*b843c749SSergey Zigachev enum amdgpu_pageflip_irq { 112*b843c749SSergey Zigachev AMDGPU_PAGEFLIP_IRQ_D1 = 0, 113*b843c749SSergey Zigachev AMDGPU_PAGEFLIP_IRQ_D2, 114*b843c749SSergey Zigachev AMDGPU_PAGEFLIP_IRQ_D3, 115*b843c749SSergey Zigachev AMDGPU_PAGEFLIP_IRQ_D4, 116*b843c749SSergey Zigachev AMDGPU_PAGEFLIP_IRQ_D5, 117*b843c749SSergey Zigachev AMDGPU_PAGEFLIP_IRQ_D6, 118*b843c749SSergey Zigachev AMDGPU_PAGEFLIP_IRQ_NONE = 0xff 119*b843c749SSergey Zigachev }; 120*b843c749SSergey Zigachev 121*b843c749SSergey Zigachev enum amdgpu_flip_status { 122*b843c749SSergey Zigachev AMDGPU_FLIP_NONE, 123*b843c749SSergey Zigachev AMDGPU_FLIP_PENDING, 124*b843c749SSergey Zigachev AMDGPU_FLIP_SUBMITTED 125*b843c749SSergey Zigachev }; 126*b843c749SSergey Zigachev 127*b843c749SSergey Zigachev #define AMDGPU_MAX_I2C_BUS 16 128*b843c749SSergey Zigachev 129*b843c749SSergey Zigachev /* amdgpu gpio-based i2c 130*b843c749SSergey Zigachev * 1. "mask" reg and bits 131*b843c749SSergey Zigachev * grabs the gpio pins for software use 132*b843c749SSergey Zigachev * 0=not held 1=held 133*b843c749SSergey Zigachev * 2. "a" reg and bits 134*b843c749SSergey Zigachev * output pin value 135*b843c749SSergey Zigachev * 0=low 1=high 136*b843c749SSergey Zigachev * 3. "en" reg and bits 137*b843c749SSergey Zigachev * sets the pin direction 138*b843c749SSergey Zigachev * 0=input 1=output 139*b843c749SSergey Zigachev * 4. "y" reg and bits 140*b843c749SSergey Zigachev * input pin value 141*b843c749SSergey Zigachev * 0=low 1=high 142*b843c749SSergey Zigachev */ 143*b843c749SSergey Zigachev struct amdgpu_i2c_bus_rec { 144*b843c749SSergey Zigachev bool valid; 145*b843c749SSergey Zigachev /* id used by atom */ 146*b843c749SSergey Zigachev uint8_t i2c_id; 147*b843c749SSergey Zigachev /* id used by atom */ 148*b843c749SSergey Zigachev enum amdgpu_hpd_id hpd; 149*b843c749SSergey Zigachev /* can be used with hw i2c engine */ 150*b843c749SSergey Zigachev bool hw_capable; 151*b843c749SSergey Zigachev /* uses multi-media i2c engine */ 152*b843c749SSergey Zigachev bool mm_i2c; 153*b843c749SSergey Zigachev /* regs and bits */ 154*b843c749SSergey Zigachev uint32_t mask_clk_reg; 155*b843c749SSergey Zigachev uint32_t mask_data_reg; 156*b843c749SSergey Zigachev uint32_t a_clk_reg; 157*b843c749SSergey Zigachev uint32_t a_data_reg; 158*b843c749SSergey Zigachev uint32_t en_clk_reg; 159*b843c749SSergey Zigachev uint32_t en_data_reg; 160*b843c749SSergey Zigachev uint32_t y_clk_reg; 161*b843c749SSergey Zigachev uint32_t y_data_reg; 162*b843c749SSergey Zigachev uint32_t mask_clk_mask; 163*b843c749SSergey Zigachev uint32_t mask_data_mask; 164*b843c749SSergey Zigachev uint32_t a_clk_mask; 165*b843c749SSergey Zigachev uint32_t a_data_mask; 166*b843c749SSergey Zigachev uint32_t en_clk_mask; 167*b843c749SSergey Zigachev uint32_t en_data_mask; 168*b843c749SSergey Zigachev uint32_t y_clk_mask; 169*b843c749SSergey Zigachev uint32_t y_data_mask; 170*b843c749SSergey Zigachev }; 171*b843c749SSergey Zigachev 172*b843c749SSergey Zigachev #define AMDGPU_MAX_BIOS_CONNECTOR 16 173*b843c749SSergey Zigachev 174*b843c749SSergey Zigachev /* pll flags */ 175*b843c749SSergey Zigachev #define AMDGPU_PLL_USE_BIOS_DIVS (1 << 0) 176*b843c749SSergey Zigachev #define AMDGPU_PLL_NO_ODD_POST_DIV (1 << 1) 177*b843c749SSergey Zigachev #define AMDGPU_PLL_USE_REF_DIV (1 << 2) 178*b843c749SSergey Zigachev #define AMDGPU_PLL_LEGACY (1 << 3) 179*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_LOW_REF_DIV (1 << 4) 180*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_HIGH_REF_DIV (1 << 5) 181*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_LOW_FB_DIV (1 << 6) 182*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_HIGH_FB_DIV (1 << 7) 183*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_LOW_POST_DIV (1 << 8) 184*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_HIGH_POST_DIV (1 << 9) 185*b843c749SSergey Zigachev #define AMDGPU_PLL_USE_FRAC_FB_DIV (1 << 10) 186*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_CLOSEST_LOWER (1 << 11) 187*b843c749SSergey Zigachev #define AMDGPU_PLL_USE_POST_DIV (1 << 12) 188*b843c749SSergey Zigachev #define AMDGPU_PLL_IS_LCD (1 << 13) 189*b843c749SSergey Zigachev #define AMDGPU_PLL_PREFER_MINM_OVER_MAXP (1 << 14) 190*b843c749SSergey Zigachev 191*b843c749SSergey Zigachev struct amdgpu_pll { 192*b843c749SSergey Zigachev /* reference frequency */ 193*b843c749SSergey Zigachev uint32_t reference_freq; 194*b843c749SSergey Zigachev 195*b843c749SSergey Zigachev /* fixed dividers */ 196*b843c749SSergey Zigachev uint32_t reference_div; 197*b843c749SSergey Zigachev uint32_t post_div; 198*b843c749SSergey Zigachev 199*b843c749SSergey Zigachev /* pll in/out limits */ 200*b843c749SSergey Zigachev uint32_t pll_in_min; 201*b843c749SSergey Zigachev uint32_t pll_in_max; 202*b843c749SSergey Zigachev uint32_t pll_out_min; 203*b843c749SSergey Zigachev uint32_t pll_out_max; 204*b843c749SSergey Zigachev uint32_t lcd_pll_out_min; 205*b843c749SSergey Zigachev uint32_t lcd_pll_out_max; 206*b843c749SSergey Zigachev uint32_t best_vco; 207*b843c749SSergey Zigachev 208*b843c749SSergey Zigachev /* divider limits */ 209*b843c749SSergey Zigachev uint32_t min_ref_div; 210*b843c749SSergey Zigachev uint32_t max_ref_div; 211*b843c749SSergey Zigachev uint32_t min_post_div; 212*b843c749SSergey Zigachev uint32_t max_post_div; 213*b843c749SSergey Zigachev uint32_t min_feedback_div; 214*b843c749SSergey Zigachev uint32_t max_feedback_div; 215*b843c749SSergey Zigachev uint32_t min_frac_feedback_div; 216*b843c749SSergey Zigachev uint32_t max_frac_feedback_div; 217*b843c749SSergey Zigachev 218*b843c749SSergey Zigachev /* flags for the current clock */ 219*b843c749SSergey Zigachev uint32_t flags; 220*b843c749SSergey Zigachev 221*b843c749SSergey Zigachev /* pll id */ 222*b843c749SSergey Zigachev uint32_t id; 223*b843c749SSergey Zigachev }; 224*b843c749SSergey Zigachev 225*b843c749SSergey Zigachev struct amdgpu_i2c_chan { 226*b843c749SSergey Zigachev struct i2c_adapter adapter; 227*b843c749SSergey Zigachev struct drm_device *dev; 228*b843c749SSergey Zigachev struct i2c_algo_bit_data bit; 229*b843c749SSergey Zigachev struct amdgpu_i2c_bus_rec rec; 230*b843c749SSergey Zigachev struct drm_dp_aux aux; 231*b843c749SSergey Zigachev bool has_aux; 232*b843c749SSergey Zigachev struct mutex mutex; 233*b843c749SSergey Zigachev }; 234*b843c749SSergey Zigachev 235*b843c749SSergey Zigachev struct amdgpu_fbdev; 236*b843c749SSergey Zigachev 237*b843c749SSergey Zigachev struct amdgpu_afmt { 238*b843c749SSergey Zigachev bool enabled; 239*b843c749SSergey Zigachev int offset; 240*b843c749SSergey Zigachev bool last_buffer_filled_status; 241*b843c749SSergey Zigachev int id; 242*b843c749SSergey Zigachev struct amdgpu_audio_pin *pin; 243*b843c749SSergey Zigachev }; 244*b843c749SSergey Zigachev 245*b843c749SSergey Zigachev /* 246*b843c749SSergey Zigachev * Audio 247*b843c749SSergey Zigachev */ 248*b843c749SSergey Zigachev struct amdgpu_audio_pin { 249*b843c749SSergey Zigachev int channels; 250*b843c749SSergey Zigachev int rate; 251*b843c749SSergey Zigachev int bits_per_sample; 252*b843c749SSergey Zigachev u8 status_bits; 253*b843c749SSergey Zigachev u8 category_code; 254*b843c749SSergey Zigachev u32 offset; 255*b843c749SSergey Zigachev bool connected; 256*b843c749SSergey Zigachev u32 id; 257*b843c749SSergey Zigachev }; 258*b843c749SSergey Zigachev 259*b843c749SSergey Zigachev struct amdgpu_audio { 260*b843c749SSergey Zigachev bool enabled; 261*b843c749SSergey Zigachev struct amdgpu_audio_pin pin[AMDGPU_MAX_AFMT_BLOCKS]; 262*b843c749SSergey Zigachev int num_pins; 263*b843c749SSergey Zigachev }; 264*b843c749SSergey Zigachev 265*b843c749SSergey Zigachev struct amdgpu_display_funcs { 266*b843c749SSergey Zigachev /* display watermarks */ 267*b843c749SSergey Zigachev void (*bandwidth_update)(struct amdgpu_device *adev); 268*b843c749SSergey Zigachev /* get frame count */ 269*b843c749SSergey Zigachev u32 (*vblank_get_counter)(struct amdgpu_device *adev, int crtc); 270*b843c749SSergey Zigachev /* set backlight level */ 271*b843c749SSergey Zigachev void (*backlight_set_level)(struct amdgpu_encoder *amdgpu_encoder, 272*b843c749SSergey Zigachev u8 level); 273*b843c749SSergey Zigachev /* get backlight level */ 274*b843c749SSergey Zigachev u8 (*backlight_get_level)(struct amdgpu_encoder *amdgpu_encoder); 275*b843c749SSergey Zigachev /* hotplug detect */ 276*b843c749SSergey Zigachev bool (*hpd_sense)(struct amdgpu_device *adev, enum amdgpu_hpd_id hpd); 277*b843c749SSergey Zigachev void (*hpd_set_polarity)(struct amdgpu_device *adev, 278*b843c749SSergey Zigachev enum amdgpu_hpd_id hpd); 279*b843c749SSergey Zigachev u32 (*hpd_get_gpio_reg)(struct amdgpu_device *adev); 280*b843c749SSergey Zigachev /* pageflipping */ 281*b843c749SSergey Zigachev void (*page_flip)(struct amdgpu_device *adev, 282*b843c749SSergey Zigachev int crtc_id, u64 crtc_base, bool async); 283*b843c749SSergey Zigachev int (*page_flip_get_scanoutpos)(struct amdgpu_device *adev, int crtc, 284*b843c749SSergey Zigachev u32 *vbl, u32 *position); 285*b843c749SSergey Zigachev /* display topology setup */ 286*b843c749SSergey Zigachev void (*add_encoder)(struct amdgpu_device *adev, 287*b843c749SSergey Zigachev uint32_t encoder_enum, 288*b843c749SSergey Zigachev uint32_t supported_device, 289*b843c749SSergey Zigachev u16 caps); 290*b843c749SSergey Zigachev void (*add_connector)(struct amdgpu_device *adev, 291*b843c749SSergey Zigachev uint32_t connector_id, 292*b843c749SSergey Zigachev uint32_t supported_device, 293*b843c749SSergey Zigachev int connector_type, 294*b843c749SSergey Zigachev struct amdgpu_i2c_bus_rec *i2c_bus, 295*b843c749SSergey Zigachev uint16_t connector_object_id, 296*b843c749SSergey Zigachev struct amdgpu_hpd *hpd, 297*b843c749SSergey Zigachev struct amdgpu_router *router); 298*b843c749SSergey Zigachev /* it is used to enter or exit into free sync mode */ 299*b843c749SSergey Zigachev int (*notify_freesync)(struct drm_device *dev, void *data, 300*b843c749SSergey Zigachev struct drm_file *filp); 301*b843c749SSergey Zigachev /* it is used to allow enablement of freesync mode */ 302*b843c749SSergey Zigachev int (*set_freesync_property)(struct drm_connector *connector, 303*b843c749SSergey Zigachev struct drm_property *property, 304*b843c749SSergey Zigachev uint64_t val); 305*b843c749SSergey Zigachev 306*b843c749SSergey Zigachev 307*b843c749SSergey Zigachev }; 308*b843c749SSergey Zigachev 309*b843c749SSergey Zigachev struct amdgpu_framebuffer { 310*b843c749SSergey Zigachev struct drm_framebuffer base; 311*b843c749SSergey Zigachev 312*b843c749SSergey Zigachev /* caching for later use */ 313*b843c749SSergey Zigachev uint64_t address; 314*b843c749SSergey Zigachev }; 315*b843c749SSergey Zigachev 316*b843c749SSergey Zigachev struct amdgpu_fbdev { 317*b843c749SSergey Zigachev struct drm_fb_helper helper; 318*b843c749SSergey Zigachev struct amdgpu_framebuffer rfb; 319*b843c749SSergey Zigachev struct list_head fbdev_list; 320*b843c749SSergey Zigachev struct amdgpu_device *adev; 321*b843c749SSergey Zigachev }; 322*b843c749SSergey Zigachev 323*b843c749SSergey Zigachev struct amdgpu_mode_info { 324*b843c749SSergey Zigachev struct atom_context *atom_context; 325*b843c749SSergey Zigachev struct card_info *atom_card_info; 326*b843c749SSergey Zigachev bool mode_config_initialized; 327*b843c749SSergey Zigachev struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; 328*b843c749SSergey Zigachev struct amdgpu_plane *planes[AMDGPU_MAX_PLANES]; 329*b843c749SSergey Zigachev struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; 330*b843c749SSergey Zigachev /* DVI-I properties */ 331*b843c749SSergey Zigachev struct drm_property *coherent_mode_property; 332*b843c749SSergey Zigachev /* DAC enable load detect */ 333*b843c749SSergey Zigachev struct drm_property *load_detect_property; 334*b843c749SSergey Zigachev /* underscan */ 335*b843c749SSergey Zigachev struct drm_property *underscan_property; 336*b843c749SSergey Zigachev struct drm_property *underscan_hborder_property; 337*b843c749SSergey Zigachev struct drm_property *underscan_vborder_property; 338*b843c749SSergey Zigachev /* audio */ 339*b843c749SSergey Zigachev struct drm_property *audio_property; 340*b843c749SSergey Zigachev /* FMT dithering */ 341*b843c749SSergey Zigachev struct drm_property *dither_property; 342*b843c749SSergey Zigachev /* maximum number of bits per channel for monitor color */ 343*b843c749SSergey Zigachev struct drm_property *max_bpc_property; 344*b843c749SSergey Zigachev /* hardcoded DFP edid from BIOS */ 345*b843c749SSergey Zigachev struct edid *bios_hardcoded_edid; 346*b843c749SSergey Zigachev int bios_hardcoded_edid_size; 347*b843c749SSergey Zigachev 348*b843c749SSergey Zigachev /* pointer to fbdev info structure */ 349*b843c749SSergey Zigachev struct amdgpu_fbdev *rfbdev; 350*b843c749SSergey Zigachev /* firmware flags */ 351*b843c749SSergey Zigachev u16 firmware_flags; 352*b843c749SSergey Zigachev /* pointer to backlight encoder */ 353*b843c749SSergey Zigachev struct amdgpu_encoder *bl_encoder; 354*b843c749SSergey Zigachev u8 bl_level; /* saved backlight level */ 355*b843c749SSergey Zigachev struct amdgpu_audio audio; /* audio stuff */ 356*b843c749SSergey Zigachev int num_crtc; /* number of crtcs */ 357*b843c749SSergey Zigachev int num_hpd; /* number of hpd pins */ 358*b843c749SSergey Zigachev int num_dig; /* number of dig blocks */ 359*b843c749SSergey Zigachev int disp_priority; 360*b843c749SSergey Zigachev const struct amdgpu_display_funcs *funcs; 361*b843c749SSergey Zigachev const enum drm_plane_type *plane_type; 362*b843c749SSergey Zigachev }; 363*b843c749SSergey Zigachev 364*b843c749SSergey Zigachev #define AMDGPU_MAX_BL_LEVEL 0xFF 365*b843c749SSergey Zigachev 366*b843c749SSergey Zigachev #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) 367*b843c749SSergey Zigachev 368*b843c749SSergey Zigachev struct amdgpu_backlight_privdata { 369*b843c749SSergey Zigachev struct amdgpu_encoder *encoder; 370*b843c749SSergey Zigachev uint8_t negative; 371*b843c749SSergey Zigachev }; 372*b843c749SSergey Zigachev 373*b843c749SSergey Zigachev #endif 374*b843c749SSergey Zigachev 375*b843c749SSergey Zigachev struct amdgpu_atom_ss { 376*b843c749SSergey Zigachev uint16_t percentage; 377*b843c749SSergey Zigachev uint16_t percentage_divider; 378*b843c749SSergey Zigachev uint8_t type; 379*b843c749SSergey Zigachev uint16_t step; 380*b843c749SSergey Zigachev uint8_t delay; 381*b843c749SSergey Zigachev uint8_t range; 382*b843c749SSergey Zigachev uint8_t refdiv; 383*b843c749SSergey Zigachev /* asic_ss */ 384*b843c749SSergey Zigachev uint16_t rate; 385*b843c749SSergey Zigachev uint16_t amount; 386*b843c749SSergey Zigachev }; 387*b843c749SSergey Zigachev 388*b843c749SSergey Zigachev struct amdgpu_crtc { 389*b843c749SSergey Zigachev struct drm_crtc base; 390*b843c749SSergey Zigachev int crtc_id; 391*b843c749SSergey Zigachev bool enabled; 392*b843c749SSergey Zigachev bool can_tile; 393*b843c749SSergey Zigachev uint32_t crtc_offset; 394*b843c749SSergey Zigachev struct drm_gem_object *cursor_bo; 395*b843c749SSergey Zigachev uint64_t cursor_addr; 396*b843c749SSergey Zigachev int cursor_x; 397*b843c749SSergey Zigachev int cursor_y; 398*b843c749SSergey Zigachev int cursor_hot_x; 399*b843c749SSergey Zigachev int cursor_hot_y; 400*b843c749SSergey Zigachev int cursor_width; 401*b843c749SSergey Zigachev int cursor_height; 402*b843c749SSergey Zigachev int max_cursor_width; 403*b843c749SSergey Zigachev int max_cursor_height; 404*b843c749SSergey Zigachev enum amdgpu_rmx_type rmx_type; 405*b843c749SSergey Zigachev u8 h_border; 406*b843c749SSergey Zigachev u8 v_border; 407*b843c749SSergey Zigachev fixed20_12 vsc; 408*b843c749SSergey Zigachev fixed20_12 hsc; 409*b843c749SSergey Zigachev struct drm_display_mode native_mode; 410*b843c749SSergey Zigachev u32 pll_id; 411*b843c749SSergey Zigachev /* page flipping */ 412*b843c749SSergey Zigachev struct amdgpu_flip_work *pflip_works; 413*b843c749SSergey Zigachev enum amdgpu_flip_status pflip_status; 414*b843c749SSergey Zigachev int deferred_flip_completion; 415*b843c749SSergey Zigachev /* pll sharing */ 416*b843c749SSergey Zigachev struct amdgpu_atom_ss ss; 417*b843c749SSergey Zigachev bool ss_enabled; 418*b843c749SSergey Zigachev u32 adjusted_clock; 419*b843c749SSergey Zigachev int bpc; 420*b843c749SSergey Zigachev u32 pll_reference_div; 421*b843c749SSergey Zigachev u32 pll_post_div; 422*b843c749SSergey Zigachev u32 pll_flags; 423*b843c749SSergey Zigachev struct drm_encoder *encoder; 424*b843c749SSergey Zigachev struct drm_connector *connector; 425*b843c749SSergey Zigachev /* for dpm */ 426*b843c749SSergey Zigachev u32 line_time; 427*b843c749SSergey Zigachev u32 wm_low; 428*b843c749SSergey Zigachev u32 wm_high; 429*b843c749SSergey Zigachev u32 lb_vblank_lead_lines; 430*b843c749SSergey Zigachev struct drm_display_mode hw_mode; 431*b843c749SSergey Zigachev /* for virtual dce */ 432*b843c749SSergey Zigachev struct hrtimer vblank_timer; 433*b843c749SSergey Zigachev enum amdgpu_interrupt_state vsync_timer_enabled; 434*b843c749SSergey Zigachev 435*b843c749SSergey Zigachev int otg_inst; 436*b843c749SSergey Zigachev struct drm_pending_vblank_event *event; 437*b843c749SSergey Zigachev }; 438*b843c749SSergey Zigachev 439*b843c749SSergey Zigachev struct amdgpu_plane { 440*b843c749SSergey Zigachev struct drm_plane base; 441*b843c749SSergey Zigachev enum drm_plane_type plane_type; 442*b843c749SSergey Zigachev }; 443*b843c749SSergey Zigachev 444*b843c749SSergey Zigachev struct amdgpu_encoder_atom_dig { 445*b843c749SSergey Zigachev bool linkb; 446*b843c749SSergey Zigachev /* atom dig */ 447*b843c749SSergey Zigachev bool coherent_mode; 448*b843c749SSergey Zigachev int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB, etc. */ 449*b843c749SSergey Zigachev /* atom lvds/edp */ 450*b843c749SSergey Zigachev uint32_t lcd_misc; 451*b843c749SSergey Zigachev uint16_t panel_pwr_delay; 452*b843c749SSergey Zigachev uint32_t lcd_ss_id; 453*b843c749SSergey Zigachev /* panel mode */ 454*b843c749SSergey Zigachev struct drm_display_mode native_mode; 455*b843c749SSergey Zigachev struct backlight_device *bl_dev; 456*b843c749SSergey Zigachev int dpms_mode; 457*b843c749SSergey Zigachev uint8_t backlight_level; 458*b843c749SSergey Zigachev int panel_mode; 459*b843c749SSergey Zigachev struct amdgpu_afmt *afmt; 460*b843c749SSergey Zigachev }; 461*b843c749SSergey Zigachev 462*b843c749SSergey Zigachev struct amdgpu_encoder { 463*b843c749SSergey Zigachev struct drm_encoder base; 464*b843c749SSergey Zigachev uint32_t encoder_enum; 465*b843c749SSergey Zigachev uint32_t encoder_id; 466*b843c749SSergey Zigachev uint32_t devices; 467*b843c749SSergey Zigachev uint32_t active_device; 468*b843c749SSergey Zigachev uint32_t flags; 469*b843c749SSergey Zigachev uint32_t pixel_clock; 470*b843c749SSergey Zigachev enum amdgpu_rmx_type rmx_type; 471*b843c749SSergey Zigachev enum amdgpu_underscan_type underscan_type; 472*b843c749SSergey Zigachev uint32_t underscan_hborder; 473*b843c749SSergey Zigachev uint32_t underscan_vborder; 474*b843c749SSergey Zigachev struct drm_display_mode native_mode; 475*b843c749SSergey Zigachev void *enc_priv; 476*b843c749SSergey Zigachev int audio_polling_active; 477*b843c749SSergey Zigachev bool is_ext_encoder; 478*b843c749SSergey Zigachev u16 caps; 479*b843c749SSergey Zigachev }; 480*b843c749SSergey Zigachev 481*b843c749SSergey Zigachev struct amdgpu_connector_atom_dig { 482*b843c749SSergey Zigachev /* displayport */ 483*b843c749SSergey Zigachev u8 dpcd[DP_RECEIVER_CAP_SIZE]; 484*b843c749SSergey Zigachev u8 dp_sink_type; 485*b843c749SSergey Zigachev int dp_clock; 486*b843c749SSergey Zigachev int dp_lane_count; 487*b843c749SSergey Zigachev bool edp_on; 488*b843c749SSergey Zigachev }; 489*b843c749SSergey Zigachev 490*b843c749SSergey Zigachev struct amdgpu_gpio_rec { 491*b843c749SSergey Zigachev bool valid; 492*b843c749SSergey Zigachev u8 id; 493*b843c749SSergey Zigachev u32 reg; 494*b843c749SSergey Zigachev u32 mask; 495*b843c749SSergey Zigachev u32 shift; 496*b843c749SSergey Zigachev }; 497*b843c749SSergey Zigachev 498*b843c749SSergey Zigachev struct amdgpu_hpd { 499*b843c749SSergey Zigachev enum amdgpu_hpd_id hpd; 500*b843c749SSergey Zigachev u8 plugged_state; 501*b843c749SSergey Zigachev struct amdgpu_gpio_rec gpio; 502*b843c749SSergey Zigachev }; 503*b843c749SSergey Zigachev 504*b843c749SSergey Zigachev struct amdgpu_router { 505*b843c749SSergey Zigachev u32 router_id; 506*b843c749SSergey Zigachev struct amdgpu_i2c_bus_rec i2c_info; 507*b843c749SSergey Zigachev u8 i2c_addr; 508*b843c749SSergey Zigachev /* i2c mux */ 509*b843c749SSergey Zigachev bool ddc_valid; 510*b843c749SSergey Zigachev u8 ddc_mux_type; 511*b843c749SSergey Zigachev u8 ddc_mux_control_pin; 512*b843c749SSergey Zigachev u8 ddc_mux_state; 513*b843c749SSergey Zigachev /* clock/data mux */ 514*b843c749SSergey Zigachev bool cd_valid; 515*b843c749SSergey Zigachev u8 cd_mux_type; 516*b843c749SSergey Zigachev u8 cd_mux_control_pin; 517*b843c749SSergey Zigachev u8 cd_mux_state; 518*b843c749SSergey Zigachev }; 519*b843c749SSergey Zigachev 520*b843c749SSergey Zigachev enum amdgpu_connector_audio { 521*b843c749SSergey Zigachev AMDGPU_AUDIO_DISABLE = 0, 522*b843c749SSergey Zigachev AMDGPU_AUDIO_ENABLE = 1, 523*b843c749SSergey Zigachev AMDGPU_AUDIO_AUTO = 2 524*b843c749SSergey Zigachev }; 525*b843c749SSergey Zigachev 526*b843c749SSergey Zigachev enum amdgpu_connector_dither { 527*b843c749SSergey Zigachev AMDGPU_FMT_DITHER_DISABLE = 0, 528*b843c749SSergey Zigachev AMDGPU_FMT_DITHER_ENABLE = 1, 529*b843c749SSergey Zigachev }; 530*b843c749SSergey Zigachev 531*b843c749SSergey Zigachev struct amdgpu_dm_dp_aux { 532*b843c749SSergey Zigachev struct drm_dp_aux aux; 533*b843c749SSergey Zigachev struct ddc_service *ddc_service; 534*b843c749SSergey Zigachev }; 535*b843c749SSergey Zigachev 536*b843c749SSergey Zigachev struct amdgpu_i2c_adapter { 537*b843c749SSergey Zigachev struct i2c_adapter base; 538*b843c749SSergey Zigachev 539*b843c749SSergey Zigachev struct ddc_service *ddc_service; 540*b843c749SSergey Zigachev }; 541*b843c749SSergey Zigachev 542*b843c749SSergey Zigachev #define TO_DM_AUX(x) container_of((x), struct amdgpu_dm_dp_aux, aux) 543*b843c749SSergey Zigachev 544*b843c749SSergey Zigachev struct amdgpu_connector { 545*b843c749SSergey Zigachev struct drm_connector base; 546*b843c749SSergey Zigachev uint32_t connector_id; 547*b843c749SSergey Zigachev uint32_t devices; 548*b843c749SSergey Zigachev struct amdgpu_i2c_chan *ddc_bus; 549*b843c749SSergey Zigachev /* some systems have an hdmi and vga port with a shared ddc line */ 550*b843c749SSergey Zigachev bool shared_ddc; 551*b843c749SSergey Zigachev bool use_digital; 552*b843c749SSergey Zigachev /* we need to mind the EDID between detect 553*b843c749SSergey Zigachev and get modes due to analog/digital/tvencoder */ 554*b843c749SSergey Zigachev struct edid *edid; 555*b843c749SSergey Zigachev void *con_priv; 556*b843c749SSergey Zigachev bool dac_load_detect; 557*b843c749SSergey Zigachev bool detected_by_load; /* if the connection status was determined by load */ 558*b843c749SSergey Zigachev uint16_t connector_object_id; 559*b843c749SSergey Zigachev struct amdgpu_hpd hpd; 560*b843c749SSergey Zigachev struct amdgpu_router router; 561*b843c749SSergey Zigachev struct amdgpu_i2c_chan *router_bus; 562*b843c749SSergey Zigachev enum amdgpu_connector_audio audio; 563*b843c749SSergey Zigachev enum amdgpu_connector_dither dither; 564*b843c749SSergey Zigachev unsigned pixelclock_for_modeset; 565*b843c749SSergey Zigachev }; 566*b843c749SSergey Zigachev 567*b843c749SSergey Zigachev /* TODO: start to use this struct and remove same field from base one */ 568*b843c749SSergey Zigachev struct amdgpu_mst_connector { 569*b843c749SSergey Zigachev struct amdgpu_connector base; 570*b843c749SSergey Zigachev 571*b843c749SSergey Zigachev struct drm_dp_mst_topology_mgr mst_mgr; 572*b843c749SSergey Zigachev struct amdgpu_dm_dp_aux dm_dp_aux; 573*b843c749SSergey Zigachev struct drm_dp_mst_port *port; 574*b843c749SSergey Zigachev struct amdgpu_connector *mst_port; 575*b843c749SSergey Zigachev bool is_mst_connector; 576*b843c749SSergey Zigachev struct amdgpu_encoder *mst_encoder; 577*b843c749SSergey Zigachev }; 578*b843c749SSergey Zigachev 579*b843c749SSergey Zigachev #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ 580*b843c749SSergey Zigachev ((em) == ATOM_ENCODER_MODE_DP_MST)) 581*b843c749SSergey Zigachev 582*b843c749SSergey Zigachev /* Driver internal use only flags of amdgpu_display_get_crtc_scanoutpos() */ 583*b843c749SSergey Zigachev #define DRM_SCANOUTPOS_VALID (1 << 0) 584*b843c749SSergey Zigachev #define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) 585*b843c749SSergey Zigachev #define DRM_SCANOUTPOS_ACCURATE (1 << 2) 586*b843c749SSergey Zigachev #define USE_REAL_VBLANKSTART (1 << 30) 587*b843c749SSergey Zigachev #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) 588*b843c749SSergey Zigachev 589*b843c749SSergey Zigachev void amdgpu_link_encoder_connector(struct drm_device *dev); 590*b843c749SSergey Zigachev 591*b843c749SSergey Zigachev struct drm_connector * 592*b843c749SSergey Zigachev amdgpu_get_connector_for_encoder(struct drm_encoder *encoder); 593*b843c749SSergey Zigachev struct drm_connector * 594*b843c749SSergey Zigachev amdgpu_get_connector_for_encoder_init(struct drm_encoder *encoder); 595*b843c749SSergey Zigachev bool amdgpu_dig_monitor_is_duallink(struct drm_encoder *encoder, 596*b843c749SSergey Zigachev u32 pixel_clock); 597*b843c749SSergey Zigachev 598*b843c749SSergey Zigachev u16 amdgpu_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); 599*b843c749SSergey Zigachev struct drm_encoder *amdgpu_get_external_encoder(struct drm_encoder *encoder); 600*b843c749SSergey Zigachev 601*b843c749SSergey Zigachev bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, 602*b843c749SSergey Zigachev bool use_aux); 603*b843c749SSergey Zigachev 604*b843c749SSergey Zigachev void amdgpu_encoder_set_active_device(struct drm_encoder *encoder); 605*b843c749SSergey Zigachev 606*b843c749SSergey Zigachev int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev, 607*b843c749SSergey Zigachev unsigned int pipe, unsigned int flags, int *vpos, 608*b843c749SSergey Zigachev int *hpos, ktime_t *stime, ktime_t *etime, 609*b843c749SSergey Zigachev const struct drm_display_mode *mode); 610*b843c749SSergey Zigachev 611*b843c749SSergey Zigachev int amdgpu_display_framebuffer_init(struct drm_device *dev, 612*b843c749SSergey Zigachev struct amdgpu_framebuffer *rfb, 613*b843c749SSergey Zigachev const struct drm_mode_fb_cmd2 *mode_cmd, 614*b843c749SSergey Zigachev struct drm_gem_object *obj); 615*b843c749SSergey Zigachev 616*b843c749SSergey Zigachev int amdgpufb_remove(struct drm_device *dev, struct drm_framebuffer *fb); 617*b843c749SSergey Zigachev 618*b843c749SSergey Zigachev void amdgpu_enc_destroy(struct drm_encoder *encoder); 619*b843c749SSergey Zigachev void amdgpu_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); 620*b843c749SSergey Zigachev bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc, 621*b843c749SSergey Zigachev const struct drm_display_mode *mode, 622*b843c749SSergey Zigachev struct drm_display_mode *adjusted_mode); 623*b843c749SSergey Zigachev void amdgpu_panel_mode_fixup(struct drm_encoder *encoder, 624*b843c749SSergey Zigachev struct drm_display_mode *adjusted_mode); 625*b843c749SSergey Zigachev int amdgpu_display_crtc_idx_to_irq_type(struct amdgpu_device *adev, int crtc); 626*b843c749SSergey Zigachev 627*b843c749SSergey Zigachev /* fbdev layer */ 628*b843c749SSergey Zigachev int amdgpu_fbdev_init(struct amdgpu_device *adev); 629*b843c749SSergey Zigachev void amdgpu_fbdev_fini(struct amdgpu_device *adev); 630*b843c749SSergey Zigachev void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state); 631*b843c749SSergey Zigachev int amdgpu_fbdev_total_size(struct amdgpu_device *adev); 632*b843c749SSergey Zigachev bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj); 633*b843c749SSergey Zigachev 634*b843c749SSergey Zigachev int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tiled); 635*b843c749SSergey Zigachev 636*b843c749SSergey Zigachev /* amdgpu_display.c */ 637*b843c749SSergey Zigachev void amdgpu_display_print_display_setup(struct drm_device *dev); 638*b843c749SSergey Zigachev int amdgpu_display_modeset_create_props(struct amdgpu_device *adev); 639*b843c749SSergey Zigachev int amdgpu_display_crtc_set_config(struct drm_mode_set *set, 640*b843c749SSergey Zigachev struct drm_modeset_acquire_ctx *ctx); 641*b843c749SSergey Zigachev int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, 642*b843c749SSergey Zigachev struct drm_framebuffer *fb, 643*b843c749SSergey Zigachev struct drm_pending_vblank_event *event, 644*b843c749SSergey Zigachev uint32_t page_flip_flags, uint32_t target, 645*b843c749SSergey Zigachev struct drm_modeset_acquire_ctx *ctx); 646*b843c749SSergey Zigachev extern const struct drm_mode_config_funcs amdgpu_mode_funcs; 647*b843c749SSergey Zigachev 648*b843c749SSergey Zigachev #endif 649