mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-01-30 06:42:18 +00:00
Update vc4_txp.c
Fix the core dump error for GUI under qortal's mempow crunch.
This commit is contained in:
parent
049dcd6ace
commit
5d221765c0
@ -1,10 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright © 2018 Broadcom
|
||||
*
|
||||
* Copyright (C) 2018 Broadcom
|
||||
* Copyright (C) 2022 Qortal Project
|
||||
* Authors:
|
||||
* Eric Anholt <eric@anholt.net>
|
||||
* Boris Brezillon <boris.brezillon@bootlin.com>
|
||||
* Scare Crowe <dmax@crowetic.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
@ -15,6 +16,7 @@
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_fb_cma_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
@ -154,7 +156,6 @@ struct vc4_txp {
|
||||
struct drm_writeback_connector connector;
|
||||
|
||||
void __iomem *regs;
|
||||
struct debugfs_regset32 regset;
|
||||
};
|
||||
|
||||
static inline struct vc4_txp *encoder_to_vc4_txp(struct drm_encoder *encoder)
|
||||
@ -275,6 +276,7 @@ static int vc4_txp_connector_atomic_check(struct drm_connector *conn,
|
||||
static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_device *drm = conn->dev;
|
||||
struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(state,
|
||||
conn);
|
||||
struct vc4_txp *txp = connector_to_vc4_txp(conn);
|
||||
@ -282,6 +284,7 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
|
||||
struct drm_display_mode *mode;
|
||||
struct drm_framebuffer *fb;
|
||||
u32 ctrl;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (WARN_ON(!conn_state->writeback_job))
|
||||
@ -305,8 +308,15 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
|
||||
if (fb->format->has_alpha)
|
||||
ctrl |= TXP_ALPHA_ENABLE;
|
||||
else
|
||||
/*
|
||||
* If TXP_ALPHA_ENABLE isn't set and TXP_ALPHA_INVERT is, the
|
||||
* hardware will force the output padding to be 0xff.
|
||||
*/
|
||||
ctrl |= TXP_ALPHA_INVERT;
|
||||
|
||||
if (!drm_dev_enter(drm, &idx))
|
||||
return;
|
||||
|
||||
gem = drm_fb_cma_get_gem_obj(fb, 0);
|
||||
TXP_WRITE(TXP_DST_PTR, gem->paddr + fb->offsets[0]);
|
||||
TXP_WRITE(TXP_DST_PITCH, fb->pitches[0]);
|
||||
@ -317,6 +327,8 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
|
||||
TXP_WRITE(TXP_DST_CTRL, ctrl);
|
||||
|
||||
drm_writeback_queue_job(&txp->connector, conn_state);
|
||||
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs vc4_txp_connector_helper_funcs = {
|
||||
@ -332,16 +344,10 @@ vc4_txp_connector_detect(struct drm_connector *connector, bool force)
|
||||
return connector_status_connected;
|
||||
}
|
||||
|
||||
static void vc4_txp_connector_destroy(struct drm_connector *connector)
|
||||
{
|
||||
drm_connector_unregister(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs vc4_txp_connector_funcs = {
|
||||
.detect = vc4_txp_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = vc4_txp_connector_destroy,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
@ -349,7 +355,12 @@ static const struct drm_connector_funcs vc4_txp_connector_funcs = {
|
||||
|
||||
static void vc4_txp_encoder_disable(struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_device *drm = encoder->dev;
|
||||
struct vc4_txp *txp = encoder_to_vc4_txp(encoder);
|
||||
int idx;
|
||||
|
||||
if (!drm_dev_enter(drm, &idx))
|
||||
return;
|
||||
|
||||
if (TXP_READ(TXP_DST_CTRL) & TXP_BUSY) {
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
|
||||
@ -364,6 +375,8 @@ static void vc4_txp_encoder_disable(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
TXP_WRITE(TXP_DST_CTRL, TXP_POWERDOWN);
|
||||
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs vc4_txp_encoder_helper_funcs = {
|
||||
@ -379,13 +392,13 @@ static void vc4_txp_disable_vblank(struct drm_crtc *crtc) {}
|
||||
|
||||
static const struct drm_crtc_funcs vc4_txp_crtc_funcs = {
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.destroy = vc4_crtc_destroy,
|
||||
.page_flip = vc4_page_flip,
|
||||
.reset = vc4_crtc_reset,
|
||||
.atomic_duplicate_state = vc4_crtc_duplicate_state,
|
||||
.atomic_destroy_state = vc4_crtc_destroy_state,
|
||||
.enable_vblank = vc4_txp_enable_vblank,
|
||||
.disable_vblank = vc4_txp_disable_vblank,
|
||||
.late_register = vc4_crtc_late_register,
|
||||
};
|
||||
|
||||
static int vc4_txp_atomic_check(struct drm_crtc *crtc,
|
||||
@ -448,6 +461,16 @@ static irqreturn_t vc4_txp_interrupt(int irq, void *data)
|
||||
struct vc4_txp *txp = data;
|
||||
struct vc4_crtc *vc4_crtc = &txp->base;
|
||||
|
||||
/*
|
||||
* We don't need to protect the register access using
|
||||
* drm_dev_enter() there because the interrupt handler lifetime
|
||||
* is tied to the device itself, and not to the DRM device.
|
||||
*
|
||||
* So when the device will be gone, one of the first thing we
|
||||
* will be doing will be to unregister the interrupt handler,
|
||||
* and then unregister the DRM device. drm_dev_enter() would
|
||||
* thus always succeed if we are here.
|
||||
*/
|
||||
TXP_WRITE(TXP_DST_CTRL, TXP_READ(TXP_DST_CTRL) & ~TXP_EI);
|
||||
vc4_crtc_handle_vblank(vc4_crtc);
|
||||
drm_writeback_signal_completion(&txp->connector, 0);
|
||||
@ -456,6 +479,7 @@ static irqreturn_t vc4_txp_interrupt(int irq, void *data)
|
||||
}
|
||||
|
||||
static const struct vc4_crtc_data vc4_txp_crtc_data = {
|
||||
.debugfs_name = "txp_regs",
|
||||
.hvs_available_channels = BIT(2),
|
||||
.hvs_output = 2,
|
||||
};
|
||||
@ -464,7 +488,6 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct drm_device *drm = dev_get_drvdata(master);
|
||||
struct vc4_dev *vc4 = to_vc4_dev(drm);
|
||||
struct vc4_crtc *vc4_crtc;
|
||||
struct vc4_txp *txp;
|
||||
struct drm_crtc *crtc;
|
||||
@ -475,7 +498,7 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
txp = devm_kzalloc(dev, sizeof(*txp), GFP_KERNEL);
|
||||
txp = drmm_kzalloc(drm, sizeof(*txp), GFP_KERNEL);
|
||||
if (!txp)
|
||||
return -ENOMEM;
|
||||
vc4_crtc = &txp->base;
|
||||
@ -490,9 +513,9 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
|
||||
txp->regs = vc4_ioremap_regs(pdev, 0);
|
||||
if (IS_ERR(txp->regs))
|
||||
return PTR_ERR(txp->regs);
|
||||
txp->regset.base = txp->regs;
|
||||
txp->regset.regs = txp_regs;
|
||||
txp->regset.nregs = ARRAY_SIZE(txp_regs);
|
||||
vc4_crtc->regset.base = txp->regs;
|
||||
vc4_crtc->regset.regs = txp_regs;
|
||||
vc4_crtc->regset.nregs = ARRAY_SIZE(txp_regs);
|
||||
|
||||
drm_connector_helper_add(&txp->connector.base,
|
||||
&vc4_txp_connector_helper_funcs);
|
||||
@ -517,9 +540,6 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
|
||||
return ret;
|
||||
|
||||
dev_set_drvdata(dev, txp);
|
||||
vc4->txp = txp;
|
||||
|
||||
vc4_debugfs_add_regset32(drm, "txp_regs", &txp->regset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -527,13 +547,9 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
|
||||
static void vc4_txp_unbind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(master);
|
||||
struct vc4_dev *vc4 = to_vc4_dev(drm);
|
||||
struct vc4_txp *txp = dev_get_drvdata(dev);
|
||||
|
||||
vc4_txp_connector_destroy(&txp->connector.base);
|
||||
|
||||
vc4->txp = NULL;
|
||||
drm_connector_cleanup(&txp->connector.base);
|
||||
}
|
||||
|
||||
static const struct component_ops vc4_txp_ops = {
|
||||
|
Loading…
Reference in New Issue
Block a user