Loading drivers/video/msm/mdss/mdss.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/types.h> #include <linux/types.h> #include <linux/workqueue.h> #include <linux/workqueue.h> #include <linux/irqreturn.h> #include <linux/irqreturn.h> #include <linux/irqdomain.h> #include <linux/mdss_io_util.h> #include <linux/mdss_io_util.h> #include <linux/msm-bus.h> #include <linux/msm-bus.h> Loading Loading @@ -128,6 +129,7 @@ enum mdss_hw_index { MDSS_HW_DSI1, MDSS_HW_DSI1, MDSS_HW_HDMI, MDSS_HW_HDMI, MDSS_HW_EDP, MDSS_HW_EDP, MDSS_HW_MISC, MDSS_MAX_HW_BLK MDSS_MAX_HW_BLK }; }; Loading Loading @@ -292,6 +294,7 @@ struct mdss_data_type { u32 default_ot_rd_limit; u32 default_ot_rd_limit; u32 default_ot_wr_limit; u32 default_ot_wr_limit; struct irq_domain *irq_domain; u32 mdp_irq_mask; u32 mdp_irq_mask; u32 mdp_hist_irq_mask; u32 mdp_hist_irq_mask; Loading drivers/video/msm/mdss/mdss_mdp.c +101 −4 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,8 @@ #include <linux/semaphore.h> #include <linux/semaphore.h> #include <linux/uaccess.h> #include <linux/uaccess.h> #include <linux/clk/msm-clk.h> #include <linux/clk/msm-clk.h> #include <linux/irqdomain.h> #include <linux/irq.h> #include <linux/msm-bus.h> #include <linux/msm-bus.h> #include <linux/msm-bus-board.h> #include <linux/msm-bus-board.h> Loading Loading @@ -108,6 +110,13 @@ struct mdss_hw mdss_mdp_hw = { .irq_handler = mdss_mdp_isr, .irq_handler = mdss_mdp_isr, }; }; /* define for h/w block with external driver */ struct mdss_hw mdss_misc_hw = { .hw_ndx = MDSS_HW_MISC, .ptr = NULL, .irq_handler = NULL, }; #define MDP_REG_BUS_VECTOR_ENTRY(ab_val, ib_val) \ #define MDP_REG_BUS_VECTOR_ENTRY(ab_val, ib_val) \ { \ { \ .src = MSM_BUS_MASTER_AMPSS_M0, \ .src = MSM_BUS_MASTER_AMPSS_M0, \ Loading Loading @@ -174,6 +183,62 @@ u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp) return xres * bpp; return xres * bpp; } } static void mdss_irq_mask(struct irq_data *data) { struct mdss_data_type *mdata = irq_data_get_irq_chip_data(data); unsigned long irq_flags; if (!mdata) return; pr_debug("irq_domain_mask %lu\n", data->hwirq); if (data->hwirq < 32) { spin_lock_irqsave(&mdp_lock, irq_flags); mdata->mdss_util->disable_irq(&mdss_misc_hw); spin_unlock_irqrestore(&mdp_lock, irq_flags); } } static void mdss_irq_unmask(struct irq_data *data) { struct mdss_data_type *mdata = irq_data_get_irq_chip_data(data); unsigned long irq_flags; if (!mdata) return; pr_debug("irq_domain_unmask %lu\n", data->hwirq); if (data->hwirq < 32) { spin_lock_irqsave(&mdp_lock, irq_flags); mdata->mdss_util->enable_irq(&mdss_misc_hw); spin_unlock_irqrestore(&mdp_lock, irq_flags); } } static struct irq_chip mdss_irq_chip = { .name = "mdss", .irq_mask = mdss_irq_mask, .irq_unmask = mdss_irq_unmask, }; static int mdss_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw) { struct mdss_data_type *mdata = d->host_data; /* check here if virq is a valid interrupt line */ irq_set_chip_and_handler(virq, &mdss_irq_chip, handle_level_irq); irq_set_chip_data(virq, mdata); set_irq_flags(virq, IRQF_VALID); return 0; } static struct irq_domain_ops mdss_irq_domain_ops = { .map = mdss_irq_domain_map, .xlate = irq_domain_xlate_onecell, }; static irqreturn_t mdss_irq_handler(int irq, void *ptr) static irqreturn_t mdss_irq_handler(int irq, void *ptr) { { struct mdss_data_type *mdata = ptr; struct mdss_data_type *mdata = ptr; Loading @@ -192,19 +257,37 @@ static irqreturn_t mdss_irq_handler(int irq, void *ptr) spin_lock(&mdp_lock); spin_lock(&mdp_lock); mdata->mdss_util->irq_dispatch(MDSS_HW_MDP, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_MDP, irq, ptr); spin_unlock(&mdp_lock); spin_unlock(&mdp_lock); intr &= ~MDSS_INTR_MDP; } } if (intr & MDSS_INTR_DSI0) if (intr & MDSS_INTR_DSI0) { mdata->mdss_util->irq_dispatch(MDSS_HW_DSI0, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_DSI0, irq, ptr); intr &= ~MDSS_INTR_DSI0; } if (intr & MDSS_INTR_DSI1) if (intr & MDSS_INTR_DSI1) { mdata->mdss_util->irq_dispatch(MDSS_HW_DSI1, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_DSI1, irq, ptr); intr &= ~MDSS_INTR_DSI1; } if (intr & MDSS_INTR_EDP) if (intr & MDSS_INTR_EDP) { mdata->mdss_util->irq_dispatch(MDSS_HW_EDP, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_EDP, irq, ptr); intr &= ~MDSS_INTR_EDP; } if (intr & MDSS_INTR_HDMI) if (intr & MDSS_INTR_HDMI) { mdata->mdss_util->irq_dispatch(MDSS_HW_HDMI, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_HDMI, irq, ptr); intr &= ~MDSS_INTR_HDMI; } /* route misc. interrupts to external drivers */ while (intr) { irq_hw_number_t hwirq = fls(intr) - 1; generic_handle_irq(irq_find_mapping( mdata->irq_domain, hwirq)); intr &= ~(1 << hwirq); } mdss_mdp_hw.irq_info->irq_buzy = false; mdss_mdp_hw.irq_info->irq_buzy = false; Loading Loading @@ -1959,6 +2042,20 @@ static int mdss_mdp_probe(struct platform_device *pdev) mdss_mdp_hw.irq_info->irq = res->start; mdss_mdp_hw.irq_info->irq = res->start; mdss_mdp_hw.ptr = mdata; mdss_mdp_hw.ptr = mdata; /* export misc. interrupts to external driver */ mdata->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 32, &mdss_irq_domain_ops, mdata); if (!mdata->irq_domain) { pr_err("unable to add linear domain\n"); rc = -ENOMEM; goto probe_done; } mdss_misc_hw.irq_info = mdss_intr_line(); rc = mdss_res->mdss_util->register_irq(&mdss_misc_hw); if (rc) pr_err("mdss_register_irq failed.\n"); /*populate hw iomem base info from device tree*/ /*populate hw iomem base info from device tree*/ rc = mdss_mdp_parse_dt(pdev); rc = mdss_mdp_parse_dt(pdev); if (rc) { if (rc) { Loading Loading
drivers/video/msm/mdss/mdss.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/types.h> #include <linux/types.h> #include <linux/workqueue.h> #include <linux/workqueue.h> #include <linux/irqreturn.h> #include <linux/irqreturn.h> #include <linux/irqdomain.h> #include <linux/mdss_io_util.h> #include <linux/mdss_io_util.h> #include <linux/msm-bus.h> #include <linux/msm-bus.h> Loading Loading @@ -128,6 +129,7 @@ enum mdss_hw_index { MDSS_HW_DSI1, MDSS_HW_DSI1, MDSS_HW_HDMI, MDSS_HW_HDMI, MDSS_HW_EDP, MDSS_HW_EDP, MDSS_HW_MISC, MDSS_MAX_HW_BLK MDSS_MAX_HW_BLK }; }; Loading Loading @@ -292,6 +294,7 @@ struct mdss_data_type { u32 default_ot_rd_limit; u32 default_ot_rd_limit; u32 default_ot_wr_limit; u32 default_ot_wr_limit; struct irq_domain *irq_domain; u32 mdp_irq_mask; u32 mdp_irq_mask; u32 mdp_hist_irq_mask; u32 mdp_hist_irq_mask; Loading
drivers/video/msm/mdss/mdss_mdp.c +101 −4 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,8 @@ #include <linux/semaphore.h> #include <linux/semaphore.h> #include <linux/uaccess.h> #include <linux/uaccess.h> #include <linux/clk/msm-clk.h> #include <linux/clk/msm-clk.h> #include <linux/irqdomain.h> #include <linux/irq.h> #include <linux/msm-bus.h> #include <linux/msm-bus.h> #include <linux/msm-bus-board.h> #include <linux/msm-bus-board.h> Loading Loading @@ -108,6 +110,13 @@ struct mdss_hw mdss_mdp_hw = { .irq_handler = mdss_mdp_isr, .irq_handler = mdss_mdp_isr, }; }; /* define for h/w block with external driver */ struct mdss_hw mdss_misc_hw = { .hw_ndx = MDSS_HW_MISC, .ptr = NULL, .irq_handler = NULL, }; #define MDP_REG_BUS_VECTOR_ENTRY(ab_val, ib_val) \ #define MDP_REG_BUS_VECTOR_ENTRY(ab_val, ib_val) \ { \ { \ .src = MSM_BUS_MASTER_AMPSS_M0, \ .src = MSM_BUS_MASTER_AMPSS_M0, \ Loading Loading @@ -174,6 +183,62 @@ u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp) return xres * bpp; return xres * bpp; } } static void mdss_irq_mask(struct irq_data *data) { struct mdss_data_type *mdata = irq_data_get_irq_chip_data(data); unsigned long irq_flags; if (!mdata) return; pr_debug("irq_domain_mask %lu\n", data->hwirq); if (data->hwirq < 32) { spin_lock_irqsave(&mdp_lock, irq_flags); mdata->mdss_util->disable_irq(&mdss_misc_hw); spin_unlock_irqrestore(&mdp_lock, irq_flags); } } static void mdss_irq_unmask(struct irq_data *data) { struct mdss_data_type *mdata = irq_data_get_irq_chip_data(data); unsigned long irq_flags; if (!mdata) return; pr_debug("irq_domain_unmask %lu\n", data->hwirq); if (data->hwirq < 32) { spin_lock_irqsave(&mdp_lock, irq_flags); mdata->mdss_util->enable_irq(&mdss_misc_hw); spin_unlock_irqrestore(&mdp_lock, irq_flags); } } static struct irq_chip mdss_irq_chip = { .name = "mdss", .irq_mask = mdss_irq_mask, .irq_unmask = mdss_irq_unmask, }; static int mdss_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw) { struct mdss_data_type *mdata = d->host_data; /* check here if virq is a valid interrupt line */ irq_set_chip_and_handler(virq, &mdss_irq_chip, handle_level_irq); irq_set_chip_data(virq, mdata); set_irq_flags(virq, IRQF_VALID); return 0; } static struct irq_domain_ops mdss_irq_domain_ops = { .map = mdss_irq_domain_map, .xlate = irq_domain_xlate_onecell, }; static irqreturn_t mdss_irq_handler(int irq, void *ptr) static irqreturn_t mdss_irq_handler(int irq, void *ptr) { { struct mdss_data_type *mdata = ptr; struct mdss_data_type *mdata = ptr; Loading @@ -192,19 +257,37 @@ static irqreturn_t mdss_irq_handler(int irq, void *ptr) spin_lock(&mdp_lock); spin_lock(&mdp_lock); mdata->mdss_util->irq_dispatch(MDSS_HW_MDP, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_MDP, irq, ptr); spin_unlock(&mdp_lock); spin_unlock(&mdp_lock); intr &= ~MDSS_INTR_MDP; } } if (intr & MDSS_INTR_DSI0) if (intr & MDSS_INTR_DSI0) { mdata->mdss_util->irq_dispatch(MDSS_HW_DSI0, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_DSI0, irq, ptr); intr &= ~MDSS_INTR_DSI0; } if (intr & MDSS_INTR_DSI1) if (intr & MDSS_INTR_DSI1) { mdata->mdss_util->irq_dispatch(MDSS_HW_DSI1, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_DSI1, irq, ptr); intr &= ~MDSS_INTR_DSI1; } if (intr & MDSS_INTR_EDP) if (intr & MDSS_INTR_EDP) { mdata->mdss_util->irq_dispatch(MDSS_HW_EDP, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_EDP, irq, ptr); intr &= ~MDSS_INTR_EDP; } if (intr & MDSS_INTR_HDMI) if (intr & MDSS_INTR_HDMI) { mdata->mdss_util->irq_dispatch(MDSS_HW_HDMI, irq, ptr); mdata->mdss_util->irq_dispatch(MDSS_HW_HDMI, irq, ptr); intr &= ~MDSS_INTR_HDMI; } /* route misc. interrupts to external drivers */ while (intr) { irq_hw_number_t hwirq = fls(intr) - 1; generic_handle_irq(irq_find_mapping( mdata->irq_domain, hwirq)); intr &= ~(1 << hwirq); } mdss_mdp_hw.irq_info->irq_buzy = false; mdss_mdp_hw.irq_info->irq_buzy = false; Loading Loading @@ -1959,6 +2042,20 @@ static int mdss_mdp_probe(struct platform_device *pdev) mdss_mdp_hw.irq_info->irq = res->start; mdss_mdp_hw.irq_info->irq = res->start; mdss_mdp_hw.ptr = mdata; mdss_mdp_hw.ptr = mdata; /* export misc. interrupts to external driver */ mdata->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 32, &mdss_irq_domain_ops, mdata); if (!mdata->irq_domain) { pr_err("unable to add linear domain\n"); rc = -ENOMEM; goto probe_done; } mdss_misc_hw.irq_info = mdss_intr_line(); rc = mdss_res->mdss_util->register_irq(&mdss_misc_hw); if (rc) pr_err("mdss_register_irq failed.\n"); /*populate hw iomem base info from device tree*/ /*populate hw iomem base info from device tree*/ rc = mdss_mdp_parse_dt(pdev); rc = mdss_mdp_parse_dt(pdev); if (rc) { if (rc) { Loading