Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion arch/arm/boot/dts/bcm2708_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,6 @@
reg = <0x7e902000 0x600>,
<0x7e808000 0x100>;
ddc = <&i2c2>;
hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
clocks = <&cprman BCM2835_PLLH_PIX>,
<&cprman BCM2835_CLOCK_HSM>;
clock-names = "pixel", "hdmi";
Expand All @@ -366,6 +365,7 @@
v3d: v3d@7ec00000 {
compatible = "brcm,vc4-v3d";
reg = <0x7ec00000 0x1000>;
power-domains = <&power RPI_POWER_DOMAIN_V3D>;
status = "disabled";
};

Expand Down
4 changes: 0 additions & 4 deletions arch/arm/boot/dts/bcm2710-rpi-3-b.dts
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,6 @@
};
};

&hdmi {
hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
};

&audio {
pinctrl-names = "default";
pinctrl-0 = <&audio_pins>;
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ struct regdump {
static int rpi_touchscreen_disable(struct drm_panel *panel)
{
struct rpi_touchscreen *ts = panel_to_ts(panel);
pr_err("disable\n");

if (!ts->enabled)
return 0;
Expand Down
55 changes: 45 additions & 10 deletions drivers/gpu/drm/vc4/vc4_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <soc/bcm2835/raspberrypi-firmware.h>
#include <linux/pm_runtime.h>
#include "drm_fb_cma_helper.h"

#include "uapi/drm/vc4_drm.h"
Expand Down Expand Up @@ -65,6 +65,49 @@ void vc4_dump_regs32(const struct debugfs_reg32 *regs, unsigned int num_regs,
}
}

static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_vc4_get_param *args = data;
int ret;

if (args->pad != 0)
return -EINVAL;

switch (args->param) {
case DRM_VC4_PARAM_V3D_IDENT0:
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
if (ret < 0)
return ret;
args->value = V3D_READ(V3D_IDENT0);
pm_runtime_put(&vc4->v3d->pdev->dev);
break;
case DRM_VC4_PARAM_V3D_IDENT1:
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
if (ret < 0)
return ret;
args->value = V3D_READ(V3D_IDENT1);
pm_runtime_put(&vc4->v3d->pdev->dev);
break;
case DRM_VC4_PARAM_V3D_IDENT2:
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
if (ret < 0)
return ret;
args->value = V3D_READ(V3D_IDENT2);
pm_runtime_put(&vc4->v3d->pdev->dev);
break;
case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
args->value = true;
break;
default:
DRM_DEBUG("Unknown parameter %d\n", args->param);
return -EINVAL;
}

return 0;
}

static void vc4_lastclose(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
Expand Down Expand Up @@ -96,6 +139,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
DRM_ROOT_ONLY),
DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW),
};

static struct drm_driver vc4_drm_driver = {
Expand Down Expand Up @@ -204,7 +248,6 @@ static int vc4_drm_bind(struct device *dev)
struct drm_device *drm;
struct drm_connector *connector;
struct vc4_dev *vc4;
struct device_node *firmware_node;
int ret = 0;

dev->coherent_dma_mask = DMA_BIT_MASK(32);
Expand All @@ -213,14 +256,6 @@ static int vc4_drm_bind(struct device *dev)
if (!vc4)
return -ENOMEM;

firmware_node = of_parse_phandle(dev->of_node, "firmware", 0);
vc4->firmware = rpi_firmware_get(firmware_node);
if (!vc4->firmware) {
DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n");
return -EPROBE_DEFER;
}
of_node_put(firmware_node);

drm = drm_dev_alloc(&vc4_drm_driver, dev);
if (!drm)
return -ENOMEM;
Expand Down
20 changes: 18 additions & 2 deletions drivers/gpu/drm/vc4/vc4_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ struct vc4_dev {
struct vc4_dsi *dsi1;

struct drm_fbdev_cma *fbdev;
struct rpi_firmware *firmware;

struct vc4_hang_state *hang_state;

Expand Down Expand Up @@ -105,6 +104,11 @@ struct vc4_dev {
struct vc4_bo *overflow_mem;
struct work_struct overflow_mem_work;

int power_refcount;

/* Mutex controlling the power refcount. */
struct mutex power_lock;

struct {
struct timer_list timer;
struct work_struct reset_work;
Expand Down Expand Up @@ -155,6 +159,7 @@ struct vc4_seqno_cb {
};

struct vc4_v3d {
struct vc4_dev *vc4;
struct platform_device *pdev;
void __iomem *regs;
};
Expand Down Expand Up @@ -324,6 +329,15 @@ vc4_first_render_job(struct vc4_dev *vc4)
struct vc4_exec_info, head);
}

static inline struct vc4_exec_info *
vc4_last_render_job(struct vc4_dev *vc4)
{
if (list_empty(&vc4->render_job_list))
return NULL;
return list_last_entry(&vc4->render_job_list,
struct vc4_exec_info, head);
}

/**
* struct vc4_texture_sample_info - saves the offsets into the UBO for texture
* setup parameters.
Expand Down Expand Up @@ -358,6 +372,9 @@ struct vc4_validated_shader_info {
uint32_t uniforms_src_size;
uint32_t num_texture_samples;
struct vc4_texture_sample_info *texture_samples;

uint32_t num_uniform_addr_offsets;
uint32_t *uniform_addr_offsets;
};

/**
Expand Down Expand Up @@ -495,7 +512,6 @@ void vc4_plane_async_set_fb(struct drm_plane *plane,
extern struct platform_driver vc4_v3d_driver;
int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused);
int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused);
int vc4_v3d_set_power(struct vc4_dev *vc4, bool on);

/* vc4_validate.c */
int
Expand Down
40 changes: 31 additions & 9 deletions drivers/gpu/drm/vc4/vc4_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/device.h>
#include <linux/io.h>

Expand Down Expand Up @@ -260,8 +261,16 @@ vc4_reset(struct drm_device *dev)
struct vc4_dev *vc4 = to_vc4_dev(dev);

DRM_INFO("Resetting GPU.\n");
vc4_v3d_set_power(vc4, false);
vc4_v3d_set_power(vc4, true);

mutex_lock(&vc4->power_lock);
if (vc4->power_refcount) {
/* Power the device off and back on the by dropping the
* reference on runtime PM.
*/
pm_runtime_put_sync_suspend(&vc4->v3d->pdev->dev);
pm_runtime_get_sync(&vc4->v3d->pdev->dev);
}
mutex_unlock(&vc4->power_lock);

vc4_irq_reset(dev);

Expand Down Expand Up @@ -426,10 +435,6 @@ vc4_submit_next_bin_job(struct drm_device *dev)

vc4_flush_caches(dev);

/* Disable the binner's pre-loaded overflow memory address */
V3D_WRITE(V3D_BPOA, 0);
V3D_WRITE(V3D_BPOS, 0);

/* Either put the job in the binner if it uses the binner, or
* immediately move it to the to-be-rendered queue.
*/
Expand Down Expand Up @@ -579,8 +584,8 @@ vc4_cl_lookup_bos(struct drm_device *dev,
spin_unlock(&file_priv->table_lock);

fail:
kfree(handles);
return 0;
drm_free_large(handles);
return ret;
}

static int
Expand Down Expand Up @@ -689,6 +694,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
static void
vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
unsigned i;

/* Need the struct lock for drm_gem_object_unreference(). */
Expand All @@ -707,6 +713,11 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
}
mutex_unlock(&dev->struct_mutex);

mutex_lock(&vc4->power_lock);
if (--vc4->power_refcount == 0)
pm_runtime_put(&vc4->v3d->pdev->dev);
mutex_unlock(&vc4->power_lock);

kfree(exec);
}

