diff options
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_crtc.c')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_crtc.c | 144 |
1 files changed, 90 insertions, 54 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 0108613e79d5..35a6b5907278 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -50,8 +50,17 @@ #define HVS_FIFO_LATENCY_PIX 6 -#define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset)) -#define CRTC_READ(offset) readl(vc4_crtc->regs + (offset)) +#define CRTC_WRITE(offset, val) \ + do { \ + kunit_fail_current_test("Accessing a register in a unit test!\n"); \ + writel(val, vc4_crtc->regs + (offset)); \ + } while (0) + +#define CRTC_READ(offset) \ + ({ \ + kunit_fail_current_test("Accessing a register in a unit test!\n"); \ + readl(vc4_crtc->regs + (offset)); \ + }) static const struct debugfs_reg32 crtc_regs[] = { VC4_REG32(PV_CONTROL), @@ -486,21 +495,6 @@ static int vc4_crtc_disable(struct drm_crtc *crtc, return 0; } -static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc *crtc, - enum vc4_encoder_type type) -{ - struct drm_encoder *encoder; - - drm_for_each_encoder(encoder, crtc->dev) { - struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); - - if (vc4_encoder->type == type) - return encoder; - } - - return NULL; -} - int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) { struct drm_device *drm = crtc->dev; @@ -536,7 +530,7 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); encoder_type = pv_data->encoder_types[encoder_sel]; - encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type); + encoder = vc4_find_encoder_by_type(drm, encoder_type); if (WARN_ON(!encoder)) return 0; @@ -690,8 +684,8 @@ void vc4_crtc_get_margins(struct drm_crtc_state *state, } } -static int vc4_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_atomic_state *state) +int vc4_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_state *state) { struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); @@ -1096,12 +1090,9 @@ int vc4_crtc_late_register(struct drm_crtc *crtc) struct drm_device *drm = crtc->dev; struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc); - int ret; - ret = vc4_debugfs_add_regset32(drm->primary, crtc_data->debugfs_name, - &vc4_crtc->regset); - if (ret) - return ret; + vc4_debugfs_add_regset32(drm, crtc_data->debugfs_name, + &vc4_crtc->regset); return 0; } @@ -1131,8 +1122,9 @@ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { .get_scanout_position = vc4_crtc_get_scanout_position, }; -static const struct vc4_pv_data bcm2835_pv0_data = { +const struct vc4_pv_data bcm2835_pv0_data = { .base = { + .name = "pixelvalve-0", .debugfs_name = "crtc0_regs", .hvs_available_channels = BIT(0), .hvs_output = 0, @@ -1145,8 +1137,9 @@ static const struct vc4_pv_data bcm2835_pv0_data = { }, }; -static const struct vc4_pv_data bcm2835_pv1_data = { +const struct vc4_pv_data bcm2835_pv1_data = { .base = { + .name = "pixelvalve-1", .debugfs_name = "crtc1_regs", .hvs_available_channels = BIT(2), .hvs_output = 2, @@ -1159,8 +1152,9 @@ static const struct vc4_pv_data bcm2835_pv1_data = { }, }; -static const struct vc4_pv_data bcm2835_pv2_data = { +const struct vc4_pv_data bcm2835_pv2_data = { .base = { + .name = "pixelvalve-2", .debugfs_name = "crtc2_regs", .hvs_available_channels = BIT(1), .hvs_output = 1, @@ -1173,8 +1167,9 @@ static const struct vc4_pv_data bcm2835_pv2_data = { }, }; -static const struct vc4_pv_data bcm2711_pv0_data = { +const struct vc4_pv_data bcm2711_pv0_data = { .base = { + .name = "pixelvalve-0", .debugfs_name = "crtc0_regs", .hvs_available_channels = BIT(0), .hvs_output = 0, @@ -1187,8 +1182,9 @@ static const struct vc4_pv_data bcm2711_pv0_data = { }, }; -static const struct vc4_pv_data bcm2711_pv1_data = { +const struct vc4_pv_data bcm2711_pv1_data = { .base = { + .name = "pixelvalve-1", .debugfs_name = "crtc1_regs", .hvs_available_channels = BIT(0) | BIT(1) | BIT(2), .hvs_output = 3, @@ -1201,8 +1197,9 @@ static const struct vc4_pv_data bcm2711_pv1_data = { }, }; -static const struct vc4_pv_data bcm2711_pv2_data = { +const struct vc4_pv_data bcm2711_pv2_data = { .base = { + .name = "pixelvalve-2", .debugfs_name = "crtc2_regs", .hvs_available_channels = BIT(0) | BIT(1) | BIT(2), .hvs_output = 4, @@ -1214,8 +1211,9 @@ static const struct vc4_pv_data bcm2711_pv2_data = { }, }; -static const struct vc4_pv_data bcm2711_pv3_data = { +const struct vc4_pv_data bcm2711_pv3_data = { .base = { + .name = "pixelvalve-3", .debugfs_name = "crtc3_regs", .hvs_available_channels = BIT(1), .hvs_output = 1, @@ -1227,8 +1225,9 @@ static const struct vc4_pv_data bcm2711_pv3_data = { }, }; -static const struct vc4_pv_data bcm2711_pv4_data = { +const struct vc4_pv_data bcm2711_pv4_data = { .base = { + .name = "pixelvalve-4", .debugfs_name = "crtc4_regs", .hvs_available_channels = BIT(0) | BIT(1) | BIT(2), .hvs_output = 5, @@ -1278,31 +1277,44 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm, } } -int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc, - const struct drm_crtc_funcs *crtc_funcs, - const struct drm_crtc_helper_funcs *crtc_helper_funcs) +/** + * __vc4_crtc_init - Initializes a CRTC + * @drm: DRM Device + * @pdev: CRTC Platform Device + * @vc4_crtc: CRTC Object to Initialize + * @data: Configuration data associated with this CRTC + * @primary_plane: Primary plane for CRTC + * @crtc_funcs: Callbacks for the new CRTC + * @crtc_helper_funcs: Helper Callbacks for the new CRTC + * @feeds_txp: Is this CRTC connected to the TXP? + * + * Initializes our private CRTC structure. This function is mostly + * relevant for KUnit testing, all other users should use + * vc4_crtc_init() instead. + * + * Returns: + * 0 on success, a negative error code on failure. + */ +int __vc4_crtc_init(struct drm_device *drm, + struct platform_device *pdev, + struct vc4_crtc *vc4_crtc, + const struct vc4_crtc_data *data, + struct drm_plane *primary_plane, + const struct drm_crtc_funcs *crtc_funcs, + const struct drm_crtc_helper_funcs *crtc_helper_funcs, + bool feeds_txp) { struct vc4_dev *vc4 = to_vc4_dev(drm); struct drm_crtc *crtc = &vc4_crtc->base; - struct drm_plane *primary_plane; unsigned int i; int ret; - /* For now, we create just the primary and the legacy cursor - * planes. We should be able to stack more planes on easily, - * but to do that we would need to compute the bandwidth - * requirement of the plane configuration, and reject ones - * that will take too much. - */ - primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); - if (IS_ERR(primary_plane)) { - dev_err(drm->dev, "failed to construct primary plane\n"); - return PTR_ERR(primary_plane); - } - + vc4_crtc->data = data; + vc4_crtc->pdev = pdev; + vc4_crtc->feeds_txp = feeds_txp; spin_lock_init(&vc4_crtc->irq_lock); ret = drmm_crtc_init_with_planes(drm, crtc, primary_plane, NULL, - crtc_funcs, NULL); + crtc_funcs, data->name); if (ret) return ret; @@ -1328,6 +1340,31 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc, return 0; } +int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev, + struct vc4_crtc *vc4_crtc, + const struct vc4_crtc_data *data, + const struct drm_crtc_funcs *crtc_funcs, + const struct drm_crtc_helper_funcs *crtc_helper_funcs, + bool feeds_txp) +{ + struct drm_plane *primary_plane; + + /* For now, we create just the primary and the legacy cursor + * planes. We should be able to stack more planes on easily, + * but to do that we would need to compute the bandwidth + * requirement of the plane configuration, and reject ones + * that will take too much. + */ + primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); + if (IS_ERR(primary_plane)) { + dev_err(drm->dev, "failed to construct primary plane\n"); + return PTR_ERR(primary_plane); + } + + return __vc4_crtc_init(drm, pdev, vc4_crtc, data, primary_plane, + crtc_funcs, crtc_helper_funcs, feeds_txp); +} + static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); @@ -1345,8 +1382,6 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) pv_data = of_device_get_match_data(dev); if (!pv_data) return -ENODEV; - vc4_crtc->data = &pv_data->base; - vc4_crtc->pdev = pdev; vc4_crtc->regs = vc4_ioremap_regs(pdev, 0); if (IS_ERR(vc4_crtc->regs)) @@ -1356,8 +1391,9 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) vc4_crtc->regset.regs = crtc_regs; vc4_crtc->regset.nregs = ARRAY_SIZE(crtc_regs); - ret = vc4_crtc_init(drm, vc4_crtc, - &vc4_crtc_funcs, &vc4_crtc_helper_funcs); + ret = vc4_crtc_init(drm, pdev, vc4_crtc, &pv_data->base, + &vc4_crtc_funcs, &vc4_crtc_helper_funcs, + false); if (ret) return ret; vc4_set_crtc_possible_masks(drm, crtc); |