There are certainly some improvements one could make, although I wouldn't call any of them simplifications. First, we can get rid of the Eq constraint, by using pattern matching instead:
f :: [[a]] -> [[a]]
f [] = [[]]
f x = x
Or we could get rid of it in another way, by using foldr:
f :: [[a]] -> [[a]]
f x = foldr (const (const x)) [[]] x
Now we don't actually need the input to be a list anymore. It could be anything Foldable, except that it has to be the same as the output type. But the only reason we need the output to be a list is so we can build a singleton out of it. So we don't really need to specialize to list after all - anything Applicative will do:
f :: (Foldable f, Applicative f) => f [a] -> f [a]
f x = foldr (const (const x)) (pure []) x
Finally we could try to generalize over the last [], to make this function applicable in the most places possible. Some obvious choices for [] are Monoid or Alternative - either of these have a concept of emptiness. I'd probably choose Monoid for being the simplest, yielding:
f :: (Foldable f, Applicative f, Monoid a) => f a -> f a
f x = foldr (const (const x)) (pure mempty) x
What does all this abstraction buy us? We can now do a similar operation with different data types. Suppose, for example, we arbitrarily choose f ~ Maybe and a ~ Ordering. Then our function acts like this (inlining definitions from the relevant typeclass instances):
f :: Maybe Ordering -> Maybe Ordering
f (Just result) = Just result
f Nothing = Just EQ
Kinda a weird function (it would be more natural to unwrap the Maybe than to put it in Just), but I'd argue no weirder than your original function (why is [[]] any better than [] anyway?).