Expand Down Expand Up @@ -847,7 +858,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_vc4_submit_cl *args = data;
struct vc4_exec_info *exec;
int ret;
int ret = 0;

if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) {
DRM_ERROR("Unknown flags: 0x%02x\n", args->flags);
Expand All @@ -860,6 +871,15 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
return -ENOMEM;
}

mutex_lock(&vc4->power_lock);
if (vc4->power_refcount++ == 0)
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
mutex_unlock(&vc4->power_lock);
if (ret < 0) {
kfree(exec);
return ret;
}

exec->args = args;
INIT_LIST_HEAD(&exec->unref_list);

Expand Down Expand Up @@ -915,6 +935,8 @@ vc4_gem_init(struct drm_device *dev)
(unsigned long)dev);

INIT_WORK(&vc4->job_done_work, vc4_job_done_work);

mutex_init(&vc4->power_lock);
}

void
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/vc4/vc4_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,6 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
struct drm_device *dev = connector->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);

return connector_status_connected;

if (vc4->hdmi->hpd_gpio) {
if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
vc4->hdmi->hpd_active_low)
Expand All @@ -176,6 +174,9 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
return connector_status_disconnected;
}

if (drm_probe_ddc(vc4->hdmi->ddc))
return connector_status_connected;

if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
return connector_status_connected;
else
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/vc4/vc4_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ vc4_overflow_mem_work(struct work_struct *work)

spin_lock_irqsave(&vc4->job_lock, irqflags);
current_exec = vc4_first_bin_job(vc4);
if (!current_exec)
current_exec = vc4_last_render_job(vc4);
if (current_exec) {
vc4->overflow_mem->seqno = vc4->finished_seqno + 1;
vc4->overflow_mem->seqno = current_exec->seqno;
list_add_tail(&vc4->overflow_mem->unref_head,
&current_exec->unref_list);
vc4->overflow_mem = NULL;
Expand Down
15 changes: 15 additions & 0 deletions drivers/gpu/drm/vc4/vc4_qpu_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ enum qpu_unpack_r4 {
#define QPU_COND_MUL_SHIFT 46
#define QPU_COND_MUL_MASK QPU_MASK(48, 46)

#define QPU_BRANCH_COND_SHIFT 52
#define QPU_BRANCH_COND_MASK QPU_MASK(55, 52)

#define QPU_BRANCH_REL ((uint64_t)1 << 51)
#define QPU_BRANCH_REG ((uint64_t)1 << 50)

#define QPU_BRANCH_RADDR_A_SHIFT 45
#define QPU_BRANCH_RADDR_A_MASK QPU_MASK(49, 45)

#define QPU_SF ((uint64_t)1 << 45)

#define QPU_WADDR_ADD_SHIFT 38
Expand Down Expand Up @@ -261,4 +270,10 @@ enum qpu_unpack_r4 {
#define QPU_OP_ADD_SHIFT 24
#define QPU_OP_ADD_MASK QPU_MASK(28, 24)

#define QPU_LOAD_IMM_SHIFT 0
#define QPU_LOAD_IMM_MASK QPU_MASK(31, 0)

#define QPU_BRANCH_TARGET_SHIFT 0
#define QPU_BRANCH_TARGET_MASK QPU_MASK(31, 0)

#endif /* VC4_QPU_DEFINES_H */
Loading