diff options
| author | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 06:52:34 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 06:52:34 -0400 |
| commit | cfd1b63af78bfce8161e5f65a1d799a9c33b52c6 (patch) | |
| tree | b8aeb45c2329f70bebea37da62583184a661c8dd /drivers/gpu/drm/armada | |
| parent | f9a13bb3baf6009225e91f2b9748ed27f2db9c2c (diff) | |
drm/armada: use core of primary update_plane for mode set
Use the core of the update_plane method to configure the primary plane
within mode_set() rather than duplicating this code. This moves us
closer to the same code structure that the atomic modeset transitional
helpers will use.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'drivers/gpu/drm/armada')
| -rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.c | 137 |
1 files changed, 59 insertions, 78 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 683b2cec3d55..6dd54f1d3ac9 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
| @@ -613,17 +613,8 @@ static void armada_drm_gra_plane_regs(struct armada_regs *regs, | |||
| 613 | armada_reg_queue_end(regs, i); | 613 | armada_reg_queue_end(regs, i); |
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | static void armada_drm_primary_set(struct drm_crtc *crtc, | 616 | static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, |
| 617 | struct drm_plane *plane, int x, int y) | 617 | struct drm_framebuffer *old_fb); |
| 618 | { | ||
| 619 | struct armada_plane_state *state = &drm_to_armada_plane(plane)->state; | ||
| 620 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | ||
| 621 | struct armada_regs regs[8]; | ||
| 622 | bool interlaced = dcrtc->interlaced; | ||
| 623 | |||
| 624 | armada_drm_gra_plane_regs(regs, plane->fb, state, x, y, interlaced); | ||
| 625 | armada_drm_crtc_update_regs(dcrtc, regs); | ||
| 626 | } | ||
| 627 | 618 | ||
| 628 | /* The mode_config.mutex will be held for this call */ | 619 | /* The mode_config.mutex will be held for this call */ |
| 629 | static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | 620 | static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, |
| @@ -637,24 +628,13 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
| 637 | unsigned i; | 628 | unsigned i; |
| 638 | bool interlaced; | 629 | bool interlaced; |
| 639 | 630 | ||
| 640 | drm_framebuffer_get(crtc->primary->fb); | 631 | /* Take a reference on the old fb for armada_drm_crtc_commit() */ |
| 632 | if (old_fb) | ||
| 633 | drm_framebuffer_get(old_fb); | ||
| 641 | dcrtc->old_modeset_fb = old_fb; | 634 | dcrtc->old_modeset_fb = old_fb; |
| 642 | 635 | ||
| 643 | interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE); | 636 | interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE); |
| 644 | 637 | ||
| 645 | val = CFG_GRA_ENA; | ||
| 646 | val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt); | ||
| 647 | val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod); | ||
| 648 | |||
| 649 | if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420) | ||
| 650 | val |= CFG_PALETTE_ENA; | ||
| 651 | |||
| 652 | drm_to_armada_plane(crtc->primary)->state.ctrl0 = val; | ||
| 653 | drm_to_armada_plane(crtc->primary)->state.src_hw = | ||
| 654 | drm_to_armada_plane(crtc->primary)->state.dst_hw = | ||
| 655 | adj->crtc_vdisplay << 16 | adj->crtc_hdisplay; | ||
| 656 | drm_to_armada_plane(crtc->primary)->state.dst_yx = 0; | ||
| 657 | |||
| 658 | i = 0; | 638 | i = 0; |
| 659 | rm = adj->crtc_hsync_start - adj->crtc_hdisplay; | 639 | rm = adj->crtc_hsync_start - adj->crtc_hdisplay; |
| 660 | lm = adj->crtc_htotal - adj->crtc_hsync_end; | 640 | lm = adj->crtc_htotal - adj->crtc_hsync_end; |
| @@ -694,9 +674,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
| 694 | 674 | ||
| 695 | spin_lock_irqsave(&dcrtc->irq_lock, flags); | 675 | spin_lock_irqsave(&dcrtc->irq_lock, flags); |
| 696 | 676 | ||
| 697 | /* Ensure graphic fifo is enabled */ | ||
| 698 | armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1); | ||
| 699 | |||
| 700 | /* Even interlaced/progressive frame */ | 677 | /* Even interlaced/progressive frame */ |
| 701 | dcrtc->v[1].spu_v_h_total = adj->crtc_vtotal << 16 | | 678 | dcrtc->v[1].spu_v_h_total = adj->crtc_vtotal << 16 | |
| 702 | adj->crtc_htotal; | 679 | adj->crtc_htotal; |
| @@ -739,37 +716,34 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
| 739 | armada_reg_queue_end(regs, i); | 716 | armada_reg_queue_end(regs, i); |
| 740 | 717 | ||
| 741 | armada_drm_crtc_update_regs(dcrtc, regs); | 718 | armada_drm_crtc_update_regs(dcrtc, regs); |
| 742 | |||
| 743 | armada_drm_primary_set(crtc, crtc->primary, x, y); | ||
| 744 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); | 719 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); |
| 745 | 720 | ||
| 746 | return 0; | 721 | return armada_drm_crtc_mode_set_base(crtc, x, y, old_fb); |
| 747 | } | 722 | } |
| 748 | 723 | ||
| 724 | static int armada_drm_do_primary_update(struct drm_plane *plane, | ||
| 725 | struct drm_plane_state *state, struct drm_framebuffer *old_fb); | ||
| 726 | |||
| 749 | /* The mode_config.mutex will be held for this call */ | 727 | /* The mode_config.mutex will be held for this call */ |
| 750 | static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | 728 | static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, |
| 751 | struct drm_framebuffer *old_fb) | 729 | struct drm_framebuffer *old_fb) |
| 752 | { | 730 | { |
| 753 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 731 | struct drm_plane_state state = { |
| 754 | struct armada_regs regs[4]; | 732 | .plane = crtc->primary, |
| 755 | unsigned i; | 733 | .crtc = crtc, |
| 756 | 734 | .fb = crtc->primary->fb, | |
| 757 | i = armada_drm_crtc_calc_fb(crtc->primary->fb, crtc->x, crtc->y, regs, | 735 | .crtc_x = 0, |
| 758 | dcrtc->interlaced); | 736 | .crtc_y = 0, |
| 759 | armada_reg_queue_end(regs, i); | 737 | .crtc_w = crtc->mode.hdisplay, |
| 760 | 738 | .crtc_h = crtc->mode.vdisplay, | |
| 761 | /* Wait for pending flips to complete */ | 739 | .src_x = x << 16, |
| 762 | armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary), | 740 | .src_y = y << 16, |
| 763 | MAX_SCHEDULE_TIMEOUT); | 741 | .src_w = crtc->mode.hdisplay << 16, |
| 764 | 742 | .src_h = crtc->mode.vdisplay << 16, | |
| 765 | /* Take a reference to the new fb as we're using it */ | 743 | .rotation = DRM_MODE_ROTATE_0, |
| 766 | drm_framebuffer_get(crtc->primary->fb); | 744 | }; |
| 767 | |||
| 768 | /* Update the base in the CRTC */ | ||
| 769 | armada_drm_crtc_update_regs(dcrtc, regs); | ||
| 770 | 745 | ||
| 771 | /* Drop our previously held reference */ | 746 | armada_drm_do_primary_update(crtc->primary, &state, old_fb); |
| 772 | armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms)); | ||
| 773 | 747 | ||
| 774 | return 0; | 748 | return 0; |
| 775 | } | 749 | } |
| @@ -1169,37 +1143,20 @@ static void armada_drm_primary_update_state(struct drm_plane_state *state, | |||
| 1169 | dplane->state.changed = true; | 1143 | dplane->state.changed = true; |
| 1170 | } | 1144 | } |
| 1171 | 1145 | ||
| 1172 | static int armada_drm_primary_update(struct drm_plane *plane, | 1146 | static int armada_drm_do_primary_update(struct drm_plane *plane, |
| 1173 | struct drm_crtc *crtc, struct drm_framebuffer *fb, | 1147 | struct drm_plane_state *state, struct drm_framebuffer *old_fb) |
| 1174 | int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, | ||
| 1175 | uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, | ||
| 1176 | struct drm_modeset_acquire_ctx *ctx) | ||
| 1177 | { | 1148 | { |
| 1178 | struct armada_plane *dplane = drm_to_armada_plane(plane); | 1149 | struct armada_plane *dplane = drm_to_armada_plane(plane); |
| 1179 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 1150 | struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc); |
| 1180 | struct armada_plane_work *work; | 1151 | struct armada_plane_work *work; |
| 1181 | struct drm_plane_state state = { | ||
| 1182 | .plane = plane, | ||
| 1183 | .crtc = crtc, | ||
| 1184 | .fb = fb, | ||
| 1185 | .src_x = src_x, | ||
| 1186 | .src_y = src_y, | ||
| 1187 | .src_w = src_w, | ||
| 1188 | .src_h = src_h, | ||
| 1189 | .crtc_x = crtc_x, | ||
| 1190 | .crtc_y = crtc_y, | ||
| 1191 | .crtc_w = crtc_w, | ||
| 1192 | .crtc_h = crtc_h, | ||
| 1193 | .rotation = DRM_MODE_ROTATE_0, | ||
| 1194 | }; | ||
| 1195 | struct drm_crtc_state crtc_state = { | 1152 | struct drm_crtc_state crtc_state = { |
| 1196 | .crtc = crtc, | 1153 | .crtc = state->crtc, |
| 1197 | .enable = crtc->enabled, | 1154 | .enable = state->crtc->enabled, |
| 1198 | .mode = crtc->mode, | 1155 | .mode = state->crtc->mode, |
| 1199 | }; | 1156 | }; |
| 1200 | int ret; | 1157 | int ret; |
| 1201 | 1158 | ||
| 1202 | ret = drm_atomic_helper_check_plane_state(&state, &crtc_state, 0, | 1159 | ret = drm_atomic_helper_check_plane_state(state, &crtc_state, 0, |
| 1203 | INT_MAX, true, false); | 1160 | INT_MAX, true, false); |
| 1204 | if (ret) | 1161 | if (ret) |
| 1205 | return ret; | 1162 | return ret; |
| @@ -1207,19 +1164,19 @@ static int armada_drm_primary_update(struct drm_plane *plane, | |||
| 1207 | work = &dplane->works[dplane->next_work]; | 1164 | work = &dplane->works[dplane->next_work]; |
| 1208 | work->fn = armada_drm_crtc_complete_frame_work; | 1165 | work->fn = armada_drm_crtc_complete_frame_work; |
| 1209 | 1166 | ||
| 1210 | if (plane->fb != fb) { | 1167 | if (old_fb != state->fb) { |
| 1211 | /* | 1168 | /* |
| 1212 | * Take a reference on the new framebuffer - we want to | 1169 | * Take a reference on the new framebuffer - we want to |
| 1213 | * hold on to it while the hardware is displaying it. | 1170 | * hold on to it while the hardware is displaying it. |
| 1214 | */ | 1171 | */ |
| 1215 | drm_framebuffer_reference(fb); | 1172 | drm_framebuffer_reference(state->fb); |
| 1216 | 1173 | ||
| 1217 | work->old_fb = plane->fb; | 1174 | work->old_fb = old_fb; |
| 1218 | } else { | 1175 | } else { |
| 1219 | work->old_fb = NULL; | 1176 | work->old_fb = NULL; |
| 1220 | } | 1177 | } |
| 1221 | 1178 | ||
| 1222 | armada_drm_primary_update_state(&state, work->regs); | 1179 | armada_drm_primary_update_state(state, work->regs); |
| 1223 | 1180 | ||
| 1224 | if (!dplane->state.changed) | 1181 | if (!dplane->state.changed) |
| 1225 | return 0; | 1182 | return 0; |
| @@ -1248,6 +1205,30 @@ static int armada_drm_primary_update(struct drm_plane *plane, | |||
| 1248 | return 0; | 1205 | return 0; |
| 1249 | } | 1206 | } |
| 1250 | 1207 | ||
| 1208 | static int armada_drm_primary_update(struct drm_plane *plane, | ||
| 1209 | struct drm_crtc *crtc, struct drm_framebuffer *fb, | ||
| 1210 | int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, | ||
| 1211 | uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, | ||
| 1212 | struct drm_modeset_acquire_ctx *ctx) | ||
| 1213 | { | ||
| 1214 | struct drm_plane_state state = { | ||
| 1215 | .plane = plane, | ||
| 1216 | .crtc = crtc, | ||
| 1217 | .fb = fb, | ||
| 1218 | .src_x = src_x, | ||
| 1219 | .src_y = src_y, | ||
| 1220 | .src_w = src_w, | ||
| 1221 | .src_h = src_h, | ||
| 1222 | .crtc_x = crtc_x, | ||
| 1223 | .crtc_y = crtc_y, | ||
| 1224 | .crtc_w = crtc_w, | ||
| 1225 | .crtc_h = crtc_h, | ||
| 1226 | .rotation = DRM_MODE_ROTATE_0, | ||
| 1227 | }; | ||
| 1228 | |||
| 1229 | return armada_drm_do_primary_update(plane, &state, plane->fb); | ||
| 1230 | } | ||
| 1231 | |||
| 1251 | int armada_drm_plane_disable(struct drm_plane *plane, | 1232 | int armada_drm_plane_disable(struct drm_plane *plane, |
| 1252 | struct drm_modeset_acquire_ctx *ctx) | 1233 | struct drm_modeset_acquire_ctx *ctx) |
| 1253 | { | 1234 | { |
