aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiviu Dudau <Liviu.Dudau@arm.com>2017-08-31 10:48:43 -0400
committerLiviu Dudau <Liviu.Dudau@arm.com>2017-11-24 10:42:59 -0500
commita6993b215a719ad5758c1bced5f8df95add070bf (patch)
tree8d4409645890d095e4d06e04fbdf902391a57ffa
parent0970d7a2f5b0dcdd520c7655210d677f6e9a878e (diff)
drm: mali-dp: Separate static internal data into a read-only structure.
The malidp_hw_device structure that the driver uses to handle the differences between versions of the IP contains both non-changeable data and fields that get updated at probe time. Previously we were copying the read-only part into allocated memory, but that can be completely avoided by splitting the structure into a read-only part and keeping the runtime modifiable fields into the old structure. Reviewed-by: Brian Starkey <brian.starkey@arm.com> Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
-rw-r--r--drivers/gpu/drm/arm/malidp_crtc.c13
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c30
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c46
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.h65
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c19
5 files changed, 93 insertions, 80 deletions
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c
index 3615d18a7ddf..153a49670626 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -65,8 +65,8 @@ static void malidp_crtc_atomic_enable(struct drm_crtc *crtc,
65 /* We rely on firmware to set mclk to a sensible level. */ 65 /* We rely on firmware to set mclk to a sensible level. */
66 clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 1000); 66 clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 1000);
67 67
68 hwdev->modeset(hwdev, &vm); 68 hwdev->hw->modeset(hwdev, &vm);
69 hwdev->leave_config_mode(hwdev); 69 hwdev->hw->leave_config_mode(hwdev);
70 drm_crtc_vblank_on(crtc); 70 drm_crtc_vblank_on(crtc);
71} 71}
72 72
@@ -78,7 +78,8 @@ static void malidp_crtc_atomic_disable(struct drm_crtc *crtc,
78 int err; 78 int err;
79 79
80 drm_crtc_vblank_off(crtc); 80 drm_crtc_vblank_off(crtc);
81 hwdev->enter_config_mode(hwdev); 81 hwdev->hw->enter_config_mode(hwdev);
82
82 clk_disable_unprepare(hwdev->pxlclk); 83 clk_disable_unprepare(hwdev->pxlclk);
83 84
84 err = pm_runtime_put(crtc->dev->dev); 85 err = pm_runtime_put(crtc->dev->dev);
@@ -319,7 +320,7 @@ static int malidp_crtc_atomic_check_scaling(struct drm_crtc *crtc,
319 320
320mclk_calc: 321mclk_calc:
321 drm_display_mode_to_videomode(&state->adjusted_mode, &vm); 322 drm_display_mode_to_videomode(&state->adjusted_mode, &vm);
322 ret = hwdev->se_calc_mclk(hwdev, s, &vm); 323 ret = hwdev->hw->se_calc_mclk(hwdev, s, &vm);
323 if (ret < 0) 324 if (ret < 0)
324 return -EINVAL; 325 return -EINVAL;
325 return 0; 326 return 0;
@@ -475,7 +476,7 @@ static int malidp_crtc_enable_vblank(struct drm_crtc *crtc)
475 struct malidp_hw_device *hwdev = malidp->dev; 476 struct malidp_hw_device *hwdev = malidp->dev;
476 477
477 malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK, 478 malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK,
478 hwdev->map.de_irq_map.vsync_irq); 479 hwdev->hw->map.de_irq_map.vsync_irq);
479 return 0; 480 return 0;
480} 481}
481 482
@@ -485,7 +486,7 @@ static void malidp_crtc_disable_vblank(struct drm_crtc *crtc)
485 struct malidp_hw_device *hwdev = malidp->dev; 486 struct malidp_hw_device *hwdev = malidp->dev;
486 487
487 malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK, 488 malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK,
488 hwdev->map.de_irq_map.vsync_irq); 489 hwdev->hw->map.de_irq_map.vsync_irq);
489} 490}
490 491
491static const struct drm_crtc_funcs malidp_crtc_funcs = { 492static const struct drm_crtc_funcs malidp_crtc_funcs = {
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index a2b698c983b4..91f2b0191368 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -47,10 +47,10 @@ static void malidp_write_gamma_table(struct malidp_hw_device *hwdev,
47 * directly. 47 * directly.
48 */ 48 */
49 malidp_hw_write(hwdev, gamma_write_mask, 49 malidp_hw_write(hwdev, gamma_write_mask,
50 hwdev->map.coeffs_base + MALIDP_COEF_TABLE_ADDR); 50 hwdev->hw->map.coeffs_base + MALIDP_COEF_TABLE_ADDR);
51 for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i) 51 for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i)
52 malidp_hw_write(hwdev, data[i], 52 malidp_hw_write(hwdev, data[i],
53 hwdev->map.coeffs_base + 53 hwdev->hw->map.coeffs_base +
54 MALIDP_COEF_TABLE_DATA); 54 MALIDP_COEF_TABLE_DATA);
55} 55}
56 56
@@ -103,7 +103,7 @@ void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc,
103 for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i) 103 for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i)
104 malidp_hw_write(hwdev, 104 malidp_hw_write(hwdev,
105 mc->coloradj_coeffs[i], 105 mc->coloradj_coeffs[i],
106 hwdev->map.coeffs_base + 106 hwdev->hw->map.coeffs_base +
107 MALIDP_COLOR_ADJ_COEF + 4 * i); 107 MALIDP_COLOR_ADJ_COEF + 4 * i);
108 108
109 malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ, 109 malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ,
@@ -120,8 +120,8 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
120 struct malidp_hw_device *hwdev = malidp->dev; 120 struct malidp_hw_device *hwdev = malidp->dev;
121 struct malidp_se_config *s = &cs->scaler_config; 121 struct malidp_se_config *s = &cs->scaler_config;
122 struct malidp_se_config *old_s = &old_cs->scaler_config; 122 struct malidp_se_config *old_s = &old_cs->scaler_config;
123 u32 se_control = hwdev->map.se_base + 123 u32 se_control = hwdev->hw->map.se_base +
124 ((hwdev->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ? 124 ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
125 0x10 : 0xC); 125 0x10 : 0xC);
126 u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL; 126 u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL;
127 u32 scr = se_control + MALIDP_SE_SCALING_CONTROL; 127 u32 scr = se_control + MALIDP_SE_SCALING_CONTROL;
@@ -135,7 +135,7 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
135 return; 135 return;
136 } 136 }
137 137
138 hwdev->se_set_scaling_coeffs(hwdev, s, old_s); 138 hwdev->hw->se_set_scaling_coeffs(hwdev, s, old_s);
139 val = malidp_hw_read(hwdev, se_control); 139 val = malidp_hw_read(hwdev, se_control);
140 val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN; 140 val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN;
141 141
@@ -170,9 +170,9 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm)
170 int ret; 170 int ret;
171 171
172 atomic_set(&malidp->config_valid, 0); 172 atomic_set(&malidp->config_valid, 0);
173 hwdev->set_config_valid(hwdev); 173 hwdev->hw->set_config_valid(hwdev);
174 /* don't wait for config_valid flag if we are in config mode */ 174 /* don't wait for config_valid flag if we are in config mode */
175 if (hwdev->in_config_mode(hwdev)) 175 if (hwdev->hw->in_config_mode(hwdev))
176 return 0; 176 return 0;
177 177
178 ret = wait_event_interruptible_timeout(malidp->wq, 178 ret = wait_event_interruptible_timeout(malidp->wq,
@@ -455,7 +455,7 @@ static int malidp_runtime_pm_suspend(struct device *dev)
455 struct malidp_hw_device *hwdev = malidp->dev; 455 struct malidp_hw_device *hwdev = malidp->dev;
456 456
457 /* we can only suspend if the hardware is in config mode */ 457 /* we can only suspend if the hardware is in config mode */
458 WARN_ON(!hwdev->in_config_mode(hwdev)); 458 WARN_ON(!hwdev->hw->in_config_mode(hwdev));
459 459
460 hwdev->pm_suspended = true; 460 hwdev->pm_suspended = true;
461 clk_disable_unprepare(hwdev->mclk); 461 clk_disable_unprepare(hwdev->mclk);
@@ -500,11 +500,7 @@ static int malidp_bind(struct device *dev)
500 if (!hwdev) 500 if (!hwdev)
501 return -ENOMEM; 501 return -ENOMEM;
502 502
503 /* 503 hwdev->hw = (struct malidp_hw *)of_device_get_match_data(dev);
504 * copy the associated data from malidp_drm_of_match to avoid
505 * having to keep a reference to the OF node after binding
506 */
507 memcpy(hwdev, of_device_get_match_data(dev), sizeof(*hwdev));
508 malidp->dev = hwdev; 504 malidp->dev = hwdev;
509 505
510 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 506 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -568,13 +564,13 @@ static int malidp_bind(struct device *dev)
568 goto query_hw_fail; 564 goto query_hw_fail;
569 } 565 }
570 566
571 ret = hwdev->query_hw(hwdev); 567 ret = hwdev->hw->query_hw(hwdev);
572 if (ret) { 568 if (ret) {
573 DRM_ERROR("Invalid HW configuration\n"); 569 DRM_ERROR("Invalid HW configuration\n");
574 goto query_hw_fail; 570 goto query_hw_fail;
575 } 571 }
576 572
577 version = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_DE_CORE_ID); 573 version = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_DE_CORE_ID);
578 DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16, 574 DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16,
579 (version >> 12) & 0xf, (version >> 8) & 0xf); 575 (version >> 12) & 0xf, (version >> 8) & 0xf);
580 576
@@ -589,7 +585,7 @@ static int malidp_bind(struct device *dev)
589 585
590 for (i = 0; i < MAX_OUTPUT_CHANNELS; i++) 586 for (i = 0; i < MAX_OUTPUT_CHANNELS; i++)
591 out_depth = (out_depth << 8) | (output_width[i] & 0xf); 587 out_depth = (out_depth << 8) | (output_width[i] & 0xf);
592 malidp_hw_write(hwdev, out_depth, hwdev->map.out_depth_base); 588 malidp_hw_write(hwdev, out_depth, hwdev->hw->map.out_depth_base);
593 589
594 atomic_set(&malidp->config_valid, 0); 590 atomic_set(&malidp->config_valid, 0);
595 init_waitqueue_head(&malidp->wq); 591 init_waitqueue_head(&malidp->wq);
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 17bca99e8ac8..2bfb542135ac 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -183,7 +183,7 @@ static void malidp500_enter_config_mode(struct malidp_hw_device *hwdev)
183 183
184 malidp_hw_setbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL); 184 malidp_hw_setbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL);
185 while (count) { 185 while (count) {
186 status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 186 status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
187 if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ) 187 if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ)
188 break; 188 break;
189 /* 189 /*
@@ -203,7 +203,7 @@ static void malidp500_leave_config_mode(struct malidp_hw_device *hwdev)
203 malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP500_CONFIG_VALID); 203 malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP500_CONFIG_VALID);
204 malidp_hw_clearbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL); 204 malidp_hw_clearbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL);
205 while (count) { 205 while (count) {
206 status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 206 status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
207 if ((status & MALIDP500_DC_CONFIG_REQ) == 0) 207 if ((status & MALIDP500_DC_CONFIG_REQ) == 0)
208 break; 208 break;
209 usleep_range(100, 1000); 209 usleep_range(100, 1000);
@@ -216,7 +216,7 @@ static bool malidp500_in_config_mode(struct malidp_hw_device *hwdev)
216{ 216{
217 u32 status; 217 u32 status;
218 218
219 status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 219 status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
220 if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ) 220 if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ)
221 return true; 221 return true;
222 222
@@ -407,7 +407,7 @@ static void malidp550_enter_config_mode(struct malidp_hw_device *hwdev)
407 407
408 malidp_hw_setbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL); 408 malidp_hw_setbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL);
409 while (count) { 409 while (count) {
410 status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 410 status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
411 if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ) 411 if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ)
412 break; 412 break;
413 /* 413 /*
@@ -427,7 +427,7 @@ static void malidp550_leave_config_mode(struct malidp_hw_device *hwdev)
427 malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP550_CONFIG_VALID); 427 malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP550_CONFIG_VALID);
428 malidp_hw_clearbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL); 428 malidp_hw_clearbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL);
429 while (count) { 429 while (count) {
430 status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 430 status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
431 if ((status & MALIDP550_DC_CONFIG_REQ) == 0) 431 if ((status & MALIDP550_DC_CONFIG_REQ) == 0)
432 break; 432 break;
433 usleep_range(100, 1000); 433 usleep_range(100, 1000);
@@ -440,7 +440,7 @@ static bool malidp550_in_config_mode(struct malidp_hw_device *hwdev)
440{ 440{
441 u32 status; 441 u32 status;
442 442
443 status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 443 status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
444 if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ) 444 if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ)
445 return true; 445 return true;
446 446
@@ -616,7 +616,7 @@ static int malidp650_query_hw(struct malidp_hw_device *hwdev)
616 return 0; 616 return 0;
617} 617}
618 618
619const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { 619const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
620 [MALIDP_500] = { 620 [MALIDP_500] = {
621 .map = { 621 .map = {
622 .coeffs_base = MALIDP500_COEFFS_BASE, 622 .coeffs_base = MALIDP500_COEFFS_BASE,
@@ -751,7 +751,7 @@ static void malidp_hw_clear_irq(struct malidp_hw_device *hwdev, u8 block, u32 ir
751{ 751{
752 u32 base = malidp_get_block_base(hwdev, block); 752 u32 base = malidp_get_block_base(hwdev, block);
753 753
754 if (hwdev->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) 754 if (hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ)
755 malidp_hw_write(hwdev, irq, base + MALIDP_REG_CLEARIRQ); 755 malidp_hw_write(hwdev, irq, base + MALIDP_REG_CLEARIRQ);
756 else 756 else
757 malidp_hw_write(hwdev, irq, base + MALIDP_REG_STATUS); 757 malidp_hw_write(hwdev, irq, base + MALIDP_REG_STATUS);
@@ -762,12 +762,14 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
762 struct drm_device *drm = arg; 762 struct drm_device *drm = arg;
763 struct malidp_drm *malidp = drm->dev_private; 763 struct malidp_drm *malidp = drm->dev_private;
764 struct malidp_hw_device *hwdev; 764 struct malidp_hw_device *hwdev;
765 struct malidp_hw *hw;
765 const struct malidp_irq_map *de; 766 const struct malidp_irq_map *de;
766 u32 status, mask, dc_status; 767 u32 status, mask, dc_status;
767 irqreturn_t ret = IRQ_NONE; 768 irqreturn_t ret = IRQ_NONE;
768 769
769 hwdev = malidp->dev; 770 hwdev = malidp->dev;
770 de = &hwdev->map.de_irq_map; 771 hw = hwdev->hw;
772 de = &hw->map.de_irq_map;
771 773
772 /* 774 /*
773 * if we are suspended it is likely that we were invoked because 775 * if we are suspended it is likely that we were invoked because
@@ -778,8 +780,8 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
778 return IRQ_NONE; 780 return IRQ_NONE;
779 781
780 /* first handle the config valid IRQ */ 782 /* first handle the config valid IRQ */
781 dc_status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 783 dc_status = malidp_hw_read(hwdev, hw->map.dc_base + MALIDP_REG_STATUS);
782 if (dc_status & hwdev->map.dc_irq_map.vsync_irq) { 784 if (dc_status & hw->map.dc_irq_map.vsync_irq) {
783 /* we have a page flip event */ 785 /* we have a page flip event */
784 atomic_set(&malidp->config_valid, 1); 786 atomic_set(&malidp->config_valid, 1);
785 malidp_hw_clear_irq(hwdev, MALIDP_DC_BLOCK, dc_status); 787 malidp_hw_clear_irq(hwdev, MALIDP_DC_BLOCK, dc_status);
@@ -832,11 +834,11 @@ int malidp_de_irq_init(struct drm_device *drm, int irq)
832 834
833 /* first enable the DC block IRQs */ 835 /* first enable the DC block IRQs */
834 malidp_hw_enable_irq(hwdev, MALIDP_DC_BLOCK, 836 malidp_hw_enable_irq(hwdev, MALIDP_DC_BLOCK,
835 hwdev->map.dc_irq_map.irq_mask); 837 hwdev->hw->map.dc_irq_map.irq_mask);
836 838
837 /* now enable the DE block IRQs */ 839 /* now enable the DE block IRQs */
838 malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK, 840 malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK,
839 hwdev->map.de_irq_map.irq_mask); 841 hwdev->hw->map.de_irq_map.irq_mask);
840 842
841 return 0; 843 return 0;
842} 844}
@@ -847,9 +849,9 @@ void malidp_de_irq_fini(struct drm_device *drm)
847 struct malidp_hw_device *hwdev = malidp->dev; 849 struct malidp_hw_device *hwdev = malidp->dev;
848 850
849 malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK, 851 malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK,
850 hwdev->map.de_irq_map.irq_mask); 852 hwdev->hw->map.de_irq_map.irq_mask);
851 malidp_hw_disable_irq(hwdev, MALIDP_DC_BLOCK, 853 malidp_hw_disable_irq(hwdev, MALIDP_DC_BLOCK,
852 hwdev->map.dc_irq_map.irq_mask); 854 hwdev->hw->map.dc_irq_map.irq_mask);
853} 855}
854 856
855static irqreturn_t malidp_se_irq(int irq, void *arg) 857static irqreturn_t malidp_se_irq(int irq, void *arg)
@@ -857,6 +859,8 @@ static irqreturn_t malidp_se_irq(int irq, void *arg)
857 struct drm_device *drm = arg; 859 struct drm_device *drm = arg;
858 struct malidp_drm *malidp = drm->dev_private; 860 struct malidp_drm *malidp = drm->dev_private;
859 struct malidp_hw_device *hwdev = malidp->dev; 861 struct malidp_hw_device *hwdev = malidp->dev;
862 struct malidp_hw *hw = hwdev->hw;
863 const struct malidp_irq_map *se = &hw->map.se_irq_map;
860 u32 status, mask; 864 u32 status, mask;
861 865
862 /* 866 /*
@@ -867,12 +871,12 @@ static irqreturn_t malidp_se_irq(int irq, void *arg)
867 if (hwdev->pm_suspended) 871 if (hwdev->pm_suspended)
868 return IRQ_NONE; 872 return IRQ_NONE;
869 873
870 status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS); 874 status = malidp_hw_read(hwdev, hw->map.se_base + MALIDP_REG_STATUS);
871 if (!(status & hwdev->map.se_irq_map.irq_mask)) 875 if (!(status & se->irq_mask))
872 return IRQ_NONE; 876 return IRQ_NONE;
873 877
874 mask = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_MASKIRQ); 878 mask = malidp_hw_read(hwdev, hw->map.se_base + MALIDP_REG_MASKIRQ);
875 status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS); 879 status = malidp_hw_read(hwdev, hw->map.se_base + MALIDP_REG_STATUS);
876 status &= mask; 880 status &= mask;
877 /* ToDo: status decoding and firing up of VSYNC and page flip events */ 881 /* ToDo: status decoding and firing up of VSYNC and page flip events */
878 882
@@ -905,7 +909,7 @@ int malidp_se_irq_init(struct drm_device *drm, int irq)
905 } 909 }
906 910
907 malidp_hw_enable_irq(hwdev, MALIDP_SE_BLOCK, 911 malidp_hw_enable_irq(hwdev, MALIDP_SE_BLOCK,
908 hwdev->map.se_irq_map.irq_mask); 912 hwdev->hw->map.se_irq_map.irq_mask);
909 913
910 return 0; 914 return 0;
911} 915}
@@ -916,5 +920,5 @@ void malidp_se_irq_fini(struct drm_device *drm)
916 struct malidp_hw_device *hwdev = malidp->dev; 920 struct malidp_hw_device *hwdev = malidp->dev;
917 921
918 malidp_hw_disable_irq(hwdev, MALIDP_SE_BLOCK, 922 malidp_hw_disable_irq(hwdev, MALIDP_SE_BLOCK,
919 hwdev->map.se_irq_map.irq_mask); 923 hwdev->hw->map.se_irq_map.irq_mask);
920} 924}
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index 849ad9a30c3a..b0690ebb3565 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -120,18 +120,14 @@ struct malidp_hw_regmap {
120/* Unlike DP550/650, DP500 has 3 stride registers in its video layer. */ 120/* Unlike DP550/650, DP500 has 3 stride registers in its video layer. */
121#define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0) 121#define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0)
122 122
123struct malidp_hw_device { 123struct malidp_hw_device;
124 const struct malidp_hw_regmap map;
125 void __iomem *regs;
126 124
127 /* APB clock */ 125/*
128 struct clk *pclk; 126 * Static structure containing hardware specific data and pointers to
129 /* AXI clock */ 127 * functions that behave differently between various versions of the IP.
130 struct clk *aclk; 128 */
131 /* main clock for display core */ 129struct malidp_hw {
132 struct clk *mclk; 130 const struct malidp_hw_regmap map;
133 /* pixel clock for display core */
134 struct clk *pxlclk;
135 131
136 /* 132 /*
137 * Validate the driver instance against the hardware bits 133 * Validate the driver instance against the hardware bits
@@ -182,15 +178,6 @@ struct malidp_hw_device {
182 struct videomode *vm); 178 struct videomode *vm);
183 179
184 u8 features; 180 u8 features;
185
186 u8 min_line_size;
187 u16 max_line_size;
188
189 /* track the device PM state */
190 bool pm_suspended;
191
192 /* size of memory used for rotating layers, up to two banks available */
193 u32 rotation_memory[2];
194}; 181};
195 182
196/* Supported variants of the hardware */ 183/* Supported variants of the hardware */
@@ -202,7 +189,33 @@ enum {
202 MALIDP_MAX_DEVICES 189 MALIDP_MAX_DEVICES
203}; 190};
204 191
205extern const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES]; 192extern const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES];
193
194/*
195 * Structure used by the driver during runtime operation.
196 */
197struct malidp_hw_device {
198 struct malidp_hw *hw;
199 void __iomem *regs;
200
201 /* APB clock */
202 struct clk *pclk;
203 /* AXI clock */
204 struct clk *aclk;
205 /* main clock for display core */
206 struct clk *mclk;
207 /* pixel clock for display core */
208 struct clk *pxlclk;
209
210 u8 min_line_size;
211 u16 max_line_size;
212
213 /* track the device PM state */
214 bool pm_suspended;
215
216 /* size of memory used for rotating layers, up to two banks available */
217 u32 rotation_memory[2];
218};
206 219
207static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg) 220static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg)
208{ 221{
@@ -240,9 +253,9 @@ static inline u32 malidp_get_block_base(struct malidp_hw_device *hwdev,
240{ 253{
241 switch (block) { 254 switch (block) {
242 case MALIDP_SE_BLOCK: 255 case MALIDP_SE_BLOCK:
243 return hwdev->map.se_base; 256 return hwdev->hw->map.se_base;
244 case MALIDP_DC_BLOCK: 257 case MALIDP_DC_BLOCK:
245 return hwdev->map.dc_base; 258 return hwdev->hw->map.dc_base;
246 } 259 }
247 260
248 return 0; 261 return 0;
@@ -275,7 +288,7 @@ u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map,
275static inline bool malidp_hw_pitch_valid(struct malidp_hw_device *hwdev, 288static inline bool malidp_hw_pitch_valid(struct malidp_hw_device *hwdev,
276 unsigned int pitch) 289 unsigned int pitch)
277{ 290{
278 return !(pitch & (hwdev->map.bus_align_bytes - 1)); 291 return !(pitch & (hwdev->hw->map.bus_align_bytes - 1));
279} 292}
280 293
281/* U16.16 */ 294/* U16.16 */
@@ -308,8 +321,8 @@ static inline void malidp_se_set_enh_coeffs(struct malidp_hw_device *hwdev)
308 }; 321 };
309 u32 val = MALIDP_SE_SET_ENH_LIMIT_LOW(MALIDP_SE_ENH_LOW_LEVEL) | 322 u32 val = MALIDP_SE_SET_ENH_LIMIT_LOW(MALIDP_SE_ENH_LOW_LEVEL) |
310 MALIDP_SE_SET_ENH_LIMIT_HIGH(MALIDP_SE_ENH_HIGH_LEVEL); 323 MALIDP_SE_SET_ENH_LIMIT_HIGH(MALIDP_SE_ENH_HIGH_LEVEL);
311 u32 image_enh = hwdev->map.se_base + 324 u32 image_enh = hwdev->hw->map.se_base +
312 ((hwdev->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ? 325 ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
313 0x10 : 0xC) + MALIDP_SE_IMAGE_ENH; 326 0x10 : 0xC) + MALIDP_SE_IMAGE_ENH;
314 u32 enh_coeffs = image_enh + MALIDP_SE_ENH_COEFF0; 327 u32 enh_coeffs = image_enh + MALIDP_SE_ENH_COEFF0;
315 int i; 328 int i;
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index f12f8eb126be..e7419797bbd1 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -185,8 +185,9 @@ static int malidp_de_plane_check(struct drm_plane *plane,
185 185
186 fb = state->fb; 186 fb = state->fb;
187 187
188 ms->format = malidp_hw_get_format_id(&mp->hwdev->map, mp->layer->id, 188 ms->format = malidp_hw_get_format_id(&mp->hwdev->hw->map,
189 fb->format->format); 189 mp->layer->id,
190 fb->format->format);
190 if (ms->format == MALIDP_INVALID_FORMAT_ID) 191 if (ms->format == MALIDP_INVALID_FORMAT_ID)
191 return -EINVAL; 192 return -EINVAL;
192 193
@@ -211,7 +212,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
211 * third plane stride register. 212 * third plane stride register.
212 */ 213 */
213 if (ms->n_planes == 3 && 214 if (ms->n_planes == 3 &&
214 !(mp->hwdev->features & MALIDP_DEVICE_LV_HAS_3_STRIDES) && 215 !(mp->hwdev->hw->features & MALIDP_DEVICE_LV_HAS_3_STRIDES) &&
215 (state->fb->pitches[1] != state->fb->pitches[2])) 216 (state->fb->pitches[1] != state->fb->pitches[2]))
216 return -EINVAL; 217 return -EINVAL;
217 218
@@ -229,9 +230,9 @@ static int malidp_de_plane_check(struct drm_plane *plane,
229 if (state->rotation & MALIDP_ROTATED_MASK) { 230 if (state->rotation & MALIDP_ROTATED_MASK) {
230 int val; 231 int val;
231 232
232 val = mp->hwdev->rotmem_required(mp->hwdev, state->crtc_h, 233 val = mp->hwdev->hw->rotmem_required(mp->hwdev, state->crtc_h,
233 state->crtc_w, 234 state->crtc_w,
234 fb->format->format); 235 fb->format->format);
235 if (val < 0) 236 if (val < 0)
236 return val; 237 return val;
237 238
@@ -251,7 +252,7 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
251 return; 252 return;
252 253
253 if (num_planes == 3) 254 if (num_planes == 3)
254 num_strides = (mp->hwdev->features & 255 num_strides = (mp->hwdev->hw->features &
255 MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2; 256 MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
256 257
257 for (i = 0; i < num_strides; ++i) 258 for (i = 0; i < num_strides; ++i)
@@ -264,13 +265,11 @@ static void malidp_de_plane_update(struct drm_plane *plane,
264 struct drm_plane_state *old_state) 265 struct drm_plane_state *old_state)
265{ 266{
266 struct malidp_plane *mp; 267 struct malidp_plane *mp;
267 const struct malidp_hw_regmap *map;
268 struct malidp_plane_state *ms = to_malidp_plane_state(plane->state); 268 struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
269 u32 src_w, src_h, dest_w, dest_h, val; 269 u32 src_w, src_h, dest_w, dest_h, val;
270 int i; 270 int i;
271 271
272 mp = to_malidp_plane(plane); 272 mp = to_malidp_plane(plane);
273 map = &mp->hwdev->map;
274 273
275 /* convert src values from Q16 fixed point to integer */ 274 /* convert src values from Q16 fixed point to integer */
276 src_w = plane->state->src_w >> 16; 275 src_w = plane->state->src_w >> 16;
@@ -363,7 +362,7 @@ static const struct drm_plane_helper_funcs malidp_de_plane_helper_funcs = {
363int malidp_de_planes_init(struct drm_device *drm) 362int malidp_de_planes_init(struct drm_device *drm)
364{ 363{
365 struct malidp_drm *malidp = drm->dev_private; 364 struct malidp_drm *malidp = drm->dev_private;
366 const struct malidp_hw_regmap *map = &malidp->dev->map; 365 const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
367 struct malidp_plane *plane = NULL; 366 struct malidp_plane *plane = NULL;
368 enum drm_plane_type plane_type; 367 enum drm_plane_type plane_type;
369 unsigned long crtcs = 1 << drm->mode_config.num_crtc; 368 unsigned long crtcs = 1 << drm->mode_config.num_crtc;