linux/drivers/media/platform/mtk-vpu/mtk_vpu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3* Copyright (c) 2016 MediaTek Inc.
   4* Author: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
   5*/
   6#include <linux/clk.h>
   7#include <linux/debugfs.h>
   8#include <linux/firmware.h>
   9#include <linux/interrupt.h>
  10#include <linux/iommu.h>
  11#include <linux/module.h>
  12#include <linux/of_address.h>
  13#include <linux/of_irq.h>
  14#include <linux/of_platform.h>
  15#include <linux/of_reserved_mem.h>
  16#include <linux/sched.h>
  17#include <linux/sizes.h>
  18#include <linux/dma-mapping.h>
  19
  20#include "mtk_vpu.h"
  21
  22/**
  23 * VPU (video processor unit) is a tiny processor controlling video hardware
  24 * related to video codec, scaling and color format converting.
  25 * VPU interfaces with other blocks by share memory and interrupt.
  26 **/
  27
  28#define INIT_TIMEOUT_MS         2000U
  29#define IPI_TIMEOUT_MS          2000U
  30#define VPU_FW_VER_LEN          16
  31
  32/* maximum program/data TCM (Tightly-Coupled Memory) size */
  33#define VPU_PTCM_SIZE           (96 * SZ_1K)
  34#define VPU_DTCM_SIZE           (32 * SZ_1K)
  35/* the offset to get data tcm address */
  36#define VPU_DTCM_OFFSET         0x18000UL
  37/* daynamic allocated maximum extended memory size */
  38#define VPU_EXT_P_SIZE          SZ_1M
  39#define VPU_EXT_D_SIZE          SZ_4M
  40/* maximum binary firmware size */
  41#define VPU_P_FW_SIZE           (VPU_PTCM_SIZE + VPU_EXT_P_SIZE)
  42#define VPU_D_FW_SIZE           (VPU_DTCM_SIZE + VPU_EXT_D_SIZE)
  43/* the size of share buffer between Host and  VPU */
  44#define SHARE_BUF_SIZE          48
  45
  46/* binary firmware name */
  47#define VPU_P_FW                "vpu_p.bin"
  48#define VPU_D_FW                "vpu_d.bin"
  49#define VPU_P_FW_NEW            "mediatek/mt8173/vpu_p.bin"
  50#define VPU_D_FW_NEW            "mediatek/mt8173/vpu_d.bin"
  51
  52#define VPU_RESET               0x0
  53#define VPU_TCM_CFG             0x0008
  54#define VPU_PMEM_EXT0_ADDR      0x000C
  55#define VPU_PMEM_EXT1_ADDR      0x0010
  56#define VPU_TO_HOST             0x001C
  57#define VPU_DMEM_EXT0_ADDR      0x0014
  58#define VPU_DMEM_EXT1_ADDR      0x0018
  59#define HOST_TO_VPU             0x0024
  60#define VPU_PC_REG              0x0060
  61#define VPU_WDT_REG             0x0084
  62
  63/* vpu inter-processor communication interrupt */
  64#define VPU_IPC_INT             BIT(8)
  65
  66/**
  67 * enum vpu_fw_type - VPU firmware type
  68 *
  69 * @P_FW: program firmware
  70 * @D_FW: data firmware
  71 *
  72 */
  73enum vpu_fw_type {
  74        P_FW,
  75        D_FW,
  76};
  77
  78/**
  79 * struct vpu_mem - VPU extended program/data memory information
  80 *
  81 * @va:         the kernel virtual memory address of VPU extended memory
  82 * @pa:         the physical memory address of VPU extended memory
  83 *
  84 */
  85struct vpu_mem {
  86        void *va;
  87        dma_addr_t pa;
  88};
  89
  90/**
  91 * struct vpu_regs - VPU TCM and configuration registers
  92 *
  93 * @tcm:        the register for VPU Tightly-Coupled Memory
  94 * @cfg:        the register for VPU configuration
  95 * @irq:        the irq number for VPU interrupt
  96 */
  97struct vpu_regs {
  98        void __iomem *tcm;
  99        void __iomem *cfg;
 100        int irq;
 101};
 102
 103/**
 104 * struct vpu_wdt_handler - VPU watchdog reset handler
 105 *
 106 * @reset_func: reset handler
 107 * @priv:       private data
 108 */
 109struct vpu_wdt_handler {
 110        void (*reset_func)(void *);
 111        void *priv;
 112};
 113
 114/**
 115 * struct vpu_wdt - VPU watchdog workqueue
 116 *
 117 * @handler:    VPU watchdog reset handler
 118 * @ws:         workstruct for VPU watchdog
 119 * @wq:         workqueue for VPU watchdog
 120 */
 121struct vpu_wdt {
 122        struct vpu_wdt_handler handler[VPU_RST_MAX];
 123        struct work_struct ws;
 124        struct workqueue_struct *wq;
 125};
 126
 127/**
 128 * struct vpu_run - VPU initialization status
 129 *
 130 * @signaled:           the signal of vpu initialization completed
 131 * @fw_ver:             VPU firmware version
 132 * @dec_capability:     decoder capability which is not used for now and
 133 *                      the value is reserved for future use
 134 * @enc_capability:     encoder capability which is not used for now and
 135 *                      the value is reserved for future use
 136 * @wq:                 wait queue for VPU initialization status
 137 */
 138struct vpu_run {
 139        u32 signaled;
 140        char fw_ver[VPU_FW_VER_LEN];
 141        unsigned int    dec_capability;
 142        unsigned int    enc_capability;
 143        wait_queue_head_t wq;
 144};
 145
 146/**
 147 * struct vpu_ipi_desc - VPU IPI descriptor
 148 *
 149 * @handler:    IPI handler
 150 * @name:       the name of IPI handler
 151 * @priv:       the private data of IPI handler
 152 */
 153struct vpu_ipi_desc {
 154        ipi_handler_t handler;
 155        const char *name;
 156        void *priv;
 157};
 158
 159/**
 160 * struct share_obj - DTCM (Data Tightly-Coupled Memory) buffer shared with
 161 *                    AP and VPU
 162 *
 163 * @id:         IPI id
 164 * @len:        share buffer length
 165 * @share_buf:  share buffer data
 166 */
 167struct share_obj {
 168        s32 id;
 169        u32 len;
 170        unsigned char share_buf[SHARE_BUF_SIZE];
 171};
 172
 173/**
 174 * struct mtk_vpu - vpu driver data
 175 * @extmem:             VPU extended memory information
 176 * @reg:                VPU TCM and configuration registers
 177 * @run:                VPU initialization status
 178 * @wdt:                VPU watchdog workqueue
 179 * @ipi_desc:           VPU IPI descriptor
 180 * @recv_buf:           VPU DTCM share buffer for receiving. The
 181 *                      receive buffer is only accessed in interrupt context.
 182 * @send_buf:           VPU DTCM share buffer for sending
 183 * @dev:                VPU struct device
 184 * @clk:                VPU clock on/off
 185 * @fw_loaded:          indicate VPU firmware loaded
 186 * @enable_4GB:         VPU 4GB mode on/off
 187 * @vpu_mutex:          protect mtk_vpu (except recv_buf) and ensure only
 188 *                      one client to use VPU service at a time. For example,
 189 *                      suppose a client is using VPU to decode VP8.
 190 *                      If the other client wants to encode VP8,
 191 *                      it has to wait until VP8 decode completes.
 192 * @wdt_refcnt:         WDT reference count to make sure the watchdog can be
 193 *                      disabled if no other client is using VPU service
 194 * @ack_wq:             The wait queue for each codec and mdp. When sleeping
 195 *                      processes wake up, they will check the condition
 196 *                      "ipi_id_ack" to run the corresponding action or
 197 *                      go back to sleep.
 198 * @ipi_id_ack:         The ACKs for registered IPI function sending
 199 *                      interrupt to VPU
 200 *
 201 */
 202struct mtk_vpu {
 203        struct vpu_mem extmem[2];
 204        struct vpu_regs reg;
 205        struct vpu_run run;
 206        struct vpu_wdt wdt;
 207        struct vpu_ipi_desc ipi_desc[IPI_MAX];
 208        struct share_obj __iomem *recv_buf;
 209        struct share_obj __iomem *send_buf;
 210        struct device *dev;
 211        struct clk *clk;
 212        bool fw_loaded;
 213        bool enable_4GB;
 214        struct mutex vpu_mutex; /* for protecting vpu data data structure */
 215        u32 wdt_refcnt;
 216        wait_queue_head_t ack_wq;
 217        bool ipi_id_ack[IPI_MAX];
 218};
 219
 220static inline void vpu_cfg_writel(struct mtk_vpu *vpu, u32 val, u32 offset)
 221{
 222        writel(val, vpu->reg.cfg + offset);
 223}
 224
 225static inline u32 vpu_cfg_readl(struct mtk_vpu *vpu, u32 offset)
 226{
 227        return readl(vpu->reg.cfg + offset);
 228}
 229
 230static inline bool vpu_running(struct mtk_vpu *vpu)
 231{
 232        return vpu_cfg_readl(vpu, VPU_RESET) & BIT(0);
 233}
 234
 235static void vpu_clock_disable(struct mtk_vpu *vpu)
 236{
 237        /* Disable VPU watchdog */
 238        mutex_lock(&vpu->vpu_mutex);
 239        if (!--vpu->wdt_refcnt)
 240                vpu_cfg_writel(vpu,
 241                               vpu_cfg_readl(vpu, VPU_WDT_REG) & ~(1L << 31),
 242                               VPU_WDT_REG);
 243        mutex_unlock(&vpu->vpu_mutex);
 244
 245        clk_disable(vpu->clk);
 246}
 247
 248static int vpu_clock_enable(struct mtk_vpu *vpu)
 249{
 250        int ret;
 251
 252        ret = clk_enable(vpu->clk);
 253        if (ret)
 254                return ret;
 255        /* Enable VPU watchdog */
 256        mutex_lock(&vpu->vpu_mutex);
 257        if (!vpu->wdt_refcnt++)
 258                vpu_cfg_writel(vpu,
 259                               vpu_cfg_readl(vpu, VPU_WDT_REG) | (1L << 31),
 260                               VPU_WDT_REG);
 261        mutex_unlock(&vpu->vpu_mutex);
 262
 263        return ret;
 264}
 265
 266int vpu_ipi_register(struct platform_device *pdev,
 267                     enum ipi_id id, ipi_handler_t handler,
 268                     const char *name, void *priv)
 269{
 270        struct mtk_vpu *vpu = platform_get_drvdata(pdev);
 271        struct vpu_ipi_desc *ipi_desc;
 272
 273        if (!vpu) {
 274                dev_err(&pdev->dev, "vpu device in not ready\n");
 275                return -EPROBE_DEFER;
 276        }
 277
 278        if (id < IPI_MAX && handler) {
 279                ipi_desc = vpu->ipi_desc;
 280                ipi_desc[id].name = name;
 281                ipi_desc[id].handler = handler;
 282                ipi_desc[id].priv = priv;
 283                return 0;
 284        }
 285
 286        dev_err(&pdev->dev, "register vpu ipi id %d with invalid arguments\n",
 287                id);
 288        return -EINVAL;
 289}
 290EXPORT_SYMBOL_GPL(vpu_ipi_register);
 291
 292int vpu_ipi_send(struct platform_device *pdev,
 293                 enum ipi_id id, void *buf,
 294                 unsigned int len)
 295{
 296        struct mtk_vpu *vpu = platform_get_drvdata(pdev);
 297        struct share_obj __iomem *send_obj = vpu->send_buf;
 298        unsigned long timeout;
 299        int ret = 0;
 300
 301        if (id <= IPI_VPU_INIT || id >= IPI_MAX ||
 302            len > sizeof(send_obj->share_buf) || !buf) {
 303                dev_err(vpu->dev, "failed to send ipi message\n");
 304                return -EINVAL;
 305        }
 306
 307        ret = vpu_clock_enable(vpu);
 308        if (ret) {
 309                dev_err(vpu->dev, "failed to enable vpu clock\n");
 310                return ret;
 311        }
 312        if (!vpu_running(vpu)) {
 313                dev_err(vpu->dev, "vpu_ipi_send: VPU is not running\n");
 314                ret = -EINVAL;
 315                goto clock_disable;
 316        }
 317
 318        mutex_lock(&vpu->vpu_mutex);
 319
 320         /* Wait until VPU receives the last command */
 321        timeout = jiffies + msecs_to_jiffies(IPI_TIMEOUT_MS);
 322        do {
 323                if (time_after(jiffies, timeout)) {
 324                        dev_err(vpu->dev, "vpu_ipi_send: IPI timeout!\n");
 325                        ret = -EIO;
 326                        goto mut_unlock;
 327                }
 328        } while (vpu_cfg_readl(vpu, HOST_TO_VPU));
 329
 330        memcpy_toio(send_obj->share_buf, buf, len);
 331        writel(len, &send_obj->len);
 332        writel(id, &send_obj->id);
 333
 334        vpu->ipi_id_ack[id] = false;
 335        /* send the command to VPU */
 336        vpu_cfg_writel(vpu, 0x1, HOST_TO_VPU);
 337
 338        mutex_unlock(&vpu->vpu_mutex);
 339
 340        /* wait for VPU's ACK */
 341        timeout = msecs_to_jiffies(IPI_TIMEOUT_MS);
 342        ret = wait_event_timeout(vpu->ack_wq, vpu->ipi_id_ack[id], timeout);
 343        vpu->ipi_id_ack[id] = false;
 344        if (ret == 0) {
 345                dev_err(vpu->dev, "vpu ipi %d ack time out !", id);
 346                ret = -EIO;
 347                goto clock_disable;
 348        }
 349        vpu_clock_disable(vpu);
 350
 351        return 0;
 352
 353mut_unlock:
 354        mutex_unlock(&vpu->vpu_mutex);
 355clock_disable:
 356        vpu_clock_disable(vpu);
 357
 358        return ret;
 359}
 360EXPORT_SYMBOL_GPL(vpu_ipi_send);
 361
 362static void vpu_wdt_reset_func(struct work_struct *ws)
 363{
 364        struct vpu_wdt *wdt = container_of(ws, struct vpu_wdt, ws);
 365        struct mtk_vpu *vpu = container_of(wdt, struct mtk_vpu, wdt);
 366        struct vpu_wdt_handler *handler = wdt->handler;
 367        int index, ret;
 368
 369        dev_info(vpu->dev, "vpu reset\n");
 370        ret = vpu_clock_enable(vpu);
 371        if (ret) {
 372                dev_err(vpu->dev, "[VPU] wdt enables clock failed %d\n", ret);
 373                return;
 374        }
 375        mutex_lock(&vpu->vpu_mutex);
 376        vpu_cfg_writel(vpu, 0x0, VPU_RESET);
 377        vpu->fw_loaded = false;
 378        mutex_unlock(&vpu->vpu_mutex);
 379        vpu_clock_disable(vpu);
 380
 381        for (index = 0; index < VPU_RST_MAX; index++) {
 382                if (handler[index].reset_func) {
 383                        handler[index].reset_func(handler[index].priv);
 384                        dev_dbg(vpu->dev, "wdt handler func %d\n", index);
 385                }
 386        }
 387}
 388
 389int vpu_wdt_reg_handler(struct platform_device *pdev,
 390                        void wdt_reset(void *),
 391                        void *priv, enum rst_id id)
 392{
 393        struct mtk_vpu *vpu = platform_get_drvdata(pdev);
 394        struct vpu_wdt_handler *handler;
 395
 396        if (!vpu) {
 397                dev_err(&pdev->dev, "vpu device in not ready\n");
 398                return -EPROBE_DEFER;
 399        }
 400
 401        handler = vpu->wdt.handler;
 402
 403        if (id < VPU_RST_MAX && wdt_reset) {
 404                dev_dbg(vpu->dev, "wdt register id %d\n", id);
 405                mutex_lock(&vpu->vpu_mutex);
 406                handler[id].reset_func = wdt_reset;
 407                handler[id].priv = priv;
 408                mutex_unlock(&vpu->vpu_mutex);
 409                return 0;
 410        }
 411
 412        dev_err(vpu->dev, "register vpu wdt handler failed\n");
 413        return -EINVAL;
 414}
 415EXPORT_SYMBOL_GPL(vpu_wdt_reg_handler);
 416
 417unsigned int vpu_get_vdec_hw_capa(struct platform_device *pdev)
 418{
 419        struct mtk_vpu *vpu = platform_get_drvdata(pdev);
 420
 421        return vpu->run.dec_capability;
 422}
 423EXPORT_SYMBOL_GPL(vpu_get_vdec_hw_capa);
 424
 425unsigned int vpu_get_venc_hw_capa(struct platform_device *pdev)
 426{
 427        struct mtk_vpu *vpu = platform_get_drvdata(pdev);
 428
 429        return vpu->run.enc_capability;
 430}
 431EXPORT_SYMBOL_GPL(vpu_get_venc_hw_capa);
 432
 433void *vpu_mapping_dm_addr(struct platform_device *pdev,
 434                          u32 dtcm_dmem_addr)
 435{
 436        struct mtk_vpu *vpu = platform_get_drvdata(pdev);
 437
 438        if (!dtcm_dmem_addr ||
 439            (dtcm_dmem_addr > (VPU_DTCM_SIZE + VPU_EXT_D_SIZE))) {
 440                dev_err(vpu->dev, "invalid virtual data memory address\n");
 441                return ERR_PTR(-EINVAL);
 442        }
 443
 444        if (dtcm_dmem_addr < VPU_DTCM_SIZE)
 445                return (__force void *)(dtcm_dmem_addr + vpu->reg.tcm +
 446                                        VPU_DTCM_OFFSET);
 447
 448        return vpu->extmem[D_FW].va + (dtcm_dmem_addr - VPU_DTCM_SIZE);
 449}
 450EXPORT_SYMBOL_GPL(vpu_mapping_dm_addr);
 451
 452struct platform_device *vpu_get_plat_device(struct platform_device *pdev)
 453{
 454        struct device *dev = &pdev->dev;
 455        struct device_node *vpu_node;
 456        struct platform_device *vpu_pdev;
 457
 458        vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
 459        if (!vpu_node) {
 460                dev_err(dev, "can't get vpu node\n");
 461                return NULL;
 462        }
 463
 464        vpu_pdev = of_find_device_by_node(vpu_node);
 465        of_node_put(vpu_node);
 466        if (WARN_ON(!vpu_pdev)) {
 467                dev_err(dev, "vpu pdev failed\n");
 468                return NULL;
 469        }
 470
 471        return vpu_pdev;
 472}
 473EXPORT_SYMBOL_GPL(vpu_get_plat_device);
 474
 475/* load vpu program/data memory */
 476static int load_requested_vpu(struct mtk_vpu *vpu,
 477                              u8 fw_type)
 478{
 479        size_t tcm_size = fw_type ? VPU_DTCM_SIZE : VPU_PTCM_SIZE;
 480        size_t fw_size = fw_type ? VPU_D_FW_SIZE : VPU_P_FW_SIZE;
 481        char *fw_name = fw_type ? VPU_D_FW : VPU_P_FW;
 482        char *fw_new_name = fw_type ? VPU_D_FW_NEW : VPU_P_FW_NEW;
 483        const struct firmware *vpu_fw;
 484        size_t dl_size = 0;
 485        size_t extra_fw_size = 0;
 486        void *dest;
 487        int ret;
 488
 489        ret = request_firmware(&vpu_fw, fw_new_name, vpu->dev);
 490        if (ret < 0) {
 491                dev_info(vpu->dev, "Failed to load %s, %d, retry\n",
 492                         fw_new_name, ret);
 493
 494                ret = request_firmware(&vpu_fw, fw_name, vpu->dev);
 495                if (ret < 0) {
 496                        dev_err(vpu->dev, "Failed to load %s, %d\n", fw_name,
 497                                ret);
 498                        return ret;
 499                }
 500        }
 501        dl_size = vpu_fw->size;
 502        if (dl_size > fw_size) {
 503                dev_err(vpu->dev, "fw %s size %zu is abnormal\n", fw_name,
 504                        dl_size);
 505                release_firmware(vpu_fw);
 506                return  -EFBIG;
 507        }
 508        dev_dbg(vpu->dev, "Downloaded fw %s size: %zu.\n",
 509                fw_name,
 510                dl_size);
 511        /* reset VPU */
 512        vpu_cfg_writel(vpu, 0x0, VPU_RESET);
 513
 514        /* handle extended firmware size */
 515        if (dl_size > tcm_size) {
 516                dev_dbg(vpu->dev, "fw size %zu > limited fw size %zu\n",
 517                        dl_size, tcm_size);
 518                extra_fw_size = dl_size - tcm_size;
 519                dev_dbg(vpu->dev, "extra_fw_size %zu\n", extra_fw_size);
 520                dl_size = tcm_size;
 521        }
 522        dest = (__force void *)vpu->reg.tcm;
 523        if (fw_type == D_FW)
 524                dest += VPU_DTCM_OFFSET;
 525        memcpy(dest, vpu_fw->data, dl_size);
 526        /* download to extended memory if need */
 527        if (extra_fw_size > 0) {
 528                dest = vpu->extmem[fw_type].va;
 529                dev_dbg(vpu->dev, "download extended memory type %x\n",
 530                        fw_type);
 531                memcpy(dest, vpu_fw->data + tcm_size, extra_fw_size);
 532        }
 533
 534        release_firmware(vpu_fw);
 535
 536        return 0;
 537}
 538
 539int vpu_load_firmware(struct platform_device *pdev)
 540{
 541        struct mtk_vpu *vpu;
 542        struct device *dev = &pdev->dev;
 543        struct vpu_run *run;
 544        int ret;
 545
 546        if (!pdev) {
 547                dev_err(dev, "VPU platform device is invalid\n");
 548                return -EINVAL;
 549        }
 550
 551        vpu = platform_get_drvdata(pdev);
 552        run = &vpu->run;
 553
 554        mutex_lock(&vpu->vpu_mutex);
 555        if (vpu->fw_loaded) {
 556                mutex_unlock(&vpu->vpu_mutex);
 557                return 0;
 558        }
 559        mutex_unlock(&vpu->vpu_mutex);
 560
 561        ret = vpu_clock_enable(vpu);
 562        if (ret) {
 563                dev_err(dev, "enable clock failed %d\n", ret);
 564                return ret;
 565        }
 566
 567        mutex_lock(&vpu->vpu_mutex);
 568
 569        run->signaled = false;
 570        dev_dbg(vpu->dev, "firmware request\n");
 571        /* Downloading program firmware to device*/
 572        ret = load_requested_vpu(vpu, P_FW);
 573        if (ret < 0) {
 574                dev_err(dev, "Failed to request %s, %d\n", VPU_P_FW, ret);
 575                goto OUT_LOAD_FW;
 576        }
 577
 578        /* Downloading data firmware to device */
 579        ret = load_requested_vpu(vpu, D_FW);
 580        if (ret < 0) {
 581                dev_err(dev, "Failed to request %s, %d\n", VPU_D_FW, ret);
 582                goto OUT_LOAD_FW;
 583        }
 584
 585        vpu->fw_loaded = true;
 586        /* boot up vpu */
 587        vpu_cfg_writel(vpu, 0x1, VPU_RESET);
 588
 589        ret = wait_event_interruptible_timeout(run->wq,
 590                                               run->signaled,
 591                                               msecs_to_jiffies(INIT_TIMEOUT_MS)
 592                                               );
 593        if (ret == 0) {
 594                ret = -ETIME;
 595                dev_err(dev, "wait vpu initialization timeout!\n");
 596                goto OUT_LOAD_FW;
 597        } else if (-ERESTARTSYS == ret) {
 598                dev_err(dev, "wait vpu interrupted by a signal!\n");
 599                goto OUT_LOAD_FW;
 600        }
 601
 602        ret = 0;
 603        dev_info(dev, "vpu is ready. Fw version %s\n", run->fw_ver);
 604
 605OUT_LOAD_FW:
 606        mutex_unlock(&vpu->vpu_mutex);
 607        vpu_clock_disable(vpu);
 608
 609        return ret;
 610}
 611EXPORT_SYMBOL_GPL(vpu_load_firmware);
 612
 613static void vpu_init_ipi_handler(const void *data, unsigned int len, void *priv)
 614{
 615        struct mtk_vpu *vpu = priv;
 616        const struct vpu_run *run = data;
 617
 618        vpu->run.signaled = run->signaled;
 619        strscpy(vpu->run.fw_ver, run->fw_ver, sizeof(vpu->run.fw_ver));
 620        vpu->run.dec_capability = run->dec_capability;
 621        vpu->run.enc_capability = run->enc_capability;
 622        wake_up_interruptible(&vpu->run.wq);
 623}
 624
 625#ifdef CONFIG_DEBUG_FS
 626static ssize_t vpu_debug_read(struct file *file, char __user *user_buf,
 627                              size_t count, loff_t *ppos)
 628{
 629        char buf[256];
 630        unsigned int len;
 631        unsigned int running, pc, vpu_to_host, host_to_vpu, wdt;
 632        int ret;
 633        struct device *dev = file->private_data;
 634        struct mtk_vpu *vpu = dev_get_drvdata(dev);
 635
 636        ret = vpu_clock_enable(vpu);
 637        if (ret) {
 638                dev_err(vpu->dev, "[VPU] enable clock failed %d\n", ret);
 639                return 0;
 640        }
 641
 642        /* vpu register status */
 643        running = vpu_running(vpu);
 644        pc = vpu_cfg_readl(vpu, VPU_PC_REG);
 645        wdt = vpu_cfg_readl(vpu, VPU_WDT_REG);
 646        host_to_vpu = vpu_cfg_readl(vpu, HOST_TO_VPU);
 647        vpu_to_host = vpu_cfg_readl(vpu, VPU_TO_HOST);
 648        vpu_clock_disable(vpu);
 649
 650        if (running) {
 651                len = snprintf(buf, sizeof(buf), "VPU is running\n\n"
 652                "FW Version: %s\n"
 653                "PC: 0x%x\n"
 654                "WDT: 0x%x\n"
 655                "Host to VPU: 0x%x\n"
 656                "VPU to Host: 0x%x\n",
 657                vpu->run.fw_ver, pc, wdt,
 658                host_to_vpu, vpu_to_host);
 659        } else {
 660                len = snprintf(buf, sizeof(buf), "VPU not running\n");
 661        }
 662
 663        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 664}
 665
 666static const struct file_operations vpu_debug_fops = {
 667        .open = simple_open,
 668        .read = vpu_debug_read,
 669};
 670#endif /* CONFIG_DEBUG_FS */
 671
 672static void vpu_free_ext_mem(struct mtk_vpu *vpu, u8 fw_type)
 673{
 674        struct device *dev = vpu->dev;
 675        size_t fw_ext_size = fw_type ? VPU_EXT_D_SIZE : VPU_EXT_P_SIZE;
 676
 677        dma_free_coherent(dev, fw_ext_size, vpu->extmem[fw_type].va,
 678                          vpu->extmem[fw_type].pa);
 679}
 680
 681static int vpu_alloc_ext_mem(struct mtk_vpu *vpu, u32 fw_type)
 682{
 683        struct device *dev = vpu->dev;
 684        size_t fw_ext_size = fw_type ? VPU_EXT_D_SIZE : VPU_EXT_P_SIZE;
 685        u32 vpu_ext_mem0 = fw_type ? VPU_DMEM_EXT0_ADDR : VPU_PMEM_EXT0_ADDR;
 686        u32 vpu_ext_mem1 = fw_type ? VPU_DMEM_EXT1_ADDR : VPU_PMEM_EXT1_ADDR;
 687        u32 offset_4gb = vpu->enable_4GB ? 0x40000000 : 0;
 688
 689        vpu->extmem[fw_type].va = dma_alloc_coherent(dev,
 690                                               fw_ext_size,
 691                                               &vpu->extmem[fw_type].pa,
 692                                               GFP_KERNEL);
 693        if (!vpu->extmem[fw_type].va) {
 694                dev_err(dev, "Failed to allocate the extended program memory\n");
 695                return -ENOMEM;
 696        }
 697
 698        /* Disable extend0. Enable extend1 */
 699        vpu_cfg_writel(vpu, 0x1, vpu_ext_mem0);
 700        vpu_cfg_writel(vpu, (vpu->extmem[fw_type].pa & 0xFFFFF000) + offset_4gb,
 701                       vpu_ext_mem1);
 702
 703        dev_info(dev, "%s extend memory phy=0x%llx virt=0x%p\n",
 704                 fw_type ? "Data" : "Program",
 705                 (unsigned long long)vpu->extmem[fw_type].pa,
 706                 vpu->extmem[fw_type].va);
 707
 708        return 0;
 709}
 710
 711static void vpu_ipi_handler(struct mtk_vpu *vpu)
 712{
 713        struct share_obj __iomem *rcv_obj = vpu->recv_buf;
 714        struct vpu_ipi_desc *ipi_desc = vpu->ipi_desc;
 715        unsigned char data[SHARE_BUF_SIZE];
 716        s32 id = readl(&rcv_obj->id);
 717
 718        memcpy_fromio(data, rcv_obj->share_buf, sizeof(data));
 719        if (id < IPI_MAX && ipi_desc[id].handler) {
 720                ipi_desc[id].handler(data, readl(&rcv_obj->len),
 721                                     ipi_desc[id].priv);
 722                if (id > IPI_VPU_INIT) {
 723                        vpu->ipi_id_ack[id] = true;
 724                        wake_up(&vpu->ack_wq);
 725                }
 726        } else {
 727                dev_err(vpu->dev, "No such ipi id = %d\n", id);
 728        }
 729}
 730
 731static int vpu_ipi_init(struct mtk_vpu *vpu)
 732{
 733        /* Disable VPU to host interrupt */
 734        vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);
 735
 736        /* shared buffer initialization */
 737        vpu->recv_buf = vpu->reg.tcm + VPU_DTCM_OFFSET;
 738        vpu->send_buf = vpu->recv_buf + 1;
 739        memset_io(vpu->recv_buf, 0, sizeof(struct share_obj));
 740        memset_io(vpu->send_buf, 0, sizeof(struct share_obj));
 741
 742        return 0;
 743}
 744
 745static irqreturn_t vpu_irq_handler(int irq, void *priv)
 746{
 747        struct mtk_vpu *vpu = priv;
 748        u32 vpu_to_host;
 749        int ret;
 750
 751        /*
 752         * Clock should have been enabled already.
 753         * Enable again in case vpu_ipi_send times out
 754         * and has disabled the clock.
 755         */
 756        ret = clk_enable(vpu->clk);
 757        if (ret) {
 758                dev_err(vpu->dev, "[VPU] enable clock failed %d\n", ret);
 759                return IRQ_NONE;
 760        }
 761        vpu_to_host = vpu_cfg_readl(vpu, VPU_TO_HOST);
 762        if (vpu_to_host & VPU_IPC_INT) {
 763                vpu_ipi_handler(vpu);
 764        } else {
 765                dev_err(vpu->dev, "vpu watchdog timeout! 0x%x", vpu_to_host);
 766                queue_work(vpu->wdt.wq, &vpu->wdt.ws);
 767        }
 768
 769        /* VPU won't send another interrupt until we set VPU_TO_HOST to 0. */
 770        vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);
 771        clk_disable(vpu->clk);
 772
 773        return IRQ_HANDLED;
 774}
 775
 776#ifdef CONFIG_DEBUG_FS
 777static struct dentry *vpu_debugfs;
 778#endif
 779static int mtk_vpu_probe(struct platform_device *pdev)
 780{
 781        struct mtk_vpu *vpu;
 782        struct device *dev;
 783        struct resource *res;
 784        int ret = 0;
 785
 786        dev_dbg(&pdev->dev, "initialization\n");
 787
 788        dev = &pdev->dev;
 789        vpu = devm_kzalloc(dev, sizeof(*vpu), GFP_KERNEL);
 790        if (!vpu)
 791                return -ENOMEM;
 792
 793        vpu->dev = &pdev->dev;
 794        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcm");
 795        vpu->reg.tcm = devm_ioremap_resource(dev, res);
 796        if (IS_ERR((__force void *)vpu->reg.tcm))
 797                return PTR_ERR((__force void *)vpu->reg.tcm);
 798
 799        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_reg");
 800        vpu->reg.cfg = devm_ioremap_resource(dev, res);
 801        if (IS_ERR((__force void *)vpu->reg.cfg))
 802                return PTR_ERR((__force void *)vpu->reg.cfg);
 803
 804        /* Get VPU clock */
 805        vpu->clk = devm_clk_get(dev, "main");
 806        if (IS_ERR(vpu->clk)) {
 807                dev_err(dev, "get vpu clock failed\n");
 808                return PTR_ERR(vpu->clk);
 809        }
 810
 811        platform_set_drvdata(pdev, vpu);
 812
 813        ret = clk_prepare(vpu->clk);
 814        if (ret) {
 815                dev_err(dev, "prepare vpu clock failed\n");
 816                return ret;
 817        }
 818
 819        /* VPU watchdog */
 820        vpu->wdt.wq = create_singlethread_workqueue("vpu_wdt");
 821        if (!vpu->wdt.wq) {
 822                dev_err(dev, "initialize wdt workqueue failed\n");
 823                return -ENOMEM;
 824        }
 825        INIT_WORK(&vpu->wdt.ws, vpu_wdt_reset_func);
 826        mutex_init(&vpu->vpu_mutex);
 827
 828        ret = vpu_clock_enable(vpu);
 829        if (ret) {
 830                dev_err(dev, "enable vpu clock failed\n");
 831                goto workqueue_destroy;
 832        }
 833
 834        dev_dbg(dev, "vpu ipi init\n");
 835        ret = vpu_ipi_init(vpu);
 836        if (ret) {
 837                dev_err(dev, "Failed to init ipi\n");
 838                goto disable_vpu_clk;
 839        }
 840
 841        /* register vpu initialization IPI */
 842        ret = vpu_ipi_register(pdev, IPI_VPU_INIT, vpu_init_ipi_handler,
 843                               "vpu_init", vpu);
 844        if (ret) {
 845                dev_err(dev, "Failed to register IPI_VPU_INIT\n");
 846                goto vpu_mutex_destroy;
 847        }
 848
 849#ifdef CONFIG_DEBUG_FS
 850        vpu_debugfs = debugfs_create_file("mtk_vpu", S_IRUGO, NULL, (void *)dev,
 851                                          &vpu_debug_fops);
 852#endif
 853
 854        /* Set PTCM to 96K and DTCM to 32K */
 855        vpu_cfg_writel(vpu, 0x2, VPU_TCM_CFG);
 856
 857        vpu->enable_4GB = !!(totalram_pages() > (SZ_2G >> PAGE_SHIFT));
 858        dev_info(dev, "4GB mode %u\n", vpu->enable_4GB);
 859
 860        if (vpu->enable_4GB) {
 861                ret = of_reserved_mem_device_init(dev);
 862                if (ret)
 863                        dev_info(dev, "init reserved memory failed\n");
 864                        /* continue to use dynamic allocation if failed */
 865        }
 866
 867        ret = vpu_alloc_ext_mem(vpu, D_FW);
 868        if (ret) {
 869                dev_err(dev, "Allocate DM failed\n");
 870                goto remove_debugfs;
 871        }
 872
 873        ret = vpu_alloc_ext_mem(vpu, P_FW);
 874        if (ret) {
 875                dev_err(dev, "Allocate PM failed\n");
 876                goto free_d_mem;
 877        }
 878
 879        init_waitqueue_head(&vpu->run.wq);
 880        init_waitqueue_head(&vpu->ack_wq);
 881
 882        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 883        if (!res) {
 884                dev_err(dev, "get IRQ resource failed.\n");
 885                ret = -ENXIO;
 886                goto free_p_mem;
 887        }
 888        vpu->reg.irq = platform_get_irq(pdev, 0);
 889        ret = devm_request_irq(dev, vpu->reg.irq, vpu_irq_handler, 0,
 890                               pdev->name, vpu);
 891        if (ret) {
 892                dev_err(dev, "failed to request irq\n");
 893                goto free_p_mem;
 894        }
 895
 896        vpu_clock_disable(vpu);
 897        dev_dbg(dev, "initialization completed\n");
 898
 899        return 0;
 900
 901free_p_mem:
 902        vpu_free_ext_mem(vpu, P_FW);
 903free_d_mem:
 904        vpu_free_ext_mem(vpu, D_FW);
 905remove_debugfs:
 906        of_reserved_mem_device_release(dev);
 907#ifdef CONFIG_DEBUG_FS
 908        debugfs_remove(vpu_debugfs);
 909#endif
 910        memset(vpu->ipi_desc, 0, sizeof(struct vpu_ipi_desc) * IPI_MAX);
 911vpu_mutex_destroy:
 912        mutex_destroy(&vpu->vpu_mutex);
 913disable_vpu_clk:
 914        vpu_clock_disable(vpu);
 915workqueue_destroy:
 916        destroy_workqueue(vpu->wdt.wq);
 917
 918        return ret;
 919}
 920
 921static const struct of_device_id mtk_vpu_match[] = {
 922        {
 923                .compatible = "mediatek,mt8173-vpu",
 924        },
 925        {},
 926};
 927MODULE_DEVICE_TABLE(of, mtk_vpu_match);
 928
 929static int mtk_vpu_remove(struct platform_device *pdev)
 930{
 931        struct mtk_vpu *vpu = platform_get_drvdata(pdev);
 932
 933#ifdef CONFIG_DEBUG_FS
 934        debugfs_remove(vpu_debugfs);
 935#endif
 936        if (vpu->wdt.wq) {
 937                flush_workqueue(vpu->wdt.wq);
 938                destroy_workqueue(vpu->wdt.wq);
 939        }
 940        vpu_free_ext_mem(vpu, P_FW);
 941        vpu_free_ext_mem(vpu, D_FW);
 942        mutex_destroy(&vpu->vpu_mutex);
 943        clk_unprepare(vpu->clk);
 944
 945        return 0;
 946}
 947
 948static struct platform_driver mtk_vpu_driver = {
 949        .probe  = mtk_vpu_probe,
 950        .remove = mtk_vpu_remove,
 951        .driver = {
 952                .name   = "mtk_vpu",
 953                .of_match_table = mtk_vpu_match,
 954        },
 955};
 956
 957module_platform_driver(mtk_vpu_driver);
 958
 959MODULE_LICENSE("GPL v2");
 960MODULE_DESCRIPTION("Mediatek Video Processor Unit driver");
 961