0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/errno.h>
0016 #include <linux/fb.h>
0017 #include <linux/io.h>
0018 #include <linux/module.h>
0019 #include <linux/platform_data/simplefb.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/clk.h>
0022 #include <linux/of.h>
0023 #include <linux/of_clk.h>
0024 #include <linux/of_platform.h>
0025 #include <linux/parser.h>
0026 #include <linux/regulator/consumer.h>
0027
0028 static const struct fb_fix_screeninfo simplefb_fix = {
0029 .id = "simple",
0030 .type = FB_TYPE_PACKED_PIXELS,
0031 .visual = FB_VISUAL_TRUECOLOR,
0032 .accel = FB_ACCEL_NONE,
0033 };
0034
0035 static const struct fb_var_screeninfo simplefb_var = {
0036 .height = -1,
0037 .width = -1,
0038 .activate = FB_ACTIVATE_NOW,
0039 .vmode = FB_VMODE_NONINTERLACED,
0040 };
0041
0042 #define PSEUDO_PALETTE_SIZE 16
0043
0044 static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
0045 u_int transp, struct fb_info *info)
0046 {
0047 u32 *pal = info->pseudo_palette;
0048 u32 cr = red >> (16 - info->var.red.length);
0049 u32 cg = green >> (16 - info->var.green.length);
0050 u32 cb = blue >> (16 - info->var.blue.length);
0051 u32 value;
0052
0053 if (regno >= PSEUDO_PALETTE_SIZE)
0054 return -EINVAL;
0055
0056 value = (cr << info->var.red.offset) |
0057 (cg << info->var.green.offset) |
0058 (cb << info->var.blue.offset);
0059 if (info->var.transp.length > 0) {
0060 u32 mask = (1 << info->var.transp.length) - 1;
0061 mask <<= info->var.transp.offset;
0062 value |= mask;
0063 }
0064 pal[regno] = value;
0065
0066 return 0;
0067 }
0068
0069 struct simplefb_par {
0070 u32 palette[PSEUDO_PALETTE_SIZE];
0071 struct resource *mem;
0072 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
0073 bool clks_enabled;
0074 unsigned int clk_count;
0075 struct clk **clks;
0076 #endif
0077 #if defined CONFIG_OF && defined CONFIG_REGULATOR
0078 bool regulators_enabled;
0079 u32 regulator_count;
0080 struct regulator **regulators;
0081 #endif
0082 };
0083
0084 static void simplefb_clocks_destroy(struct simplefb_par *par);
0085 static void simplefb_regulators_destroy(struct simplefb_par *par);
0086
0087
0088
0089
0090
0091 static void simplefb_destroy(struct fb_info *info)
0092 {
0093 struct simplefb_par *par = info->par;
0094 struct resource *mem = par->mem;
0095
0096 simplefb_regulators_destroy(info->par);
0097 simplefb_clocks_destroy(info->par);
0098 if (info->screen_base)
0099 iounmap(info->screen_base);
0100
0101 framebuffer_release(info);
0102
0103 if (mem)
0104 release_mem_region(mem->start, resource_size(mem));
0105 }
0106
0107 static const struct fb_ops simplefb_ops = {
0108 .owner = THIS_MODULE,
0109 .fb_destroy = simplefb_destroy,
0110 .fb_setcolreg = simplefb_setcolreg,
0111 .fb_fillrect = cfb_fillrect,
0112 .fb_copyarea = cfb_copyarea,
0113 .fb_imageblit = cfb_imageblit,
0114 };
0115
0116 static struct simplefb_format simplefb_formats[] = SIMPLEFB_FORMATS;
0117
0118 struct simplefb_params {
0119 u32 width;
0120 u32 height;
0121 u32 stride;
0122 struct simplefb_format *format;
0123 };
0124
0125 static int simplefb_parse_dt(struct platform_device *pdev,
0126 struct simplefb_params *params)
0127 {
0128 struct device_node *np = pdev->dev.of_node;
0129 int ret;
0130 const char *format;
0131 int i;
0132
0133 ret = of_property_read_u32(np, "width", ¶ms->width);
0134 if (ret) {
0135 dev_err(&pdev->dev, "Can't parse width property\n");
0136 return ret;
0137 }
0138
0139 ret = of_property_read_u32(np, "height", ¶ms->height);
0140 if (ret) {
0141 dev_err(&pdev->dev, "Can't parse height property\n");
0142 return ret;
0143 }
0144
0145 ret = of_property_read_u32(np, "stride", ¶ms->stride);
0146 if (ret) {
0147 dev_err(&pdev->dev, "Can't parse stride property\n");
0148 return ret;
0149 }
0150
0151 ret = of_property_read_string(np, "format", &format);
0152 if (ret) {
0153 dev_err(&pdev->dev, "Can't parse format property\n");
0154 return ret;
0155 }
0156 params->format = NULL;
0157 for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) {
0158 if (strcmp(format, simplefb_formats[i].name))
0159 continue;
0160 params->format = &simplefb_formats[i];
0161 break;
0162 }
0163 if (!params->format) {
0164 dev_err(&pdev->dev, "Invalid format value\n");
0165 return -EINVAL;
0166 }
0167
0168 return 0;
0169 }
0170
0171 static int simplefb_parse_pd(struct platform_device *pdev,
0172 struct simplefb_params *params)
0173 {
0174 struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);
0175 int i;
0176
0177 params->width = pd->width;
0178 params->height = pd->height;
0179 params->stride = pd->stride;
0180
0181 params->format = NULL;
0182 for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) {
0183 if (strcmp(pd->format, simplefb_formats[i].name))
0184 continue;
0185
0186 params->format = &simplefb_formats[i];
0187 break;
0188 }
0189
0190 if (!params->format) {
0191 dev_err(&pdev->dev, "Invalid format value\n");
0192 return -EINVAL;
0193 }
0194
0195 return 0;
0196 }
0197
0198 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 static int simplefb_clocks_get(struct simplefb_par *par,
0218 struct platform_device *pdev)
0219 {
0220 struct device_node *np = pdev->dev.of_node;
0221 struct clk *clock;
0222 int i;
0223
0224 if (dev_get_platdata(&pdev->dev) || !np)
0225 return 0;
0226
0227 par->clk_count = of_clk_get_parent_count(np);
0228 if (!par->clk_count)
0229 return 0;
0230
0231 par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL);
0232 if (!par->clks)
0233 return -ENOMEM;
0234
0235 for (i = 0; i < par->clk_count; i++) {
0236 clock = of_clk_get(np, i);
0237 if (IS_ERR(clock)) {
0238 if (PTR_ERR(clock) == -EPROBE_DEFER) {
0239 while (--i >= 0) {
0240 clk_put(par->clks[i]);
0241 }
0242 kfree(par->clks);
0243 return -EPROBE_DEFER;
0244 }
0245 dev_err(&pdev->dev, "%s: clock %d not found: %ld\n",
0246 __func__, i, PTR_ERR(clock));
0247 continue;
0248 }
0249 par->clks[i] = clock;
0250 }
0251
0252 return 0;
0253 }
0254
0255 static void simplefb_clocks_enable(struct simplefb_par *par,
0256 struct platform_device *pdev)
0257 {
0258 int i, ret;
0259
0260 for (i = 0; i < par->clk_count; i++) {
0261 if (par->clks[i]) {
0262 ret = clk_prepare_enable(par->clks[i]);
0263 if (ret) {
0264 dev_err(&pdev->dev,
0265 "%s: failed to enable clock %d: %d\n",
0266 __func__, i, ret);
0267 clk_put(par->clks[i]);
0268 par->clks[i] = NULL;
0269 }
0270 }
0271 }
0272 par->clks_enabled = true;
0273 }
0274
0275 static void simplefb_clocks_destroy(struct simplefb_par *par)
0276 {
0277 int i;
0278
0279 if (!par->clks)
0280 return;
0281
0282 for (i = 0; i < par->clk_count; i++) {
0283 if (par->clks[i]) {
0284 if (par->clks_enabled)
0285 clk_disable_unprepare(par->clks[i]);
0286 clk_put(par->clks[i]);
0287 }
0288 }
0289
0290 kfree(par->clks);
0291 }
0292 #else
0293 static int simplefb_clocks_get(struct simplefb_par *par,
0294 struct platform_device *pdev) { return 0; }
0295 static void simplefb_clocks_enable(struct simplefb_par *par,
0296 struct platform_device *pdev) { }
0297 static void simplefb_clocks_destroy(struct simplefb_par *par) { }
0298 #endif
0299
0300 #if defined CONFIG_OF && defined CONFIG_REGULATOR
0301
0302 #define SUPPLY_SUFFIX "-supply"
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 static int simplefb_regulators_get(struct simplefb_par *par,
0324 struct platform_device *pdev)
0325 {
0326 struct device_node *np = pdev->dev.of_node;
0327 struct property *prop;
0328 struct regulator *regulator;
0329 const char *p;
0330 int count = 0, i = 0;
0331
0332 if (dev_get_platdata(&pdev->dev) || !np)
0333 return 0;
0334
0335
0336 for_each_property_of_node(np, prop) {
0337 p = strstr(prop->name, SUPPLY_SUFFIX);
0338 if (p && p != prop->name)
0339 count++;
0340 }
0341
0342 if (!count)
0343 return 0;
0344
0345 par->regulators = devm_kcalloc(&pdev->dev, count,
0346 sizeof(struct regulator *), GFP_KERNEL);
0347 if (!par->regulators)
0348 return -ENOMEM;
0349
0350
0351 for_each_property_of_node(np, prop) {
0352 char name[32];
0353
0354 p = strstr(prop->name, SUPPLY_SUFFIX);
0355 if (!p || p == prop->name)
0356 continue;
0357
0358 strscpy(name, prop->name,
0359 strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1);
0360 regulator = devm_regulator_get_optional(&pdev->dev, name);
0361 if (IS_ERR(regulator)) {
0362 if (PTR_ERR(regulator) == -EPROBE_DEFER)
0363 return -EPROBE_DEFER;
0364 dev_err(&pdev->dev, "regulator %s not found: %ld\n",
0365 name, PTR_ERR(regulator));
0366 continue;
0367 }
0368 par->regulators[i++] = regulator;
0369 }
0370 par->regulator_count = i;
0371
0372 return 0;
0373 }
0374
0375 static void simplefb_regulators_enable(struct simplefb_par *par,
0376 struct platform_device *pdev)
0377 {
0378 int i, ret;
0379
0380
0381 for (i = 0; i < par->regulator_count; i++) {
0382 ret = regulator_enable(par->regulators[i]);
0383 if (ret) {
0384 dev_err(&pdev->dev,
0385 "failed to enable regulator %d: %d\n",
0386 i, ret);
0387 devm_regulator_put(par->regulators[i]);
0388 par->regulators[i] = NULL;
0389 }
0390 }
0391 par->regulators_enabled = true;
0392 }
0393
0394 static void simplefb_regulators_destroy(struct simplefb_par *par)
0395 {
0396 int i;
0397
0398 if (!par->regulators || !par->regulators_enabled)
0399 return;
0400
0401 for (i = 0; i < par->regulator_count; i++)
0402 if (par->regulators[i])
0403 regulator_disable(par->regulators[i]);
0404 }
0405 #else
0406 static int simplefb_regulators_get(struct simplefb_par *par,
0407 struct platform_device *pdev) { return 0; }
0408 static void simplefb_regulators_enable(struct simplefb_par *par,
0409 struct platform_device *pdev) { }
0410 static void simplefb_regulators_destroy(struct simplefb_par *par) { }
0411 #endif
0412
0413 static int simplefb_probe(struct platform_device *pdev)
0414 {
0415 int ret;
0416 struct simplefb_params params;
0417 struct fb_info *info;
0418 struct simplefb_par *par;
0419 struct resource *res, *mem;
0420
0421 if (fb_get_options("simplefb", NULL))
0422 return -ENODEV;
0423
0424 ret = -ENODEV;
0425 if (dev_get_platdata(&pdev->dev))
0426 ret = simplefb_parse_pd(pdev, ¶ms);
0427 else if (pdev->dev.of_node)
0428 ret = simplefb_parse_dt(pdev, ¶ms);
0429
0430 if (ret)
0431 return ret;
0432
0433 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0434 if (!res) {
0435 dev_err(&pdev->dev, "No memory resource\n");
0436 return -EINVAL;
0437 }
0438
0439 mem = request_mem_region(res->start, resource_size(res), "simplefb");
0440 if (!mem) {
0441
0442
0443
0444
0445
0446 dev_warn(&pdev->dev, "simplefb: cannot reserve video memory at %pR\n", res);
0447 mem = res;
0448 }
0449
0450 info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
0451 if (!info) {
0452 ret = -ENOMEM;
0453 goto error_release_mem_region;
0454 }
0455 platform_set_drvdata(pdev, info);
0456
0457 par = info->par;
0458
0459 info->fix = simplefb_fix;
0460 info->fix.smem_start = mem->start;
0461 info->fix.smem_len = resource_size(mem);
0462 info->fix.line_length = params.stride;
0463
0464 info->var = simplefb_var;
0465 info->var.xres = params.width;
0466 info->var.yres = params.height;
0467 info->var.xres_virtual = params.width;
0468 info->var.yres_virtual = params.height;
0469 info->var.bits_per_pixel = params.format->bits_per_pixel;
0470 info->var.red = params.format->red;
0471 info->var.green = params.format->green;
0472 info->var.blue = params.format->blue;
0473 info->var.transp = params.format->transp;
0474
0475 info->apertures = alloc_apertures(1);
0476 if (!info->apertures) {
0477 ret = -ENOMEM;
0478 goto error_fb_release;
0479 }
0480 info->apertures->ranges[0].base = info->fix.smem_start;
0481 info->apertures->ranges[0].size = info->fix.smem_len;
0482
0483 info->fbops = &simplefb_ops;
0484 info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE;
0485 info->screen_base = ioremap_wc(info->fix.smem_start,
0486 info->fix.smem_len);
0487 if (!info->screen_base) {
0488 ret = -ENOMEM;
0489 goto error_fb_release;
0490 }
0491 info->pseudo_palette = par->palette;
0492
0493 ret = simplefb_clocks_get(par, pdev);
0494 if (ret < 0)
0495 goto error_unmap;
0496
0497 ret = simplefb_regulators_get(par, pdev);
0498 if (ret < 0)
0499 goto error_clocks;
0500
0501 simplefb_clocks_enable(par, pdev);
0502 simplefb_regulators_enable(par, pdev);
0503
0504 dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes\n",
0505 info->fix.smem_start, info->fix.smem_len);
0506 dev_info(&pdev->dev, "format=%s, mode=%dx%dx%d, linelength=%d\n",
0507 params.format->name,
0508 info->var.xres, info->var.yres,
0509 info->var.bits_per_pixel, info->fix.line_length);
0510
0511 if (mem != res)
0512 par->mem = mem;
0513
0514 ret = register_framebuffer(info);
0515 if (ret < 0) {
0516 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
0517 goto error_regulators;
0518 }
0519
0520 dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
0521
0522 return 0;
0523
0524 error_regulators:
0525 simplefb_regulators_destroy(par);
0526 error_clocks:
0527 simplefb_clocks_destroy(par);
0528 error_unmap:
0529 iounmap(info->screen_base);
0530 error_fb_release:
0531 framebuffer_release(info);
0532 error_release_mem_region:
0533 if (mem != res)
0534 release_mem_region(mem->start, resource_size(mem));
0535 return ret;
0536 }
0537
0538 static int simplefb_remove(struct platform_device *pdev)
0539 {
0540 struct fb_info *info = platform_get_drvdata(pdev);
0541
0542
0543 unregister_framebuffer(info);
0544
0545 return 0;
0546 }
0547
0548 static const struct of_device_id simplefb_of_match[] = {
0549 { .compatible = "simple-framebuffer", },
0550 { },
0551 };
0552 MODULE_DEVICE_TABLE(of, simplefb_of_match);
0553
0554 static struct platform_driver simplefb_driver = {
0555 .driver = {
0556 .name = "simple-framebuffer",
0557 .of_match_table = simplefb_of_match,
0558 },
0559 .probe = simplefb_probe,
0560 .remove = simplefb_remove,
0561 };
0562
0563 module_platform_driver(simplefb_driver);
0564
0565 MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
0566 MODULE_DESCRIPTION("Simple framebuffer driver");
0567 MODULE_LICENSE("GPL v2");