Commit c25b6960 authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/simpledrm: Inline device-init helpers

Inline the helpers for initializing the hardware FB, the memory
management and the modesetting into the device-creation function.
No functional changes.

In the original code, init helpers depended on values from other
init helpers. Inlining the functions ensures that steps are taken
in the correct order. It's also easier to see what happens. The
device is simple enough to be set up in one function. Only clocks
and regulators are still set up in their own helpers, as their
presence is system dependent.
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220801135028.30647-3-tzimmermann@suse.de
parent 03d38605
...@@ -449,119 +449,6 @@ static int simpledrm_device_init_regulators(struct simpledrm_device *sdev) ...@@ -449,119 +449,6 @@ static int simpledrm_device_init_regulators(struct simpledrm_device *sdev)
} }
#endif #endif
/*
* Simplefb settings
*/
static struct drm_display_mode simpledrm_mode(unsigned int width,
unsigned int height)
{
struct drm_display_mode mode = { SIMPLEDRM_MODE(width, height) };
mode.clock = mode.hdisplay * mode.vdisplay * 60 / 1000 /* kHz */;
drm_mode_set_name(&mode);
return mode;
}
static int simpledrm_device_init_fb(struct simpledrm_device *sdev)
{
int width, height, stride;
const struct drm_format_info *format;
struct drm_device *dev = &sdev->dev;
struct platform_device *pdev = sdev->pdev;
const struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);
struct device_node *of_node = pdev->dev.of_node;
if (pd) {
width = simplefb_get_width_pd(dev, pd);
if (width < 0)
return width;
height = simplefb_get_height_pd(dev, pd);
if (height < 0)
return height;
stride = simplefb_get_stride_pd(dev, pd);
if (stride < 0)
return stride;
format = simplefb_get_format_pd(dev, pd);
if (IS_ERR(format))
return PTR_ERR(format);
} else if (of_node) {
width = simplefb_get_width_of(dev, of_node);
if (width < 0)
return width;
height = simplefb_get_height_of(dev, of_node);
if (height < 0)
return height;
stride = simplefb_get_stride_of(dev, of_node);
if (stride < 0)
return stride;
format = simplefb_get_format_of(dev, of_node);
if (IS_ERR(format))
return PTR_ERR(format);
} else {
drm_err(dev, "no simplefb configuration found\n");
return -ENODEV;
}
sdev->mode = simpledrm_mode(width, height);
sdev->format = format;
sdev->pitch = stride;
drm_dbg_kms(dev, "display mode={" DRM_MODE_FMT "}\n",
DRM_MODE_ARG(&sdev->mode));
drm_dbg_kms(dev,
"framebuffer format=%p4cc, size=%dx%d, stride=%d byte\n",
&format->format, width, height, stride);
return 0;
}
/*
* Memory management
*/
static int simpledrm_device_init_mm(struct simpledrm_device *sdev)
{
struct drm_device *dev = &sdev->dev;
struct platform_device *pdev = sdev->pdev;
struct resource *res, *mem;
void __iomem *screen_base;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res));
if (ret) {
drm_err(dev, "could not acquire memory range %pr: error %d\n",
res, ret);
return ret;
}
mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
sdev->dev.driver->name);
if (!mem) {
/*
* We cannot make this fatal. Sometimes this comes from magic
* spaces our resource handlers simply don't know about. Use
* the I/O-memory resource as-is and try to map that instead.
*/
drm_warn(dev, "could not acquire memory region %pr\n", res);
mem = res;
}
screen_base = devm_ioremap_wc(&pdev->dev, mem->start,
resource_size(mem));
if (!screen_base)
return -ENOMEM;
sdev->screen_base = screen_base;
return 0;
}
/* /*
* Modesetting * Modesetting
*/ */
...@@ -738,6 +625,21 @@ static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = { ...@@ -738,6 +625,21 @@ static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit, .atomic_commit = drm_atomic_helper_commit,
}; };
/*
* Init / Cleanup
*/
static struct drm_display_mode simpledrm_mode(unsigned int width,
unsigned int height)
{
struct drm_display_mode mode = { SIMPLEDRM_MODE(width, height) };
mode.clock = mode.hdisplay * mode.vdisplay * 60 / 1000 /* kHz */;
drm_mode_set_name(&mode);
return mode;
}
static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev, static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev,
size_t *nformats_out) size_t *nformats_out)
{ {
...@@ -777,88 +679,151 @@ static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev, ...@@ -777,88 +679,151 @@ static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev,
return sdev->formats; return sdev->formats;
} }
static int simpledrm_device_init_modeset(struct simpledrm_device *sdev) static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
struct platform_device *pdev)
{ {
struct drm_device *dev = &sdev->dev; const struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);
struct drm_display_mode *mode = &sdev->mode; struct device_node *of_node = pdev->dev.of_node;
struct drm_connector *connector = &sdev->connector; struct simpledrm_device *sdev;
struct drm_simple_display_pipe *pipe = &sdev->pipe; struct drm_device *dev;
int width, height, stride;
const struct drm_format_info *format;
struct resource *res, *mem;
void __iomem *screen_base;
struct drm_connector *connector;
struct drm_simple_display_pipe *pipe;
unsigned long max_width, max_height; unsigned long max_width, max_height;
const uint32_t *formats; const uint32_t *formats;
size_t nformats; size_t nformats;
int ret; int ret;
sdev = devm_drm_dev_alloc(&pdev->dev, drv, struct simpledrm_device, dev);
if (IS_ERR(sdev))
return ERR_CAST(sdev);
dev = &sdev->dev;
sdev->pdev = pdev;
platform_set_drvdata(pdev, sdev);
/*
* Hardware settings
*/
ret = simpledrm_device_init_clocks(sdev);
if (ret)
return ERR_PTR(ret);
ret = simpledrm_device_init_regulators(sdev);
if (ret)
return ERR_PTR(ret);
if (pd) {
width = simplefb_get_width_pd(dev, pd);
if (width < 0)
return ERR_PTR(width);
height = simplefb_get_height_pd(dev, pd);
if (height < 0)
return ERR_PTR(height);
stride = simplefb_get_stride_pd(dev, pd);
if (stride < 0)
return ERR_PTR(stride);
format = simplefb_get_format_pd(dev, pd);
if (IS_ERR(format))
return ERR_CAST(format);
} else if (of_node) {
width = simplefb_get_width_of(dev, of_node);
if (width < 0)
return ERR_PTR(width);
height = simplefb_get_height_of(dev, of_node);
if (height < 0)
return ERR_PTR(height);
stride = simplefb_get_stride_of(dev, of_node);
if (stride < 0)
return ERR_PTR(stride);
format = simplefb_get_format_of(dev, of_node);
if (IS_ERR(format))
return ERR_CAST(format);
} else {
drm_err(dev, "no simplefb configuration found\n");
return ERR_PTR(-ENODEV);
}
sdev->mode = simpledrm_mode(width, height);
sdev->format = format;
sdev->pitch = stride;
drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&sdev->mode));
drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d byte\n",
&format->format, width, height, stride);
/*
* Memory management
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return ERR_PTR(-EINVAL);
ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res));
if (ret) {
drm_err(dev, "could not acquire memory range %pr: error %d\n", res, ret);
return ERR_PTR(ret);
}
mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res), drv->name);
if (!mem) {
/*
* We cannot make this fatal. Sometimes this comes from magic
* spaces our resource handlers simply don't know about. Use
* the I/O-memory resource as-is and try to map that instead.
*/
drm_warn(dev, "could not acquire memory region %pr\n", res);
mem = res;
}
screen_base = devm_ioremap_wc(&pdev->dev, mem->start, resource_size(mem));
if (!screen_base)
return ERR_PTR(-ENOMEM);
sdev->screen_base = screen_base;
/*
* Modesetting
*/
ret = drmm_mode_config_init(dev); ret = drmm_mode_config_init(dev);
if (ret) if (ret)
return ret; return ERR_PTR(ret);
max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH); max_width = max_t(unsigned long, width, DRM_SHADOW_PLANE_MAX_WIDTH);
max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT); max_height = max_t(unsigned long, height, DRM_SHADOW_PLANE_MAX_HEIGHT);
dev->mode_config.min_width = mode->hdisplay; dev->mode_config.min_width = width;
dev->mode_config.max_width = max_width; dev->mode_config.max_width = max_width;
dev->mode_config.min_height = mode->vdisplay; dev->mode_config.min_height = height;
dev->mode_config.max_height = max_height; dev->mode_config.max_height = max_height;
dev->mode_config.preferred_depth = sdev->format->cpp[0] * 8; dev->mode_config.preferred_depth = format->cpp[0] * 8;
dev->mode_config.funcs = &simpledrm_mode_config_funcs; dev->mode_config.funcs = &simpledrm_mode_config_funcs;
connector = &sdev->connector;
ret = drm_connector_init(dev, connector, &simpledrm_connector_funcs, ret = drm_connector_init(dev, connector, &simpledrm_connector_funcs,
DRM_MODE_CONNECTOR_Unknown); DRM_MODE_CONNECTOR_Unknown);
if (ret) if (ret)
return ret; return ERR_PTR(ret);
drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs); drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs);
drm_connector_set_panel_orientation_with_quirk(connector, drm_connector_set_panel_orientation_with_quirk(connector,
DRM_MODE_PANEL_ORIENTATION_UNKNOWN, DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
mode->hdisplay, mode->vdisplay); width, height);
formats = simpledrm_device_formats(sdev, &nformats); formats = simpledrm_device_formats(sdev, &nformats);
pipe = &sdev->pipe;
ret = drm_simple_display_pipe_init(dev, pipe, &simpledrm_simple_display_pipe_funcs, ret = drm_simple_display_pipe_init(dev, pipe, &simpledrm_simple_display_pipe_funcs,
formats, nformats, simpledrm_format_modifiers, formats, nformats, simpledrm_format_modifiers,
connector); connector);
if (ret) if (ret)
return ret; return ERR_PTR(ret);
drm_plane_enable_fb_damage_clips(&pipe->plane); drm_plane_enable_fb_damage_clips(&pipe->plane);
drm_mode_config_reset(dev); drm_mode_config_reset(dev);
return 0;
}
/*
* Init / Cleanup
*/
static struct simpledrm_device *
simpledrm_device_create(struct drm_driver *drv, struct platform_device *pdev)
{
struct simpledrm_device *sdev;
int ret;
sdev = devm_drm_dev_alloc(&pdev->dev, drv, struct simpledrm_device,
dev);
if (IS_ERR(sdev))
return ERR_CAST(sdev);
sdev->pdev = pdev;
platform_set_drvdata(pdev, sdev);
ret = simpledrm_device_init_clocks(sdev);
if (ret)
return ERR_PTR(ret);
ret = simpledrm_device_init_regulators(sdev);
if (ret)
return ERR_PTR(ret);
ret = simpledrm_device_init_fb(sdev);
if (ret)
return ERR_PTR(ret);
ret = simpledrm_device_init_mm(sdev);
if (ret)
return ERR_PTR(ret);
ret = simpledrm_device_init_modeset(sdev);
if (ret)
return ERR_PTR(ret);
return sdev; return sdev;
} }
......
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