Commit 1f913730 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2024-04-05' of...

Merge tag 'drm-misc-next-2024-04-05' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for v6.10:

Core Changes:
- Fix DRM_DISPLAY_DP_HELPER dependencies.

Driver Changes:
- i2c and polling fixes to ast.
- Small fixes to panthor.
- Allow IRQ to share GPIO pins in bridge/adv7511.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/2ad89d5a-4096-4cc5-badb-4ad61ff1df7d@linux.intel.com
parents fee54d08 d1ef8fc1
......@@ -7,4 +7,4 @@ Description:
Valid values are:
0: Don't enable fdinfo job profiling sources.
1: Enable fdinfo job profiling sources, this enables both the GPU's
timestamp and cycle counter registers.
\ No newline at end of file
timestamp and cycle counter registers.
......@@ -22,6 +22,8 @@ properties:
enum:
# Anberic RG353V-V2 5.0" 640x480 TFT LCD panel
- anbernic,rg353v-panel-v2
# GameForce Chi 3.5" 640x480 TFT LCD panel
- gameforce,chi-panel
# Powkiddy RGB10MAX3 5.0" 720x1280 TFT LCD panel
- powkiddy,rgb10max3-panel
# Powkiddy RGB30 3.0" 720x720 TFT LCD panel
......
......@@ -531,6 +531,8 @@ patternProperties:
description: FX Technology Ltd.
"^galaxycore,.*":
description: GalaxyCore Inc.
"^gameforce,.*":
description: GameForce
"^gardena,.*":
description: GARDENA GmbH
"^gateway,.*":
......
......@@ -3,6 +3,14 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ast-y := ast_drv.o ast_i2c.o ast_main.o ast_mm.o ast_mode.o ast_post.o ast_dp501.o ast_dp.o
ast-y := \
ast_ddc.o \
ast_dp501.o \
ast_dp.o \
ast_drv.o \
ast_main.o \
ast_mm.o \
ast_mode.o \
ast_post.o
obj-$(CONFIG_DRM_AST) := ast.o
......@@ -24,17 +24,18 @@
#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include "ast_ddc.h"
#include "ast_drv.h"
static void ast_i2c_setsda(void *i2c_priv, int data)
static void ast_ddc_algo_bit_data_setsda(void *data, int state)
{
struct ast_i2c_chan *i2c = i2c_priv;
struct ast_device *ast = to_ast_device(i2c->dev);
struct ast_ddc *ddc = data;
struct ast_device *ast = ddc->ast;
int i;
u8 ujcrb7, jtemp;
for (i = 0; i < 0x10000; i++) {
ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
ujcrb7 = ((state & 0x01) ? 0 : 1) << 2;
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf1, ujcrb7);
jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x04);
if (ujcrb7 == jtemp)
......@@ -42,15 +43,15 @@ static void ast_i2c_setsda(void *i2c_priv, int data)
}
}
static void ast_i2c_setscl(void *i2c_priv, int clock)
static void ast_ddc_algo_bit_data_setscl(void *data, int state)
{
struct ast_i2c_chan *i2c = i2c_priv;
struct ast_device *ast = to_ast_device(i2c->dev);
struct ast_ddc *ddc = data;
struct ast_device *ast = ddc->ast;
int i;
u8 ujcrb7, jtemp;
for (i = 0; i < 0x10000; i++) {
ujcrb7 = ((clock & 0x01) ? 0 : 1);
ujcrb7 = ((state & 0x01) ? 0 : 1);
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf4, ujcrb7);
jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x01);
if (ujcrb7 == jtemp)
......@@ -58,10 +59,32 @@ static void ast_i2c_setscl(void *i2c_priv, int clock)
}
}
static int ast_i2c_getsda(void *i2c_priv)
static int ast_ddc_algo_bit_data_pre_xfer(struct i2c_adapter *adapter)
{
struct ast_i2c_chan *i2c = i2c_priv;
struct ast_device *ast = to_ast_device(i2c->dev);
struct ast_ddc *ddc = i2c_get_adapdata(adapter);
struct ast_device *ast = ddc->ast;
/*
* Protect access to I/O registers from concurrent modesetting
* by acquiring the I/O-register lock.
*/
mutex_lock(&ast->modeset_lock);
return 0;
}
static void ast_ddc_algo_bit_data_post_xfer(struct i2c_adapter *adapter)
{
struct ast_ddc *ddc = i2c_get_adapdata(adapter);
struct ast_device *ast = ddc->ast;
mutex_unlock(&ast->modeset_lock);
}
static int ast_ddc_algo_bit_data_getsda(void *data)
{
struct ast_ddc *ddc = data;
struct ast_device *ast = ddc->ast;
uint32_t val, val2, count, pass;
count = 0;
......@@ -80,10 +103,10 @@ static int ast_i2c_getsda(void *i2c_priv)
return val & 1 ? 1 : 0;
}
static int ast_i2c_getscl(void *i2c_priv)
static int ast_ddc_algo_bit_data_getscl(void *data)
{
struct ast_i2c_chan *i2c = i2c_priv;
struct ast_device *ast = to_ast_device(i2c->dev);
struct ast_ddc *ddc = data;
struct ast_device *ast = ddc->ast;
uint32_t val, val2, count, pass;
count = 0;
......@@ -102,50 +125,53 @@ static int ast_i2c_getscl(void *i2c_priv)
return val & 1 ? 1 : 0;
}
static void ast_i2c_release(struct drm_device *dev, void *res)
static void ast_ddc_release(struct drm_device *dev, void *res)
{
struct ast_i2c_chan *i2c = res;
struct ast_ddc *ddc = res;
i2c_del_adapter(&i2c->adapter);
kfree(i2c);
i2c_del_adapter(&ddc->adapter);
}
struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
struct ast_ddc *ast_ddc_create(struct ast_device *ast)
{
struct ast_i2c_chan *i2c;
struct drm_device *dev = &ast->base;
struct ast_ddc *ddc;
struct i2c_adapter *adapter;
struct i2c_algo_bit_data *bit;
int ret;
i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL);
if (!i2c)
return NULL;
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.dev.parent = dev->dev;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"AST i2c bit bus");
i2c->adapter.algo_data = &i2c->bit;
i2c->bit.udelay = 20;
i2c->bit.timeout = 2;
i2c->bit.data = i2c;
i2c->bit.setsda = ast_i2c_setsda;
i2c->bit.setscl = ast_i2c_setscl;
i2c->bit.getsda = ast_i2c_getsda;
i2c->bit.getscl = ast_i2c_getscl;
ret = i2c_bit_add_bus(&i2c->adapter);
ddc = drmm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL);
if (!ddc)
return ERR_PTR(-ENOMEM);
ddc->ast = ast;
adapter = &ddc->adapter;
adapter->owner = THIS_MODULE;
adapter->dev.parent = dev->dev;
i2c_set_adapdata(adapter, ddc);
snprintf(adapter->name, sizeof(adapter->name), "AST DDC bus");
bit = &ddc->bit;
bit->udelay = 20;
bit->timeout = 2;
bit->data = ddc;
bit->setsda = ast_ddc_algo_bit_data_setsda;
bit->setscl = ast_ddc_algo_bit_data_setscl;
bit->getsda = ast_ddc_algo_bit_data_getsda;
bit->getscl = ast_ddc_algo_bit_data_getscl;
bit->pre_xfer = ast_ddc_algo_bit_data_pre_xfer;
bit->post_xfer = ast_ddc_algo_bit_data_post_xfer;
adapter->algo_data = bit;
ret = i2c_bit_add_bus(adapter);
if (ret) {
drm_err(dev, "Failed to register bit i2c\n");
goto out_kfree;
return ERR_PTR(ret);
}
ret = drmm_add_action_or_reset(dev, ast_i2c_release, i2c);
ret = drmm_add_action_or_reset(dev, ast_ddc_release, ddc);
if (ret)
return NULL;
return i2c;
return ERR_PTR(ret);
out_kfree:
kfree(i2c);
return NULL;
return ddc;
}
/* SPDX-License-Identifier: MIT */
#ifndef __AST_DDC_H__
#define __AST_DDC_H__
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
struct ast_device;
struct ast_ddc {
struct ast_device *ast;
struct i2c_adapter adapter;
struct i2c_algo_bit_data bit;
};
struct ast_ddc *ast_ddc_create(struct ast_device *ast);
#endif
......@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pci.h>
#include <drm/drm_aperture.h>
......
......@@ -28,8 +28,6 @@
#ifndef __AST_DRV_H__
#define __AST_DRV_H__
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/io.h>
#include <linux/types.h>
......@@ -149,37 +147,9 @@ static inline struct ast_plane *to_ast_plane(struct drm_plane *plane)
}
/*
* Connector with i2c channel
* BMC
*/
struct ast_i2c_chan {
struct i2c_adapter adapter;
struct drm_device *dev;
struct i2c_algo_bit_data bit;
};
struct ast_vga_connector {
struct drm_connector base;
struct ast_i2c_chan *i2c;
};
static inline struct ast_vga_connector *
to_ast_vga_connector(struct drm_connector *connector)
{
return container_of(connector, struct ast_vga_connector, base);
}
struct ast_sil164_connector {
struct drm_connector base;
struct ast_i2c_chan *i2c;
};
static inline struct ast_sil164_connector *
to_ast_sil164_connector(struct drm_connector *connector)
{
return container_of(connector, struct ast_sil164_connector, base);
}
struct ast_bmc_connector {
struct drm_connector base;
struct drm_connector *physical_connector;
......@@ -222,11 +192,11 @@ struct ast_device {
struct {
struct {
struct drm_encoder encoder;
struct ast_vga_connector vga_connector;
struct drm_connector connector;
} vga;
struct {
struct drm_encoder encoder;
struct ast_sil164_connector sil164_connector;
struct drm_connector connector;
} sil164;
struct {
struct drm_encoder encoder;
......@@ -498,9 +468,6 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
u8 ast_get_dp501_max_clk(struct drm_device *dev);
void ast_init_3rdtx(struct drm_device *dev);
/* ast_i2c.c */
struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
/* aspeed DP */
bool ast_astdp_is_connected(struct ast_device *ast);
int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata);
......
......@@ -26,6 +26,7 @@
* Authors: Dave Airlie <airlied@redhat.com>
*/
#include <linux/of.h>
#include <linux/pci.h>
#include <drm/drm_atomic_helper.h>
......
......@@ -46,6 +46,7 @@
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include "ast_ddc.h"
#include "ast_drv.h"
#include "ast_tables.h"
......@@ -1343,43 +1344,9 @@ static int ast_crtc_init(struct drm_device *dev)
* VGA Connector
*/
static int ast_vga_connector_helper_get_modes(struct drm_connector *connector)
{
struct ast_vga_connector *ast_vga_connector = to_ast_vga_connector(connector);
struct drm_device *dev = connector->dev;
struct ast_device *ast = to_ast_device(dev);
struct edid *edid;
int count;
if (!ast_vga_connector->i2c)
goto err_drm_connector_update_edid_property;
/*
* Protect access to I/O registers from concurrent modesetting
* by acquiring the I/O-register lock.
*/
mutex_lock(&ast->modeset_lock);
edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter);
if (!edid)
goto err_mutex_unlock;
mutex_unlock(&ast->modeset_lock);
count = drm_add_edid_modes(connector, edid);
kfree(edid);
return count;
err_mutex_unlock:
mutex_unlock(&ast->modeset_lock);
err_drm_connector_update_edid_property:
drm_connector_update_edid_property(connector, NULL);
return 0;
}
static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = {
.get_modes = ast_vga_connector_helper_get_modes,
.get_modes = drm_connector_helper_get_modes,
.detect_ctx = drm_connector_helper_detect_from_ddc,
};
static const struct drm_connector_funcs ast_vga_connector_funcs = {
......@@ -1390,23 +1357,21 @@ static const struct drm_connector_funcs ast_vga_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static int ast_vga_connector_init(struct drm_device *dev,
struct ast_vga_connector *ast_vga_connector)
static int ast_vga_connector_init(struct drm_device *dev, struct drm_connector *connector)
{
struct drm_connector *connector = &ast_vga_connector->base;
struct ast_device *ast = to_ast_device(dev);
struct ast_ddc *ddc;
int ret;
ast_vga_connector->i2c = ast_i2c_create(dev);
if (!ast_vga_connector->i2c)
drm_err(dev, "failed to add ddc bus for connector\n");
ddc = ast_ddc_create(ast);
if (IS_ERR(ddc)) {
ret = PTR_ERR(ddc);
drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret);
return ret;
}
if (ast_vga_connector->i2c)
ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs,
DRM_MODE_CONNECTOR_VGA,
&ast_vga_connector->i2c->adapter);
else
ret = drm_connector_init(dev, connector, &ast_vga_connector_funcs,
DRM_MODE_CONNECTOR_VGA);
ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs,
DRM_MODE_CONNECTOR_VGA, &ddc->adapter);
if (ret)
return ret;
......@@ -1415,7 +1380,7 @@ static int ast_vga_connector_init(struct drm_device *dev,
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
return 0;
}
......@@ -1425,8 +1390,7 @@ static int ast_vga_output_init(struct ast_device *ast)
struct drm_device *dev = &ast->base;
struct drm_crtc *crtc = &ast->crtc;
struct drm_encoder *encoder = &ast->output.vga.encoder;
struct ast_vga_connector *ast_vga_connector = &ast->output.vga.vga_connector;
struct drm_connector *connector = &ast_vga_connector->base;
struct drm_connector *connector = &ast->output.vga.connector;
int ret;
ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
......@@ -1434,7 +1398,7 @@ static int ast_vga_output_init(struct ast_device *ast)
return ret;
encoder->possible_crtcs = drm_crtc_mask(crtc);
ret = ast_vga_connector_init(dev, ast_vga_connector);
ret = ast_vga_connector_init(dev, connector);
if (ret)
return ret;
......@@ -1449,43 +1413,9 @@ static int ast_vga_output_init(struct ast_device *ast)
* SIL164 Connector
*/
static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector)
{
struct ast_sil164_connector *ast_sil164_connector = to_ast_sil164_connector(connector);
struct drm_device *dev = connector->dev;
struct ast_device *ast = to_ast_device(dev);
struct edid *edid;
int count;
if (!ast_sil164_connector->i2c)
goto err_drm_connector_update_edid_property;
/*
* Protect access to I/O registers from concurrent modesetting
* by acquiring the I/O-register lock.
*/
mutex_lock(&ast->modeset_lock);
edid = drm_get_edid(connector, &ast_sil164_connector->i2c->adapter);
if (!edid)
goto err_mutex_unlock;
mutex_unlock(&ast->modeset_lock);
count = drm_add_edid_modes(connector, edid);
kfree(edid);
return count;
err_mutex_unlock:
mutex_unlock(&ast->modeset_lock);
err_drm_connector_update_edid_property:
drm_connector_update_edid_property(connector, NULL);
return 0;
}
static const struct drm_connector_helper_funcs ast_sil164_connector_helper_funcs = {
.get_modes = ast_sil164_connector_helper_get_modes,
.get_modes = drm_connector_helper_get_modes,
.detect_ctx = drm_connector_helper_detect_from_ddc,
};
static const struct drm_connector_funcs ast_sil164_connector_funcs = {
......@@ -1496,23 +1426,21 @@ static const struct drm_connector_funcs ast_sil164_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static int ast_sil164_connector_init(struct drm_device *dev,
struct ast_sil164_connector *ast_sil164_connector)
static int ast_sil164_connector_init(struct drm_device *dev, struct drm_connector *connector)
{
struct drm_connector *connector = &ast_sil164_connector->base;
struct ast_device *ast = to_ast_device(dev);
struct ast_ddc *ddc;
int ret;
ast_sil164_connector->i2c = ast_i2c_create(dev);
if (!ast_sil164_connector->i2c)
drm_err(dev, "failed to add ddc bus for connector\n");
ddc = ast_ddc_create(ast);
if (IS_ERR(ddc)) {
ret = PTR_ERR(ddc);
drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret);
return ret;
}
if (ast_sil164_connector->i2c)
ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs,
DRM_MODE_CONNECTOR_DVII,
&ast_sil164_connector->i2c->adapter);
else
ret = drm_connector_init(dev, connector, &ast_sil164_connector_funcs,
DRM_MODE_CONNECTOR_DVII);
ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs,
DRM_MODE_CONNECTOR_DVII, &ddc->adapter);
if (ret)
return ret;
......@@ -1521,7 +1449,7 @@ static int ast_sil164_connector_init(struct drm_device *dev,
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
return 0;
}
......@@ -1531,8 +1459,7 @@ static int ast_sil164_output_init(struct ast_device *ast)
struct drm_device *dev = &ast->base;
struct drm_crtc *crtc = &ast->crtc;
struct drm_encoder *encoder = &ast->output.sil164.encoder;
struct ast_sil164_connector *ast_sil164_connector = &ast->output.sil164.sil164_connector;
struct drm_connector *connector = &ast_sil164_connector->base;
struct drm_connector *connector = &ast->output.sil164.connector;
int ret;
ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
......@@ -1540,7 +1467,7 @@ static int ast_sil164_output_init(struct ast_device *ast)
return ret;
encoder->possible_crtcs = drm_crtc_mask(crtc);
ret = ast_sil164_connector_init(dev, ast_sil164_connector);
ret = ast_sil164_connector_init(dev, connector);
if (ret)
return ret;
......@@ -1952,13 +1879,13 @@ int ast_mode_config_init(struct ast_device *ast)
ret = ast_vga_output_init(ast);
if (ret)
return ret;
physical_connector = &ast->output.vga.vga_connector.base;
physical_connector = &ast->output.vga.connector;
}
if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
ret = ast_sil164_output_init(ast);
if (ret)
return ret;
physical_connector = &ast->output.sil164.sil164_connector.base;
physical_connector = &ast->output.sil164.connector;
}
if (ast->tx_chip_types & AST_TX_DP501_BIT) {
ret = ast_dp501_output_init(ast);
......@@ -1978,7 +1905,9 @@ int ast_mode_config_init(struct ast_device *ast)
drm_mode_config_reset(dev);
drm_kms_helper_poll_init(dev);
ret = drmm_kms_helper_poll_init(dev);
if (ret)
return ret;
return 0;
}
......@@ -477,6 +477,11 @@ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
if (ret < 0)
return ret;
/* If there is no IRQ to handle, exit indicating no IRQ data */
if (!(irq0 & (ADV7511_INT0_HPD | ADV7511_INT0_EDID_READY)) &&
!(irq1 & ADV7511_INT1_DDC_ERROR))
return -ENODATA;
regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
......@@ -1318,7 +1323,8 @@ static int adv7511_probe(struct i2c_client *i2c)
ret = devm_request_threaded_irq(dev, i2c->irq, NULL,
adv7511_irq_handler,
IRQF_ONESHOT, dev_name(dev),
IRQF_ONESHOT | IRQF_SHARED,
dev_name(dev),
adv7511);
if (ret)
goto err_unregister_audio;
......
......@@ -37,6 +37,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
......@@ -951,6 +952,32 @@ void drm_kms_helper_poll_fini(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
static void drm_kms_helper_poll_init_release(struct drm_device *dev, void *res)
{
drm_kms_helper_poll_fini(dev);
}
/**
* drmm_kms_helper_poll_init - initialize and enable output polling
* @dev: drm_device
*
* This function initializes and then also enables output polling support for
* @dev similar to drm_kms_helper_poll_init(). Polling will automatically be
* cleaned up when the DRM device goes away.
*
* See drm_kms_helper_poll_init() for more information.
*
* Returns:
* 0 on success, or a negative errno code otherwise.
*/
int drmm_kms_helper_poll_init(struct drm_device *dev)
{
drm_kms_helper_poll_init(dev);
return drmm_add_action_or_reset(dev, drm_kms_helper_poll_init_release, dev);
}
EXPORT_SYMBOL(drmm_kms_helper_poll_init);
static bool check_connector_changed(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
......@@ -1279,3 +1306,32 @@ int drm_connector_helper_tv_get_modes(struct drm_connector *connector)
return i;
}
EXPORT_SYMBOL(drm_connector_helper_tv_get_modes);
/**
* drm_connector_helper_detect_from_ddc - Read EDID and detect connector status.
* @connector: The connector
* @ctx: Acquire context
* @force: Perform screen-destructive operations, if necessary
*
* Detects the connector status by reading the EDID using drm_probe_ddc(),
* which requires connector->ddc to be set. Returns connector_status_connected
* on success or connector_status_disconnected on failure.
*
* Returns:
* The connector status as defined by enum drm_connector_status.
*/
int drm_connector_helper_detect_from_ddc(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx,
bool force)
{
struct i2c_adapter *ddc = connector->ddc;
if (!ddc)
return connector_status_unknown;
if (drm_probe_ddc(ddc))
return connector_status_connected;
return connector_status_disconnected;
}
EXPORT_SYMBOL(drm_connector_helper_detect_from_ddc);
......@@ -68,7 +68,7 @@ config DRM_EXYNOS_DP
bool "Exynos specific extensions for Analogix DP driver"
depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON
depends on DRM_DISPLAY_DP_HELPER
depends on DRM_DISPLAY_HELPER
depends on DRM_DISPLAY_HELPER=y || (DRM_DISPLAY_HELPER=m && DRM_EXYNOS=m)
select DRM_ANALOGIX_DP
default DRM_EXYNOS
select DRM_PANEL
......
......@@ -790,13 +790,13 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
FREQ_1000_1001(params[i].pixel_freq));
DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
i, params[i].phy_freq,
FREQ_1000_1001(params[i].phy_freq/10)*10);
FREQ_1000_1001(params[i].phy_freq/1000)*1000);
/* Match strict frequency */
if (phy_freq == params[i].phy_freq &&
vclk_freq == params[i].vclk_freq)
return MODE_OK;
/* Match 1000/1001 variant */
if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) &&
vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
return MODE_OK;
}
......@@ -1070,7 +1070,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
if ((phy_freq == params[freq].phy_freq ||
phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) &&
(vclk_freq == params[freq].vclk_freq ||
vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
if (vclk_freq != params[freq].vclk_freq)
......
......@@ -612,6 +612,92 @@ static const struct st7703_panel_desc rgb10max3_panel_desc = {
.init_sequence = rgb10max3_panel_init_sequence,
};
static int gameforcechi_init_sequence(struct st7703 *ctx)
{
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
/*
* Init sequence was supplied by the panel vendor. Panel will not
* respond to commands until it is brought out of sleep mode first.
*/
mipi_dsi_dcs_exit_sleep_mode(dsi);
msleep(250);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x31, 0x81, 0x05, 0xf9,
0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x44, 0x25, 0x00, 0x91, 0x0a, 0x00,
0x00, 0x02, 0x4f, 0xd1, 0x00, 0x00, 0x37);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x0c, 0x10, 0x0a,
0x50, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50,
0x00, 0x00, 0x08, 0x70, 0x00);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x46);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x00, 0x13, 0xf0);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b,
0x03, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xc0, 0x10);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x53, 0x00, 0x1e,
0x1e, 0x77, 0xe1, 0xcc, 0xdd, 0x67, 0x77, 0x33,
0x33);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x10, 0x10);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x6c, 0x7c);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0x08, 0x00, 0x0e, 0x00,
0x00, 0xb0, 0xb1, 0x11, 0x31, 0x23, 0x28, 0x10,
0xb0, 0xb1, 0x27, 0x08, 0x00, 0x04, 0x02, 0x00,
0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00,
0x88, 0x88, 0xba, 0x60, 0x24, 0x08, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0xba, 0x71, 0x35,
0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x97, 0x0a, 0x82, 0x02,
0x13, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x88, 0xba, 0x17, 0x53, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x81, 0x88, 0xba, 0x06, 0x42,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x10,
0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x07, 0x0b,
0x27, 0x2d, 0x3f, 0x3b, 0x37, 0x05, 0x0a, 0x0b,
0x0f, 0x11, 0x0f, 0x12, 0x12, 0x18, 0x00, 0x07,
0x0b, 0x27, 0x2d, 0x3f, 0x3b, 0x37, 0x05, 0xa0,
0x0b, 0x0f, 0x11, 0x0f, 0x12, 0x12, 0x18);
return 0;
}
static const struct drm_display_mode gameforcechi_mode = {
.hdisplay = 640,
.hsync_start = 640 + 40,
.hsync_end = 640 + 40 + 2,
.htotal = 640 + 40 + 2 + 80,
.vdisplay = 480,
.vsync_start = 480 + 17,
.vsync_end = 480 + 17 + 5,
.vtotal = 480 + 17 + 5 + 13,
.clock = 23546,
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
.width_mm = 71,
.height_mm = 53,
};
static const struct st7703_panel_desc gameforcechi_desc = {
.mode = &gameforcechi_mode,
.lanes = 2,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM,
.format = MIPI_DSI_FMT_RGB888,
.init_sequence = gameforcechi_init_sequence,
};
static int st7703_enable(struct drm_panel *panel)
{
struct st7703 *ctx = panel_to_st7703(panel);
......@@ -887,6 +973,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi)
static const struct of_device_id st7703_of_match[] = {
{ .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc },
{ .compatible = "gameforce,chi-panel", .data = &gameforcechi_desc },
{ .compatible = "powkiddy,rgb10max3-panel", .data = &rgb10max3_panel_desc },
{ .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc },
{ .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc },
......
......@@ -348,7 +348,7 @@ static vm_fault_t panthor_mmio_vm_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
struct panthor_device *ptdev = vma->vm_private_data;
u64 id = (u64)vma->vm_pgoff << PAGE_SHIFT;
u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT;
unsigned long pfn;
pgprot_t pgprot;
vm_fault_t ret;
......@@ -361,7 +361,7 @@ static vm_fault_t panthor_mmio_vm_fault(struct vm_fault *vmf)
mutex_lock(&ptdev->pm.mmio_lock);
active = atomic_read(&ptdev->pm.state) == PANTHOR_DEVICE_PM_STATE_ACTIVE;
switch (panthor_device_mmio_offset(id)) {
switch (offset) {
case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET:
if (active)
pfn = __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID);
......@@ -392,9 +392,9 @@ static const struct vm_operations_struct panthor_mmio_vm_ops = {
int panthor_device_mmap_io(struct panthor_device *ptdev, struct vm_area_struct *vma)
{
u64 id = (u64)vma->vm_pgoff << PAGE_SHIFT;
u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT;
switch (panthor_device_mmio_offset(id)) {
switch (offset) {
case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET:
if (vma->vm_end - vma->vm_start != PAGE_SIZE ||
(vma->vm_flags & (VM_WRITE | VM_EXEC)))
......
......@@ -323,31 +323,18 @@ static irqreturn_t panthor_ ## __name ## _irq_threaded_handler(int irq, void *da
\
static inline void panthor_ ## __name ## _irq_suspend(struct panthor_irq *pirq) \
{ \
int cookie; \
\
atomic_set(&pirq->suspended, true); \
\
if (drm_dev_enter(&pirq->ptdev->base, &cookie)) { \
gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, 0); \
synchronize_irq(pirq->irq); \
drm_dev_exit(cookie); \
} \
\
pirq->mask = 0; \
gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, 0); \
synchronize_irq(pirq->irq); \
atomic_set(&pirq->suspended, true); \
} \
\
static inline void panthor_ ## __name ## _irq_resume(struct panthor_irq *pirq, u32 mask) \
{ \
int cookie; \
\
atomic_set(&pirq->suspended, false); \
pirq->mask = mask; \
\
if (drm_dev_enter(&pirq->ptdev->base, &cookie)) { \
gpu_write(pirq->ptdev, __reg_prefix ## _INT_CLEAR, mask); \
gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, mask); \
drm_dev_exit(cookie); \
} \
gpu_write(pirq->ptdev, __reg_prefix ## _INT_CLEAR, mask); \
gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, mask); \
} \
\
static int panthor_request_ ## __name ## _irq(struct panthor_device *ptdev, \
......@@ -365,30 +352,6 @@ static int panthor_request_ ## __name ## _irq(struct panthor_device *ptdev, \
pirq); \
}
/**
* panthor_device_mmio_offset() - Turn a user MMIO offset into a kernel one
* @offset: Offset to convert.
*
* With 32-bit systems being limited by the 32-bit representation of mmap2's
* pgoffset field, we need to make the MMIO offset arch specific. This function
* converts a user MMIO offset into something the kernel driver understands.
*
* If the kernel and userspace architecture match, the offset is unchanged. If
* the kernel is 64-bit and userspace is 32-bit, the offset is adjusted to match
* 64-bit offsets. 32-bit kernel with 64-bit userspace is impossible.
*
* Return: Adjusted offset.
*/
static inline u64 panthor_device_mmio_offset(u64 offset)
{
#ifdef CONFIG_ARM64
if (test_tsk_thread_flag(current, TIF_32BIT))
offset += DRM_PANTHOR_USER_MMIO_OFFSET_64BIT - DRM_PANTHOR_USER_MMIO_OFFSET_32BIT;
#endif
return offset;
}
extern struct workqueue_struct *panthor_cleanup_wq;
#endif
......@@ -1090,8 +1090,8 @@ static int panthor_ioctl_tiler_heap_destroy(struct drm_device *ddev, void *data,
return -EINVAL;
pool = panthor_vm_get_heap_pool(vm, false);
if (!pool) {
ret = -EINVAL;
if (IS_ERR(pool)) {
ret = PTR_ERR(pool);
goto out_put_vm;
}
......@@ -1327,7 +1327,22 @@ static int panthor_mmap(struct file *filp, struct vm_area_struct *vma)
if (!drm_dev_enter(file->minor->dev, &cookie))
return -ENODEV;
if (panthor_device_mmio_offset(offset) >= DRM_PANTHOR_USER_MMIO_OFFSET)
#ifdef CONFIG_ARM64
/*
* With 32-bit systems being limited by the 32-bit representation of
* mmap2's pgoffset field, we need to make the MMIO offset arch
* specific. This converts a user MMIO offset into something the kernel
* driver understands.
*/
if (test_tsk_thread_flag(current, TIF_32BIT) &&
offset >= DRM_PANTHOR_USER_MMIO_OFFSET_32BIT) {
offset += DRM_PANTHOR_USER_MMIO_OFFSET_64BIT -
DRM_PANTHOR_USER_MMIO_OFFSET_32BIT;
vma->vm_pgoff = offset >> PAGE_SHIFT;
}
#endif
if (offset >= DRM_PANTHOR_USER_MMIO_OFFSET)
ret = panthor_device_mmap_io(ptdev, vma);
else
ret = drm_gem_mmap(filp, vma);
......@@ -1385,7 +1400,7 @@ static int panthor_probe(struct platform_device *pdev)
ptdev = devm_drm_dev_alloc(&pdev->dev, &panthor_drm_driver,
struct panthor_device, base);
if (!ptdev)
if (IS_ERR(ptdev))
return -ENOMEM;
platform_set_drvdata(pdev, ptdev);
......
......@@ -308,7 +308,7 @@ panthor_fw_get_csg_iface(struct panthor_device *ptdev, u32 csg_slot)
struct panthor_fw_cs_iface *
panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot)
{
if (drm_WARN_ON(&ptdev->base, csg_slot >= MAX_CSGS || cs_slot > MAX_CS_PER_CSG))
if (drm_WARN_ON(&ptdev->base, csg_slot >= MAX_CSGS || cs_slot >= MAX_CS_PER_CSG))
return NULL;
return &ptdev->fw->iface.streams[csg_slot][cs_slot];
......
......@@ -211,8 +211,8 @@ int panthor_gpu_init(struct panthor_device *ptdev)
return ret;
irq = platform_get_irq_byname(to_platform_device(ptdev->base.dev), "gpu");
if (irq <= 0)
return ret;
if (irq < 0)
return irq;
ret = panthor_request_gpu_irq(ptdev, &ptdev->gpu->irq, irq, GPU_INTERRUPTS_MASK);
if (ret)
......
......@@ -1264,8 +1264,10 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx,
op_ctx->rsvd_page_tables.pages = kcalloc(pt_count,
sizeof(*op_ctx->rsvd_page_tables.pages),
GFP_KERNEL);
if (!op_ctx->rsvd_page_tables.pages)
if (!op_ctx->rsvd_page_tables.pages) {
ret = -ENOMEM;
goto err_cleanup;
}
ret = kmem_cache_alloc_bulk(pt_cache, GFP_KERNEL, pt_count,
op_ctx->rsvd_page_tables.pages);
......@@ -1318,8 +1320,10 @@ static int panthor_vm_prepare_unmap_op_ctx(struct panthor_vm_op_ctx *op_ctx,
op_ctx->rsvd_page_tables.pages = kcalloc(pt_count,
sizeof(*op_ctx->rsvd_page_tables.pages),
GFP_KERNEL);
if (!op_ctx->rsvd_page_tables.pages)
if (!op_ctx->rsvd_page_tables.pages) {
ret = -ENOMEM;
goto err_cleanup;
}
ret = kmem_cache_alloc_bulk(pt_cache, GFP_KERNEL, pt_count,
op_ctx->rsvd_page_tables.pages);
......@@ -1893,6 +1897,8 @@ struct panthor_heap_pool *panthor_vm_get_heap_pool(struct panthor_vm *vm, bool c
vm->heaps.pool = panthor_heap_pool_get(pool);
} else {
pool = panthor_heap_pool_get(vm->heaps.pool);
if (!pool)
pool = ERR_PTR(-ENOENT);
}
mutex_unlock(&vm->heaps.lock);
......
......@@ -517,7 +517,7 @@ struct panthor_group {
/** @max_compute_cores: Maximum number of shader cores used for compute jobs. */
u8 max_compute_cores;
/** @max_compute_cores: Maximum number of shader cores used for fragment jobs. */
/** @max_fragment_cores: Maximum number of shader cores used for fragment jobs. */
u8 max_fragment_cores;
/** @max_tiler_cores: Maximum number of tiler cores used for tiler jobs. */
......@@ -993,7 +993,7 @@ cs_slot_prog_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs_id)
}
/**
* @cs_slot_reset_locked() - Reset a queue slot
* cs_slot_reset_locked() - Reset a queue slot
* @ptdev: Device.
* @csg_id: Group slot.
* @cs_id: Queue slot.
......@@ -1343,7 +1343,7 @@ static int group_process_tiler_oom(struct panthor_group *group, u32 cs_id)
if (unlikely(csg_id < 0))
return 0;
if (!heaps || frag_end > vt_end || vt_end >= vt_start) {
if (IS_ERR(heaps) || frag_end > vt_end || vt_end >= vt_start) {
ret = -EINVAL;
} else {
/* We do the allocation without holding the scheduler lock to avoid
......@@ -1591,7 +1591,7 @@ static void sched_process_idle_event_locked(struct panthor_device *ptdev)
}
/**
* panthor_sched_process_global_irq() - Process the scheduling part of a global IRQ
* sched_process_global_irq_locked() - Process the scheduling part of a global IRQ
* @ptdev: Device.
*/
static void sched_process_global_irq_locked(struct panthor_device *ptdev)
......@@ -1660,8 +1660,6 @@ static const struct dma_fence_ops panthor_queue_fence_ops = {
.get_timeline_name = queue_fence_get_timeline_name,
};
/**
*/
struct panthor_csg_slots_upd_ctx {
u32 update_mask;
u32 timedout_mask;
......@@ -2045,7 +2043,7 @@ tick_ctx_apply(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *c
struct panthor_device *ptdev = sched->ptdev;
struct panthor_csg_slot *csg_slot;
int prio, new_csg_prio = MAX_CSG_PRIO, i;
u32 csg_mod_mask = 0, free_csg_slots = 0;
u32 free_csg_slots = 0;
struct panthor_csg_slots_upd_ctx upd_ctx;
int ret;
......@@ -2139,7 +2137,6 @@ tick_ctx_apply(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *c
csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id);
csg_slot = &sched->csg_slots[csg_id];
csg_mod_mask |= BIT(csg_id);
group_bind_locked(group, csg_id);
csg_slot_prog_locked(ptdev, csg_id, new_csg_prio--);
csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id,
......
......@@ -46,7 +46,7 @@ config ROCKCHIP_ANALOGIX_DP
config ROCKCHIP_CDN_DP
bool "Rockchip cdn DP"
depends on DRM_DISPLAY_DP_HELPER
depends on DRM_DISPLAY_HELPER
depends on DRM_DISPLAY_HELPER=y || (DRM_DISPLAY_HELPER=m && DRM_ROCKCHIP=m)
depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m)
help
This selects support for Rockchip SoC specific extensions
......
......@@ -87,14 +87,11 @@ struct ttm_object_file {
*
* @object_lock: lock that protects idr.
*
* @object_count: Per device object count.
*
* This is the per-device data structure needed for ttm object management.
*/
struct ttm_object_device {
spinlock_t object_lock;
atomic_t object_count;
struct dma_buf_ops ops;
void (*dmabuf_release)(struct dma_buf *dma_buf);
struct idr idr;
......@@ -431,7 +428,6 @@ ttm_object_device_init(const struct dma_buf_ops *ops)
return NULL;
spin_lock_init(&tdev->object_lock);
atomic_set(&tdev->object_count, 0);
/*
* Our base is at VMWGFX_NUM_MOB + 1 because we want to create
......
......@@ -117,25 +117,8 @@ struct vmwgfx_hash_item {
unsigned long key;
};
/**
* struct vmw_validate_buffer - Carries validation info about buffers.
*
* @base: Validation info for TTM.
* @hash: Hash entry for quick lookup of the TTM buffer object.
*
* This structure contains also driver private validation info
* on top of the info needed by TTM.
*/
struct vmw_validate_buffer {
struct ttm_validate_buffer base;
struct vmwgfx_hash_item hash;
bool validate_as_mob;
};
struct vmw_res_func;
/**
* struct vmw-resource - base class for hardware resources
*
......@@ -445,15 +428,6 @@ struct vmw_sw_context{
struct vmw_legacy_display;
struct vmw_overlay;
struct vmw_vga_topology_state {
uint32_t width;
uint32_t height;
uint32_t primary;
uint32_t pos_x;
uint32_t pos_y;
};
/*
* struct vmw_otable - Guest Memory OBject table metadata
*
......@@ -501,7 +475,6 @@ struct vmw_private {
struct drm_device drm;
struct ttm_device bdev;
struct drm_vma_offset_manager vma_manager;
u32 pci_id;
resource_size_t io_start;
resource_size_t vram_start;
......
......@@ -775,7 +775,6 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
hotspot_y = du->hotspot_y + new_state->hotspot_y;
du->cursor_surface = vps->surf;
du->cursor_bo = vps->bo;
if (!vps->surf && !vps->bo) {
vmw_cursor_update_position(dev_priv, false, 0, 0);
......@@ -858,15 +857,6 @@ int vmw_du_primary_plane_atomic_check(struct drm_plane *plane,
DRM_PLANE_NO_SCALING,
DRM_PLANE_NO_SCALING,
false, true);
if (!ret && new_fb) {
struct drm_crtc *crtc = new_state->crtc;
struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
vmw_connector_state_to_vcs(du->connector.state);
}
return ret;
}
......@@ -1361,7 +1351,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
drm_helper_mode_fill_fb_struct(dev, &vfbs->base.base, mode_cmd);
vfbs->surface = vmw_surface_reference(surface);
vfbs->base.user_handle = mode_cmd->handles[0];
vfbs->is_bo_proxy = is_bo_proxy;
*out = &vfbs->base;
......@@ -1529,7 +1518,6 @@ static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv,
drm_helper_mode_fill_fb_struct(dev, &vfbd->base.base, mode_cmd);
vfbd->base.bo = true;
vfbd->buffer = vmw_bo_reference(bo);
vfbd->base.user_handle = mode_cmd->handles[0];
*out = &vfbd->base;
ret = drm_framebuffer_init(dev, &vfbd->base.base,
......
......@@ -217,21 +217,11 @@ struct vmw_kms_dirty {
struct vmw_framebuffer {
struct drm_framebuffer base;
bool bo;
uint32_t user_handle;
};
/*
* Clip rectangle
*/
struct vmw_clip_rect {
int x1, x2, y1, y2;
};
struct vmw_framebuffer_surface {
struct vmw_framebuffer base;
struct vmw_surface *surface;
struct vmw_bo *buffer;
struct list_head head;
bool is_bo_proxy; /* true if this is proxy surface for DMA buf */
};
......@@ -359,7 +349,6 @@ struct vmw_display_unit {
struct vmw_cursor_plane cursor;
struct vmw_surface *cursor_surface;
struct vmw_bo *cursor_bo;
size_t cursor_age;
int cursor_x;
......@@ -389,11 +378,6 @@ struct vmw_display_unit {
int set_gui_y;
};
struct vmw_validation_ctx {
struct vmw_resource *res;
struct vmw_bo *buf;
};
#define vmw_crtc_to_du(x) \
container_of(x, struct vmw_display_unit, crtc)
#define vmw_connector_to_du(x) \
......
......@@ -89,7 +89,6 @@ struct vmw_kms_sou_define_gmrfb {
struct vmw_screen_object_unit {
struct vmw_display_unit base;
unsigned long buffer_size; /**< Size of allocated buffer */
struct vmw_bo *buffer; /**< Backing store buffer */
bool defined;
......@@ -240,7 +239,6 @@ static void vmw_sou_crtc_mode_set_nofb(struct drm_crtc *crtc)
int x, y;
sou->buffer = vps->bo;
sou->buffer_size = vps->bo_size;
conn_state = sou->base.connector.state;
vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
......@@ -255,7 +253,6 @@ static void vmw_sou_crtc_mode_set_nofb(struct drm_crtc *crtc)
} else {
sou->buffer = NULL;
sou->buffer_size = 0;
}
}
......
// SPDX-License-Identifier: GPL-2.0 OR MIT
/**************************************************************************
*
* Copyright 2009-2011 VMware, Inc., Palo Alto, CA., USA
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "vmwgfx_drv.h"
static int vmw_bo_vm_lookup(struct ttm_device *bdev,
struct drm_file *filp,
unsigned long offset,
unsigned long pages,
struct ttm_buffer_object **p_bo)
{
struct vmw_private *dev_priv = container_of(bdev, struct vmw_private, bdev);
struct drm_device *drm = &dev_priv->drm;
struct drm_vma_offset_node *node;
int ret;
*p_bo = NULL;
drm_vma_offset_lock_lookup(bdev->vma_manager);
node = drm_vma_offset_lookup_locked(bdev->vma_manager, offset, pages);
if (likely(node)) {
*p_bo = container_of(node, struct ttm_buffer_object,
base.vma_node);
*p_bo = ttm_bo_get_unless_zero(*p_bo);
}
drm_vma_offset_unlock_lookup(bdev->vma_manager);
if (!*p_bo) {
drm_err(drm, "Could not find buffer object to map\n");
return -EINVAL;
}
if (!drm_vma_node_is_allowed(node, filp)) {
ret = -EACCES;
goto out_no_access;
}
return 0;
out_no_access:
ttm_bo_put(*p_bo);
return ret;
}
int vmw_mmap(struct file *filp, struct vm_area_struct *vma)
{
static const struct vm_operations_struct vmw_vm_ops = {
.pfn_mkwrite = vmw_bo_vm_mkwrite,
.page_mkwrite = vmw_bo_vm_mkwrite,
.fault = vmw_bo_vm_fault,
.open = ttm_bo_vm_open,
.close = ttm_bo_vm_close,
};
struct drm_file *file_priv = filp->private_data;
struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev);
struct ttm_device *bdev = &dev_priv->bdev;
struct ttm_buffer_object *bo;
int ret;
if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET_START))
return -EINVAL;
ret = vmw_bo_vm_lookup(bdev, file_priv, vma->vm_pgoff, vma_pages(vma), &bo);
if (unlikely(ret != 0))
return ret;
ret = ttm_bo_mmap_obj(vma, bo);
if (unlikely(ret != 0))
goto out_unref;
vma->vm_ops = &vmw_vm_ops;
/* Use VM_PFNMAP rather than VM_MIXEDMAP if not a COW mapping */
if (!is_cow_mapping(vma->vm_flags))
vm_flags_mod(vma, VM_PFNMAP, VM_MIXEDMAP);
ttm_bo_put(bo); /* release extra ref taken by ttm_bo_mmap_obj() */
return 0;
out_unref:
ttm_bo_put(bo);
return ret;
}
......@@ -32,9 +32,6 @@
#include <linux/slab.h>
#define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE)
/**
* struct vmw_validation_bo_node - Buffer object validation metadata.
* @base: Metadata used for TTM reservation- and validation.
......@@ -112,20 +109,10 @@ void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx,
return NULL;
if (ctx->mem_size_left < size) {
struct page *page;
if (ctx->vm && ctx->vm_size_left < PAGE_SIZE) {
ctx->vm_size_left += VMWGFX_VALIDATION_MEM_GRAN;
ctx->total_mem += VMWGFX_VALIDATION_MEM_GRAN;
}
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!page)
return NULL;
if (ctx->vm)
ctx->vm_size_left -= PAGE_SIZE;
list_add_tail(&page->lru, &ctx->page_list);
ctx->page_address = page_address(page);
ctx->mem_size_left = PAGE_SIZE;
......@@ -155,10 +142,6 @@ static void vmw_validation_mem_free(struct vmw_validation_context *ctx)
}
ctx->mem_size_left = 0;
if (ctx->vm && ctx->total_mem) {
ctx->total_mem = 0;
ctx->vm_size_left = 0;
}
}
/**
......
......@@ -52,10 +52,6 @@
* buffer objects
* @mem_size_left: Free memory left in the last page in @page_list
* @page_address: Kernel virtual address of the last page in @page_list
* @vm: A pointer to the memory reservation interface or NULL if no
* memory reservation is needed.
* @vm_size_left: Amount of reserved memory that so far has not been allocated.
* @total_mem: Amount of reserved memory.
*/
struct vmw_validation_context {
struct vmw_sw_context *sw_context;
......@@ -68,9 +64,6 @@ struct vmw_validation_context {
unsigned int merge_dups;
unsigned int mem_size_left;
u8 *page_address;
struct vmw_validation_mem *vm;
size_t vm_size_left;
size_t total_mem;
};
struct vmw_bo;
......
......@@ -16,6 +16,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector
int drm_helper_probe_detect(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx,
bool force);
int drmm_kms_helper_poll_init(struct drm_device *dev);
void drm_kms_helper_poll_init(struct drm_device *dev);
void drm_kms_helper_poll_fini(struct drm_device *dev);
bool drm_helper_hpd_irq_event(struct drm_device *dev);
......@@ -37,4 +39,8 @@ int drm_connector_helper_get_modes_fixed(struct drm_connector *connector,
int drm_connector_helper_get_modes(struct drm_connector *connector);
int drm_connector_helper_tv_get_modes(struct drm_connector *connector);
int drm_connector_helper_detect_from_ddc(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx,
bool force);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment