Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 
0003 #include <linux/clk.h>
0004 #include <linux/of_clk.h>
0005 #include <linux/minmax.h>
0006 #include <linux/platform_data/simplefb.h>
0007 #include <linux/platform_device.h>
0008 #include <linux/regulator/consumer.h>
0009 
0010 #include <drm/drm_aperture.h>
0011 #include <drm/drm_atomic_state_helper.h>
0012 #include <drm/drm_connector.h>
0013 #include <drm/drm_damage_helper.h>
0014 #include <drm/drm_device.h>
0015 #include <drm/drm_drv.h>
0016 #include <drm/drm_fb_helper.h>
0017 #include <drm/drm_format_helper.h>
0018 #include <drm/drm_gem_atomic_helper.h>
0019 #include <drm/drm_gem_framebuffer_helper.h>
0020 #include <drm/drm_gem_shmem_helper.h>
0021 #include <drm/drm_managed.h>
0022 #include <drm/drm_modeset_helper_vtables.h>
0023 #include <drm/drm_probe_helper.h>
0024 #include <drm/drm_simple_kms_helper.h>
0025 
0026 #define DRIVER_NAME "simpledrm"
0027 #define DRIVER_DESC "DRM driver for simple-framebuffer platform devices"
0028 #define DRIVER_DATE "20200625"
0029 #define DRIVER_MAJOR    1
0030 #define DRIVER_MINOR    0
0031 
0032 /*
0033  * Assume a monitor resolution of 96 dpi to
0034  * get a somewhat reasonable screen size.
0035  */
0036 #define RES_MM(d)   \
0037     (((d) * 254ul) / (96ul * 10ul))
0038 
0039 #define SIMPLEDRM_MODE(hd, vd)  \
0040     DRM_SIMPLE_MODE(hd, vd, RES_MM(hd), RES_MM(vd))
0041 
0042 /*
0043  * Helpers for simplefb
0044  */
0045 
0046 static int
0047 simplefb_get_validated_int(struct drm_device *dev, const char *name,
0048                uint32_t value)
0049 {
0050     if (value > INT_MAX) {
0051         drm_err(dev, "simplefb: invalid framebuffer %s of %u\n",
0052             name, value);
0053         return -EINVAL;
0054     }
0055     return (int)value;
0056 }
0057 
0058 static int
0059 simplefb_get_validated_int0(struct drm_device *dev, const char *name,
0060                 uint32_t value)
0061 {
0062     if (!value) {
0063         drm_err(dev, "simplefb: invalid framebuffer %s of %u\n",
0064             name, value);
0065         return -EINVAL;
0066     }
0067     return simplefb_get_validated_int(dev, name, value);
0068 }
0069 
0070 static const struct drm_format_info *
0071 simplefb_get_validated_format(struct drm_device *dev, const char *format_name)
0072 {
0073     static const struct simplefb_format formats[] = SIMPLEFB_FORMATS;
0074     const struct simplefb_format *fmt = formats;
0075     const struct simplefb_format *end = fmt + ARRAY_SIZE(formats);
0076     const struct drm_format_info *info;
0077 
0078     if (!format_name) {
0079         drm_err(dev, "simplefb: missing framebuffer format\n");
0080         return ERR_PTR(-EINVAL);
0081     }
0082 
0083     while (fmt < end) {
0084         if (!strcmp(format_name, fmt->name)) {
0085             info = drm_format_info(fmt->fourcc);
0086             if (!info)
0087                 return ERR_PTR(-EINVAL);
0088             return info;
0089         }
0090         ++fmt;
0091     }
0092 
0093     drm_err(dev, "simplefb: unknown framebuffer format %s\n",
0094         format_name);
0095 
0096     return ERR_PTR(-EINVAL);
0097 }
0098 
0099 static int
0100 simplefb_get_width_pd(struct drm_device *dev,
0101               const struct simplefb_platform_data *pd)
0102 {
0103     return simplefb_get_validated_int0(dev, "width", pd->width);
0104 }
0105 
0106 static int
0107 simplefb_get_height_pd(struct drm_device *dev,
0108                const struct simplefb_platform_data *pd)
0109 {
0110     return simplefb_get_validated_int0(dev, "height", pd->height);
0111 }
0112 
0113 static int
0114 simplefb_get_stride_pd(struct drm_device *dev,
0115                const struct simplefb_platform_data *pd)
0116 {
0117     return simplefb_get_validated_int(dev, "stride", pd->stride);
0118 }
0119 
0120 static const struct drm_format_info *
0121 simplefb_get_format_pd(struct drm_device *dev,
0122                const struct simplefb_platform_data *pd)
0123 {
0124     return simplefb_get_validated_format(dev, pd->format);
0125 }
0126 
0127 static int
0128 simplefb_read_u32_of(struct drm_device *dev, struct device_node *of_node,
0129              const char *name, u32 *value)
0130 {
0131     int ret = of_property_read_u32(of_node, name, value);
0132 
0133     if (ret)
0134         drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n",
0135             name, ret);
0136     return ret;
0137 }
0138 
0139 static int
0140 simplefb_read_string_of(struct drm_device *dev, struct device_node *of_node,
0141             const char *name, const char **value)
0142 {
0143     int ret = of_property_read_string(of_node, name, value);
0144 
0145     if (ret)
0146         drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n",
0147             name, ret);
0148     return ret;
0149 }
0150 
0151 static int
0152 simplefb_get_width_of(struct drm_device *dev, struct device_node *of_node)
0153 {
0154     u32 width;
0155     int ret = simplefb_read_u32_of(dev, of_node, "width", &width);
0156 
0157     if (ret)
0158         return ret;
0159     return simplefb_get_validated_int0(dev, "width", width);
0160 }
0161 
0162 static int
0163 simplefb_get_height_of(struct drm_device *dev, struct device_node *of_node)
0164 {
0165     u32 height;
0166     int ret = simplefb_read_u32_of(dev, of_node, "height", &height);
0167 
0168     if (ret)
0169         return ret;
0170     return simplefb_get_validated_int0(dev, "height", height);
0171 }
0172 
0173 static int
0174 simplefb_get_stride_of(struct drm_device *dev, struct device_node *of_node)
0175 {
0176     u32 stride;
0177     int ret = simplefb_read_u32_of(dev, of_node, "stride", &stride);
0178 
0179     if (ret)
0180         return ret;
0181     return simplefb_get_validated_int(dev, "stride", stride);
0182 }
0183 
0184 static const struct drm_format_info *
0185 simplefb_get_format_of(struct drm_device *dev, struct device_node *of_node)
0186 {
0187     const char *format;
0188     int ret = simplefb_read_string_of(dev, of_node, "format", &format);
0189 
0190     if (ret)
0191         return ERR_PTR(ret);
0192     return simplefb_get_validated_format(dev, format);
0193 }
0194 
0195 /*
0196  * Simple Framebuffer device
0197  */
0198 
0199 struct simpledrm_device {
0200     struct drm_device dev;
0201     struct platform_device *pdev;
0202 
0203     /* clocks */
0204 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
0205     unsigned int clk_count;
0206     struct clk **clks;
0207 #endif
0208     /* regulators */
0209 #if defined CONFIG_OF && defined CONFIG_REGULATOR
0210     unsigned int regulator_count;
0211     struct regulator **regulators;
0212 #endif
0213 
0214     /* simplefb settings */
0215     struct drm_display_mode mode;
0216     const struct drm_format_info *format;
0217     unsigned int pitch;
0218 
0219     /* memory management */
0220     struct resource *mem;
0221     void __iomem *screen_base;
0222 
0223     /* modesetting */
0224     uint32_t formats[8];
0225     size_t nformats;
0226     struct drm_connector connector;
0227     struct drm_simple_display_pipe pipe;
0228 };
0229 
0230 static struct simpledrm_device *simpledrm_device_of_dev(struct drm_device *dev)
0231 {
0232     return container_of(dev, struct simpledrm_device, dev);
0233 }
0234 
0235 /*
0236  * Hardware
0237  */
0238 
0239 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
0240 /*
0241  * Clock handling code.
0242  *
0243  * Here we handle the clocks property of our "simple-framebuffer" dt node.
0244  * This is necessary so that we can make sure that any clocks needed by
0245  * the display engine that the bootloader set up for us (and for which it
0246  * provided a simplefb dt node), stay up, for the life of the simplefb
0247  * driver.
0248  *
0249  * When the driver unloads, we cleanly disable, and then release the clocks.
0250  *
0251  * We only complain about errors here, no action is taken as the most likely
0252  * error can only happen due to a mismatch between the bootloader which set
0253  * up simplefb, and the clock definitions in the device tree. Chances are
0254  * that there are no adverse effects, and if there are, a clean teardown of
0255  * the fb probe will not help us much either. So just complain and carry on,
0256  * and hope that the user actually gets a working fb at the end of things.
0257  */
0258 
0259 static void simpledrm_device_release_clocks(void *res)
0260 {
0261     struct simpledrm_device *sdev = simpledrm_device_of_dev(res);
0262     unsigned int i;
0263 
0264     for (i = 0; i < sdev->clk_count; ++i) {
0265         if (sdev->clks[i]) {
0266             clk_disable_unprepare(sdev->clks[i]);
0267             clk_put(sdev->clks[i]);
0268         }
0269     }
0270 }
0271 
0272 static int simpledrm_device_init_clocks(struct simpledrm_device *sdev)
0273 {
0274     struct drm_device *dev = &sdev->dev;
0275     struct platform_device *pdev = sdev->pdev;
0276     struct device_node *of_node = pdev->dev.of_node;
0277     struct clk *clock;
0278     unsigned int i;
0279     int ret;
0280 
0281     if (dev_get_platdata(&pdev->dev) || !of_node)
0282         return 0;
0283 
0284     sdev->clk_count = of_clk_get_parent_count(of_node);
0285     if (!sdev->clk_count)
0286         return 0;
0287 
0288     sdev->clks = drmm_kzalloc(dev, sdev->clk_count * sizeof(sdev->clks[0]),
0289                   GFP_KERNEL);
0290     if (!sdev->clks)
0291         return -ENOMEM;
0292 
0293     for (i = 0; i < sdev->clk_count; ++i) {
0294         clock = of_clk_get(of_node, i);
0295         if (IS_ERR(clock)) {
0296             ret = PTR_ERR(clock);
0297             if (ret == -EPROBE_DEFER)
0298                 goto err;
0299             drm_err(dev, "clock %u not found: %d\n", i, ret);
0300             continue;
0301         }
0302         ret = clk_prepare_enable(clock);
0303         if (ret) {
0304             drm_err(dev, "failed to enable clock %u: %d\n",
0305                 i, ret);
0306             clk_put(clock);
0307             continue;
0308         }
0309         sdev->clks[i] = clock;
0310     }
0311 
0312     return devm_add_action_or_reset(&pdev->dev,
0313                     simpledrm_device_release_clocks,
0314                     sdev);
0315 
0316 err:
0317     while (i) {
0318         --i;
0319         if (sdev->clks[i]) {
0320             clk_disable_unprepare(sdev->clks[i]);
0321             clk_put(sdev->clks[i]);
0322         }
0323     }
0324     return ret;
0325 }
0326 #else
0327 static int simpledrm_device_init_clocks(struct simpledrm_device *sdev)
0328 {
0329     return 0;
0330 }
0331 #endif
0332 
0333 #if defined CONFIG_OF && defined CONFIG_REGULATOR
0334 
0335 #define SUPPLY_SUFFIX "-supply"
0336 
0337 /*
0338  * Regulator handling code.
0339  *
0340  * Here we handle the num-supplies and vin*-supply properties of our
0341  * "simple-framebuffer" dt node. This is necessary so that we can make sure
0342  * that any regulators needed by the display hardware that the bootloader
0343  * set up for us (and for which it provided a simplefb dt node), stay up,
0344  * for the life of the simplefb driver.
0345  *
0346  * When the driver unloads, we cleanly disable, and then release the
0347  * regulators.
0348  *
0349  * We only complain about errors here, no action is taken as the most likely
0350  * error can only happen due to a mismatch between the bootloader which set
0351  * up simplefb, and the regulator definitions in the device tree. Chances are
0352  * that there are no adverse effects, and if there are, a clean teardown of
0353  * the fb probe will not help us much either. So just complain and carry on,
0354  * and hope that the user actually gets a working fb at the end of things.
0355  */
0356 
0357 static void simpledrm_device_release_regulators(void *res)
0358 {
0359     struct simpledrm_device *sdev = simpledrm_device_of_dev(res);
0360     unsigned int i;
0361 
0362     for (i = 0; i < sdev->regulator_count; ++i) {
0363         if (sdev->regulators[i]) {
0364             regulator_disable(sdev->regulators[i]);
0365             regulator_put(sdev->regulators[i]);
0366         }
0367     }
0368 }
0369 
0370 static int simpledrm_device_init_regulators(struct simpledrm_device *sdev)
0371 {
0372     struct drm_device *dev = &sdev->dev;
0373     struct platform_device *pdev = sdev->pdev;
0374     struct device_node *of_node = pdev->dev.of_node;
0375     struct property *prop;
0376     struct regulator *regulator;
0377     const char *p;
0378     unsigned int count = 0, i = 0;
0379     int ret;
0380 
0381     if (dev_get_platdata(&pdev->dev) || !of_node)
0382         return 0;
0383 
0384     /* Count the number of regulator supplies */
0385     for_each_property_of_node(of_node, prop) {
0386         p = strstr(prop->name, SUPPLY_SUFFIX);
0387         if (p && p != prop->name)
0388             ++count;
0389     }
0390 
0391     if (!count)
0392         return 0;
0393 
0394     sdev->regulators = drmm_kzalloc(dev,
0395                     count * sizeof(sdev->regulators[0]),
0396                     GFP_KERNEL);
0397     if (!sdev->regulators)
0398         return -ENOMEM;
0399 
0400     for_each_property_of_node(of_node, prop) {
0401         char name[32]; /* 32 is max size of property name */
0402         size_t len;
0403 
0404         p = strstr(prop->name, SUPPLY_SUFFIX);
0405         if (!p || p == prop->name)
0406             continue;
0407         len = strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1;
0408         strscpy(name, prop->name, min(sizeof(name), len));
0409 
0410         regulator = regulator_get_optional(&pdev->dev, name);
0411         if (IS_ERR(regulator)) {
0412             ret = PTR_ERR(regulator);
0413             if (ret == -EPROBE_DEFER)
0414                 goto err;
0415             drm_err(dev, "regulator %s not found: %d\n",
0416                 name, ret);
0417             continue;
0418         }
0419 
0420         ret = regulator_enable(regulator);
0421         if (ret) {
0422             drm_err(dev, "failed to enable regulator %u: %d\n",
0423                 i, ret);
0424             regulator_put(regulator);
0425             continue;
0426         }
0427 
0428         sdev->regulators[i++] = regulator;
0429     }
0430     sdev->regulator_count = i;
0431 
0432     return devm_add_action_or_reset(&pdev->dev,
0433                     simpledrm_device_release_regulators,
0434                     sdev);
0435 
0436 err:
0437     while (i) {
0438         --i;
0439         if (sdev->regulators[i]) {
0440             regulator_disable(sdev->regulators[i]);
0441             regulator_put(sdev->regulators[i]);
0442         }
0443     }
0444     return ret;
0445 }
0446 #else
0447 static int simpledrm_device_init_regulators(struct simpledrm_device *sdev)
0448 {
0449     return 0;
0450 }
0451 #endif
0452 
0453 /*
0454  *  Simplefb settings
0455  */
0456 
0457 static struct drm_display_mode simpledrm_mode(unsigned int width,
0458                           unsigned int height)
0459 {
0460     struct drm_display_mode mode = { SIMPLEDRM_MODE(width, height) };
0461 
0462     mode.clock = mode.hdisplay * mode.vdisplay * 60 / 1000 /* kHz */;
0463     drm_mode_set_name(&mode);
0464 
0465     return mode;
0466 }
0467 
0468 static int simpledrm_device_init_fb(struct simpledrm_device *sdev)
0469 {
0470     int width, height, stride;
0471     const struct drm_format_info *format;
0472     struct drm_device *dev = &sdev->dev;
0473     struct platform_device *pdev = sdev->pdev;
0474     const struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);
0475     struct device_node *of_node = pdev->dev.of_node;
0476 
0477     if (pd) {
0478         width = simplefb_get_width_pd(dev, pd);
0479         if (width < 0)
0480             return width;
0481         height = simplefb_get_height_pd(dev, pd);
0482         if (height < 0)
0483             return height;
0484         stride = simplefb_get_stride_pd(dev, pd);
0485         if (stride < 0)
0486             return stride;
0487         format = simplefb_get_format_pd(dev, pd);
0488         if (IS_ERR(format))
0489             return PTR_ERR(format);
0490     } else if (of_node) {
0491         width = simplefb_get_width_of(dev, of_node);
0492         if (width < 0)
0493             return width;
0494         height = simplefb_get_height_of(dev, of_node);
0495         if (height < 0)
0496             return height;
0497         stride = simplefb_get_stride_of(dev, of_node);
0498         if (stride < 0)
0499             return stride;
0500         format = simplefb_get_format_of(dev, of_node);
0501         if (IS_ERR(format))
0502             return PTR_ERR(format);
0503     } else {
0504         drm_err(dev, "no simplefb configuration found\n");
0505         return -ENODEV;
0506     }
0507 
0508     sdev->mode = simpledrm_mode(width, height);
0509     sdev->format = format;
0510     sdev->pitch = stride;
0511 
0512     drm_dbg_kms(dev, "display mode={" DRM_MODE_FMT "}\n",
0513             DRM_MODE_ARG(&sdev->mode));
0514     drm_dbg_kms(dev,
0515             "framebuffer format=%p4cc, size=%dx%d, stride=%d byte\n",
0516             &format->format, width, height, stride);
0517 
0518     return 0;
0519 }
0520 
0521 /*
0522  * Memory management
0523  */
0524 
0525 static int simpledrm_device_init_mm(struct simpledrm_device *sdev)
0526 {
0527     struct drm_device *dev = &sdev->dev;
0528     struct platform_device *pdev = sdev->pdev;
0529     struct resource *res, *mem;
0530     void __iomem *screen_base;
0531     int ret;
0532 
0533     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0534     if (!res)
0535         return -EINVAL;
0536 
0537     ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res));
0538     if (ret) {
0539         drm_err(dev, "could not acquire memory range %pr: error %d\n",
0540             res, ret);
0541         return ret;
0542     }
0543 
0544     mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
0545                       sdev->dev.driver->name);
0546     if (!mem) {
0547         /*
0548          * We cannot make this fatal. Sometimes this comes from magic
0549          * spaces our resource handlers simply don't know about. Use
0550          * the I/O-memory resource as-is and try to map that instead.
0551          */
0552         drm_warn(dev, "could not acquire memory region %pr\n", res);
0553         mem = res;
0554     }
0555 
0556     screen_base = devm_ioremap_wc(&pdev->dev, mem->start,
0557                       resource_size(mem));
0558     if (!screen_base)
0559         return -ENOMEM;
0560 
0561     sdev->mem = mem;
0562     sdev->screen_base = screen_base;
0563 
0564     return 0;
0565 }
0566 
0567 /*
0568  * Modesetting
0569  */
0570 
0571 /*
0572  * Support all formats of simplefb and maybe more; in order
0573  * of preference. The display's update function will do any
0574  * conversion necessary.
0575  *
0576  * TODO: Add blit helpers for remaining formats and uncomment
0577  *       constants.
0578  */
0579 static const uint32_t simpledrm_default_formats[] = {
0580     DRM_FORMAT_XRGB8888,
0581     DRM_FORMAT_ARGB8888,
0582     DRM_FORMAT_RGB565,
0583     //DRM_FORMAT_XRGB1555,
0584     //DRM_FORMAT_ARGB1555,
0585     DRM_FORMAT_RGB888,
0586     DRM_FORMAT_XRGB2101010,
0587     DRM_FORMAT_ARGB2101010,
0588 };
0589 
0590 static const uint64_t simpledrm_format_modifiers[] = {
0591     DRM_FORMAT_MOD_LINEAR,
0592     DRM_FORMAT_MOD_INVALID
0593 };
0594 
0595 static int simpledrm_connector_helper_get_modes(struct drm_connector *connector)
0596 {
0597     struct simpledrm_device *sdev = simpledrm_device_of_dev(connector->dev);
0598     struct drm_display_mode *mode;
0599 
0600     mode = drm_mode_duplicate(connector->dev, &sdev->mode);
0601     if (!mode)
0602         return 0;
0603 
0604     if (mode->name[0] == '\0')
0605         drm_mode_set_name(mode);
0606 
0607     mode->type |= DRM_MODE_TYPE_PREFERRED;
0608     drm_mode_probed_add(connector, mode);
0609 
0610     if (mode->width_mm)
0611         connector->display_info.width_mm = mode->width_mm;
0612     if (mode->height_mm)
0613         connector->display_info.height_mm = mode->height_mm;
0614 
0615     return 1;
0616 }
0617 
0618 static const struct drm_connector_helper_funcs simpledrm_connector_helper_funcs = {
0619     .get_modes = simpledrm_connector_helper_get_modes,
0620 };
0621 
0622 static const struct drm_connector_funcs simpledrm_connector_funcs = {
0623     .reset = drm_atomic_helper_connector_reset,
0624     .fill_modes = drm_helper_probe_single_connector_modes,
0625     .destroy = drm_connector_cleanup,
0626     .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0627     .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0628 };
0629 
0630 static enum drm_mode_status
0631 simpledrm_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
0632                     const struct drm_display_mode *mode)
0633 {
0634     struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
0635 
0636     if (mode->hdisplay != sdev->mode.hdisplay &&
0637         mode->vdisplay != sdev->mode.vdisplay)
0638         return MODE_ONE_SIZE;
0639     else if (mode->hdisplay != sdev->mode.hdisplay)
0640         return MODE_ONE_WIDTH;
0641     else if (mode->vdisplay != sdev->mode.vdisplay)
0642         return MODE_ONE_HEIGHT;
0643 
0644     return MODE_OK;
0645 }
0646 
0647 static void
0648 simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
0649                      struct drm_crtc_state *crtc_state,
0650                      struct drm_plane_state *plane_state)
0651 {
0652     struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
0653     struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
0654     struct drm_framebuffer *fb = plane_state->fb;
0655     void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */
0656     struct drm_device *dev = &sdev->dev;
0657     void __iomem *dst = sdev->screen_base;
0658     struct drm_rect src_clip, dst_clip;
0659     int idx;
0660 
0661     if (!fb)
0662         return;
0663 
0664     drm_rect_fp_to_int(&src_clip, &plane_state->src);
0665 
0666     dst_clip = plane_state->dst;
0667     if (!drm_rect_intersect(&dst_clip, &src_clip))
0668         return;
0669 
0670     if (!drm_dev_enter(dev, &idx))
0671         return;
0672 
0673     dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip);
0674     drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip);
0675 
0676     drm_dev_exit(idx);
0677 }
0678 
0679 static void
0680 simpledrm_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
0681 {
0682     struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
0683     struct drm_device *dev = &sdev->dev;
0684     int idx;
0685 
0686     if (!drm_dev_enter(dev, &idx))
0687         return;
0688 
0689     /* Clear screen to black if disabled */
0690     memset_io(sdev->screen_base, 0, sdev->pitch * sdev->mode.vdisplay);
0691 
0692     drm_dev_exit(idx);
0693 }
0694 
0695 static void
0696 simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
0697                      struct drm_plane_state *old_plane_state)
0698 {
0699     struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
0700     struct drm_plane_state *plane_state = pipe->plane.state;
0701     struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
0702     void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */
0703     struct drm_framebuffer *fb = plane_state->fb;
0704     struct drm_device *dev = &sdev->dev;
0705     void __iomem *dst = sdev->screen_base;
0706     struct drm_rect src_clip, dst_clip;
0707     int idx;
0708 
0709     if (!fb)
0710         return;
0711 
0712     if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &src_clip))
0713         return;
0714 
0715     dst_clip = plane_state->dst;
0716     if (!drm_rect_intersect(&dst_clip, &src_clip))
0717         return;
0718 
0719     if (!drm_dev_enter(dev, &idx))
0720         return;
0721 
0722     dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip);
0723     drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip);
0724 
0725     drm_dev_exit(idx);
0726 }
0727 
0728 static const struct drm_simple_display_pipe_funcs
0729 simpledrm_simple_display_pipe_funcs = {
0730     .mode_valid = simpledrm_simple_display_pipe_mode_valid,
0731     .enable = simpledrm_simple_display_pipe_enable,
0732     .disable = simpledrm_simple_display_pipe_disable,
0733     .update = simpledrm_simple_display_pipe_update,
0734     DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
0735 };
0736 
0737 static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = {
0738     .fb_create = drm_gem_fb_create_with_dirty,
0739     .atomic_check = drm_atomic_helper_check,
0740     .atomic_commit = drm_atomic_helper_commit,
0741 };
0742 
0743 static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev,
0744                         size_t *nformats_out)
0745 {
0746     struct drm_device *dev = &sdev->dev;
0747     size_t i;
0748 
0749     if (sdev->nformats)
0750         goto out; /* don't rebuild list on recurring calls */
0751 
0752     /* native format goes first */
0753     sdev->formats[0] = sdev->format->format;
0754     sdev->nformats = 1;
0755 
0756     /* default formats go second */
0757     for (i = 0; i < ARRAY_SIZE(simpledrm_default_formats); ++i) {
0758         if (simpledrm_default_formats[i] == sdev->format->format)
0759             continue; /* native format already went first */
0760         sdev->formats[sdev->nformats] = simpledrm_default_formats[i];
0761         sdev->nformats++;
0762     }
0763 
0764     /*
0765      * TODO: The simpledrm driver converts framebuffers to the native
0766      * format when copying them to device memory. If there are more
0767      * formats listed than supported by the driver, the native format
0768      * is not supported by the conversion helpers. Therefore *only*
0769      * support the native format and add a conversion helper ASAP.
0770      */
0771     if (drm_WARN_ONCE(dev, i != sdev->nformats,
0772               "format conversion helpers required for %p4cc",
0773               &sdev->format->format)) {
0774         sdev->nformats = 1;
0775     }
0776 
0777 out:
0778     *nformats_out = sdev->nformats;
0779     return sdev->formats;
0780 }
0781 
0782 static int simpledrm_device_init_modeset(struct simpledrm_device *sdev)
0783 {
0784     struct drm_device *dev = &sdev->dev;
0785     struct drm_display_mode *mode = &sdev->mode;
0786     struct drm_connector *connector = &sdev->connector;
0787     struct drm_simple_display_pipe *pipe = &sdev->pipe;
0788     unsigned long max_width, max_height;
0789     const uint32_t *formats;
0790     size_t nformats;
0791     int ret;
0792 
0793     ret = drmm_mode_config_init(dev);
0794     if (ret)
0795         return ret;
0796 
0797     max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH);
0798     max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT);
0799 
0800     dev->mode_config.min_width = mode->hdisplay;
0801     dev->mode_config.max_width = max_width;
0802     dev->mode_config.min_height = mode->vdisplay;
0803     dev->mode_config.max_height = max_height;
0804     dev->mode_config.preferred_depth = sdev->format->cpp[0] * 8;
0805     dev->mode_config.funcs = &simpledrm_mode_config_funcs;
0806 
0807     ret = drm_connector_init(dev, connector, &simpledrm_connector_funcs,
0808                  DRM_MODE_CONNECTOR_Unknown);
0809     if (ret)
0810         return ret;
0811     drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs);
0812     drm_connector_set_panel_orientation_with_quirk(connector,
0813                                DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
0814                                mode->hdisplay, mode->vdisplay);
0815 
0816     formats = simpledrm_device_formats(sdev, &nformats);
0817 
0818     ret = drm_simple_display_pipe_init(dev, pipe, &simpledrm_simple_display_pipe_funcs,
0819                        formats, nformats, simpledrm_format_modifiers,
0820                        connector);
0821     if (ret)
0822         return ret;
0823 
0824     drm_plane_enable_fb_damage_clips(&pipe->plane);
0825 
0826     drm_mode_config_reset(dev);
0827 
0828     return 0;
0829 }
0830 
0831 /*
0832  * Init / Cleanup
0833  */
0834 
0835 static struct simpledrm_device *
0836 simpledrm_device_create(struct drm_driver *drv, struct platform_device *pdev)
0837 {
0838     struct simpledrm_device *sdev;
0839     int ret;
0840 
0841     sdev = devm_drm_dev_alloc(&pdev->dev, drv, struct simpledrm_device,
0842                   dev);
0843     if (IS_ERR(sdev))
0844         return ERR_CAST(sdev);
0845     sdev->pdev = pdev;
0846     platform_set_drvdata(pdev, sdev);
0847 
0848     ret = simpledrm_device_init_clocks(sdev);
0849     if (ret)
0850         return ERR_PTR(ret);
0851     ret = simpledrm_device_init_regulators(sdev);
0852     if (ret)
0853         return ERR_PTR(ret);
0854     ret = simpledrm_device_init_fb(sdev);
0855     if (ret)
0856         return ERR_PTR(ret);
0857     ret = simpledrm_device_init_mm(sdev);
0858     if (ret)
0859         return ERR_PTR(ret);
0860     ret = simpledrm_device_init_modeset(sdev);
0861     if (ret)
0862         return ERR_PTR(ret);
0863 
0864     return sdev;
0865 }
0866 
0867 /*
0868  * DRM driver
0869  */
0870 
0871 DEFINE_DRM_GEM_FOPS(simpledrm_fops);
0872 
0873 static struct drm_driver simpledrm_driver = {
0874     DRM_GEM_SHMEM_DRIVER_OPS,
0875     .name           = DRIVER_NAME,
0876     .desc           = DRIVER_DESC,
0877     .date           = DRIVER_DATE,
0878     .major          = DRIVER_MAJOR,
0879     .minor          = DRIVER_MINOR,
0880     .driver_features    = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
0881     .fops           = &simpledrm_fops,
0882 };
0883 
0884 /*
0885  * Platform driver
0886  */
0887 
0888 static int simpledrm_probe(struct platform_device *pdev)
0889 {
0890     struct simpledrm_device *sdev;
0891     struct drm_device *dev;
0892     int ret;
0893 
0894     sdev = simpledrm_device_create(&simpledrm_driver, pdev);
0895     if (IS_ERR(sdev))
0896         return PTR_ERR(sdev);
0897     dev = &sdev->dev;
0898 
0899     ret = drm_dev_register(dev, 0);
0900     if (ret)
0901         return ret;
0902 
0903     drm_fbdev_generic_setup(dev, 0);
0904 
0905     return 0;
0906 }
0907 
0908 static int simpledrm_remove(struct platform_device *pdev)
0909 {
0910     struct simpledrm_device *sdev = platform_get_drvdata(pdev);
0911     struct drm_device *dev = &sdev->dev;
0912 
0913     drm_dev_unplug(dev);
0914 
0915     return 0;
0916 }
0917 
0918 static const struct of_device_id simpledrm_of_match_table[] = {
0919     { .compatible = "simple-framebuffer", },
0920     { },
0921 };
0922 MODULE_DEVICE_TABLE(of, simpledrm_of_match_table);
0923 
0924 static struct platform_driver simpledrm_platform_driver = {
0925     .driver = {
0926         .name = "simple-framebuffer", /* connect to sysfb */
0927         .of_match_table = simpledrm_of_match_table,
0928     },
0929     .probe = simpledrm_probe,
0930     .remove = simpledrm_remove,
0931 };
0932 
0933 module_platform_driver(simpledrm_platform_driver);
0934 
0935 MODULE_DESCRIPTION(DRIVER_DESC);
0936 MODULE_LICENSE("GPL v2");