2 * Copyright 2014 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
24 #include <drm/drm_vblank.h>
27 #include "amdgpu_pm.h"
28 #include "amdgpu_i2c.h"
30 #include "amdgpu_pll.h"
31 #include "amdgpu_connectors.h"
32 #ifdef CONFIG_DRM_AMDGPU_SI
35 #ifdef CONFIG_DRM_AMDGPU_CIK
38 #include "dce_v10_0.h"
39 #include "dce_v11_0.h"
40 #include "dce_virtual.h"
41 #include "ivsrcid/ivsrcid_vislands30.h"
43 #define DCE_VIRTUAL_VBLANK_PERIOD 16666666
46 static void dce_virtual_set_display_funcs(struct amdgpu_device
*adev
);
47 static void dce_virtual_set_irq_funcs(struct amdgpu_device
*adev
);
48 static int dce_virtual_connector_encoder_init(struct amdgpu_device
*adev
,
50 static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device
*adev
,
52 enum amdgpu_interrupt_state state
);
54 static u32
dce_virtual_vblank_get_counter(struct amdgpu_device
*adev
, int crtc
)
59 static void dce_virtual_page_flip(struct amdgpu_device
*adev
,
60 int crtc_id
, u64 crtc_base
, bool async
)
65 static int dce_virtual_crtc_get_scanoutpos(struct amdgpu_device
*adev
, int crtc
,
66 u32
*vbl
, u32
*position
)
74 static bool dce_virtual_hpd_sense(struct amdgpu_device
*adev
,
75 enum amdgpu_hpd_id hpd
)
80 static void dce_virtual_hpd_set_polarity(struct amdgpu_device
*adev
,
81 enum amdgpu_hpd_id hpd
)
86 static u32
dce_virtual_hpd_get_gpio_reg(struct amdgpu_device
*adev
)
92 * dce_virtual_bandwidth_update - program display watermarks
94 * @adev: amdgpu_device pointer
96 * Calculate and program the display watermarks and line
97 * buffer allocation (CIK).
99 static void dce_virtual_bandwidth_update(struct amdgpu_device
*adev
)
104 static int dce_virtual_crtc_gamma_set(struct drm_crtc
*crtc
, u16
*red
,
105 u16
*green
, u16
*blue
, uint32_t size
,
106 struct drm_modeset_acquire_ctx
*ctx
)
111 static void dce_virtual_crtc_destroy(struct drm_crtc
*crtc
)
113 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
115 drm_crtc_cleanup(crtc
);
119 static const struct drm_crtc_funcs dce_virtual_crtc_funcs
= {
122 .gamma_set
= dce_virtual_crtc_gamma_set
,
123 .set_config
= amdgpu_display_crtc_set_config
,
124 .destroy
= dce_virtual_crtc_destroy
,
125 .page_flip_target
= amdgpu_display_crtc_page_flip_target
,
128 static void dce_virtual_crtc_dpms(struct drm_crtc
*crtc
, int mode
)
130 struct drm_device
*dev
= crtc
->dev
;
131 struct amdgpu_device
*adev
= dev
->dev_private
;
132 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
135 if (amdgpu_sriov_vf(adev
))
139 case DRM_MODE_DPMS_ON
:
140 amdgpu_crtc
->enabled
= true;
141 /* Make sure VBLANK interrupts are still enabled */
142 type
= amdgpu_display_crtc_idx_to_irq_type(adev
,
143 amdgpu_crtc
->crtc_id
);
144 amdgpu_irq_update(adev
, &adev
->crtc_irq
, type
);
145 drm_crtc_vblank_on(crtc
);
147 case DRM_MODE_DPMS_STANDBY
:
148 case DRM_MODE_DPMS_SUSPEND
:
149 case DRM_MODE_DPMS_OFF
:
150 drm_crtc_vblank_off(crtc
);
151 amdgpu_crtc
->enabled
= false;
157 static void dce_virtual_crtc_prepare(struct drm_crtc
*crtc
)
159 dce_virtual_crtc_dpms(crtc
, DRM_MODE_DPMS_OFF
);
162 static void dce_virtual_crtc_commit(struct drm_crtc
*crtc
)
164 dce_virtual_crtc_dpms(crtc
, DRM_MODE_DPMS_ON
);
167 static void dce_virtual_crtc_disable(struct drm_crtc
*crtc
)
169 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
171 dce_virtual_crtc_dpms(crtc
, DRM_MODE_DPMS_OFF
);
173 amdgpu_crtc
->pll_id
= ATOM_PPLL_INVALID
;
174 amdgpu_crtc
->encoder
= NULL
;
175 amdgpu_crtc
->connector
= NULL
;
178 static int dce_virtual_crtc_mode_set(struct drm_crtc
*crtc
,
179 struct drm_display_mode
*mode
,
180 struct drm_display_mode
*adjusted_mode
,
181 int x
, int y
, struct drm_framebuffer
*old_fb
)
183 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
185 /* update the hw version fpr dpm */
186 amdgpu_crtc
->hw_mode
= *adjusted_mode
;
191 static bool dce_virtual_crtc_mode_fixup(struct drm_crtc
*crtc
,
192 const struct drm_display_mode
*mode
,
193 struct drm_display_mode
*adjusted_mode
)
199 static int dce_virtual_crtc_set_base(struct drm_crtc
*crtc
, int x
, int y
,
200 struct drm_framebuffer
*old_fb
)
205 static int dce_virtual_crtc_set_base_atomic(struct drm_crtc
*crtc
,
206 struct drm_framebuffer
*fb
,
207 int x
, int y
, enum mode_set_atomic state
)
212 static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs
= {
213 .dpms
= dce_virtual_crtc_dpms
,
214 .mode_fixup
= dce_virtual_crtc_mode_fixup
,
215 .mode_set
= dce_virtual_crtc_mode_set
,
216 .mode_set_base
= dce_virtual_crtc_set_base
,
217 .mode_set_base_atomic
= dce_virtual_crtc_set_base_atomic
,
218 .prepare
= dce_virtual_crtc_prepare
,
219 .commit
= dce_virtual_crtc_commit
,
220 .disable
= dce_virtual_crtc_disable
,
223 static int dce_virtual_crtc_init(struct amdgpu_device
*adev
, int index
)
225 struct amdgpu_crtc
*amdgpu_crtc
;
227 amdgpu_crtc
= kzalloc(sizeof(struct amdgpu_crtc
) +
228 (AMDGPUFB_CONN_LIMIT
* sizeof(struct drm_connector
*)), GFP_KERNEL
);
229 if (amdgpu_crtc
== NULL
)
232 drm_crtc_init(adev
->ddev
, &amdgpu_crtc
->base
, &dce_virtual_crtc_funcs
);
234 drm_mode_crtc_set_gamma_size(&amdgpu_crtc
->base
, 256);
235 amdgpu_crtc
->crtc_id
= index
;
236 adev
->mode_info
.crtcs
[index
] = amdgpu_crtc
;
238 amdgpu_crtc
->pll_id
= ATOM_PPLL_INVALID
;
239 amdgpu_crtc
->encoder
= NULL
;
240 amdgpu_crtc
->connector
= NULL
;
241 amdgpu_crtc
->vsync_timer_enabled
= AMDGPU_IRQ_STATE_DISABLE
;
242 drm_crtc_helper_add(&amdgpu_crtc
->base
, &dce_virtual_crtc_helper_funcs
);
247 static int dce_virtual_early_init(void *handle
)
249 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
251 dce_virtual_set_display_funcs(adev
);
252 dce_virtual_set_irq_funcs(adev
);
254 adev
->mode_info
.num_hpd
= 1;
255 adev
->mode_info
.num_dig
= 1;
259 static struct drm_encoder
*
260 dce_virtual_encoder(struct drm_connector
*connector
)
262 struct drm_encoder
*encoder
;
264 drm_connector_for_each_possible_encoder(connector
, encoder
) {
265 if (encoder
->encoder_type
== DRM_MODE_ENCODER_VIRTUAL
)
269 /* pick the first one */
270 drm_connector_for_each_possible_encoder(connector
, encoder
)
276 static int dce_virtual_get_modes(struct drm_connector
*connector
)
278 struct drm_device
*dev
= connector
->dev
;
279 struct drm_display_mode
*mode
= NULL
;
281 static const struct mode_size
{
284 } common_modes
[17] = {
304 for (i
= 0; i
< 17; i
++) {
305 mode
= drm_cvt_mode(dev
, common_modes
[i
].w
, common_modes
[i
].h
, 60, false, false, false);
306 drm_mode_probed_add(connector
, mode
);
312 static enum drm_mode_status
dce_virtual_mode_valid(struct drm_connector
*connector
,
313 struct drm_display_mode
*mode
)
319 dce_virtual_dpms(struct drm_connector
*connector
, int mode
)
325 dce_virtual_set_property(struct drm_connector
*connector
,
326 struct drm_property
*property
,
332 static void dce_virtual_destroy(struct drm_connector
*connector
)
334 drm_connector_unregister(connector
);
335 drm_connector_cleanup(connector
);
339 static void dce_virtual_force(struct drm_connector
*connector
)
344 static const struct drm_connector_helper_funcs dce_virtual_connector_helper_funcs
= {
345 .get_modes
= dce_virtual_get_modes
,
346 .mode_valid
= dce_virtual_mode_valid
,
347 .best_encoder
= dce_virtual_encoder
,
350 static const struct drm_connector_funcs dce_virtual_connector_funcs
= {
351 .dpms
= dce_virtual_dpms
,
352 .fill_modes
= drm_helper_probe_single_connector_modes
,
353 .set_property
= dce_virtual_set_property
,
354 .destroy
= dce_virtual_destroy
,
355 .force
= dce_virtual_force
,
358 static int dce_virtual_sw_init(void *handle
)
361 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
363 r
= amdgpu_irq_add_id(adev
, AMDGPU_IRQ_CLIENTID_LEGACY
, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER
, &adev
->crtc_irq
);
367 adev
->ddev
->max_vblank_count
= 0;
369 adev
->ddev
->mode_config
.funcs
= &amdgpu_mode_funcs
;
371 adev
->ddev
->mode_config
.max_width
= 16384;
372 adev
->ddev
->mode_config
.max_height
= 16384;
374 adev
->ddev
->mode_config
.preferred_depth
= 24;
375 adev
->ddev
->mode_config
.prefer_shadow
= 1;
377 adev
->ddev
->mode_config
.fb_base
= adev
->gmc
.aper_base
;
379 r
= amdgpu_display_modeset_create_props(adev
);
383 adev
->ddev
->mode_config
.max_width
= 16384;
384 adev
->ddev
->mode_config
.max_height
= 16384;
386 /* allocate crtcs, encoders, connectors */
387 for (i
= 0; i
< adev
->mode_info
.num_crtc
; i
++) {
388 r
= dce_virtual_crtc_init(adev
, i
);
391 r
= dce_virtual_connector_encoder_init(adev
, i
);
396 drm_kms_helper_poll_init(adev
->ddev
);
398 adev
->mode_info
.mode_config_initialized
= true;
402 static int dce_virtual_sw_fini(void *handle
)
404 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
406 kfree(adev
->mode_info
.bios_hardcoded_edid
);
408 drm_kms_helper_poll_fini(adev
->ddev
);
410 drm_mode_config_cleanup(adev
->ddev
);
411 /* clear crtcs pointer to avoid dce irq finish routine access freed data */
412 memset(adev
->mode_info
.crtcs
, 0, sizeof(adev
->mode_info
.crtcs
[0]) * AMDGPU_MAX_CRTCS
);
413 adev
->mode_info
.mode_config_initialized
= false;
417 static int dce_virtual_hw_init(void *handle
)
419 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
421 switch (adev
->asic_type
) {
422 #ifdef CONFIG_DRM_AMDGPU_SI
427 dce_v6_0_disable_dce(adev
);
430 #ifdef CONFIG_DRM_AMDGPU_CIK
436 dce_v8_0_disable_dce(adev
);
441 dce_v10_0_disable_dce(adev
);
448 dce_v11_0_disable_dce(adev
);
451 #ifdef CONFIG_DRM_AMDGPU_SI
462 static int dce_virtual_hw_fini(void *handle
)
464 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
467 for (i
= 0; i
<adev
->mode_info
.num_crtc
; i
++)
468 if (adev
->mode_info
.crtcs
[i
])
469 dce_virtual_set_crtc_vblank_interrupt_state(adev
, i
, AMDGPU_IRQ_STATE_DISABLE
);
474 static int dce_virtual_suspend(void *handle
)
476 return dce_virtual_hw_fini(handle
);
479 static int dce_virtual_resume(void *handle
)
481 return dce_virtual_hw_init(handle
);
484 static bool dce_virtual_is_idle(void *handle
)
489 static int dce_virtual_wait_for_idle(void *handle
)
494 static int dce_virtual_soft_reset(void *handle
)
499 static int dce_virtual_set_clockgating_state(void *handle
,
500 enum amd_clockgating_state state
)
505 static int dce_virtual_set_powergating_state(void *handle
,
506 enum amd_powergating_state state
)
511 static const struct amd_ip_funcs dce_virtual_ip_funcs
= {
512 .name
= "dce_virtual",
513 .early_init
= dce_virtual_early_init
,
515 .sw_init
= dce_virtual_sw_init
,
516 .sw_fini
= dce_virtual_sw_fini
,
517 .hw_init
= dce_virtual_hw_init
,
518 .hw_fini
= dce_virtual_hw_fini
,
519 .suspend
= dce_virtual_suspend
,
520 .resume
= dce_virtual_resume
,
521 .is_idle
= dce_virtual_is_idle
,
522 .wait_for_idle
= dce_virtual_wait_for_idle
,
523 .soft_reset
= dce_virtual_soft_reset
,
524 .set_clockgating_state
= dce_virtual_set_clockgating_state
,
525 .set_powergating_state
= dce_virtual_set_powergating_state
,
528 /* these are handled by the primary encoders */
529 static void dce_virtual_encoder_prepare(struct drm_encoder
*encoder
)
534 static void dce_virtual_encoder_commit(struct drm_encoder
*encoder
)
540 dce_virtual_encoder_mode_set(struct drm_encoder
*encoder
,
541 struct drm_display_mode
*mode
,
542 struct drm_display_mode
*adjusted_mode
)
547 static void dce_virtual_encoder_disable(struct drm_encoder
*encoder
)
553 dce_virtual_encoder_dpms(struct drm_encoder
*encoder
, int mode
)
558 static bool dce_virtual_encoder_mode_fixup(struct drm_encoder
*encoder
,
559 const struct drm_display_mode
*mode
,
560 struct drm_display_mode
*adjusted_mode
)
565 static const struct drm_encoder_helper_funcs dce_virtual_encoder_helper_funcs
= {
566 .dpms
= dce_virtual_encoder_dpms
,
567 .mode_fixup
= dce_virtual_encoder_mode_fixup
,
568 .prepare
= dce_virtual_encoder_prepare
,
569 .mode_set
= dce_virtual_encoder_mode_set
,
570 .commit
= dce_virtual_encoder_commit
,
571 .disable
= dce_virtual_encoder_disable
,
574 static void dce_virtual_encoder_destroy(struct drm_encoder
*encoder
)
576 drm_encoder_cleanup(encoder
);
580 static const struct drm_encoder_funcs dce_virtual_encoder_funcs
= {
581 .destroy
= dce_virtual_encoder_destroy
,
584 static int dce_virtual_connector_encoder_init(struct amdgpu_device
*adev
,
587 struct drm_encoder
*encoder
;
588 struct drm_connector
*connector
;
590 /* add a new encoder */
591 encoder
= kzalloc(sizeof(struct drm_encoder
), GFP_KERNEL
);
594 encoder
->possible_crtcs
= 1 << index
;
595 drm_encoder_init(adev
->ddev
, encoder
, &dce_virtual_encoder_funcs
,
596 DRM_MODE_ENCODER_VIRTUAL
, NULL
);
597 drm_encoder_helper_add(encoder
, &dce_virtual_encoder_helper_funcs
);
599 connector
= kzalloc(sizeof(struct drm_connector
), GFP_KERNEL
);
605 /* add a new connector */
606 drm_connector_init(adev
->ddev
, connector
, &dce_virtual_connector_funcs
,
607 DRM_MODE_CONNECTOR_VIRTUAL
);
608 drm_connector_helper_add(connector
, &dce_virtual_connector_helper_funcs
);
609 connector
->display_info
.subpixel_order
= SubPixelHorizontalRGB
;
610 connector
->interlace_allowed
= false;
611 connector
->doublescan_allowed
= false;
612 drm_connector_register(connector
);
615 drm_connector_attach_encoder(connector
, encoder
);
620 static const struct amdgpu_display_funcs dce_virtual_display_funcs
= {
621 .bandwidth_update
= &dce_virtual_bandwidth_update
,
622 .vblank_get_counter
= &dce_virtual_vblank_get_counter
,
623 .backlight_set_level
= NULL
,
624 .backlight_get_level
= NULL
,
625 .hpd_sense
= &dce_virtual_hpd_sense
,
626 .hpd_set_polarity
= &dce_virtual_hpd_set_polarity
,
627 .hpd_get_gpio_reg
= &dce_virtual_hpd_get_gpio_reg
,
628 .page_flip
= &dce_virtual_page_flip
,
629 .page_flip_get_scanoutpos
= &dce_virtual_crtc_get_scanoutpos
,
631 .add_connector
= NULL
,
634 static void dce_virtual_set_display_funcs(struct amdgpu_device
*adev
)
636 adev
->mode_info
.funcs
= &dce_virtual_display_funcs
;
639 static int dce_virtual_pageflip(struct amdgpu_device
*adev
,
643 struct amdgpu_crtc
*amdgpu_crtc
;
644 struct amdgpu_flip_work
*works
;
646 amdgpu_crtc
= adev
->mode_info
.crtcs
[crtc_id
];
648 if (crtc_id
>= adev
->mode_info
.num_crtc
) {
649 DRM_ERROR("invalid pageflip crtc %d\n", crtc_id
);
653 /* IRQ could occur when in initial stage */
654 if (amdgpu_crtc
== NULL
)
657 spin_lock_irqsave(&adev
->ddev
->event_lock
, flags
);
658 works
= amdgpu_crtc
->pflip_works
;
659 if (amdgpu_crtc
->pflip_status
!= AMDGPU_FLIP_SUBMITTED
) {
660 DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
661 "AMDGPU_FLIP_SUBMITTED(%d)\n",
662 amdgpu_crtc
->pflip_status
,
663 AMDGPU_FLIP_SUBMITTED
);
664 spin_unlock_irqrestore(&adev
->ddev
->event_lock
, flags
);
668 /* page flip completed. clean up */
669 amdgpu_crtc
->pflip_status
= AMDGPU_FLIP_NONE
;
670 amdgpu_crtc
->pflip_works
= NULL
;
672 /* wakeup usersapce */
674 drm_crtc_send_vblank_event(&amdgpu_crtc
->base
, works
->event
);
676 spin_unlock_irqrestore(&adev
->ddev
->event_lock
, flags
);
678 drm_crtc_vblank_put(&amdgpu_crtc
->base
);
679 amdgpu_bo_unref(&works
->old_abo
);
680 kfree(works
->shared
);
686 static enum hrtimer_restart
dce_virtual_vblank_timer_handle(struct hrtimer
*vblank_timer
)
688 struct amdgpu_crtc
*amdgpu_crtc
= container_of(vblank_timer
,
689 struct amdgpu_crtc
, vblank_timer
);
690 struct drm_device
*ddev
= amdgpu_crtc
->base
.dev
;
691 struct amdgpu_device
*adev
= ddev
->dev_private
;
693 drm_handle_vblank(ddev
, amdgpu_crtc
->crtc_id
);
694 dce_virtual_pageflip(adev
, amdgpu_crtc
->crtc_id
);
695 hrtimer_start(vblank_timer
, DCE_VIRTUAL_VBLANK_PERIOD
,
698 return HRTIMER_NORESTART
;
701 static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device
*adev
,
703 enum amdgpu_interrupt_state state
)
705 if (crtc
>= adev
->mode_info
.num_crtc
|| !adev
->mode_info
.crtcs
[crtc
]) {
706 DRM_DEBUG("invalid crtc %d\n", crtc
);
710 if (state
&& !adev
->mode_info
.crtcs
[crtc
]->vsync_timer_enabled
) {
711 DRM_DEBUG("Enable software vsync timer\n");
712 hrtimer_init(&adev
->mode_info
.crtcs
[crtc
]->vblank_timer
,
713 CLOCK_MONOTONIC
, HRTIMER_MODE_REL
);
714 hrtimer_set_expires(&adev
->mode_info
.crtcs
[crtc
]->vblank_timer
,
715 DCE_VIRTUAL_VBLANK_PERIOD
);
716 adev
->mode_info
.crtcs
[crtc
]->vblank_timer
.function
=
717 dce_virtual_vblank_timer_handle
;
718 hrtimer_start(&adev
->mode_info
.crtcs
[crtc
]->vblank_timer
,
719 DCE_VIRTUAL_VBLANK_PERIOD
, HRTIMER_MODE_REL
);
720 } else if (!state
&& adev
->mode_info
.crtcs
[crtc
]->vsync_timer_enabled
) {
721 DRM_DEBUG("Disable software vsync timer\n");
722 hrtimer_cancel(&adev
->mode_info
.crtcs
[crtc
]->vblank_timer
);
725 adev
->mode_info
.crtcs
[crtc
]->vsync_timer_enabled
= state
;
726 DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc
, state
);
730 static int dce_virtual_set_crtc_irq_state(struct amdgpu_device
*adev
,
731 struct amdgpu_irq_src
*source
,
733 enum amdgpu_interrupt_state state
)
735 if (type
> AMDGPU_CRTC_IRQ_VBLANK6
)
738 dce_virtual_set_crtc_vblank_interrupt_state(adev
, type
, state
);
743 static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs
= {
744 .set
= dce_virtual_set_crtc_irq_state
,
748 static void dce_virtual_set_irq_funcs(struct amdgpu_device
*adev
)
750 adev
->crtc_irq
.num_types
= AMDGPU_CRTC_IRQ_VBLANK6
+ 1;
751 adev
->crtc_irq
.funcs
= &dce_virtual_crtc_irq_funcs
;
754 const struct amdgpu_ip_block_version dce_virtual_ip_block
=
756 .type
= AMD_IP_BLOCK_TYPE_DCE
,
760 .funcs
= &dce_virtual_ip_funcs
,