aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/armada
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-07-30 06:52:34 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2018-07-30 06:52:34 -0400
commitcfd1b63af78bfce8161e5f65a1d799a9c33b52c6 (patch)
treeb8aeb45c2329f70bebea37da62583184a661c8dd /drivers/gpu/drm/armada
parentf9a13bb3baf6009225e91f2b9748ed27f2db9c2c (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.c137
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
616static void armada_drm_primary_set(struct drm_crtc *crtc, 616static 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 */
629static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, 620static 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
724static 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 */
750static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 728static 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
1172static int armada_drm_primary_update(struct drm_plane *plane, 1146static 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
1208static 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
1251int armada_drm_plane_disable(struct drm_plane *plane, 1232int armada_drm_plane_disable(struct drm_plane *plane,
1252 struct drm_modeset_acquire_ctx *ctx) 1233 struct drm_modeset_acquire_ctx *ctx)
1253{ 1234{