diff options
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r-- | drivers/gpu/drm/ast/Makefile | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_ddc.c (renamed from drivers/gpu/drm/ast/ast_i2c.c) | 130 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_ddc.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 165 |
7 files changed, 164 insertions, 193 deletions
diff --git a/drivers/gpu/drm/ast/Makefile b/drivers/gpu/drm/ast/Makefile index 5a53ce51fb..d794c076bc 100644 --- a/drivers/gpu/drm/ast/Makefile +++ b/drivers/gpu/drm/ast/Makefile @@ -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 diff --git a/drivers/gpu/drm/ast/ast_i2c.c b/drivers/gpu/drm/ast/ast_ddc.c index e5d3f7121d..29cf5d157f 100644 --- a/drivers/gpu/drm/ast/ast_i2c.c +++ b/drivers/gpu/drm/ast/ast_ddc.c @@ -21,20 +21,31 @@ * of the Software. */ +#include <linux/i2c-algo-bit.h> +#include <linux/i2c.h> + #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) +struct ast_ddc { + struct ast_device *ast; + + struct i2c_algo_bit_data bit; + struct i2c_adapter adapter; +}; + +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 +53,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 +69,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_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_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; @@ -80,10 +113,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 +135,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 i2c_adapter *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; + + bit = &ddc->bit; + 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; + bit->udelay = 20; + bit->timeout = usecs_to_jiffies(2200); + + adapter = &ddc->adapter; + adapter->owner = THIS_MODULE; + adapter->algo_data = bit; + adapter->dev.parent = dev->dev; + snprintf(adapter->name, sizeof(adapter->name), "AST DDC bus"); + i2c_set_adapdata(adapter, ddc); + + 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->adapter; } diff --git a/drivers/gpu/drm/ast/ast_ddc.h b/drivers/gpu/drm/ast/ast_ddc.h new file mode 100644 index 0000000000..85c93edc9a --- /dev/null +++ b/drivers/gpu/drm/ast/ast_ddc.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef __AST_DDC_H__ +#define __AST_DDC_H__ + +struct ast_device; +struct i2c_adapter; + +struct i2c_adapter *ast_ddc_create(struct ast_device *ast); + +#endif diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 90bcb1eb9c..f8c49ba68e 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -27,6 +27,7 @@ */ #include <linux/module.h> +#include <linux/of.h> #include <linux/pci.h> #include <drm/drm_aperture.h> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 3be5ccf1f5..ba3d869739 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.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); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 2f3ad5f949..0637abb703 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -26,6 +26,7 @@ * Authors: Dave Airlie <airlied@redhat.com> */ +#include <linux/of.h> #include <linux/pci.h> #include <drm/drm_atomic_helper.h> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index a718646a66..6695af7076 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -43,9 +43,11 @@ #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_shmem_helper.h> #include <drm/drm_managed.h> +#include <drm/drm_panic.h> #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" @@ -700,12 +702,29 @@ static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20); } +static int ast_primary_plane_helper_get_scanout_buffer(struct drm_plane *plane, + struct drm_scanout_buffer *sb) +{ + struct ast_plane *ast_plane = to_ast_plane(plane); + + if (plane->state && plane->state->fb && ast_plane->vaddr) { + sb->format = plane->state->fb->format; + sb->width = plane->state->fb->width; + sb->height = plane->state->fb->height; + sb->pitch[0] = plane->state->fb->pitches[0]; + iosys_map_set_vaddr_iomem(&sb->map[0], ast_plane->vaddr); + return 0; + } + return -ENODEV; +} + static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, .atomic_check = ast_primary_plane_helper_atomic_check, .atomic_update = ast_primary_plane_helper_atomic_update, .atomic_enable = ast_primary_plane_helper_atomic_enable, .atomic_disable = ast_primary_plane_helper_atomic_disable, + .get_scanout_buffer = ast_primary_plane_helper_get_scanout_buffer, }; static const struct drm_plane_funcs ast_primary_plane_funcs = { @@ -1343,43 +1362,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 +1375,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 i2c_adapter *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); if (ret) return ret; @@ -1415,7 +1398,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 +1408,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 +1416,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 +1431,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 +1444,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 i2c_adapter *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); if (ret) return ret; @@ -1521,7 +1467,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 +1477,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 +1485,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 +1897,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 +1923,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; } |